Propper deep sleep support#39
Conversation
* port: deep sleep support from deep_sleep branch with tests * refactor: remove options flow, derive deep-sleep expiry from device config, rename to DeepSleepUploadQueue * refactor: rename per-device deep sleep item and add proactive expiry purge * Restrict deep sleep image queuing
|
I tried out this PR by linking it into an HA instance, and did the following:
I expected that last on to queue an image. When thats said. As I read the code, we're essentially starting a wait that will hold till the device comes up.. wouldn't it potentially be better to set the new image on a "pending image" entity, and persist it to storage. Then, when the device comes up and calls in, test if pending image is set, and push it immediately. This way, we don't rely on ha being up, we expose the fact something is queued, and we've prepared the image ahead of time, so the delay (dithering, rendering, ..) is as short as possible. See #20 for more info. |
|
@LordMike As far as I understand this PR relies on the display being properly configured for deep sleep and reporting this to HA with its config so turning it off manually will give you different results. (This comments is only about the testing method used not about the rest of your comment) |
|
I used the default E1002 config, which I can see has a deepsleep on battery configured for 1200s. With that said, I cannot seem to make it go to deepsleep, even on battery, I can send images to it at will. It is configured for deepsleep at least. |
|
My initial idea was as follows: If the device supports deep sleep (power.deep_sleep_time_seconds > 0), we attempt to send the image. If the upload fails, we keep the image in memory (not persisted across HA restarts) and retry sending it once the display becomes available again. The cached image has a TTL equal to deep_sleep_time_seconds * 1.1. If the device never comes back online and the TTL expires, the image is discarded. This part is already working and I've tested it on two displays: one battery-powered and one connected via USB. Both have deep sleep enabled. The remaining piece is proper support for deep sleep devices across Home Assistant restarts. Currently, if HA restarts while a device is sleeping, the device and all related entities become unavailable until the next wake-up. I've been looking at how Shelly handles battery-powered devices and I'm implementing RestoreSensor support to restore the last known state after a restart and keep the device visible while it's still within the expected deep sleep window. The implementation is mostly there, but I still need to finish it and do some additional testing before it's ready. Ideally, when we call upload, we should know if the device is online or in deep sleep and then try to upload directly to the device or store the image so we can upload it later when the device wakes up. |
|
Is it necessary to know if the device is online or sleep capable? If we really wanted to know (for correctness or to manage expectations), the various send-image service calls could have an option "allow_queueing: true|false", and if not set, its "true". |
|
@LordMike, not sure if we need that, but we need RestoreSensor to avoid device unavailability. |
* Handle 'none' sentinel in numeric service schema fields * Add regression tests for 'none' numeric schema inputs * Queue image upload on BLE timeout during deep sleep * Simplify deep-sleep queue logging * Add concise deep-sleep queue log details * Add deep-sleep startup fallback and wake-up logs * Handle deep-sleep support and runtime config sync * Tidy config sync logging formatting * Add deep-sleep runtime sync tests * Cover deep-sleep restart sync scenarios * Improve upload logging and queue replacement tests * Fix deep-sleep queued upload wake retry handling * Fix deep-sleep queue dropped on BLE cache expiry; add opendisplay mock stub and regression tests * fix: sanitize legacy OpenDisplay config entry data * add RestoreSensor * added extra sensors, fixed timeout calculation, tests.
This is WIP, I want to test it on my devices. I created this PR to get initial feedback.