Skip to content
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

Support for Mi Fresh Air Ventilator dmaker.airfresh.t2017 #502

Closed
unixko opened this issue Apr 22, 2019 · 15 comments · Fixed by #591
Closed

Support for Mi Fresh Air Ventilator dmaker.airfresh.t2017 #502

unixko opened this issue Apr 22, 2019 · 15 comments · Fixed by #591

Comments

@unixko
Copy link

unixko commented Apr 22, 2019

Product Link:
https://www.xiaomiyoupin.com/detail?gid=104643

miiocli airpurifier --ip 192.168.1.xxx --token xxx info

Model: dmaker.airfresh.t2017
Hardware version: esp32
Firmware version: 2.0.3
Network: {'localIp': '192.168.1.xxx', 'mask': '255.255.255.0', 'gw': '192.168.1.1'}
AP: {'rssi': -63, 'ssid': 'APName', 'primary': 1, 'bssid': 'AA:BB:CC:DD:EE:FF'}
miiocli airpurifier --ip 192.168.1.xxx --token xxx status

ValueError: 94 is not a valid OperationMode

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\python3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python3\Scripts\miiocli.exe\__main__.py", line 9, in <module>
  File "c:\python3\lib\site-packages\miio\cli.py", line 43, in create_cli
    return cli(auto_envvar_prefix="MIIO")
  File "c:\python3\lib\site-packages\miio\click_common.py", line 54, in __call__

    return self.main(*args, **kwargs)
  File "c:\python3\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\python3\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python3\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python3\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python3\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\python3\lib\site-packages\miio\click_common.py", line 267, in wrap
    result_msg = result_msg_fmt.format(**kwargs)
  File "c:\python3\lib\site-packages\miio\airpurifier.py", line 142, in mode
    return OperationMode(self.data["mode"])
  File "c:\python3\lib\enum.py", line 310, in __call__
    return cls.__new__(cls, value)
  File "c:\python3\lib\enum.py", line 564, in __new__
    raise exc
  File "c:\python3\lib\enum.py", line 548, in __new__
    result = cls._missing_(value)
  File "c:\python3\lib\enum.py", line 577, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 94 is not a valid OperationMode
miiocli airfresh --ip 192.168.1.xxx --token xxx info

Model: dmaker.airfresh.t2017
Hardware version: esp32
Firmware version: 2.0.3
Network: {'localIp': '192.168.1.xxx', 'mask': '255.255.255.0', 'gw': '192.168.1.1'}
AP: {'rssi': -64, 'ssid': 'APName', 'primary': 1, 'bssid': 'AA:BB:CC:DD:EE:FF'}
miiocli airfresh --ip 192.168.1.xxx --token xxx status

ValueError: 0 is not a valid OperationMode

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\python3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python3\Scripts\miiocli.exe\__main__.py", line 9, in <module>
  File "c:\python3\lib\site-packages\miio\cli.py", line 43, in create_cli
    return cli(auto_envvar_prefix="MIIO")
  File "c:\python3\lib\site-packages\miio\click_common.py", line 54, in __call__

    return self.main(*args, **kwargs)
  File "c:\python3\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\python3\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python3\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python3\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python3\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\python3\lib\site-packages\miio\click_common.py", line 267, in wrap
    result_msg = result_msg_fmt.format(**kwargs)
  File "c:\python3\lib\site-packages\miio\airfresh.py", line 81, in mode
    return OperationMode(self.data["mode"])
  File "c:\python3\lib\enum.py", line 310, in __call__
    return cls.__new__(cls, value)
  File "c:\python3\lib\enum.py", line 564, in __new__
    raise exc
  File "c:\python3\lib\enum.py", line 548, in __new__
    result = cls._missing_(value)
  File "c:\python3\lib\enum.py", line 577, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 0 is not a valid OperationMode
@rytilahti
Copy link
Owner

