Skip to content
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

Poll battery percentage remaining for sensors. #1171

Merged
merged 9 commits into from
Jan 26, 2019
Merged

Poll battery percentage remaining for sensors. #1171

merged 9 commits into from
Jan 26, 2019

Conversation

ebaauw
Copy link
Collaborator

@ebaauw ebaauw commented Jan 23, 2019

Poll battery percentage remaining (0x0001/0x0021) for /sensors resources The change is for the iCasa Pulse keypads, which don't offer attribute reporting, see #1124.

@manup, please review. This is working fine in my test network, but I worry about the potential performance implications, and battery usage implications for other devices, see #1124 (comment).

- Apply `config.offset` when updating `state.temperature` or `state.humidity`, see #1154;
- Also update etag and save to database when only `config.reachable`, `config.battery`, and/or `state.lastupdated` are updated;
- Issue event when `state.lastupdated` is updated to fire rules based on `state.lastupdated`.
For icasa keypads, see #1124
@manup
Copy link
Member

manup commented Jan 23, 2019

I think this is tricky to decide in the idle timer. Many devices sleep for a longer time, for example the Ikea switches mac polls only every 5 minutes.

Sending a zcl read attributes makes mostly sense when we can be sure the device is likely awake, otherwise the command gets lost within the next 7 seconds (mac transaction expired).

I would suggest two things:

  • On incoming commands like button press, check if reporting is working for devices which support it, and if needed bind and configure reporting. This is already done in the button event handler but might be reviewed and extended.
  • For devices which don't support reporting, like the iCasa, on a button event check if the value is fresh enough (as in your PR) and if not read it.

@ebaauw
Copy link
Collaborator Author

ebaauw commented Jan 23, 2019

Sending a zcl read attributes makes mostly sense when we can be sure the device is likely awake, otherwise the command gets lost within the next 7 seconds (mac transaction expired).

The way I understand the code (and what I observe), the idleTimerFired() only sets a flag (through sensorNode->enableRead()) that we want to read (or write) some attribute at the next convenient moment. The actual read (or write) happens in processZcLAttributes(), where we're sure we just received a message from the sensor. I remember (vaguely) using this mechanism for the Hue motion sensor config attributes, but it was already in place before that.

While idleTimerFired() sets the flag 300 seconds after the value was last updated, the Read Attributes command to the iCasa Pulse is issued only once every ~600 seconds, triggered by the switch querying the OTAU cluster of the coordinator.

I think this is tricky to decide in the idle timer.

My question is really about what logic to apply on setting the flag. It checks the timestamp of the cached ZCL value, so it will not be set if an attribute report was received recently.

@ebaauw ebaauw closed this Jan 23, 2019
@ebaauw ebaauw reopened this Jan 23, 2019
@ebaauw
Copy link
Collaborator Author

ebaauw commented Jan 25, 2019

To double-check, I changed the timing in idleTimerFired() to 1800, and surely, the battery is now polled less often. Now running with this setting in my production network. Fingers crossed...

Additional _Level Control_ attributes from ZCL spec.  Only my OSRAM Gardenspot seems to support these.
You can now PUT a light state with a body of e.g. `{"on": true, "ontime": ` _t_  }` to set a light on for _t_/10 seconds.  This generates the _On With Timed Off_ command.  Similar to `state.transitiontime`, `state.ontime` is write-only and not returned when GETting the light state.
Unchanged config attributes sometimes included in websocket notification when `webSocketNotifyAll` is false.
@ebaauw
Copy link
Collaborator Author

ebaauw commented Jan 25, 2019

Battery polling seems stable in production - I only see read attribute requests for the (non-Xiaomi) sensors that report battery at intervals > 30 minutes. No timeouts - they're issued only when the device is awake.

While the mechanism works, I'm still not happy setting the battery attribute reporting interval for the Hue motion sensor to 2 hrs to conserve battery, but then start polling every 30 minutes. Also, the default reporting interval for battery is 45 minutes. I would suggest to change the Hue motion sensor interval to 45 minutes as well (so deviating from the Hue bridge), and then setting the polling-when-awake interval to 1 hour. @manup, do you agree? The alternative would be to copy the sensor whitelist from bindings.cpp and set the polling-when-awake interval to match the reporting interval. While that seems functionally better, I really don't like the increased code complexity caused by yet another place where we whitelist models.

Found a nasty bug in web socket notifications for sensor config - been breaking my head around that one for quite a while.

@manup
Copy link
Member

manup commented Jan 25, 2019

I would prefer that devices which support reporting the battery 0x0021 attribute are excluded from polling. This can be checked in a generic way similar to https://github.com/dresden-elektronik/deconz-rest-plugin/blob/master/bindings.cpp#L1154

There is also Climax devices which have Power Configuration cluster but don't support the 0x0021 attribute and instead report only the Battery Alarm Mask attribute (0x0035). Some devices have Power Configuration cluster but might not respond to reading attributes after a button press (Trust, Paul Neuhaus, Osram?) this needs more testing with various devices to get a picture.

I'm very concerned about requests to sleeping devices which might bring back queue issues of the past. I'd like to introduce this carefully and enable it only for the iCase devices for now, since it seems to work well for them.

While the mechanism works, I'm still not happy setting the battery attribute reporting interval for the Hue motion sensor to 2 hrs to conserve battery, but then start polling every 30 minutes. Also, the default reporting interval for battery is 45 minutes. I would suggest to change the Hue motion sensor interval to 45 minutes as well (so deviating from the Hue bridge), and then setting the polling-when-awake interval to 1 hour.

I guess these intervals are very device specific; polling iCase switches shouldn't affect other devices.
Note that the configured reporting min and max times can be queried by ǸodeValue::minInterval and NodeValue::maxInterval in a generic way as it's done in the bindings.cpp file.

@ebaauw
Copy link
Collaborator Author

ebaauw commented Jan 25, 2019

I'm very concerned about requests to sleeping devices which might bring back queue issues of the past.

Yes, I share that concern. I don't oversee the full impact, and really appreciate your input.

polling iCase switches shouldn't affect other devices.

Fair point. I'll whitelist the iCasa Pulse keypads and only query the battery status for these, making sure we don't impact any other devices. When/if we'll find we need to do this for other devices, we can add them to the whitelist.

@manup
Copy link
Member

manup commented Jan 25, 2019

Fair point. I'll whitelist the iCasa Pulse keypads and only query the battery status for these, making sure we don't impact any other devices. When/if we'll find we need to do this for other devices, we can add them to the whitelist.

Agree, this should provide a smooth introduction, which can be extended over time.

@ebaauw
Copy link
Collaborator Author

ebaauw commented Jan 25, 2019

Should be good to go.

@manup manup merged commit b8e2014 into dresden-elektronik:master Jan 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants