-
-
Notifications
You must be signed in to change notification settings - Fork 563
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
Initialize and cache descriptors only once #1592
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1592 +/- ##
=======================================
Coverage 80.88% 80.88%
=======================================
Files 156 156
Lines 15254 15256 +2
Branches 3283 3283
=======================================
+ Hits 12338 12340 +2
Misses 2667 2667
Partials 249 249
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
@rytilahti something is wrong with the linting check, something about a username and gitlab??? |
@rytilahti ready to be reviewd/merged |
Co-authored-by: Teemu R. <tpr@iki.fi>
@rytilahti thanks for the review! |
Co-authored-by: Teemu R. <tpr@iki.fi>
@rytilahti thanks for the feedback! |
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.
Considering this is the main device class, please add some tests for the expected functionalities and this is then ready to be merged.
Needs to be rebased on top of the current master to fix the CI, see #1598 |
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.
Oops, I wrote some comments earlier but forgot to submit them, sorry for the delay.
@rytilahti I finnally got all tests working and fixed the looping issues with the info() call. |
@@ -185,7 +185,7 @@ def status(self) -> AirDehumidifierStatus: | |||
values = self.get_properties(properties, max_properties=1) | |||
|
|||
return AirDehumidifierStatus( | |||
defaultdict(lambda: None, zip(properties, values)), self.info() | |||
defaultdict(lambda: None, zip(properties, values)), self._fetch_info() |
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 wrong, the _fetch_info()
is device-class internals and should not be accessed by any other class.
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.
Well how do you then suggest to prevent the loop: status --> info --> _initialize_descriptors--> status --> etc.
I can just remove the info call, but I am not sure what will then break downstream.
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'm not sure what's the best approach right off the bat (especially as genericmiot constructs status containers dynamically), but for statically defined containers it would be enough to access the status container class without really initializing one, right?
In [5]: from miio.integrations.vacuum.roborock import VacuumStatus
In [6]: vars(VacuumStatus)
Out[6]:
mappingproxy({'__module__': 'miio.integrations.vacuum.roborock.vacuumcontainers',
<snip>
'_sensors': {'state_code': SensorDescriptor(id='VacuumStatus.state_code', type=<class 'int'>, name='State code', property='state_code', unit=None),
'state': SensorDescriptor(id='VacuumStatus.state', type=<class 'str'>, name='State', property='state', unit=None),
<snip>
'_settings': {'fanspeed': NumberSettingDescriptor(id='VacuumStatus.fanspeed', name='Fanspeed', property='fanspeed', unit='%', min_value=0, max_value=100, step=1, range_attribute=None, type=<SettingType.Number: 2>),
<snip>
Probably the simplest way to access the status container would be using the return type annotation like this:
_status_container = self_.status.__annotations__["return"]
Do you think that could work for the time being until we figure out a better solution for that?
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 just tried it, but that does not include the embeded sensors:
from miio import RoborockVacuum
r = RoborockVacuum(ip = "192.168.1.IP", token = "TokenTokenToken")
status = r.status.__annotations__["return"]
print(status.sensors(status))
That is missing the embeded sensors/settings....
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.
Ouch, that's indeed annoying... The real solution would be doing the "embedding" of status container classes outside of the status query (maybe inside __init__
), and performing the update on the container prior to returning it in status()
. This way:
- we can introspect the available information without performing any I/O.
- if some of the method calls required to embedded containers fail, we can remove those queries from future update cycles.
The question is how/where to do this sanely, I don't have an answer to that right now.
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 do see what you mean, and think it is a good path forward,
but I think at this point it gets a bit to complicated for me.
I think it would be more efficient if you would implement those changes.
Than we also do not need to have long wait times in between us working on it.
You could do one of the following:
- make the changes and push them to this branch.
- copy this code as a start, make your own branch with a new PR and close this one
- First merge this as a starting point and then make the changes later to get rid of the _fetch_info calls in device classes (can be added as a TO DO)
I will make some additional tests once the actual code is approved and we decided how to handle the info call. |
Closing due to merge conflicts, follow up PR is here: #1701 |
Add caching to the descriptors to prevent unnessesary IO.
Also needs to happen for action descriptors which are added in this PR: #1588 (which PR gets merged first does not matter).