Please add -dd to your calls to get more output (it'll contain the payloads), but the problem here is that those modes seems to differ from those defined in https://github.com/rytilahti/python-miio/blob/master/miio/airpurifier.py#L19 in https://github.com/rytilahti/python-miio/blob/master/miio/airfresh.py#L18 (being integers instead of strings).

Maybe those mode getters should catch the exceptions are report a new mode called "unknown" (and print out a warning) in case this happens, instead of crashing.

@unixko
Copy link
Author

unixko commented May 2, 2019

This Air Fresh device has 3 mode ["auto", "sleep", "favourite"]. This payload is from sleep mode. The word "sleep" in payload below will change to "auto", "favourite" following current mode accordingly. Errors from each mode are:

off - ValueError: 0 is not a valid OperationMode
auto - ValueError: 97 is not a valid OperationMode
sleep - ValueError: 60 is not a valid OperationMode
favourite - ValueError: 239 is not a valid OperationMode

C:\Python37\Scripts>miiocli -dd airfresh --ip 192.168.0.2 --token xxx info
INFO:miio.cli:Debug mode active
DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.device:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x05d5\x9b\x00\x01\\ ' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 00:45:20
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf
f' (total 16)
DEBUG:miio.device:Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x05d5\x9b\x00\x01\\ ' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 00:45:20
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf
f' (total 16)
DEBUG:miio.device:Discovered 0564359b with ts: 1970-01-02 00:45:20, token: b'fff
fffffffffffffffffffffffffffff'
DEBUG:miio.device:192.168.0.2:54321 >>: {'id': 1, 'method': 'miIO.info', 'params
': []}
DEBUG:miio.device:send (timeout 5): Container:
    data = Container:
        data = b'\x1a\xfb\xa3U\x1e\xa6!J+\xce\xfca<\xd6\xb3b'... (truncated, tot
al 48)
        value = {'id': 1, 'method': 'miIO.info', 'params': []}
        offset1 = 32
        offset2 = 80
        length = 48
    header = Container:
        data = b'!1\x00P\x00\x00\x00\x00\x05d5\x9b\x00\x01\\!' (total 16)
        value = Container:
            length = 80
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 00:45:21
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xce}\x17\xfcY2,\x08\xb5\x91\xbd.\xa0ntf' (total 16)
DEBUG:miio.device:recv from 192.168.0.2: Container:
    data = Container:
        data = b'\x1b\xcf\x9a\xdb\xb5\xfa\x02\x1a\xfd\x04\xeb\xe8\xbeqFr'... (tr
uncated, total 464)
        value = {'id': 1, 'result': {'life': 89121, 'uid': 1713659356, 'model':
'dmaker.airfresh.t2017', 'token': 'xxx', 'fw_ver':
'2.0.3', 'mcu_fw_ver': '0014', 'miio_ver': '0.0.3', 'hw_ver': 'esp32', 'mmfree':
 69152, 'mac': 'AA:BB:CC:DD:EE:FF', 'wifi_fw_ver': 'v3.1.3-8-gce4d3fe10', 'ap':
{'rssi': -65, 'ssid': 'APName', 'primary': 1, 'bssid': 'FF:EE:DD:CC:BB:AA'}, 'ne
tif': {'localIp': '192.168.0.2', 'mask': '255.255.255.0', 'gw': '192.168.0.1'},
'miio_times': [89120, 7, 213, 88900]}}
        offset1 = 32
        offset2 = 496
        length = 464
    header = Container:
        data = b'!1\x01\xf0\x00\x00\x00\x00\x05d5\x9b\x00\x01\\!' (total 16)
        value = Container:
            length = 496
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 00:45:21
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'w\x8b|D\xdeMpJ\xb0\xac\x01\xba\xea:\xab\x10' (total 16)
DEBUG:miio.device:192.168.0.2:54321 (ts: 1970-01-02 00:45:21, id: 1) << {'id': 1
, 'result': {'life': 89121, 'uid': 1713659356, 'model': 'dmaker.airfresh.t2017',
 'token': 'xxx', 'fw_ver': '2.0.3', 'mcu_fw_ver': '
0014', 'miio_ver': '0.0.3', 'hw_ver': 'esp32', 'mmfree': 69152, 'mac': 'AA:BB:CC
:DD:EE:FF', 'wifi_fw_ver': 'v3.1.3-8-gce4d3fe10', 'ap': {'rssi': -65, 'ssid': 'A
PName', 'primary': 1, 'bssid': 'FF:EE:DD:CC:BB:AA'}, 'netif': {'localIp': '192.1
68.0.2', 'mask': '255.255.255.0', 'gw': '192.168.0.1'}, 'miio_times': [89120, 7,
 213, 88900]}}
