-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
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
ReadYourMeter Pro integration #85986
Conversation
2fec62a
to
9a79b49
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.
Also tested locally with my meter (including changing the password to trigger reauth), great work!
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.
Please address these in a new PR.
return unload_ok | ||
|
||
|
||
class RymProDataUpdateCoordinator(DataUpdateCoordinator): |
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.
Coordinators should go into their own modules, in this case, move it into coordinator.py
.
self._reauth_entry, | ||
title=title, | ||
data=data, | ||
unique_id=info[CONF_UNIQUE_ID], |
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 can't change, right? Why is it updated?
As a matter of fact, what in this re-auth process guards that the right account is re-authed?
[ | ||
RymProSensor(coordinator, meter_id, meter["read"], config_entry.entry_id) | ||
for meter_id, meter in coordinator.data.items() | ||
] |
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.
async_add_entities
accepts a generator, you can remove the list comprehension here.
class RymProSensor(CoordinatorEntity[RymProDataUpdateCoordinator], SensorEntity): | ||
"""Sensor for RymPro meters.""" | ||
|
||
_attr_has_entity_name = 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 seems to be incorrect, as there are conditions not met for this to be set.
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.
Will change the name to sentence case. Other than that, is there any other condition that's not met?
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 about it as it seems.
"""Sensor for RymPro meters.""" | ||
|
||
_attr_has_entity_name = True | ||
_attr_name = "Last Read" |
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 must be following sentence case styling to be able to set has_entity_name
.
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.
Additionally, it is a bit of an odd name, it would suggest a date of when it was last read? But I guess it is water usage? Would that be a better name?
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 read here is in present tense, as in the meter read. Common usage, and how the service refers to it, but maybe total consumption
? As opposed to some periodic consumption (e.g. daily, monthly), which I plan on adding in future PRs.
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 don't describe entities on what they do.. we describe what they are/represent. They represent consumption or usage in this case.
"""Initialize sensor.""" | ||
super().__init__(coordinator) | ||
self._meter_id = meter_id | ||
self._entity_registry: er.EntityRegistry | 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.
This is unused?
@callback | ||
def _handle_coordinator_update(self) -> None: | ||
"""Handle updated data from the coordinator.""" | ||
self._attr_native_value = self.coordinator.data[self._meter_id]["read"] | ||
self.async_write_ha_state() |
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.
There is no need to handle it like this. The coordinator already has the data and there are no calculations involved here. Implement the native_value
property method instead.
assert result2["type"] == FlowResultType.FORM | ||
assert result2["errors"] == {"base": error} |
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 test is incomplete.
For example, if authentication is incorrect, a user can recover from it. Please make the test complete until the config entry is created (to ensure there are no side-effects from recovering from the error handling).
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.
Thanks @frenck!
I will address these in a new PR ASAP. Left some clarification comments/questions in the meantime.
class RymProSensor(CoordinatorEntity[RymProDataUpdateCoordinator], SensorEntity): | ||
"""Sensor for RymPro meters.""" | ||
|
||
_attr_has_entity_name = 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.
Will change the name to sentence case. Other than that, is there any other condition that's not met?
"""Sensor for RymPro meters.""" | ||
|
||
_attr_has_entity_name = True | ||
_attr_name = "Last Read" |
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 read here is in present tense, as in the meter read. Common usage, and how the service refers to it, but maybe total consumption
? As opposed to some periodic consumption (e.g. daily, monthly), which I plan on adding in future PRs.
except UnauthorizedError: | ||
try: | ||
token = await rympro.login(data[CONF_EMAIL], data[CONF_PASSWORD], "ha") | ||
hass.config_entries.async_update_entry( |
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.
Please only wrap the line that can raise in the try... except block. Move this line down.
Follow up PR: #86734 |
Proposed change
A new integration for the Read Your Meter Pro service, which monitors your water usage. Starting this with a single sensor reflecting the last read, and will follow up with additional sensors in the future.
Type of change
Additional information
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
.To help with the load of incoming pull requests: