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

Unsupported device: dmaker.fan.p39 #213

Closed
JoeTN opened this issue Apr 18, 2023 · 24 comments · Fixed by #225
Closed

Unsupported device: dmaker.fan.p39 #213

JoeTN opened this issue Apr 18, 2023 · 24 comments · Fixed by #225

Comments

@JoeTN
Copy link

JoeTN commented Apr 18, 2023

Just tried adding my fan in Home Assistant, getting: "Unsupported device: dmaker.fan.p39".
Are there any plans on implementing it, or some generic way of controlling it, seems that others has got it to work, although not officially supported by your integration, but there are little info on how to.

Thanks in advance.

@traysh
Copy link
Contributor

traysh commented Jun 16, 2023

Hey, I've got the same device :)

@Landrash
Copy link

@syssi The p39 is very similar to the P9 but not supported by fanmiot and instead by genericmiot.
Is there any plans of adding a way of supporting these or is adding support to fanmiot in python-miio the best way?

I'm working on both but unsure wich is the best way forward.

@dieneuser
Copy link

@Landrash I own the same device and would love to see it supported soon.

@Donsezan
Copy link

@Landrash Any updates about adding supporting dmaker.fan.p39?

@traysh
Copy link
Contributor

traysh commented Jul 27, 2023

Hi,
I updated the integration on HACS and restarted Home Assistant, but it looks like the merged code does not work, at least in my case.

My configuration is:

fan:
  - platform: xiaomi_miio_fan
    name: Xiaomi Smart Fan
    host: 10.32.33.141
    token: [[ HIDDEN ]]
    model: dmaker.fan.p39

The error I get on Home Assistant startup:

2023-07-27 20:59:23.509 INFO (MainThread) [custom_components.xiaomi_miio_fan.fan] Initializing with host 10.32.33.141 (token a83e5...)
2023-07-27 20:59:23.541 DEBUG (SyncWorker_3) [miio.miioprotocol] 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\x19t\x81\x1d\x00\x00xw' (total 16)
        value = Container:
            length = 32
            unknown = 0
            device_id = unhexlify('1974811d')
            ts = 1970-01-01 08:33:59
        offset1 = 0
        offset2 = 16
        length = 16
    checksum = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' (total 16)
2023-07-27 20:59:23.550 DEBUG (SyncWorker_3) [miio.miioprotocol] Discovered 1974811d with ts: 1970-01-01 08:33:59, token: b'ffffffffffffffffffffffffffffffff'
2023-07-27 20:59:23.555 DEBUG (SyncWorker_3) [miio.miioprotocol] 10.32.33.141:54321 >>: {'id': 1, 'method': 'get_properties', 'params': [{'did': 'power', 'siid': 2, 'piid': 1}, {'did': 'fan_level', 'siid': 2, 'piid': 2}, {'did': 'mode', 'siid': 2, 'piid': 4}, {'did': 'oscillate', 'siid': 2, 'piid': 5}, {'did': 'angle', 'siid': 2, 'piid': 6}, {'did': 'delay_off_countdown', 'siid': 2, 'piid': 8}, {'did': 'motor_control', 'siid': 2, 'piid': 10}, {'did': 'speed', 'siid': 2, 'piid': 11}, {'did': 'child_lock', 'siid': 3, 'piid': 1}]}
2023-07-27 20:59:23.810 DEBUG (SyncWorker_3) [miio.miioprotocol] 10.32.33.141:54321 (ts: 1970-01-01 08:34:00, id: 1) << {'id': 1, 'result': [{'did': 'power', 'siid': 2, 'piid': 1, 'code': -4004}, {'did': 'fan_level', 'siid': 2, 'piid': 2, 'code': -4004}, {'did': 'mode', 'siid': 2, 'piid': 4, 'code': -4004}, {'did': 'oscillate', 'siid': 2, 'piid': 5, 'code': -4004}, {'did': 'angle', 'siid': 2, 'piid': 6, 'code': -4004}, {'did': 'delay_off_countdown', 'siid': 2, 'piid': 8, 'code': -4004}, {'did': 'motor_control', 'siid': 2, 'piid': 10, 'code': -4004}, {'did': 'speed', 'siid': 2, 'piid': 11, 'code': -4004}, {'did': 'child_lock', 'siid': 3, 'piid': 1, 'code': -4004}], 'exe_time': 141}
2023-07-27 20:59:23.837 DEBUG (MainThread) [custom_components.xiaomi_miio_fan.fan] Got new state: <FanStatusP39 angle=None child_lock=None delay_off_countdown=None fan_level=None fan_speed=None mode=ValueError oscillate=None power=None>
2023-07-27 20:59:23.839 ERROR (MainThread) [homeassistant.components.fan] xiaomi_miio_fan: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 570, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 940, in async_device_update
    await self.async_update()
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2180, in async_update
    self._natural_mode = state.mode == OperationModeFanP39.Nature
                         ^^^^^^^^^^
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2281, in mode
    return OperationModeFanP39(self.data["mode"]).name
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 1128, in __new__
    raise ve_exc