Model: dmaker.airfresh.t2017
Hardware version: esp32
Firmware version: 2.0.3
Network: {'localIp': '192.168.0.2', 'mask': '255.255.255.0', 'gw': '192.168.0.1'
}
AP: {'rssi': -65, 'ssid': 'APName', 'primary': 1, 'bssid': 'FF:EE:DD:CC:BB:AA'}
C:\Python37\Scripts>miiocli -dd airfresh --ip 192.168.0.2 --token xxx status
INFO:miio.cli:Debug mode active
DEBUG:miio.protocol:Unable to decrypt, returning raw bytes: b''
DEBUG:miio.device:Got a response: Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x05d5\x9b\x00\x01b\x88' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:40
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf
f' (total 16)
DEBUG:miio.device:Container:
    data = Container:
        data = b'' (total 0)
        value = b'' (total 0)
        offset1 = 32
        offset2 = 32
        length = 0
    header = Container:
        data = b'!1\x00 \x00\x00\x00\x00\x05d5\x9b\x00\x01b\x88' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:40
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf
f' (total 16)
DEBUG:miio.device:Discovered 0564359b with ts: 1970-01-02 01:12:40, token: b'fff
fffffffffffffffffffffffffffff'
DEBUG:miio.device:192.168.0.2:54321 >>: {'id': 1, 'method': 'get_prop', 'params'
: ['power', 'temp_dec', 'aqi', 'average_aqi', 'co2', 'buzzer', 'child_lock', 'hu
midity', 'led_level', 'mode', 'motor1_speed', 'use_time', 'ntcT', 'app_extra', '
f1_hour_used']}
DEBUG:miio.device:send (timeout 5): Container:
    data = Container:
        data = b'\x1a\xfb\xa3U\x1e\xa6!J+\xce\xfca<\xd6\xb3b'... (truncated, tot
al 224)
        value = {'id': 1, 'method': 'get_prop', 'params': ['power', 'temp_dec',
'aqi', 'average_aqi', 'co2', 'buzzer', 'child_lock', 'humidity', 'led_level', 'm
ode', 'motor1_speed', 'use_time', 'ntcT', 'app_extra', 'f1_hour_used']}
        offset1 = 32
        offset2 = 256
        length = 224
    header = Container:
        data = b'!1\x01\x00\x00\x00\x00\x00\x05d5\x9b\x00\x01b\x89' (total 16)
        value = Container:
            length = 256
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:41
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xae_\xab\xb1\x8f\xdd\xdb\xf6\xd0T\xb10\x06\xe6\xd0j' (total 16
)
DEBUG:miio.device:recv from 192.168.0.2: Container:
    data = Container:
        data = b'\x1b\xcf\x9a\xdb\xb5\xfa\x02\x1a\xfd\x04\xeb\xe8\xbeqFr'... (tr
uncated, total 32)
        value = {'id': 1, 'result': [True]}
        offset1 = 32
        offset2 = 64
        length = 32
    header = Container:
        data = b'!1\x00@\x00\x00\x00\x00\x05d5\x9b\x00\x01b\x89' (total 16)
        value = Container:
            length = 64
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:41
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\x03\x9b\x1b\x93o\x0bp\x92\xedP\x95\x93W\xf6(\xfc' (total 16)
DEBUG:miio.device:192.168.0.2:54321 (ts: 1970-01-02 01:12:41, id: 1) << {'id': 1
, 'result': [True]}
DEBUG:miio.device:192.168.0.2:54321 >>: {'id': 2, 'method': 'get_prop', 'params'
: ['filter_life', 'f_hour', 'favorite_level', 'led']}
DEBUG:miio.device:send (timeout 5): Container:
    data = Container:
        data = b'\xcbL\xc4\x05&`\xba\xac\x830F\xae\n{v\x15'... (truncated, total
 96)
        value = {'id': 2, 'method': 'get_prop', 'params': ['filter_life', 'f_hou
r', 'favorite_level', 'led']}
        offset1 = 32
        offset2 = 128
        length = 96
    header = Container:
        data = b'!1\x00\x80\x00\x00\x00\x00\x05d5\x9b\x00\x01b\x8a' (total 16)
        value = Container:
            length = 128
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:42
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'qM\x05%\x15\xab{j\xe4>\xe5<\xbf\xa5+\xf9' (total 16)
DEBUG:miio.device:recv from 192.168.0.2: Container:
    data = Container:
        data = b'\xecX\xf9\x17\xce\xf4\x053\xdd\xee\xdc\x05\xe4\x7f6\x8b'... (tr
uncated, total 112)
        value = {'id': 2, 'result': [19, 595, 31, 239, 92, 82, 96, 172, 60, True
, 'sleep', True, 'medium', False, False, True, True, 'forward']}
        offset1 = 32
        offset2 = 144
        length = 112
    header = Container:
        data = b'!1\x00\x90\x00\x00\x00\x00\x05d5\x9b\x00\x01b\x89' (total 16)
        value = Container:
            length = 144
            unknown = 0
            device_id = b'\x05d5\x9b' (total 4)
            ts = 1970-01-02 01:12:41
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xbd_\xb7[\xb5\xfc\xc4\x9e\x9b\x1db\\\xc1\xdak&' (total 16)
DEBUG:miio.device:192.168.0.2:54321 (ts: 1970-01-02 01:12:41, id: 2) << {'id': 2
, 'result': [19, 595, 31, 239, 92, 82, 96, 172, 60, True, 'sleep', True, 'medium
', False, False, True, True, 'forward']}
ValueError: 60 is not a valid OperationMode

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python37\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python37\Scripts\miiocli.exe\__main__.py", line 9, in <module>
  File "c:\python37\lib\site-packages\miio\cli.py", line 43, in create_cli
    return cli(auto_envvar_prefix="MIIO")
  File "c:\python37\lib\site-packages\miio\click_common.py", line 54, in __call_
_
    return self.main(*args, **kwargs)
  File "c:\python37\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python37\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python37\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\python37\lib\site-packages\miio\click_common.py", line 267, in wrap
    result_msg = result_msg_fmt.format(**kwargs)
  File "c:\python37\lib\site-packages\miio\airfresh.py", line 81, in mode
    return OperationMode(self.data["mode"])
  File "c:\python37\lib\enum.py", line 310, in __call__
    return cls.__new__(cls, value)
  File "c:\python37\lib\enum.py", line 564, in __new__
    raise exc
  File "c:\python37\lib\enum.py", line 548, in __new__
    result = cls._missing_(value)
  File "c:\python37\lib\enum.py", line 577, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 60 is not a valid OperationMode

@unixko
Copy link
Author

unixko commented May 2, 2019

I found that OperationMode value is fan speed. If I set mode to auto, OperationMode will continuously change following current speed. Range is 60 to 300.
0 - off
60 - sleep mode or lowest setting in favourite mode
300 - highest setting in favourite mode

@rezmus
Copy link

rezmus commented May 3, 2019

    public static final String PROP_CHILD_LOCK = "child_lock";
    public static final String PROP_CO2 = "co2";
    public static final String PROP_CONTROL_SPEED = "control_speed";
    public static final String PROP_DISPLAY = "display";
    public static final String PROP_FILTER_HIGH = "filter_efficient";
    public static final String PROP_FILTER_MEDIUM = "filter_intermediate";
    public static final String PROP_HIGH_DAY = "filter_effi_day";
    public static final String PROP_INCREASE_SPEED = "increase_speed";
    public static final String PROP_MEDIUM_DAY = "filter_inter_day";
    public static final String PROP_MODE = "mode";
    public static final String PROP_PM25 = "pm25";
    public static final String PROP_POWER = "power";
    public static final String PROP_PTC_LEVEL = "ptc_level";
    public static final String PROP_PTC_ON = "ptc_on";
    public static final String PROP_PTC_STATUS = "ptc_status";
    public static final String PROP_SCREEN_DIRECTION = "screen_direction";
    public static final String PROP_SOUND = "sound";
    public static final String PROP_SPEED = "favourite_speed";
    public static final String PROP_TEMP = "temperature_outside";
    public static final String TYPE_ALL = "all";
    public static final String TYPE_CO2 = "co2";
    public static final String TYPE_DEVICE_OFFLINE = "dev_offline";
    public static final String TYPE_EFFICIENT = "efficient";
    public static final String TYPE_INTERMEDIATE = "intermediate";
    public static final String TYPE_PM25 = "pm25";

    static {
        HOME_PROPERTIES = new String[]{TYPE_PM25, TYPE_CO2, PROP_TEMP, PROP_SPEED, PROP_FILTER_MEDIUM, PROP_MEDIUM_DAY, PROP_FILTER_HIGH, PROP_HIGH_DAY, PROP_CONTROL_SPEED, PROP_POWER, PROP_MODE, PROP_PTC_ON, PROP_PTC_LEVEL, PROP_PTC_STATUS, PROP_CHILD_LOCK, PROP_SOUND, PROP_DISPLAY, PROP_SCREEN_DIRECTION, PROP_INCREASE_SPEED};
    }

    public boolean getChildLock() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_CHILD_LOCK)), false);
    }

    public boolean getSound() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_SOUND)), false);
    }

    public boolean getDisplay() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_DISPLAY)), false);
    }

    public String getScreenDirection() {
        return TypeUtil.toString(this.mPropertiesMap.get(PROP_SCREEN_DIRECTION));
    }

    public boolean getIncreaseSpeed() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_INCREASE_SPEED)), false);
    }

    public Integer getSpeed() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(PROP_SPEED));
    }

    public Integer getHighFilter() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(PROP_FILTER_HIGH));
    }

    public Integer getHighDay() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(PROP_HIGH_DAY));
    }

    public Integer getMediumFilter() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(PROP_FILTER_MEDIUM));
    }

    public Integer getMediumDay() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(PROP_MEDIUM_DAY));
    }

    public String getMode() {
        return TypeUtil.toString(this.mPropertiesMap.get(PROP_MODE));
    }

    public Integer getPm25() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(TYPE_PM25));
    }

    public boolean getPower() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_POWER)), false);
    }

    public boolean getPtcOn() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_PTC_ON)), false);
    }

    public String getPtcLevel() {
        return TypeUtil.toString(this.mPropertiesMap.get(PROP_PTC_LEVEL));
    }

    public boolean getPtcStatus() {
        return TypeUtil.getDefaultBoolean(TypeUtil.toBoolean(this.mPropertiesMap.get(PROP_PTC_STATUS)), false);
    }

    public Integer getCo2() {
        return TypeUtil.toInteger(this.mPropertiesMap.get(TYPE_CO2));
    }

    public Float getTemp() {
        return TypeUtil.toFloat(this.mPropertiesMap.get(PROP_TEMP));
    }
    
 public void getSensor(Callback<JSONArray> callback) {
        callMethod("get_sensor", callback, new Object[0]);
    }

    public void setChildLock(boolean state, Callback<JSONArray> callback) {
        callMethod("set_child_lock", callback, Boolean.valueOf(state));
    }

    public void setSound(boolean sound, Callback<JSONArray> callback) {
        callMethod("set_sound", callback, Boolean.valueOf(sound));
    }

    public void setDisplay(boolean display, Callback<JSONArray> callback) {
        callMethod("set_display", callback, Boolean.valueOf(display));
    }

    public void setScreenDirection(String direction, Callback<JSONArray> callback) {
        callMethod("set_screen_direction", callback, direction);
    }

    public void setIncreaseSpeed(boolean increase, Callback<JSONArray> callback) {
        callMethod("set_increase_speed", callback, Boolean.valueOf(increase));
    }

    public void setSpeed(int speed, Callback<JSONArray> callback) {
        callMethod("set_favourite_speed", callback, Integer.valueOf(speed));
    }

    public void setPtcLevel(String level, Callback<JSONArray> callback) {
        callMethod("set_ptc_level", callback, level);
    }

    public void setRoomArea(int area, Callback<JSONArray> callback) {
        callMethod("set_room_area", callback, Integer.valueOf(area));
    }

    public void setPower(boolean power, Callback<JSONArray> callback) {
        callMethod("set_power", callback, Boolean.valueOf(power));
    }

    public void setPtcOn(boolean ptc, Callback<JSONArray> callback) {
        callMethod("set_ptc_on", callback, Boolean.valueOf(ptc));
    }

    public void setWorkMode(String mode, Callback<JSONArray> callback) {
        callMethod("set_mode", callback, mode);
    }

    public void getTimers(Callback<JSONArray> callback) {
        callMethod("get_timer", callback, new Object[0]);
    }

    public void setTimer(String timer, Callback<JSONArray> callback) {
        callMethod("set_timer", callback, timer);
    }

    public void deleteTimer(int timer, Callback<JSONArray> callback) {
        callMethod("delete_timer", callback, Integer.valueOf(timer));
    }

    public void resetFilter(String type, Callback<JSONArray> callback) {
        callMethod("set_filter_reset", callback, type);
    }

    public void setPtcTimer(String timer, Callback<JSONArray> callback) {
        callMethod("set_ptc_timer", callback, timer);
    }

    public void getPtcTimer(Callback<JSONArray> callback) {
        callMethod("get_ptc_timer", callback, new Object[0]);
    }

@ps1x
Copy link

ps1x commented Sep 26, 2019

I'm quite far away from python (javascript) but i would love to help integrating that device to Home Assistant, where can i start with help? As of my tries with modification of original plugin, there is no PM25 sensor in original XiaomiAirfresh, so we should add first to python-miio and then create integration in home assistant plugin?

@lazzzrus
Copy link

lazzzrus commented Nov 5, 2019

One vote more. Do you need any help?

@lazzzrus
Copy link

lazzzrus commented Nov 5, 2019

Got it!
https://bbs.hassbian.com/thread-8218-1-1.html
This works!

@d-litvinov
Copy link

@lazzzrus, could you please create a PR? I have no idea how to use that data

@lazzzrus
Copy link

lazzzrus commented Nov 5, 2019

@lazzzrus, could you please create a PR? I have no idea how to use that data

Sorry, i don't know how to create PR.
Shortly zxytddd (guy from China) created his own custom component for HA. You need to registrate to download the file so i shared it:
https://drive.google.com/file/d/1nHdZjWCIhwYH9FNdKqSAZkrdmg_vvASg/view

The config:
fan:

  • platform: dairfresh
    host: $(your_IP)
    token: $(your_token)
    name: MijiaAirfresh
    model: dmaker.airfresh.t2017

So now i can turn the device on/off.

I'm newbie so don't know how to use parameters for dashboard and automation.
So would be glad for any help or link to tutorial.

  1. Properties:
    ["pm25","co2","temperature_outside","favourite_speed","filter_intermediate","filter_inter_day","filter_efficient","filter_effi_day","control_speed","power","mode","ptc_on","ptc_level","ptc_status","child_lock","sound","display","screen_direction"]
  2. Command:
    set_mode
    set_power
    set_ptc_level
    set_ptc_on
    set_ptc_timer
    set_room_area
    set_child_lock
    set_display
    set_sound
    set_screen_direction
    set_favorite
    set_favorite_area
    set_favourite_speed
    set_filter_reset
    set_increase_speed

@unixko
Copy link
Author

unixko commented Nov 14, 2019

Someone already put @zxytddd code on github at https://github.com/mypal/mi-airfresh so we can use it in this mean time. Anyway native support from python-miio and Home Assistant is surely preferred.

@lazzzrus
Copy link

Yes. This integration is far too basic.
I can't find the way to control speed and heat level.
Is it possible?

@syssi
Copy link
Collaborator

syssi commented Dec 7, 2019

# Properties
[
"pm25",
 "co2",
 "temperature_outside",
 "favourite_speed",
 "filter_intermediate",
 "filter_inter_day",
 "filter_efficient",
 "filter_effi_day",
 "control_speed",
 "power",
 "mode",
 "ptc_on",
 "ptc_level",
 "ptc_status",
 "child_lock",
 "sound",
 "display",
 "screen_direction"
]

