Basic support for Xiaomi Mi Smart Electric Rice Cooker#287
Basic support for Xiaomi Mi Smart Electric Rice Cooker#287syssi merged 35 commits intorytilahti:masterfrom
Conversation
| MODEL_NORMAL5] | ||
|
|
||
|
|
||
| class OperationMode(enum.Enum): |
| @@ -0,0 +1,199 @@ | |||
| import logging | |||
| from collections import defaultdict | |||
| from .device import Device, DeviceException | |||
There was a problem hiding this comment.
'.device.DeviceException' imported but unused
| MODEL_NORMAL_GROUP1 = [MODEL_NORMAL2, MODEL_NORMAL5] | ||
| MODEL_NRRMAL_GROUP2 = [MODEL_NORMAL3, MODEL_NORMAL4] | ||
|
|
||
| class OperationMode(enum.Enum): |
miio/cooker.py
Outdated
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] | ||
| temperature gelatinization: ['running', '0001', '0a000000ff', '031e0b23', '2', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff01000a015559'] | ||
| meal is ready: ['autokeepwarm', '0001', '1000000000', '031e0b23031e', '1', '750', '60', '0207', '05040f', '00030017', '0100', 'ffffffffffff011effff01000000535d'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] | ||
| temperature gelatinization: ['running', '0001', '0a000000ff', '031e0b23', '2', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff01000a015559'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] | ||
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] | ||
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] | ||
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| """ | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| def stage(self) -> str: | ||
| """ | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
miio/cooker.py
Outdated
| @property | ||
| def stage(self) -> str: | ||
| """ | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (189 > 100 characters)
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] | ||
| temperature gelatinization: ['running', '0001', '0a000000ff', '031e0b23', '2', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff01000a015559'] | ||
| meal is ready: ['autokeepwarm', '0001', '1000000000', '031e0b23031e', '1', '750', '60', '0207', '05040f', '00030017', '0100', 'ffffffffffff011effff01000000535d'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] | ||
| temperature gelatinization: ['running', '0001', '0a000000ff', '031e0b23', '2', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff01000a015559'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] | ||
| high temperature gelatinization: ['running', '0001', '07000000ff', '031e0b23', '22', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010007015d64'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] | ||
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] | ||
| operate at full load to boil rice: ['running', '0001', '06000000ff', '031e0b23', '29', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010006015c64'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] | ||
| operate at full load to boil rice: ['running', '0001', '03000000ff', '031e0b23', '39', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010003055332'] | ||
| operate at full load to boil rice: ['running', '0001', '04000000ff', '031e0b23', '35', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010004026460'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '48', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013f29'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| """ | ||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| def stage(self) -> str: | ||
| """ | ||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| @property | ||
| def stage(self) -> str: | ||
| """ | ||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom |
There was a problem hiding this comment.
line too long (184 > 100 characters)
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| absorb water at moderate temp: ['running', '0001', '02000000ff', '031e0b23', '54', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010002013e23'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
|
|
||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] | ||
| quickly preheat: ['running', '0001', '00000000ff', '031e0b23', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| 'custom': '13281323ffff011effff010000001617'} | ||
|
|
||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom | ||
| idle: ['waiting', '0001', 'null', '29', '60', '-1', '60', '0607', '05040f', '00030017', '0100', 'ffffffffffff011effff010000001d1f'] |
There was a problem hiding this comment.
line too long (199 > 100 characters)
| 'favorite': '0100', | ||
| 'custom': '13281323ffff011effff010000001617'} | ||
|
|
||
| func , menu , stage , temp , t_func, t_precook, t_cook, setting, delay , version , favorite, custom |
There was a problem hiding this comment.
line too long (184 > 100 characters)
e941fb0 to
5fad578
Compare
| s = "<TemperatureHistory temperatures=%s>" % self.data | ||
| return s | ||
|
|
||
| class CookerCustomizations: |
5b5cc97 to
a2b0412
Compare
rytilahti
left a comment
There was a problem hiding this comment.
Looks good in general. Consider the amount of classes and LOC, I'm wondering if this should be split into multiple files (and if we should start adding some structure into the source dir in these cases); miio/vacuum/ for vacuum, miio/cooker/ for cooker etc. What do you think?
| MODEL_NORMAL_GROUP1 = [MODEL_NORMAL2, MODEL_NORMAL5] | ||
| MODEL_NRRMAL_GROUP2 = [MODEL_NORMAL3, MODEL_NORMAL4] | ||
|
|
||
| COOKING_STAGE_NAME = [ |
There was a problem hiding this comment.
Please merge this and cooking state descriptions into a dict.
miio/cooker.py
Outdated
| self.data = [int(data[i:i + 2], 16) for i in range(0, len(data), 2)] | ||
|
|
||
| @property | ||
| def temperatures(self) -> list[int]: |
There was a problem hiding this comment.
You need to from typing import List and use List here (and elsewhere).
| Cancel = 'Отмена' | ||
|
|
||
|
|
||
| class TemperatureHistory: |
There was a problem hiding this comment.
doctstrings would be nice for this class, too. What does this dow and how can I use it? It's a container of temperatures recorded every X time interval? Is there a limit how many historical values are available?
| ResumeP = 'resumep' | ||
| Start = 'start' | ||
| StartP = 'startp' | ||
| Cancel = 'Отмена' |
There was a problem hiding this comment.
That looks weird. What does it mean that they are potential candidates? Is it necessary that these are included?
There was a problem hiding this comment.
These are possible values of the property "func". A few are internal states of the android app probably. I've just collected all occurrences of string comparisons.
| """ | ||
| Example values: | ||
|
|
||
| ffffffffffff011effff010000001d1f, |
There was a problem hiding this comment.
It would be nice to have some sort of short description for the bytes / how to interpret these.
| if len(value) == 2 and value.isdigit(): | ||
| return int(value) | ||
|
|
||
| return None |
There was a problem hiding this comment.
Exception instead of returning None here too? (and below also, for error cases)
There was a problem hiding this comment.
If the cooker isn't cooking it returns the room temperature here (property: "temp").
There was a problem hiding this comment.
Ok, what are the values otherwise? Those hex-encoded ones? Should this be printing a warning when used and the temperature is not available, and point out what to do instead of it?
There was a problem hiding this comment.
Note: Discussed at discord.
| @command( | ||
| default_output=format_output("Cooking stopped"), | ||
| ) | ||
| def stop_outdated_firmware(self): |
There was a problem hiding this comment.
Is it possible to check if outdated stop is necessary, and just expose the stop command?
There was a problem hiding this comment.
It's possible but ugly. I've to compare a lot of firmware versions and model types. It was to complicated to implement at the first step.
There was a problem hiding this comment.
Ok, then let it be like that for now.
| MODEL_NORMAL3 = 'chunmi.cooker.normal4' | ||
| MODEL_NORMAL5 = 'chunmi.cooker.normal5' | ||
|
|
||
| MODEL_PRESSURE = [MODEL_PRESSURE1, MODEL_PRESSURE2] |
There was a problem hiding this comment.
If MODEL_PRESSURE{1,2} are used nowehere else than here, better just simply use them instead of exposing a global variable.
There was a problem hiding this comment.
These consts are important in future for all the edge-cases.
miio/cooker.py
Outdated
| MODEL_NORMAL5] | ||
|
|
||
| MODEL_NORMAL_GROUP1 = [MODEL_NORMAL2, MODEL_NORMAL5] | ||
| MODEL_NRRMAL_GROUP2 = [MODEL_NORMAL3, MODEL_NORMAL4] |
There was a problem hiding this comment.
Typo in nrrmal. MODEL_NORMAL1 does not belong to any group? Are these global variables necessary?
| @@ -0,0 +1,195 @@ | |||
| { | |||
There was a problem hiding this comment.
Maybe miio/data/cooker_profiles.json to keep it from polluting the main source dir?
There was a problem hiding this comment.
To add, the setup.py and/or manifest file will require also an update, otherwise the json file won't be added when generating a package.
Typing List added
miio/cooker.py
Outdated
|
|
||
| import click | ||
|
|
||
| from .click_common import command, format_output, EnumType |
There was a problem hiding this comment.
'.click_common.EnumType' imported but unused
Closes: #282