ValueError: None is not a valid OperationModeFanP39

@jan-sindelar
Copy link

Hi,

I can confirm this behavior, same error message as traysh reported above:

Logger: homeassistant.components.fan
Source: custom_components/xiaomi_miio_fan/fan.py:2281
Integration: Ventilátor (documentation, issues)
First occurred: 21:34:28 (1 occurrences)
Last logged: 21:34:28

xiaomi_miio_fan: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 570, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 940, in async_device_update
    await self.async_update()
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2180, in async_update
    self._natural_mode = state.mode == OperationModeFanP39.Nature
                         ^^^^^^^^^^
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2281, in mode
    return OperationModeFanP39(self.data["mode"]).name
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 1128, in __new__
    raise ve_exc
ValueError: None is not a valid OperationModeFanP39

@Landrash
Copy link

@Landrash I own the same device and would love to see it supported soon.

I got as far as the pr that "fixed" this one. I'm unsure why this happens with the exception that the p39 is uses genericmiot instead of fanmiot in the upstream library.

@Landrash
Copy link

@paranerd If possible could you give and example of your use of this with your fan?

@paranerd
Copy link
Contributor

@Landrash I'm not sure I understand your question 🤔. I'll be mainly using the integration to turn the fan on and off but you COULD do all sorts of other things like:

  • Change the angle
  • Turn on/off oscillation
  • Turn on/off child lock
  • Set speed
  • ...

Hope this helps 😊

@Landrash
Copy link

@Landrash I'm not sure I understand your question 🤔. I'll be mainly using the integration to turn the fan on and off but you COULD do all sorts of other things like:

  • Change the angle
  • Turn on/off oscillation
  • Turn on/off child lock
  • Set speed
  • ...

Hope this helps 😊

Sorry for being unclear @paranerd

Your response was very clear. I'm assuming you added it in yaml?

If possible a sanitized copy of your yaml entry might help others diagnose the issue.
Also what version of HA are you running?

@paranerd
Copy link
Contributor

Oh wow, sorry, I hadn't seen the rest of this thread!

Sure, here's my configuration.yaml excerpt:

fan:
  - platform: xiaomi_miio_fan
    name: "Ventilator"
    host: 192.168.x.x
    token: 1234567890abcdef
    model: dmaker.fan.p39

However, this is running on mid-dev code. I don't have access to my dev machines atm to check if/how it works with the release but can do once I get back.

@paranerd
Copy link
Contributor

paranerd commented Aug 6, 2023

I just set up everything again with the latest code and... it works on my machine^^
One thing to keep in mind, though, is that I'm using the manual approach of copying into the custom_components/ directory and I'm not using HACS so maybe there's an issue with this combination?!

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023

I just tried the manual install approach, got exactly the same result.
I'm now running Home Assistant 2023.9.0, container version. @paranerd what version are you using? Is it possible you manually installed some dependencies we don't have? And do you suggest any way to debug this?

@paranerd
Copy link
Contributor

paranerd commented Sep 10, 2023

I checked out origin/develop - maybe that's it?
Running Home Assistant 2023.9.1

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023

I don't think so, I checked out the same branch as you.
I see in my logs the fan is responding with code -4004, it's probably related to that.

@paranerd
Copy link
Contributor

I don't know what to say. Don't have anything installed additionally, it just worked^^

A couple of debugging steps:

  • Did you use the correct token?
  • Is your Fan in the same subnet as Home Assistant?

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023 via email

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023

I installed miiocli in my computer and verified the following:

  • my token is correct
  • I can communicate with the fan and list its properties and status with miiocli genericmiot
  • The same command won't run in the Home Assistant's docker container, resuting in Error: No such command 'genericmiot'. It is probably too outdated to support genericmiot
  • Running miiocli fanmiot --ip 10.32.33.141 --token <MY_TOKEN> status in HA's container results in ValueError: None is not a valid OperationModeMiot, which is very similar to the error I get when using this custom component, so it is probably related
  • miiocli fanmiot --ip 10.32.33.141 --token <MY_TOKEN> status in my linux computer will not result in the above error, but won't print any information either

@paranerd
Copy link
Contributor

I just did a fresh deployment:

  • mkdir -p ~/ha-test/config/custom_components

  • git pull https://github.com/syssi/xiaomi_fan.git

  • cp -r xiaomi_fan/custom_components/xiaomi_miio_fan ~/ha-test/config/custom_components

  • nano ~/ha-test/config/configuration.yaml:

    fan:
      - platform: xiaomi_miio_fan
        name: "Ventilator"
        host: 192.168.x.x
        token: 1234567890abcd
        model: dmaker.fan.p39
    
  • cd ~/ha-test/

  • Added my docker-compose.yaml

  • sudo docker compose up -d

  • Logged in, Fan showed up and was fully controllable.

That's all I did. Hate to say "It works on my machine" but that's just how it is 😅

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023 via email

@traysh
Copy link
Contributor

traysh commented Sep 10, 2023

@paranerd actually, I found a bug in the code, commenting this line makes everything work for me.

I believe it happens because the motor_control property is write only, not readable, according to the spec. And the mapping variable is being used to construct the status request to the fan, so the request inappropriately includes this property, resulting in a response with nothing set and the -4004 error code.

I have no idea why it works for you, maybe you have an earlier firmware in your fan that is not so picky with the request correctness.

Fix in this PR.

@fv623
Copy link

fv623 commented Sep 11, 2023

Hi, I'm one of the few people experiencing the same problem as described above. I just tried the solution proposed by @traysh and something has definitely changed, but i am still getting an error in logs, just a different one:

Logger: homeassistant.components.fan
Source: custom_components/xiaomi_miio_fan/fan.py:2281
Integration: Ventilátor (documentation, issues)
First occurred: 09:13:43 (1 occurrences)
Last logged: 09:13:43

xiaomi_miio_fan: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 576, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 938, in async_device_update
    await self.async_update()
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2180, in async_update
    self._natural_mode = state.mode == OperationModeFanP39.Nature
                         ^^^^^^^^^^
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2281, in mode
    return OperationModeFanP39(self.data["mode"]).name
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 1128, in __new__
    raise ve_exc
ValueError: 2 is not a valid OperationModeFanP39

Does anybody know, what else could be wrong?

@traysh
Copy link
Contributor

traysh commented Sep 11, 2023

Hi, I'm one of the few people experiencing the same problem as described above. I just tried the solution proposed by @traysh and something has definitely changed, but i am still getting an error in logs, just a different one:

Logger: homeassistant.components.fan
Source: custom_components/xiaomi_miio_fan/fan.py:2281
Integration: Ventilátor (documentation, issues)
First occurred: 09:13:43 (1 occurrences)
Last logged: 09:13:43

xiaomi_miio_fan: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 576, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 938, in async_device_update
    await self.async_update()
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2180, in async_update
    self._natural_mode = state.mode == OperationModeFanP39.Nature
                         ^^^^^^^^^^
  File "/config/custom_components/xiaomi_miio_fan/fan.py", line 2281, in mode
    return OperationModeFanP39(self.data["mode"]).name
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 1128, in __new__
    raise ve_exc
ValueError: 2 is not a valid OperationModeFanP39

Does anybody know, what else could be wrong?

@fv623 looking at the spec, the code is also missing a mode type (sleep), and that's what is causing the problem for you. I can add it when I have time, maybe tonight.

Still, the PR that was just merged will make the code closer to correct.

@traysh
Copy link
Contributor

traysh commented Sep 12, 2023

@fv623 new PR is here, fixing the problem you reported: #231

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 a pull request may close this issue.

8 participants