# Websocket
`simplipy` provides a websocket that allows for near-real-time detection of certain
events from a user's SimpliSafe⢠system. This websocket can be accessed via the
`websocket` property of the {meth}`API ` object:
```python
api.websocket
# >>>
```
## Connecting
```python
await api.websocket.async_connect()
```
Then, once you are connected to the websocket, you can start listening for events:
```python
await api.websocket.async_listen()
```
## Disconnecting
```python
await api.websocket.async_disconnect()
```
## Responding to Events
Users respond to events by defining callbacks (synchronous functions _or_ coroutines).
The following events exist:
- `connect`: occurs when the websocket connection is established
- `disconnect`: occurs when the websocket connection is terminated
- `event`: occurs when any data is transmitted from the SimpliSafe⢠cloud
Note that you can register as many callbacks as you'd like.
### `connect`
```python
async def async_connect_handler():
await asyncio.sleep(1)
print("I connected to the websocket")
def connect_handler():
print("I connected to the websocket")
remove_1 = api.websocket.add_connect_callback(async_connect_handler)
remove_2 = api.websocket.add_connect_callback(connect_handler)
# remove_1 and remove_2 are functions that, when called, remove the callback.
```
### `disconnect`
```python
async def async_connect_handler():
await asyncio.sleep(1)
print("I disconnected from the websocket")
def connect_handler():
print("I disconnected from the websocket")
remove_1 = api.websocket.add_disconnect_callback(async_connect_handler)
remove_2 = api.websocket.add_disconnect_callback(connect_handler)
# remove_1 and remove_2 are functions that, when called, remove the callback.
```
### `event`
```python
async def async_connect_handler(event):
await asyncio.sleep(1)
print(f"I received a SimpliSafe⢠event: {event}")
def connect_handler():
print(f"I received a SimpliSafe⢠event: {event}")
remove_1 = api.websocket.add_event_callback(async_connect_handler)
remove_2 = api.websocket.add_event_callback(connect_handler)
# remove_1 and remove_2 are functions that, when called, remove the callback.
```
#### Response Format
The `event` argument provided to event callbacks is a
{meth}`simplipy.websocket.WebsocketEvent` object, which comes with several properties:
- `changed_by`: the PIN that caused the event (in the case of arming/disarming/etc.)
- `event_type`: the type of event (see below)
- `info`: a longer string describing the event
- `sensor_name`: the name of the entity that triggered the event
- `sensor_serial`: the serial number of the entity that triggered the event
- `sensor_type`: the type of the entity that triggered the event
- `system_id`: the SimpliSafe⢠system ID
- `timestamp`: the UTC timestamp that the event occurred
- `media_urls`: a dict containing media URLs if the `event_type` is "camera_motion_detected" (see below)
The `event_type` property will be one of the following values:
- `alarm_canceled`
- `alarm_triggered`
- `armed_away_by_keypad`
- `armed_away_by_remote`
- `armed_away`
- `armed_home`
- `automatic_test`
- `away_exit_delay_by_keypad`
- `away_exit_delay_by_remote`
- `camera_motion_detected`
- `connection_lost`
- `connection_restored`
- `disarmed_by_keypad`
- `disarmed_by_remote`
- `doorbell_detected`
- `entity_test`
- `entry_detected`
- `home_exit_delay`
- `lock_error`
- `lock_locked`
- `lock_unlocked`
- `motion_detected`
- `power_outage`
- `power_restored`
- `sensor_not_responding`
- `sensor_paired_and_named`
- `sensor_restored`
- `user_initiated_test`
If the `event_type` is `camera_motion_detected`, then the `event` attribute `media_urls`
will be a dictionary that looks like this:
```python
{
"image_url": "https://xxx.us-east-1.prd.cam.simplisafe.com/xxx",
"clip_url": "https://xxx.us-east-1.prd.cam.simplisafe.com/xxx",
}
```
The `image_url` is an absolute URL to a JPEG file. The `clip_url` is an absolute URL to
a short MPEG4 video clip. Both refer to the motion detected by the camera. You can
retrieve the raw bytes of the media files at these URLs with the following method:
```python
bytes = await api.async_media(url)
```
If the `event_type` is not `camera_motion_detected`, then `media_urls` will be set to None.
If you should come across an event type that the library does not know about (and see
a log message about it), please open an issue at
.