-
Notifications
You must be signed in to change notification settings - Fork 466
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
fix: Don't emit events for bulbs known offline #931
Conversation
731e777
to
45c9aed
Compare
Minimum allowed coverage is Generated by 🐒 cobertura-action against 18aaccb |
Channel deleted. |
@@ -681,6 +687,7 @@ light_added = function(driver, device, parent_device_id, resource_id) | |||
|
|||
driver.light_id_to_device[device_light_resource_id] = device | |||
|
|||
device:set_field(Fields.IS_ONLINE, true) |
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.
Default to ONLINE if the bulb is added
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.
Bulbs still are added if they are offline, correct? I think we should not emit any events until we know a device is online. In this case we will do the refresh for the device and emit initial state making the ST platform think the device is online when its not.
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 thought it would be better to have the field follow the synthetic state we establish in added
to populate DW, and then let the SSE onopen code handle rectifying this.
EDIT I see where this falls down after thinking about it a little harder, but this would require more code changes to make sure we have some approximation of a synthetic event emit when the device finally comes online so that the presentation isn't messed up in the mobile app.
@@ -751,8 +758,10 @@ local function do_bridge_network_init(driver, device, bridge_url, api_key) | |||
if status.status == "connected" then | |||
child_device.log.trace("Marking Online after SSE Reconnect") | |||
child_device:online() | |||
child_device:set_field(Fields.IS_ONLINE, true) |
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 runs every time the SSE stream opens, so will run at driver start
@@ -55,12 +55,18 @@ local function emit_light_status_events(light_device, light) | |||
if light.status then | |||
if light.status == "connected" then | |||
light_device:online() | |||
light_device:set_field(Fields.IS_ONLINE, true) |
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 where the SSE event gets processed.
return | ||
end | ||
end | ||
|
||
if not light_device:get_field(Fields.IS_ONLINE) then |
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 would like to understand the consequences of the difference between
if not is_online
and
if is_online is 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.
I was actually debating on making this an explicit boolean check, so I'm glad you asked that question, cuz it's forcing me to think about it harder.
if not <val>
will also capture the nil
case, e.g., the value hasn't been set yet, e.g., we haven't had a status update for that bulb in any capacity. I figured it was good to treat that the same as the false case and so treat that bulb as offline. So if not <val>
will only happen if value is false
or nil
; true
or any other value will evaluate truthy.
if <val> == false
explicitly looks for that value being assigned false, meaning in the case that we don't know what's going on, this boolean check would fail and we'd continue on to emit events.
If anything, what we may want to do is make an explicit check against the value of true
, which is what I was going back and forth on. In other words:
if light_device:get_field(Fields.IS_ONLINE) ~= true then
return
end
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.
My commit fixed an onboarding issue I was having where a bulb was onboarded as online despite being offline. Another option we could do is scan connectivity every time after a bridge comes online, and then also do a scan 1 min or so after the bridge added event. This way we have responsive device health for children when bridge is naturally coming online/offline and also attempt to correct any offline devices that are marked online immediately post join due to the synthetic capability event emission.
-- Wait bit before doing querying to allow initial state for added devices to be reported | ||
-- Children will all remain offline for this amount of time when a bridge comes back online. | ||
-- Children will all be online for this amount of time when a bridge id first joined. | ||
cosock.socket.sleep(15) --TODO is this long enough for large hue setup initial onboarding to complete for all devices? |
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.
A delay is needed for the onboarding case where we do emit events for offline devices. Perhaps there is an event based solution to do this scan at the opportune time, but I struggled to find an event for "all devices added" during the onboarding of a hue setup.
Requires tracking some non-persistent state for devices.
b5c3b6e
to
11f470c
Compare
11f470c
to
18aaccb
Compare
Does this need its field set or does it not matter because its the bridge and not a light? https://github.com/SmartThingsCommunity/SmartThingsEdgeDrivers/pull/931/files#diff-01ac799356794c771516edfa70fbd5b602c9fa11a15603b8566c2bc245fd22d5R711 |
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.
Looks good to me, the only thing I can think of is that it would be nice if you could easily override the device table's online
and offline
methods so that they could do this without having to add it everywhere we set the device offline and online but I know that is difficult/not possible with the way device tables are setup.
Right now it only needs to be set on lights. |
Yeah I discovered this when I did the tracing to validate the changes in #926. I had to replicate the entire Longer term the solution is to make the logic a little more centralized, but I want to finish developing a testing strategy for LAN devices (even if we're not mocking the comms layer) before undertaking any large-scale refactors of these drivers. Or, alternatively, figuring out the underlying plumbing work needed to have |
Requires tracking some non-persistent state for devices.