-
-
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
Add inital support for mmgg.feeder.petfeeder #1210
Conversation
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.
A very brief review, looking great! Please do not forget to add the device to README.md, too
Co-authored-by: Teemu R. <[email protected]>
Co-authored-by: Teemu R. <[email protected]>
Co-authored-by: Teemu R. <[email protected]>
Previously threw NotImplementedError, but have removed all together now.
Think that's everything fixed 😸 |
"Power source: {result.power_status}\n" | ||
"Food level: {result.food_status}\n" | ||
"Automatic feeding: {result.feed_plan}\n" | ||
"Food bin lid: {result.door_status}\n" | ||
"Dispense button lock: {result.key_lock}\n" | ||
"Days until clean: {result.clean_days}\n" | ||
"Desiccant life: {result.dryer_days}\n" | ||
"WiFi LED: {result.wifi_led}\n", |
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.
It would make sense to avoid using the property names from the protocol itself, but use more developer friendly names (similar to use for these printouts).
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.
Ah yeah I was going to ask about that.
Some names I've taken from miot spec for another feeder by mmgg (one that's actually compliant... 😠 ), but obviously some things don't translate overly well and wasn't sure on the preferred approach.
So you're suggesting (for example) "door_status" > "food_bin_lid" or something along those lines?
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.
Yes, exactly. It makes sense to separate the property names from what is being internally used, as most of the times they are not clear in their meaning. bin_lid_open
, maybe?
return self.send("resetdryer") | ||
|
||
@command( | ||
click.argument("state", type=int), |
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.
click.argument("state", type=int), | |
click.argument("state", type=bool), |
Use bool for boolean values across the board. This should work directly for the cli input values so no need for explicit conversions either.
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 used bool initially but seemingly then gets sent as literal "true" or "false" (not 1 or 0) which the device does not understand. miot spec for other mmgg products have these defined as ints rather than bools.
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.
Oh, then casting is needed; int(boolvalue)
will fix 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.
🤦
Given I wrote it at 3am I'm amazed there's not more glaring issues. I'll sort that.
return self.send("outfood", [amount]) | ||
|
||
@command(default_output=format_output("Resetting clean time")) | ||
def reset_clean_time(self) -> bool: |
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.
Are you sure this returns a bool? And same for reset_dryer_time
?
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.
Good catch, it returns a list with a string of "ok".
That said, it returns "ok" literally no matter what you send to this device 🤦
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 common on commands, coming likely from the SDK. You could either check for the "ok" in the payload or simply return it as it is, there is no real consistency in the library at the moment on that.
Co-authored-by: Teemu R. <[email protected]>
return bool(self.data["door_status"]) | ||
|
||
@property | ||
def clean_days(self) -> int: |
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.
Use timedelta
for this and the dryer one, this makes it consistent with other integrations.
Also, use naming scheme <variable>_left
.
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.
Perfect, was just about to ask about this.
"dryer_days" > "desiccant_left"
Can't quite think how to phrase "clean_days".
It's the number of days until the unit requires cleaning.
Suggestions?
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 don't have a good term for that either, time_until_clean_left
is sounds quite verbose.
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.
Yeah that's what I was trying to avoid, even though it's very pythonic to make it as long as is needed to convey it's use.
lambda state: "Enabling automatic feeding schedule" if state else "Disabling automatic feeding schedule" | ||
), | ||
) | ||
def set_feed_state(self, state: int): |
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.
set_automated_feeding
<-> automated_feeding
in state, maybe?
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.
Naming stuff is the hardest part of all this, honestly 😆
In mihome the toggle is "automatic feeding schedule".
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.
Btw, you can run the linting tests locally by executing tox -e lint
or pre-commit run -a
(or alternatively, you can do pre-commit install
and it will perform the checks prior commiting).
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 must admit I didn't with this commit, I will in future 👼
Infact yeah, although this was an "initial support" pull - give me a day or so and I'll just refactor and add everything and make it fully supported from day one. |
Work got a bit busy (chaos before Christmas change freeze!) but have started. Few questions before we have another shot ;) 1. Implementing field maximums (i.e max dispense unit is 30) 2. Timezones! datetime.time with tzinfo? 3. Boolean responses |
Good catch, please use standard exceptions. I modified #1114 to list it as something that should be consolidated across the code base.
Use booleans where possible, no need to enumize. On the topic of timezones, I'm not sure what's the best approach here. IIRC the vacuum schedules do convert the times to the local tz, maybe take a look how it's done and follow the same approach? |
Closing in favour of #1253 |
I've tried to follow the style as best I can see.
Was 50/50 on calling the integration "PetfoodDispenser" (keeps with PetWaterDispenser) or simply calling it "PetFeeder".
This device does not follow it's own (somewhat limited) miot spec (annoying since the Manufacturer does make other compliant devices!) so this is all MiiO.
There's a number of features unavailable vs the mi home app:
Added most functions:
Will look into adding support for feedplans soon.
Feedback welcome.