syssi / xiaomi_fan

Xiaomi Mi Smart Fan integration for Home Assistant
Apache License 2.0
430 stars 117 forks source link

Improve Smartmi Standing Fan 3 (zhimi.fan.za5) support #69

Closed zhenvw closed 3 years ago

zhenvw commented 4 years ago

Hello, recently purchased a new fan (model: zhimi.fan.za5) Can you add this model to supported devices? (zhimi.fan.za5) What information do you need to provide to facilitate your work? Thank you!

wolverine28 commented 4 years ago

same here !

generousRocky commented 4 years ago

is there any plan for supporting zhimi.fan.za5 or any workaround for supporting it?

Thank you

darkiller22003 commented 3 years ago

Hi Sebastian,

Will you be adding in zhimi.fan.za5 ? or do you have a tutorial on how to add unsupported devices?

thangtrancb commented 3 years ago

I also just bought 2 zhimi.fan.za5 fans, is there any way to add hassio? Thankyou very much

Chicoo commented 3 years ago

Same here. I also just got a zhimi.fan.za5 and would like to have this added.

pana800 commented 3 years ago

Please help with this new device with many thanks

pana800 commented 3 years ago

Just to update. I tried with model dmaker.fan.p21 And some of the functions works. On off, osscillation. Hope this give some clues for a full function updates. Thanks

syssi commented 3 years ago

Cross link: https://github.com/syssi/xiaomi_airpurifier/issues/180

syssi commented 3 years ago

I would like to support this device soon. I would be happy about some support.

pana800 commented 3 years ago

Thanks and looking forward to the new features

syssi commented 3 years ago
# https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:fan:0000A005:zhimi-za5:1

Device 'urn:miot-spec-v2:device:fan:0000A005:zhimi-za5:1': Fan with 7 services

* Service siid 1: (Device Information): 4 props, 0 actions

        ## Properties ##
                siid 1: piid: 1 (Device Manufacturer): (string, unit: None) (acc: ['read'])
                siid 1: piid: 2 (Device Model): (string, unit: None) (acc: ['read'])
                siid 1: piid: 3 (Device Serial Number): (string, unit: None) (acc: ['read'])
                siid 1: piid: 4 (Current Firmware Version): (string, unit: None) (acc: ['read'])

* Service siid 2: (Fan): 7 props, 0 actions

        ## Properties ##
                siid 2: piid: 1 (Switch Status): (bool, unit: None) (acc: ['read', 'write', 'notify'])
                siid 2: piid: 2 (Fan Level): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 1, 'description': '1'}
                        {'value': 2, 'description': '2'}
                        {'value': 3, 'description': '3'}
                        {'value': 4, 'description': '4'}
                siid 2: piid: 3 (Horizontal Swing): (bool, unit: None) (acc: ['read', 'write', 'notify'])
                siid 2: piid: 5 (Horizontal Angle): (uint16, unit: none) (acc: ['read', 'write', 'notify'])
                        Range: [30, 120, 1]
                siid 2: piid: 7 (Mode): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 0, 'description': 'Natural Wind'}
                        {'value': 1, 'description': 'Straight Wind'}
                siid 2: piid: 10 (Power Off Delay): (uint32, unit: none) (acc: ['read', 'write', 'notify'])
                        Range: [0, 36000, 1]
                siid 2: piid: 11 (Anion): (bool, unit: None) (acc: ['read', 'write', 'notify'])

* Service siid 3: (Physical Control Locked): 1 props, 0 actions

        ## Properties ##
                siid 3: piid: 1 (Physical Control Locked): (bool, unit: None) (acc: ['read', 'write', 'notify'])

* Service siid 4: (Indicator Light): 1 props, 0 actions

        ## Properties ##
                siid 4: piid: 3 (Brightness): (uint8, unit: percentage) (acc: ['read', 'write', 'notify'])
                        Range: [0, 100, 1]

* Service siid 5: (Alarm): 1 props, 0 actions

        ## Properties ##
                siid 5: piid: 1 (Alarm): (bool, unit: None) (acc: ['read', 'write', 'notify'])

* Service siid 7: (Environment): 2 props, 0 actions

        ## Properties ##
                siid 7: piid: 1 (Relative Humidity): (uint8, unit: percentage) (acc: ['read', 'notify'])
                        Range: [0, 100, 1]
                siid 7: piid: 7 (Temperature): (float, unit: celsius) (acc: ['read', 'notify'])
                        Range: [-30, 100, 0.1]

* Service siid 6: (用户自定义服务): 8 props, 0 actions

        ## Properties ##
                siid 6: piid: 1 (按下按键的键值): (uint8, unit: none) (acc: ['notify', 'read'])
                        {'value': 1, 'description': 'power'}
                        {'value': 2, 'description': 'swing'}
                        {'value': 0, 'description': '无按键按下'}
                siid 6: piid: 2 (是否有电池): (bool, unit: None) (acc: ['read', 'notify'])
                siid 6: piid: 3 (设定风扇水平转动7.5度): (string, unit: None) (acc: ['write'])
                siid 6: piid: 4 (当前扇叶实时转速,RPM。调试使用,不向用户开放。): (uint32, unit: None) (acc: ['read', 'notify'])
                        Range: [0, 3000, 1]
                siid 6: piid: 5 (交流电是否插入): (bool, unit: None) (acc: ['read', 'notify'])
                siid 6: piid: 6 (马达运行状况): (string, unit: None) (acc: ['notify'])
                siid 6: piid: 7 (lp-enter-second): (uint32, unit: seconds) (acc: ['write'])
                        Range: [1, 3600, 1]
                siid 6: piid: 8 (speed-level): (uint8, unit: none) (acc: ['write', 'read', 'notify'])
                        Range: [1, 100, 1]

        ## Events ##
                siid 6: eiid 1 (设备运行故障): (args: [6])
                siid 6: eiid 2 (childlock-trigger): (args: [])
syssi commented 3 years ago
# Anion?!

MODEL_FAN_ZA5: {
    # https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:fan:0000A005:zhimi-za5:1
    "power": {"siid": 2, "piid": 1},
    "fan_level": {"siid": 2, "piid": 2},
    "swing_mode": {"siid": 2, "piid": 3},
    "swing_mode_angle": {"siid": 2, "piid": 5},
    "mode": {"siid": 2, "piid": 7},
    "power_off_time": {"siid": 2, "piid": 10},
    "anion": {"siid": 2, "piid": 11},
    "child_lock": {"siid": 3, "piid": 1},
    "light": {"siid": 4, "piid": 3},
    "buzzer": {"siid": 5, "piid": 1},
    "humidity": {"siid": 7, "piid": 1},
    "button_pressed": {"siid": 6, "piid": 1},
    "battery_supported": {"siid": 6, "piid": 2},
    "speed_raw": {"siid": 6, "piid": 4},
    "powersupply_attached": {"siid": 6, "piid": 5},
    "temperature": {"siid": 5, "piid": 7},
    "fan_speed": {"siid": 6, "piid": 8},
},
syssi commented 3 years ago

I've pushed basic ZA5 support. For now this features / properties are supported:

pana800 commented 3 years ago

Thanks a lot. I replaced the new version and got this error Platform error fan.xiaomi_miio_fan - cannot import name 'Fan1C' from 'miio' (/usr/local/lib/python3.8/site-packages/miio/__init__.py)

syssi commented 3 years ago

@pana800 Which HA version do you use? Do you have additional custom components installed interfacing xiaomi devices? Please make sure every manifest.json is requiring the same python-miio version. Version 0.5.6 and HA core 2021.5.1 is required.

pana800 commented 3 years ago

@syssi Thanks a lot for the advice, I updated to HA 2021.5.1 and it worked. Great works.

pana800 commented 3 years ago

@syssi just to add, I had to put one more line here to avoid the missing zhimi.fan.za5 error. PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_HOST): cv.string, vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)), vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_MODEL): vol.In( [ MODEL_FAN_V2, MODEL_FAN_V3, MODEL_FAN_SA1, MODEL_FAN_ZA1, MODEL_FAN_ZA3, MODEL_FAN_ZA4, MODEL_FAN_ZA5, # added MODEL_FAN_P5, MODEL_FAN_P8, MODEL_FAN_P9, MODEL_FAN_P10, MODEL_FAN_P11, MODEL_FAN_P15, MODEL_FAN_LESHOW_SS4, MODEL_FAN_1C, ] ), vol.Optional(CONF_RETRIES, default=DEFAULT_RETRIES): cv.positive_int, } )

countrysideboy commented 3 years ago

I also have this model.

Anion means the negative ion mode.

This fan also have a so-called temperature-sensing mode(siid: 6, piid:10, ture or false),i found the logic is: If >28 degrees, 100% speed If >26, 74% speed If >=24, 35% If <24, 1% It's useless and the Chinese ad says it's AI tuning speed mode. I think we could add this mode if the model of the fan has a temperature sensor.

jacobhallgren commented 3 years ago

is it possible to get battery status the fan 3?

silvanverschuur commented 3 years ago

I purchased this model today and installed your integration. It works fine but it would be great if all features could be implemented (like fan level 4, swing angle, etc)

Is there anything I can do to help you?

jacobhallgren commented 3 years ago

Yes and battery status would be nice

CypherMK commented 3 years ago

Also got this fan yesterday. SoI can't select speed level 4, natural mode, and can't see temperature and humidity. Hopefully this gets added in the fututre. Glad to help testing.

nitobosch commented 3 years ago

When trying to add my new Smartmi Standing Fan 3, configuring on the configuration.yaml and restaring my home assistant i'm getting this error.

`Logger: homeassistant.components.fan Source: util/percentage.py:21 Integration: Ventilador (documentation, issues) First occurred: 14:00:10 (2 occurrences) Last logged: 14:00:10

Error adding entities for domain fan with platform xiaomi_miio_fan Error while setting up xiaomi_miio_fan platform for fan Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 615, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 368, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 404, in _async_write_ha_state attr.update(self.state_attributes or {}) File "/usr/src/homeassistant/homeassistant/components/fan/init.py", line 603, in state_attributes data[ATTR_SPEED] = self.speed File "/usr/src/homeassistant/homeassistant/components/fan/init.py", line 453, in speed percentage = self.percentage File "/config/custom_components/xiaomi_miio_fan/fan.py", line 1155, in percentage return ordered_list_item_to_percentage(FAN_SPEEDS_1C, self._preset_mode) File "/usr/src/homeassistant/homeassistant/util/percentage.py", line 21, in ordered_list_item_to_percentage raise ValueError(f'The item "{item}"" is not in "{ordered_list}"') ValueError: The item "None"" is not in "['Level 1', 'Level 2', 'Level 3']"`

fi-sch commented 3 years ago

I am also willing to help with implementing the rest of device attributes. @syssi, please let me know if I can collect any helpful data for you.

BTW, 'anion' is some new strange feature of this fan. It's supposed to generate some negative ions or whatever. I'm not sure about the benefit, just wanted to let you know ;)

idantene commented 3 years ago

With the latest HA and integration, I get this error:

2021-07-26 15:21:54 ERROR (MainThread) [homeassistant.components.fan] Error while setting up xiaomi_miio_fan platform for fan
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 258, in _async_setup_platform
await asyncio.gather(*pending)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity
await entity.add_to_platform_finish()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 666, in add_to_platform_finish
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 419, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 455, in _async_write_ha_state
attr.update(self.state_attributes or {})
File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 607, in state_attributes
data[ATTR_SPEED] = self.speed
File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 457, in speed
percentage = self.percentage
File "/config/custom_components/xiaomi_miio_fan/fan.py", line 1157, in percentage
return ordered_list_item_to_percentage(FAN_SPEEDS_1C, self._preset_mode)
File "/usr/src/homeassistant/homeassistant/util/percentage.py", line 21, in ordered_list_item_to_percentage
raise ValueError(f'The item "{item}"" is not in "{ordered_list}"')
ValueError: The item "None"" is not in "['Level 1', 'Level 2', 'Level 3']"

The configuration.yaml has:

fan:
  - platform: xiaomi_miio_fan
    name: Xiaomi Standing Fan 3
    model: zhimi.fan.za5
    host: XXX
    token: XXX
DooMMasteR commented 3 years ago

Yepp, same here.

GauntPT commented 3 years ago

With the latest HA and integration, I get this error:


2021-07-26 15:21:54 ERROR (MainThread) [homeassistant.components.fan] Error while setting up xiaomi_miio_fan platform for fan

I had the same issue. Removed the devices and reconfigured for three times. did not get it running. What was helping in my case was to Turn Off the fan (not power off of course) and restart HA.

GauntPT commented 3 years ago

@syssi You have asked if someone is able to install custom python-miio on linux system. I have the fan ZA5 here (as well as 1X) as well the knowledge to do it (I believe) I would be happy to help to push this fan to its limit :)

Top priority for myself would be: Level 4 support and Oscillate Left / Right 5 degree

idantene commented 3 years ago

I managed to get the full functionality (all speeds, all angles, plus temperature and humidity readings) by incorporating the changes here - https://github.com/rytilahti/python-miio/pull/1087/files

I can make a PR with the hard-coded values (which should then be needed to clean up once the above PR is merged).

idantene commented 3 years ago

In the meantime, a quick-and-dirty solution (done with vim 😛 my apologies) is attached. Some notes for those who end up using it (and for @syssi if you end up taking it from here) -

  1. For users - please note the following attributes:
    • direction - unused, always null
    • direct_speed - equals to natural_speed and percentage
    • natural_speed - equals to natural_speed and percentage
    • use_time - unused, always null
    • battery - always True
    • battery_charge - unused, always null
    • Introducing new raw_led_brightness (values from 0 to 100) and the accompanying service fan_set_raw_led_brightness
      • The mapping from Dim and Bright to [0, 100] range is non-trivial IMO; for now the mapping is:
        • raw_led_brightness == 0 -> Off
        • raw_led_brightness == 1 -> Dim
        • raw_led_brightness > 1 -> Bright
    • led - Corresponds to led_brightness > 0
    • battery_state - Charging when ac_power is True, otherwise Discharging
    • raw_speed offers the current speed in RPM
    • mode holds a string (either Nature or Normal)
  2. For developers - the current ad-hoc implementation abuses the XiaomiFanMiot by overloading many of FanStatusZA5 with duplicate properties (instead of renaming/setting an attribute table with a dedicated class). Similarly, a lot of the previous code for ZA5 - now unused - is not cleaned up.

Temporary install notes:

  1. Copy the code from the link below and replace /config/custom_components/xiaomi_miio_fan/fan.py with it
  2. Restart HASS

Modified fan.py

EDIT: Attributes and full functionality have been implemented in the above link now :) Sorry for not going the VCS way @syssi, but this should be good enough to start I believe 👍🏻

jonicunha commented 3 years ago

With the latest HA and integration, I get this error:

2021-07-26 15:21:54 ERROR (MainThread) [homeassistant.components.fan] Error while setting up xiaomi_miio_fan platform for fan
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 258, in _async_setup_platform
await asyncio.gather(*pending)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity
await entity.add_to_platform_finish()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 666, in add_to_platform_finish
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 419, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 455, in _async_write_ha_state
attr.update(self.state_attributes or {})
File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 607, in state_attributes
data[ATTR_SPEED] = self.speed
File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 457, in speed
percentage = self.percentage
File "/config/custom_components/xiaomi_miio_fan/fan.py", line 1157, in percentage
return ordered_list_item_to_percentage(FAN_SPEEDS_1C, self._preset_mode)
File "/usr/src/homeassistant/homeassistant/util/percentage.py", line 21, in ordered_list_item_to_percentage
raise ValueError(f'The item "{item}"" is not in "{ordered_list}"')
ValueError: The item "None"" is not in "['Level 1', 'Level 2', 'Level 3']"

The configuration.yaml has:

fan:
  - platform: xiaomi_miio_fan
    name: Xiaomi Standing Fan 3
    model: zhimi.fan.za5
    host: XXX
    token: XXX

I have the same error. What have you done to bypass it?

idantene commented 3 years ago

I have the same error. What have you done to bypass it?

@jonicunha, see my comment above. The current implementation is lacking and I've provided a drop-in replacement that adds full functionality for the Smartmi Standing Fan 3. I believe @syssi will make the necessary updates to the integration soon enough, but until that time you can use the ad-hoc solution.

EvilVir commented 3 years ago

Hi guys,

I did some changes to the @idantene solution, which you can find here.

First of all there was some bug that caused preset_modes_override to be ignored - fixed that. Second improvement is that now slider for the fan speed operates in 0-100 range, allowing to use major feature of this fan - exact speed setting instead of choosing one of four presets.

Hope this will help and will make its way to the master :)

syssi commented 3 years ago

Please feel free to contribute your changes as pull request! :-)

timconinx commented 3 years ago

I just put the changes by @idantene and @EvilVir into a pull request referenced above this comment, as requested by @syssi