# Methods:

get_prop [propArr]
get_ptc_timer []
get_sensor [propArr]
get_timer null
set_child_lock [value]
set_display [value]
set_favourite_speed [areaNum]
set_filter_reset ['efficient']
set_filter_reset ['intermediate']
set_mode [type]
set_power [status]
set_ptc_level [ptc_leavel]
set_ptc_on [ptc_leavel]
set_ptc_timer, [value]
set_screen_direction [direct]
set_sound [value]

@syssi
Copy link
Collaborator

syssi commented Dec 7, 2019

Could somebody provide the output of:

miiocli device --ip IP --token TOKEN raw_command get_prop "['pm25', 'co2', 'temperature_outside', 'favourite_speed', 'filter_intermediate', 'filter_inter_day', 'filter_efficient', 'filter_effi_day', 'control_speed', 'power', 'mode', 'ptc_on', 'ptc_level', 'ptc_status', 'child_lock', 'sound', 'display', 'screen_direction']"

@skvalex
Copy link

skvalex commented Dec 11, 2019

@syssi here is the output grabbed from Mi Home app via tcpdump:

 ->  request = {"id":4219,"method":"get_prop","params":["pm25","co2","temperature_outside","favourite_speed","filter_intermediate","filter_inter_day","filter_efficient","filter_effi_day","control_speed","power","mode","ptc_on","ptc_level","ptc_status","child_lock","sound","display","screen_direction"]}
 <-  response = {"id":4219,"result":[0,445,3,206,83,74,92,165,60,true,"sleep",false,"high",false,false,false,false,"forward"]}

P.S. I've created pull request for openHAB to add support for this device: https://github.com/openhab/openhab2-addons/pull/6558/files
It might be helpful to you.

@ps1x
Copy link

ps1x commented Oct 15, 2020

Please upvote feature request here https://community.home-assistant.io/t/support-for-xiaomi-miio-support-for-dmaker-airfresh-t2017/235798 if you want it integrated in home assistant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants