-
-
Notifications
You must be signed in to change notification settings - Fork 28.8k
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 datetime platform for supported broadlink devices #115408
base: dev
Are you sure you want to change the base?
Add datetime platform for supported broadlink devices #115408
Conversation
Hey there @Danielhiversen, @felipediel, @L-I-Am, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
868a6f0
to
e6c8923
Compare
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.
In the tests, consider validating the parameters (hour, minute, day, etc) get passed to the device call correctly. May require mocking dt_util.now().
Also considered this but decided that the simple logic does not warrant such a complex test. |
e6c8923
to
53dba01
Compare
Thanks @eifinger! Have you thought about using a datetime entity to show/update the date/time? |
I thought about supplying a datetime to the service but could not think of a valid usecase why it would be different from Also nice idea to use a datetime entity for that 👍 |
For showing the current time of the device I would need to find out how it works. Moreover I wanted to stay simple. |
For future reference: https://github.com/mjg59/python-broadlink/blob/66744707f517593de8276ed550cecae31c204c57/broadlink/climate.py#L83-L109 |
Thanks @eifinger! Here's a datetime implementation for reference. It is straightforward, we basically need:
@property
def native_value(self) -> datetime | None:
"""Return the latest value."""
if (data := self._coordinator.data) is None:
return None
now = dt.now()
device_weekday = data["dayofweek"] - 1
this_weekday = now.weekday()
if device_weekday != this_weekday:
days_diff = this_weekday - device_weekday
if days_diff < 0:
days_diff += 7
now -= timedelta(days=days_diff)
return now.replace(
hour=data["hour"],
minute=data["min"],
second=data["sec"],
)
async def async_set_value(self, value: datetime) -> None:
"""Change the value."""
await self._device.async_request(
self._device.api.set_time,
hour=value.hour,
minute=value.minute,
second=value.second,
day=value.weekday() + 1,
) I don't see any practical scenarios beyond exposing the device date/time and adjusting it manually or through automations, but I would still prefer to use the native Home Assistant component. Leveraging native components offers several benefits, such as a user-friendly interface and the potential for services and automations to be reused seemlessly, without the user having to learn the verbatim of our integration. |
6394b4f
to
967d7c5
Compare
Removed the service and implemented the datetime platform instead. |
967d7c5
to
dd56179
Compare
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 great @eifinger! A few changes and we'll be all set 🚀
now = dt_util.now() | ||
device_weekday = data["dayofweek"] - 1 | ||
this_weekday = now.weekday() | ||
|
||
if device_weekday != this_weekday: | ||
days_diff = this_weekday - device_weekday | ||
if days_diff < 0: | ||
days_diff += 7 | ||
now -= timedelta(days=days_diff) | ||
|
||
self._attr_native_value = now.replace( | ||
hour=data["hour"], | ||
minute=data["min"], | ||
second=data["sec"], | ||
) |
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 move this block to _update_state(), checking if data is None before and returning in case it is.
second=value.second, | ||
day=value.weekday() + 1, | ||
) | ||
self._update_internal_state(value) |
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.
Here we can assign self._attr_native_value = value directly instead of calling this method.
self._attr_unique_id = f"{device.unique_id}-datetime" | ||
self._update_internal_state() | ||
|
||
def _update_internal_state(self, value: datetime | None = None) -> None: |
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.
Let's try to eliminate this function.
This comment was marked as outdated.
This comment was marked as outdated.
bb87925
to
8c2a957
Compare
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.
LGTM 👍🚀
8c2a957
to
68c760f
Compare
Proposed change
The Broadlink thermostat devices have a large time drift of up to several minutes per week. This platform allows to sync time to the device.
Especially after DST changes this saves users from having to walk to each device and click buttons.
As an example this can also be run with an automation every night.
Type of change
Additional information
Checklist
ruff format 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
.To help with the load of incoming pull requests: