8000 Only query emeter on update if feature is supported by mfalzone · Pull Request #120 · python-kasa/python-kasa · GitHub
[go: up one dir, main page]

Skip to content

Only query emeter on update if feature is supported #120

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

Closed

Conversation

mfalzone
Copy link
@mfalzone mfalzone commented Dec 3, 2020

Starts to address #105 by splitting the get_sysinfo and emeter queries into two distinct API calls. As noted today by @dcmorton on #119, the underlying cause of the current request hanging is the combination of multiple queries in the same request. Making a second, standalone emeter request should always work, but since we can determine whether an emeter is present by checking the response from get_sysinfo, I figured let's just avoid the second call if it's not needed.

This PR is only designed to address points 2 and 3 of this comment from @rytilahti but I'd be interested in tackling the first point as time allows unless someone else gets there first.

Fixes #161

@mfalzone mfalzone force-pushed the conditional-emeter-check branch 2 times, most recently from 5ed3df8 to ea9e997 Compare December 3, 2020 05:14
@codecov-io
Copy link
codecov-io commented Dec 3, 2020

Codecov Report

Merging #120 (59a70af) into master (a926ff5) will increase coverage by 0.19%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #120      +/-   ##
==========================================
+ Coverage   73.02%   73.22%   +0.19%     
==========================================
  Files          10       10              
  Lines        1227     1236       +9     
  Branches      183      184       +1     
==========================================
+ Hits          896      905       +9     
  Misses        298      298              
  Partials       33       33              
Impacted Files Coverage Δ
kasa/smartdevice.py 83.18% <100.00%> (+0.45%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a926ff5...59a70af. Read the comment docs.

@mfalzone mfalzone force-pushed the conditional-emeter-check branch from ea9e997 to 7d14530 Compare December 4, 2020 14:17
Comment on lines 300 to 310
update_response = {}
update_response.update(
await self.protocol.query(
self.host, self._create_request("system", "get_sysinfo")
)
)

if SmartDevice._check_emeter_feature_presence(update_response):
update_response.update(
await self.protocol.query(self.host, self._create_emeter_request())
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would create unnecessary I/O requests on devices that support the emeter. The logic should be:

  1. If _sysinfo is None (i.e., the device hasn't ever been updated and we don't know if it supports emeter), do fetch only the sysinfo. Check if the _has_emeter is now True, and request the emeter information if so.
  2. Otherwise (on an already initialized device), if _has_emeter is True, the emeter request should be included in the query like it is at the moment.

This way only the initial update will cause two separate I/O requests.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I had a chance to play around a little more this weekend and it turns out that the fix is actually much more simple than I had originally thought.

On my HS220 device, I was able to determine that:

  1. The emeter check returns as expected when it's the only query (which is what led me to the original implementation in this PR)
  2. the emeter check returns as expected when combined with other non-system queries (i.e. time, schedule, etc...)

and finally...
3) The emeter check returns as expected when combined with the system query as long as the emeter query comes first

Since the handful of other devices that I have (HS210, HS200, KP400) were all working with the original code, I inspected the software version to figure out what the difference is. The HS220's look to be running an older version of the firmware than all the other devices, so I suspect there's probably a bug in older versions of the firmware (1.0.5 seems to be the cutoff) when querying for both emeter and system in the same request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks for the comprehensive analysis! I just missed this when doing a review on the currently changed code pieces.

A question though, what is the expected response for the emeter when it's the only query? My assumption is that HS220 does not support emeter at all => there is no need to do any tricks to add emeter queries for devices without emeter (as reported by the sysinfo)?

@SimonWilkinson
Copy link
Contributor

As an additional data point here, HS100s running the new 1.1.0 firmware will crash if asked for emeter information - so, for those at least, we definitely need to ask for sysinfo first.

8000

@mfalzone
Copy link
Author
mfalzone commented Dec 7, 2020

Thanks @SimonWilkinson, that's good to know. I've updated to remove the emeter query if it's not a feature of the device.

@mfalzone mfalzone force-pushed the conditional-emeter-check branch from 1012544 to 59a70af Compare December 11, 2020 01:58
# get_sysinfo.
if self._last_update is None:
initial_update_req = self._update_query(include_emeter=False)
await self._update_with_request(initial_update_req)
Copy link
Member
@rytilahti rytilahti Dec 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Save the response somewhere temporarily, that way there is no need to do the second query in the case if there's no emeter found.

Having two requests when the emeter is found is fine (as second one should've been made anyway).

Otherwise this looks good to me, but please add a unit test to check the update() to make sure no future refactoring will break this behavior!

@rytilahti
Copy link
Member

Obsoleted by #199 that just got merged, thanks for insights @mfalzone :-)

@rytilahti rytilahti closed this Sep 19, 2021
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.

Can't command or query HS200 v5 switch
5 participants
0