-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sensor and camera support to SimpliSafe #40129
Conversation
@bachya could you please take a look at the above? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @nzapponi – thank you for your contribution.
I've left you some specific code review comments, but in general, this PR won't work in its current form. Multiple things going on:
First, because of the popularity of the request, a previous attempt to integrate SimpliSafe sensors was made in #30926. The primary comment to notice:
After running this for a bit, I’m not happy with the results. The extra hop introduced here - in which HASS talks to the SimpliSafe cloud, which talks to the base station - can be very laggy, especially during HASS startup. I don’t think that’s a particular good user experience, so I’m going to close this. Should SimpliSafe ever update their architecture to be more responsive to what we’d like to do, I will re-open.
Your PR uses the same polling mechanisms attempted there; since nothing has fundamentally changed, I'm not comfortable with the approach.
Second, this PR is much too large - you're attempting to add multiple platforms (sensors, cameras, etc.), all while modifying code that is already there. In general, PRs should focus on a single piece of functionality/change.
Lastly, you mention tests – in general, Home Assistant allows for ignoring device/service-specific code from test coverage (via .coveragerc
); in the case of this integration, I focus my non-HASS testing efforts in simplisafe-python
.
doorbells = [] | ||
for system in simplisafe.systems.values(): | ||
if ( | ||
"cameras" in system._location_info["system"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not be accessing a protected attribute here – this should be abstracted out in simplisafe-python
.
@callback | ||
def async_update_from_rest_api(self): | ||
"""Update the entity with the provided REST API data.""" | ||
self._is_on = self._sensor.triggered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only going to show as triggered every 30 seconds (i.e., each time the REST API polls).
def async_update_from_websocket_event(self, event): | ||
"""Update the entity with the provided websocket event data.""" | ||
if ( | ||
event.event_type == EVENT_MOTION_DETECTED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that other integrations surface events like this as entities, but we already have a way to detect (and run automation on) these events: https://www.home-assistant.io/integrations/simplisafe/#events – what does your implementation provide beyond the event architecture?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to surface this as a visible binary sensor in the UI, like other motion sensors. I've taken the implementation from similar sensors already implemented in HA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why is that UI needed (especially since we're manually flipping the sensor 10 seconds later)? The events provide the same mechanism, but in a more flexible way (which can create notifications, etc.).
@property | ||
def _video_url(self): | ||
"""Provide the video URL.""" | ||
return '{} -i "https://media.simplisafe.com/v1/{}/flv?x=1280&audioEncoding=AAC"'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be so explicit and should be abstracted away in simplisafe-python
. In addition, please see this ongoing simplisafe-python
issue re: camera support; the URL you use here isn't long-lived and has several other issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL is long lived, the auth token isn't. It works for the odd check of the camera. Yes, if you want to continuously stream for hours, then this is not a good implementation, but for the odd check for a few minutes it's absolutely fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's good to know. Nevertheless, HASS shouldn't be aware of these implementation details; they belong in simplisafe-python
.
@@ -38,6 +38,11 @@ def __init__(self, simplisafe, system, lock): | |||
for event_type in (EVENT_LOCK_LOCKED, EVENT_LOCK_UNLOCKED): | |||
self.websocket_events_to_listen_for.append(event_type) | |||
|
|||
@property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? The SimpliSafeEntity
class from which the SimpliSafeLock
class inherits already has a unique ID defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough
@@ -517,7 +529,7 @@ async def async_update(self): | |||
|
|||
async def update_system(system): | |||
"""Update a system.""" | |||
await system.update() | |||
await system.update(cached=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't do this – their API isn't structured to properly support that. See this attempt for more details: #30926
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? See my comment below - it runs fine on SimpliSafe 3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the thinking, but again, I don't see the value for door/window sensors that poll for state every 30 seconds; if someone opens/closes a door within that timeframe, HASS will never hear about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use case isn't just triggering something when a door/window sensor opens, but it is also to check the current state of the sensor, e.g. check if there are any open windows before leaving the house. There's still value in this use case, and it doesn't require real time sensor data.
Also, we can poll every 15 seconds without any issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hear you and can see the validity. Overall, I'm concerned that if tens/hundreds/more of HASS users start pinging SimpliSafe's cloud every 15 seconds in an un-cached way, we're going to get blocked off for good. That's definitely my own fear and not substantiated in any way. 😆
I'm definitely open to continuing the conversation, but at a minimum, I think the simplisafe-python
work mentioned throughout needs to be looked at before this PR can proceed. Feel free to start looking around and let me know of any questions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, let me rework some of these changes into simplisafe-python. I'm aware they're meant to be in there but I wanted to start by getting something functional up and running first.
I'll close this PR and will re-open a few smaller ones once simplisafe-python is updated.
): | ||
for cam in system._location_info["system"]["cameras"]: | ||
cameras.append(cam) | ||
if cam["model"] == "SS002": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this? Seems brittle to have it hardcoded here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how doorbells are differentiated vs standard cameras.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HASS shouldn't be aware of such details. This is better suited for simplisafe-python
.
Hi @bachya , As a SimpliSafe customer, I'd rather get something in Home Assistant, even if not perfect, than nothing at all and be forced to put two sensors on each door. We can caveat all this in user documentation, but honestly I don't see why we shouldn't be providing some basic functionality here. I agree with you re cameras - we should be moving some of that logic into simplisafe-python. |
Proposed change
This PR adds support to SimpliSafe sensors, cameras and doorbells. Cameras appear not to work with HomeKit bridge, whereas everything else looks good!
Type of change
Additional information
I also need some support in writing out some tests. I noticed that the SimpliSafe component generally does not have many tests except for
config_flow
, so there are quite a few that need to be written out.Checklist
black --fast homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
..coveragerc
.The integration reached or maintains the following Integration Quality Scale:
To help with the load of incoming pull requests: