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

[Bug]: Issues with new boolean cover implementation #489

Open
3 tasks done
donaldkwong opened this issue Jan 17, 2025 · 43 comments
Open
3 tasks done

[Bug]: Issues with new boolean cover implementation #489

donaldkwong opened this issue Jan 17, 2025 · 43 comments
Labels
bug Something isn't working master/next-release Fixed in master branch, Will be ready in the next release

Comments

@donaldkwong
Copy link

donaldkwong commented Jan 17, 2025

LocalTuya Version

2025.1.1

Home Assistant Version

2025.1.2

Environment

  • Does the device work using the Home Assistant Tuya Cloud component?
  • Is this device connected to another local integration, including Home Assistant and any other tools?
  • The devices are within the same HA subnet, and they get discovered automatically when I add them

What happened?

Thanks for addressing #482 so quickly! Local Tuya is working better with my garage opener, but there are still a couple of issues:

  1. The initial state of the entity is "Open" right after creating it even though the garage door is closed.
  2. The entity's state moves immediately "Closed" while the garage door is closing (the cloud version of this entity only goes to the "Closed" state when the door is fully closed).
  3. When the entity is in the "Open" state, the close button is still disabled, so I can't close the door.

See attached video showing how the cloud and local entities are used and how they differ:

Screen.Recording.2025-01-17.at.10.23.39.AM.mov

Steps to reproduce.

  1. Add new garage device with 2025.1.1 version of Local Tuya with automatic configuration.
  2. Note that the initial state of the entity is "Open" even though the door is closed.
  3. Use Cloud version of entity to open and close garage door. Local version of entity now has correct state.
  4. Use local version of entity to open the garage door. Physical garage door opens, but entity's close button is still disabled. Cannot use it to close the garage door.
  5. Use Cloud version of entity to close the garage door. Physical garage door closes, but local version of entity's state moves immediately into "Closed" state before door is fully closed.

Relevant log output

Diagnostics information.

localtuya-01JHPZCGJGTFRBJY1GS78BRZ12-Garage door -b0cd8b7e5ad5a3ce7ba20da46c5ad83e.json

@donaldkwong donaldkwong added the bug Something isn't working label Jan 17, 2025
@donaldkwong
Copy link
Author

Just deleted and re-added the device to try again and I couldn't reproduce issues 1 and 3 above. Issue 2 (entity goes immediately into "Closed" state) still happens though.

@donaldkwong
Copy link
Author

The second time I went through manual configuration, but didn't change any of the default settings. Here is the diagnostics for the second time:

localtuya-01JHPZCGJGTFRBJY1GS78BRZ12-Garage door -b0cd8b7e5ad5a3ce7ba20da46c5ad83e (1).json

@xZetsubou
Copy link
Owner

Enable the debug for integration and device and do the same test you did above close/open and post the logs here.

@donaldkwong
Copy link
Author

Logs from adding the device:

2025-01-17 12:54:02.043 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 12:54:02.043 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 12:54:02.044 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 3 waiting for seq. number -102
2025-01-17 12:54:02.175 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 4 TuyaMessage(seqno=30013, cmd=4, retcode=0, payload=b'\xa1\xc8M!J\x87\xe6\xa3\xb9\xaa$\x81\x88\xe4\x89\xa0>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\x064;H\x07\x93\xd2\x13\xc8\xcfI8\xa0G\xa2\xcel\x14JW\x86<\xf8\x1b$0\x9e\xa3\x00\x02\x8e\xcb', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:54:02.176 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Got key negotiation response
2025-01-17 12:54:02.176 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] decrypted session key negotiation step 2: payload=b'07ebc00e7badde319e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 12:54:02.177 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 5: b'\x94\x9a\xe20\x91=\xdb\xe8\x93u(N:\x91\xea\xed~\x0cl%\x148\xa02\xd8 ^rfb\xd6b'
2025-01-17 12:54:02.177 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Session key negotiate success! session key: b"\x97[=\xb13'2nJ\xf4U.oo\xd7\x9a"
2025-01-17 12:54:02.177 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 12:54:02.177 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.177 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.228 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 30014
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=30014, cmd=16, retcode=0, payload=b"\xed\x15\xf2\xd0\x86\x92\xdbS\xb67N\x89\xcb\xfb\xca\xb9\x08R\xf5\x87Z\x8av\xbe\x05Y\xfa\x07\xb4A\x05\xc4\xb0\x15em\xa7\xdd8U\x9c]\xc1\xa9\xb2#-\x8a>\xd2\x1f\xaf\xde'\xb2\x92v\xfd\xc9\x8b\xbc(8\xd2", crc=b"\xbd\xa4\xd7\xce\xa7s3jP>\xccj\xd3BrJ'\x8a\x93q\xa1,\xa0<d\x91\x87\xad\xcdN\x0cy", crc_good=True, prefix=21930, iv=None)
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 30014
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.281 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.282 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 30015
2025-01-17 12:54:02.385 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=30015, cmd=16, retcode=0, payload=b"\xed\x15\xf2\xd0\x86\x92\xdbS\xb67N\x89\xcb\xfb\xca\xb9\x08R\xf5\x87Z\x8av\xbe\x05Y\xfa\x07\xb4A\x05\xc4\xb0\x15em\xa7\xdd8U\x9c]\xc1\xa9\xb2#-\x8a>\xd2\x1f\xaf\xde'\xb2\x92v\xfd\xc9\x8b\xbc(8\xd2", crc=b'\xf7UX\xe5\xad\x0f\x9d\x10Zm\x00\x0bX\x08\xac\xcc\xfd\xc0\xe5\xc4[\x1d\x97\x8a\xc5\xca\xdc\xe8\xeeG\xfc\x8d', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:54:02.385 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 30015
2025-01-17 12:54:02.385 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 12:54:02.386 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 12:54:02.386 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.386 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.386 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 30016
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=30016, cmd=16, retcode=0, payload=b"\xed\x15\xf2\xd0\x86\x92\xdbS\xb67N\x89\xcb\xfb\xca\xb9\x08R\xf5\x87Z\x8av\xbe\x05Y\xfa\x07\xb4A\x05\xc4\xb0\x15em\xa7\xdd8U\x9c]\xc1\xa9\xb2#-\x8a>\xd2\x1f\xaf\xde'\xb2\x92v\xfd\xc9\x8b\xbc(8\xd2", crc=b"Q'\xc3\x80\xe1\x1ck\x1d\xd2i\xf0\xa2\xa4h\xd0\xf0\x04L\xf6\x85Cq\xcdWK\xe4h\xf8ek\xbcy", crc_good=True, prefix=21930, iv=None)
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 30016
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.601 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737147242"}'
2025-01-17 12:54:02.602 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 30017
2025-01-17 12:54:02.692 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=30017, cmd=16, retcode=0, payload=b"\xed\x15\xf2\xd0\x86\x92\xdbS\xb67N\x89\xcb\xfb\xca\xb9\x08R\xf5\x87Z\x8av\xbe\x05Y\xfa\x07\xb4A\x05\xc4\xb0\x15em\xa7\xdd8U\x9c]\xc1\xa9\xb2#-\x8a>\xd2\x1f\xaf\xde'\xb2\x92v\xfd\xc9\x8b\xbc(8\xd2", crc=b'Y4t#\xa0s\xcf"\xd4ZC\xa2g\x89\xb1\xcc\x7f\xb5\xb2\x14\x90\xa78\xef\x0c#\xca\xb29G\x8b\xc9', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:54:02.692 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 30017
2025-01-17 12:54:02.692 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 12:54:02.693 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Detected DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 12:54:02.693 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Closing connection
2025-01-17 12:54:02.693 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 12:54:02.693 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Total DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 12:54:02.694 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Connection lost: None
2025-01-17 12:54:02.694 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 12:54:10.028 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 12:54:10.028 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 12:54:10.029 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 12:54:10.029 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 12:54:15.080 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 12:54:15.084 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [ebb...8mn - OmniBreeze Tower Fan 1] Connection lost: None
2025-01-17 12:54:15.084 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb1...xrv - OmniBreeze Tower Fan 2] Connection lost: None
2025-01-17 12:54:15.085 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [150...12e - Living Room Light] Connection lost: None
2025-01-17 12:54:15.087 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Closed connection
2025-01-17 12:54:15.087 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Closed connection
2025-01-17 12:54:15.087 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Closed connection
2025-01-17 12:54:15.092 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Initialized cover []
2025-01-17 12:54:15.093 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Adding cover.garage_door with configuration: {'id': '1', 'entity_category': 'None', 'commands_set': 'open_close_stop', 'positioning_mode': 'none', 'position_inverted': False, 'span_time': 25.0, 'friendly_name': '', 'platform': 'cover'}
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 12:54:15.097 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 12:54:15.103 INFO (MainThread) [custom_components.localtuya] Setup completed

@donaldkwong
Copy link
Author

Logs from using the Cloud entity's card to open and close the garage door:

2025-01-17 12:55:28.387 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:55:28.388 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:28.388 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:28.388 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:55:28.468 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64291, cmd=9, retcode=0, payload=b'', crc=b'L\xa6\x8d\x9f\x99\x90\xbc\x1fm\xcc\xff\xad.\xae\xcb\xa2\xce\x03w\x10\x85(\xea\xd3\xfc\xd7]t\xfb\x8a\xac\x8e', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:28.468 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:55:28.468 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64291
2025-01-17 12:55:30.210 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64292, cmd=8, retcode=0, payload=b"\xb19\xaa'\xf2\x83D\xc2\xcc\xfb=I\x16e_@\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s\x1e) \x05\x0e\xef\x0e\x14\xa3J\x05\x10.\x81\xaa'\xee\x0ek\xbb\x9b\x93\xdc\xde\x1c\x84\x1ew\x0e\x8f{\xb3j\xa2\xebXt\xb1\xaa\xdbah\x8c\x889\xa1\x86y", crc=b'\xecC;\xec\xfb\xd1\n#\xdbB\x85X\x93\x80\xda<\xf2\xe5\xd5\xee\x88\xa2P\xc2\xc1\n\xaa\xe8_\x15\xf1#', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:30.211 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:55:30.211 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147331,"data":{"dps":{"1":true}}}'
2025-01-17 12:55:30.213 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 12:55:30.618 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64293, cmd=8, retcode=0, payload=b"\xbfe\xda\x86?\xe7\xe8\xf3\x0e}i\xfc\x02\xe8Dg\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s\x1e) \x05\x0e\xef\x0e\x14\xa3J\x05\x10.\x81\xaa'\xb3\xd6\xe4\xb3x^\x9a\x03 \xedObI\x05\x9e\xeel\r\x1e\n\xc3$6\x80Y\xf5\xc6ii\xb3-\xd1", crc=b'Y\xb4\xea\xcb\x1e\xbc\xf4v\xe5\x90F\xfd\xe9\x95\xc5\x85]\xa7\xc3\xdb(\t\xcfA!{\xc2yt\x15\x17y', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:30.618 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:55:30.618 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147331,"data":{"dps":{"3":true,"5":600}}}'
2025-01-17 12:55:30.620 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 12:55:33.878 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 12:55:33.878 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 12:55:33.878 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 12:55:33.879 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 12:55:37.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:55:37.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:37.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:37.470 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:55:37.580 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64294, cmd=9, retcode=0, payload=b'', crc=b')q\xabn-i\xf7k\x16\x10\xd6\xc3[O,@d\xb7"\xbd2\r\x92}\xe6\x9e\xf0k\xedr\xf6^', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:37.580 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:55:37.580 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64294
2025-01-17 12:55:44.762 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64295, cmd=8, retcode=0, payload=b'\xcf\xb0\xe0\x83\x1b}\x12\x04\xc8\xcf\x12\xb9=\xb0!\x08\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03sAf\xc95i\xaa1\x96\x04\xad4\xb9Z\xb5\xdc\xe9J\x06\xa3\x12\xe0\x7f\x0c\xb8\xa6\x04\xe5\xe19Ki\xf1\xa8\x8a\xb9\x801\xd7A\x19\xf4\x06\xd4Y&\xb3Q#', crc=b'y\x91J\xe7\xf13\xadm\xa9\xf5\x05\x9b^\x11g$\x8d\x0b=\xa5\xba\xfc\xb5d\xa6x\x9b\x85\xb9\xcc\xff\xf5', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:44.762 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:55:44.762 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147345,"data":{"dps":{"1":false}}}'
2025-01-17 12:55:44.763 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 12:55:46.581 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:55:46.581 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:46.581 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:46.581 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:55:46.699 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64296, cmd=9, retcode=0, payload=b'', crc=b'\xeb\xbeu\x08~\xc6?Y\x04\x83e2\x18LC@i\xb9\xff\x8f\xd7\xac~\x8a`\x8f\x03\x81J\x94\x12l', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:46.699 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:55:46.699 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64296
2025-01-17 12:55:46.773 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 12:55:46.773 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 12:55:46.773 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 12:55:46.774 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 12:55:51.604 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64297, cmd=8, retcode=0, payload=b'\xe9\x15u\xe7z9\x82\xf4\xc7z\xeb\xaa.g\xf3\x0c\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s^\xd4N\x8b\xb2\x93\xf4-\xb7\xb8\x08\xc0\x7f\x02\x0f\xff\xf7\xe9\xc3g\xa5\xe8s\x85\xf7\xfc\xe0k\xf0\x10\r}\xb0\xd6\xfc\x91J,]\x8dZe\x13A\x96N\xbf\x10q\xc4m\x98"\xfcgH\xba\xbaF\xd2\xa1KL\xea', crc=b'\xa7\xa1\n\xcf\xc1m\x9d+|\xa2\x1a\xc4\x98\x18H\xea\xd1\x00\xe1U\xaf\x8e\xf7\xee\x90\xed\x9ee\x89\x16\x1c6', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:51.604 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:55:51.604 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147352,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'
2025-01-17 12:55:51.606 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 12:55:55.700 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:55:55.700 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:55.700 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:55:55.700 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:55:55.811 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64298, cmd=9, retcode=0, payload=b'', crc=b'\xeb\x992\t~6P\x81[wJ\x8a\x18\xde6\x82\x19\xf6v\xda\x8a\x1d+\\fP\x1f@\x9e\xd1\xfa\xe8', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:55:55.812 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:55:55.812 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64298
2025-01-17 12:56:04.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:56:04.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:04.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:04.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:56:04.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64299, cmd=9, retcode=0, payload=b'', crc=b' Vc\xcf?\x93|\xe6)\xf4\xba\xfav\xad\x0f\xddr\x93c\xaa\x1d\xe5\xdc\x8c\x95\xdeQ\x10\xaa\x9d\xd2\x9c', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:04.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:56:04.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64299

@donaldkwong
Copy link
Author

Logs from using the local entity's card to open and close the garage:

2025-01-17 12:56:29.564 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 12:56:29.565 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'1': True}
2025-01-17 12:56:29.566 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737147389,"data":{"dps":{"1":true}}}'
2025-01-17 12:56:29.566 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737147389,"data":{"dps":{"1":true}}}'
2025-01-17 12:56:29.566 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 64302
2025-01-17 12:56:29.705 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=64302, cmd=13, retcode=0, payload=b'', crc=b'\xbae<qR\xda\xb1\xf1n\x81y\x13\xab\xf3\xcd+\x0c\xfb\x9d-\xee\xb6\xab\xa4\x0cF\x04\xa7%\x7f\x91k', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:29.705 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 64302
2025-01-17 12:56:29.705 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 64302
2025-01-17 12:56:29.705 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=64302 self.seqno=64303
2025-01-17 12:56:29.705 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 64302
2025-01-17 12:56:29.881 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64303, cmd=8, retcode=0, payload=b'\xff6\x90%\xb2\x04\xf9\x15\x8f\xcf\xa8*J\xaei\xf3\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s\x10\x90\xe9\xe0\xdeD\x98{\x1aS\x86\xfd\xb3\xac\xaa\xd9\xee\x0ek\xbb\x9b\x93\xdc\xde\x1c\x84\x1ew\x0e\x8f{\xb3j\xa2\xebXt\xb1\xaa\xdbah\x8c\x889\xa1\x86y', crc=b"\xe8R\xc5T\x92v\x17,\xfbIC\x07\x08\x93BM3$\xc7\xda\\h\t\x1cx\x94\xced[*\x03'", crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:29.881 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:56:29.881 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147390,"data":{"dps":{"1":true}}}'
2025-01-17 12:56:29.882 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 12:56:30.382 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64304, cmd=8, retcode=0, payload=b'\xa2\xd4\x9b\x8dG\xderY#\xfe\xf7\xd0\xe1-\xc51\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s\xdb\xdc8\xb4$H\xa9\xd2\x8a\x14\xfa\x07\xcd\xe0g#\xb3\xd6\xe4\xb3x^\x9a\x03 \xedObI\x05\x9e\xeel\r\x1e\n\xc3$6\x80Y\xf5\xc6ii\xb3-\xd1', crc=b'\xc0\xb3UO\x80*M\xebL\xfe\x0f\xb8\x8f:c8xP\xab\xb9\xcb\xffT\x195\rm^\xeb\xc4\x05]', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:30.382 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:56:30.382 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147391,"data":{"dps":{"3":true,"5":600}}}'
2025-01-17 12:56:30.383 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 12:56:33.584 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:56:33.584 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:33.585 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:33.585 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:56:33.704 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64305, cmd=9, retcode=0, payload=b'', crc=b'aM\xac)`$\xf5\xc1x\x8f\x04\xc1\xfd<\x96\xbe\xf9\x9a\xf0yW\x05/K\x8d\x84\xf4\xb7#\xf0\xd8Q', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:33.704 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:56:33.704 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64305
2025-01-17 12:56:38.451 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 12:56:38.451 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 12:56:38.451 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 12:56:38.455 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 12:56:42.706 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:56:42.706 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:42.706 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:42.707 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:56:42.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64306, cmd=9, retcode=0, payload=b'', crc=b'\x04\x979\x1a?\xbc\xa6\x7f\x93f\x1c\xd5\xe7\xba\x0b\x00\x93g \xc3\xb4\x93\xc7Vm\xb3\xc7@\xcf\xcc\x11\x1e', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:42.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:56:42.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64306
2025-01-17 12:56:44.237 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command False to cover 
2025-01-17 12:56:44.240 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'1': False}
2025-01-17 12:56:44.240 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737147404,"data":{"dps":{"1":false}}}'
2025-01-17 12:56:44.240 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737147404,"data":{"dps":{"1":false}}}'
2025-01-17 12:56:44.241 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 64307
2025-01-17 12:56:44.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=64307, cmd=13, retcode=0, payload=b'', crc=b'\xbb\xd5\xcd\x1f-N\x84\x84X\x19\xcd\xb9\xd2\x9b\xcf\xd0\xea\xb5N\xa9oF1}4\xd0\xe0\xfd\xearY\xa5', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:44.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 64307
2025-01-17 12:56:44.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 64307
2025-01-17 12:56:44.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=64307 self.seqno=64308
2025-01-17 12:56:44.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 64307
2025-01-17 12:56:44.531 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64308, cmd=8, retcode=0, payload=b'\xb3\x91\x82 \xaaM\x8a\xbf\xfd\x12A"\xbc\xfa\xbe\xa9\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03s\xf0\x89)\xb2(\xb2\xc2\x97t\xd8\xa7\x0b\xa7\x9aY\xf9J\x06\xa3\x12\xe0\x7f\x0c\xb8\xa6\x04\xe5\xe19Ki\xf1\xa8\x8a\xb9\x801\xd7A\x19\xf4\x06\xd4Y&\xb3Q#', crc=b',0\x9e\xc1]2\xbf\xe59\xe7\xe6.\r\x81\xa0\x0fA\xdb\xa73\xda\xe9\xdebC\xfe1\xf4n\xd5\xf66', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:44.531 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:56:44.531 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147405,"data":{"dps":{"1":false}}}'
2025-01-17 12:56:44.532 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 12:56:51.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=64309, cmd=8, retcode=0, payload=b'\x14\xd6\xca\xd7$:\xb9\xb5qs\xd9\x7f\xe3\x80\xab\xef\x01\xd2K[c\x84\xab\t\x10\xf2\xc71\x1b~\x03sFFp\x99\x1cg\x98\xf7G\xb3\x97p\x7f\xe7\x17\x07\xf7\xe9\xc3g\xa5\xe8s\x85\xf7\xfc\xe0k\xf0\x10\r}\xb0\xd6\xfc\x91J,]\x8dZe\x13A\x96N\xbf\x10q\xc4m\x98"\xfcgH\xba\xbaF\xd2\xa1KL\xea', crc=b'\xf0LI\x0b\x1a\xae\xf0f\x014\xb4#\xde\xbc\xacR\x10\xf2[\xa0\xa8T\x9fG;\xc8\x88\x83^z\xf3\x8e', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:51.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 12:56:51.351 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737147412,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'
2025-01-17 12:56:51.352 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 12:56:51.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 12:56:51.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:51.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 12:56:51.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 12:56:51.923 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=64310, cmd=9, retcode=0, payload=b'', crc=b'\xbd\x8e\x1egr\xfd\xe4 \xc1\x1fWjo\xd5\x98\xdb\xf5_\xf4\x8a\x8e\x04\xd4\xfa\tzW\xa6\xcby<]', crc_good=True, prefix=21930, iv=None)
2025-01-17 12:56:51.923 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 12:56:51.923 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 64310

@xZetsubou xZetsubou added the master/next-release Fixed in master branch, Will be ready in the next release label Jan 17, 2025
@donaldkwong
Copy link
Author

❤️

Copy link

This issue was closed because it was resolved on the release: 2025.1.1

@github-actions github-actions bot added stale and removed master/next-release Fixed in master branch, Will be ready in the next release stale labels Jan 17, 2025
@xZetsubou
Copy link
Owner

xZetsubou commented Jan 17, 2025

Try with latest update, reconfigure is required since current position now support boolean state "DPID 3 for your garage"

edit: I think the issue that it's instantly return "closed" or "open" is still present can you confirm it?

@donaldkwong
Copy link
Author

Thanks again for tackling these issues so quickly. This update seems to be a bit of a regression, though. I tried both DPID 1 and DPID 3 and neither are working correctly. With DPID 1 (the default), the state never transitions from "Closed". Clicking on the open button will open the garage door, but the close button is never enabled as a result. With DPID 3, clicking on the open button doesn't do anything and the state is also never updated.

@donaldkwong
Copy link
Author

Here are logs for DPID 3 (for adding the device and clicking on the open button, which doesn't seem trigger the door to open):

2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 3 waiting for seq. number -102
2025-01-17 15:18:05.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 4 TuyaMessage(seqno=21321, cmd=4, retcode=0, payload=b'\x1c\xf7]M}\x9a"{\xf0t\x91\xe5G\xf06\'>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\xb18\x8a&\x88\xad\x12\x13 xa\x88\xba\x96\x8f\xad\xa2\xd8+\x01%\xb14\xcar\xb7tY{\xa7\xfe\x92', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:05.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Got key negotiation response
2025-01-17 15:18:05.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] decrypted session key negotiation step 2: payload=b'72d29b91b3150e539e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:18:05.815 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 5: b'\xaf]\xfb\xc5\xe5.\xcbp\x9f\xa4B\xdc\xa4\x84\x85\x91\xdd&\xc4\xdb\x85\xebD\x13\xcd\xb0\x89i/\xc3\xc5\xe2'
2025-01-17 15:18:05.835 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Session key negotiate success! session key: b'!Qf\x8e:\x9aN:\xa6\xd5Z~\x04\xfc3\x14'
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155885"}'
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155885"}'
2025-01-17 15:18:05.887 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21322
2025-01-17 15:18:06.034 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21322, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\x87V\xef\xd4$v}v\x93}\xe65\xbd\x10\x9c6\xa4\xf8\x94o\xd4-\x9b\xc8\x16\xc6\xa7Jn\xc5\x9b\x9f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21322
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21323
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21323, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\xfadd\x0c\xe0S\xb8\'\xce\x05A2\xc4l\x92"\xf9\x90\x89\x83\x98\xda\x87\xa4\xaeg\xb7\xb5qe\xb2Q', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21323
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21324
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21324, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\xbb $N}\xe0\xe7\xf7DK\xf8\xd3\xc1\xc7\x9cy$\xd8\x91=7j*\xe3W\xe1\xab\x9f\xbf\x81kR', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21324
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21325
2025-01-17 15:18:06.533 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21325, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'_9\xbc\xc2\x9fl\xad[Tv2\x10xK\xdf]\xf2\xb4\xa8\xcd\xd4$!zzu\x85DTmK\xe2', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.533 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21325
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Detected DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Closing connection
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Total DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:18:06.536 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Connection lost: None
2025-01-17 15:18:06.536 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:18:31.227 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 15:18:31.230 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [ebb...8mn - OmniBreeze Tower Fan 1] Connection lost: None
2025-01-17 15:18:31.231 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb1...xrv - OmniBreeze Tower Fan 2] Connection lost: None
2025-01-17 15:18:31.231 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [150...12e - Living Room Light] Connection lost: None
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Closed connection
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Closed connection
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Closed connection
2025-01-17 15:18:31.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Initialized cover []
2025-01-17 15:18:31.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Adding cover.garage_door with configuration: {'id': '3', 'entity_category': 'None', 'commands_set': 'open_close_stop', 'positioning_mode': 'none', 'position_inverted': False, 'span_time': 25.0, 'friendly_name': '', 'platform': 'cover'}
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:18:31.248 INFO (MainThread) [custom_components.localtuya] Setup completed
2025-01-17 15:18:31.250 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Trying to connect to: 192.168.86.35...
2025-01-17 15:18:31.251 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Trying to connect to: 192.168.86.36...
2025-01-17 15:18:31.255 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Trying to connect to: 192.168.86.33...
2025-01-17 15:18:31.256 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Trying to connect to: 192.168.86.30...
2025-01-17 15:18:31.297 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Success: connected to: 192.168.86.35
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Retrieving initial state
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 3 waiting for seq. number -102
2025-01-17 15:18:31.503 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Success: connected to: 192.168.86.33
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 15:18:31.505 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:18:31.506 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_1 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:18:31.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 4 TuyaMessage(seqno=39959, cmd=4, retcode=0, payload=b'0p\xc7\x9d\x87s\xd1 xP\xd8\xbf\xc0\xe5\xdb\x03>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\x8cZ\x95\x9bT\xecs\xc0.\x88\x1d(\x82\xc4\xa7OU\xd7\x99\x04\x94e\xa0\xda\xf6\xb9\x12;\xe6j\x92\xcc', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:31.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got key negotiation response
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] decrypted session key negotiation step 2: payload=b'5c10cbdd9c53cb5e9e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 5: b'\x11\xc4\xb5\x18\xd1\x0c\x1a&pPt\x13}\xd5\xab6\xf7\x8c\xe4\xdc\x05)9$\xad \xf0F}?\xec\xc0'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Session key negotiate success! session key: b'\x01\x1f|\x03l{\x01\x97lh_\xdc\x89\xd2\xdf\xf1'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155911"}'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155911"}'
2025-01-17 15:18:31.564 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 16 waiting for seq. number 39960
2025-01-17 15:18:31.645 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-17 15:18:31.715 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Success: connected to: 192.168.86.36
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_oscillating : True
2025-01-17 15:18:31.717 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:18:31.718 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_2 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 16 TuyaMessage(seqno=39960, cmd=16, retcode=0, payload=b'>|D\x1bA\\\xf3e\x97XU\xaa\x9f\xbd&\rv\x18Q@\x13\x97),IW`\x94\x88\xff\xa4J\xe9\xdc\x00 s\xdf+\xc3J3\xf1q\xe0J\xb0\x9e\xae\x7f\xbe\xef\xec\xde\xcd\x12$VKk\xe2\xd8\xa3Z', crc=b'x-\x86\x08\x7fVr<\x0c0.\\;5\xe9)\xc66!\xd2p\xd4\xbe\x1f\xf1"~>\xb8\xa4\xe6\xf8', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39960
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Success: connected to: 192.168.86.30
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  (DP 3) - Not restoring as restore on reconnect is disabled for this entity and the entity has an initial status or it is not a passive entity
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Started keep alive loop.
2025-01-17 15:18:31.732 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:31.732 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:39.742 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155919,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155919,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:39.745 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39961, cmd=13, retcode=0, payload=b'', crc=b'\x9c\xd4\xe3\xee\x0c\xa8\x8d\x12@\x07\xdb\xbe6\xea?(\xe1\xc2\x91G\xf0\xc0\xf4i\x95@ZBtOn\xcd', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39961 self.seqno=39962
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39961
2025-01-17 15:18:39.793 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:40.799 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39962, cmd=9, retcode=0, payload=b'', crc=b'7\x18W#m\xe0~\ti&\xb1 \xc8s\x99\xc37$]N\xf7\xa5\xdc\xec\xa3[\xdbQ#\x0b\x8c\x1f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:40.800 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:40.800 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39962
2025-01-17 15:18:41.720 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155921,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155921,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39963, cmd=13, retcode=0, payload=b'', crc=b'"q\rS\xd1\xb5\xf5\x11\xb6tA\xafU\xa4:\x9f\xba\r@\xe3$\xdd\xbe\xae\x93\x91\x88,\xa4\xe1o\xff', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39963 self.seqno=39964
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39963
2025-01-17 15:18:41.845 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:43.594 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155923,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155923,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:43.596 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39964, cmd=13, retcode=0, payload=b'', crc=b"\xd3\x86w\x10\x9a\xbf\x89\x9d\x14\xe7C!G`\x8b8\xce\x0e\x97\x0b\x8d\xe1'\x10\x9c\xc8b'w\xcd\x9a\xc0", crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39964 self.seqno=39965
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39965, cmd=9, retcode=0, payload=b'', crc=b'V\xe18\xf8\x8de\x01\xbb\x19E\x84\xd8\x01_u\xcd\x94*M\xd1\xb7_xF\xc3)\x1a\x0fv\x82\xdd\xfe', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39965
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:58.919 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39966, cmd=9, retcode=0, payload=b'', crc=b'\x9e3\x8cH#\x08\xa7\xcbIp\x86\xf7\xc5\x8f\xaf\xa2\xd5`\x00\xdf\xe6\xc3\xcf`\x8b.A\xdeWn\xbd\x7f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39966
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39967, cmd=9, retcode=0, payload=b'', crc=b'Xr5B\xe8\x8a\xe5G\xb7S\xd8lV\xbf\xee6\xc0\x8f\xc0N\xfd\x82\xe4r\x19<\xdd\xd1\x04\xee\xe8\xa4', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39967
2025-01-17 15:19:08.252 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 15:19:08.253 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Closing connection
2025-01-17 15:19:08.253 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Cleaning up session.
2025-01-17 15:19:08.263 INFO (MainThread) [custom_components.localtuya] Device eb2d92a6870c513122umtv removed.

@donaldkwong
Copy link
Author

Here are logs for DPID 1 (for adding the device and clicking on the open button, which does open the garage door, but the state is still "Closed", I had to use the Cloud version of the entity to close the door):

2025-01-17 15:17:39.155 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2025-01-17 15:17:39.156 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration localtuya which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2025-01-17 15:17:41.765 DEBUG (MainThread) [custom_components.localtuya.discovery] Listening to broadcasts on UDP port 6666, 6667
2025-01-17 15:17:42.457 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-17 15:17:43.872 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 15:17:43.872 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:17:43.873 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:17:43.886 INFO (MainThread) [custom_components.localtuya] Setup completed
2025-01-17 15:17:43.892 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Trying to connect to: 192.168.86.35...
2025-01-17 15:17:43.893 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Trying to connect to: 192.168.86.36...
2025-01-17 15:17:43.894 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Trying to connect to: 192.168.86.33...
2025-01-17 15:17:44.280 DEBUG (MainThread) [custom_components.localtuya.discovery] Discovered device: {'ip': '192.168.86.33', 'gwId': 'ebb0e3812085363279g8mn', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'c85duuajuaqjvjaj', 'version': '3.4', 'token': True, 'wf_cfg': True}
2025-01-17 15:17:44.305 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Success: connected to: 192.168.86.33
2025-01-17 15:17:44.306 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:17:44.306 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:17:44.306 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 15:17:44.309 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:17:44.310 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_1 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:17:44.321 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Success: connected to: 192.168.86.35
2025-01-17 15:17:44.406 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Success: connected to: 192.168.86.36
2025-01-17 15:17:44.407 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:17:44.407 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:17:44.407 DEBUG (SyncWorker_5) [custom_components.localtuya.fan] Fan current_oscillating : True
2025-01-17 15:17:44.409 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:17:44.409 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_2 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:17:44.879 DEBUG (MainThread) [custom_components.localtuya.discovery] Discovered device: {'ip': '192.168.86.36', 'gwId': 'eb1558c2707e8e8573qxrv', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'c85duuajuaqjvjaj', 'version': '3.4', 'token': True, 'wf_cfg': True}
2025-01-17 15:17:44.916 DEBUG (MainThread) [custom_components.localtuya.discovery] Discovered device: {'ip': '192.168.86.30', 'gwId': 'eb2d92a6870c513122umtv', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8tg9kykj4g8dw', 'version': '3.4', 'token': True, 'wf_cfg': True}
2025-01-17 15:17:56.766 DEBUG (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Devices has been updated a minutes ago.
2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:18:05.780 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 3 waiting for seq. number -102
2025-01-17 15:18:05.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 4 TuyaMessage(seqno=21321, cmd=4, retcode=0, payload=b'\x1c\xf7]M}\x9a"{\xf0t\x91\xe5G\xf06\'>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\xb18\x8a&\x88\xad\x12\x13 xa\x88\xba\x96\x8f\xad\xa2\xd8+\x01%\xb14\xcar\xb7tY{\xa7\xfe\x92', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:05.813 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Got key negotiation response
2025-01-17 15:18:05.814 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] decrypted session key negotiation step 2: payload=b'72d29b91b3150e539e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:18:05.815 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 5: b'\xaf]\xfb\xc5\xe5.\xcbp\x9f\xa4B\xdc\xa4\x84\x85\x91\xdd&\xc4\xdb\x85\xebD\x13\xcd\xb0\x89i/\xc3\xc5\xe2'
2025-01-17 15:18:05.835 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Session key negotiate success! session key: b'!Qf\x8e:\x9aN:\xa6\xd5Z~\x04\xfc3\x14'
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155885"}'
2025-01-17 15:18:05.836 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155885"}'
2025-01-17 15:18:05.887 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21322
2025-01-17 15:18:06.034 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21322, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\x87V\xef\xd4$v}v\x93}\xe65\xbd\x10\x9c6\xa4\xf8\x94o\xd4-\x9b\xc8\x16\xc6\xa7Jn\xc5\x9b\x9f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21322
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.035 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21323
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21323, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\xfadd\x0c\xe0S\xb8\'\xce\x05A2\xc4l\x92"\xf9\x90\x89\x83\x98\xda\x87\xa4\xaeg\xb7\xb5qe\xb2Q', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21323
2025-01-17 15:18:06.330 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.331 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21324
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21324, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'\xbb $N}\xe0\xe7\xf7DK\xf8\xd3\xc1\xc7\x9cy$\xd8\x91=7j*\xe3W\xe1\xab\x9f\xbf\x81kR', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21324
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155886"}'
2025-01-17 15:18:06.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 21325
2025-01-17 15:18:06.533 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=21325, cmd=16, retcode=0, payload=b"a\xbaNs\xeeJ)\xc3\x05\xac\xba\xeam\x17\x17\xa5,F\xb3\xaa\xec_'\x9b\xf8\n\xebC\x9aH\x81\xdbA\x909\xeb\xd8PM6\x96\xc2\xee\x80\x99\xbf\xae\x12\xc3y0H\xe1$\xbf+\x1a\xc5\xeb\x0e\xba2\xad\xbd", crc=b'_9\xbc\xc2\x9fl\xad[Tv2\x10xK\xdf]\xf2\xb4\xa8\xcd\xd4$!zzu\x85DTmK\xe2', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:06.533 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 21325
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Detected DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Closing connection
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:18:06.534 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Total DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:18:06.536 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Connection lost: None
2025-01-17 15:18:06.536 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:18:31.227 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 15:18:31.230 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [ebb...8mn - OmniBreeze Tower Fan 1] Connection lost: None
2025-01-17 15:18:31.231 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb1...xrv - OmniBreeze Tower Fan 2] Connection lost: None
2025-01-17 15:18:31.231 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [150...12e - Living Room Light] Connection lost: None
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Closed connection
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Closed connection
2025-01-17 15:18:31.232 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Closed connection
2025-01-17 15:18:31.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Initialized cover []
2025-01-17 15:18:31.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Adding cover.garage_door with configuration: {'id': '3', 'entity_category': 'None', 'commands_set': 'open_close_stop', 'positioning_mode': 'none', 'position_inverted': False, 'span_time': 25.0, 'friendly_name': '', 'platform': 'cover'}
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:18:31.243 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:18:31.244 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:18:31.248 INFO (MainThread) [custom_components.localtuya] Setup completed
2025-01-17 15:18:31.250 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Trying to connect to: 192.168.86.35...
2025-01-17 15:18:31.251 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Trying to connect to: 192.168.86.36...
2025-01-17 15:18:31.255 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Trying to connect to: 192.168.86.33...
2025-01-17 15:18:31.256 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Trying to connect to: 192.168.86.30...
2025-01-17 15:18:31.297 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Success: connected to: 192.168.86.35
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Retrieving initial state
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:18:31.400 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 3 waiting for seq. number -102
2025-01-17 15:18:31.503 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Success: connected to: 192.168.86.33
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:18:31.504 DEBUG (SyncWorker_3) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 15:18:31.505 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:18:31.506 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_1 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:18:31.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 4 TuyaMessage(seqno=39959, cmd=4, retcode=0, payload=b'0p\xc7\x9d\x87s\xd1 xP\xd8\xbf\xc0\xe5\xdb\x03>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\x8cZ\x95\x9bT\xecs\xc0.\x88\x1d(\x82\xc4\xa7OU\xd7\x99\x04\x94e\xa0\xda\xf6\xb9\x12;\xe6j\x92\xcc', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:31.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got key negotiation response
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] decrypted session key negotiation step 2: payload=b'5c10cbdd9c53cb5e9e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 5: b'\x11\xc4\xb5\x18\xd1\x0c\x1a&pPt\x13}\xd5\xab6\xf7\x8c\xe4\xdc\x05)9$\xad \xf0F}?\xec\xc0'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Session key negotiate success! session key: b'\x01\x1f|\x03l{\x01\x97lh_\xdc\x89\xd2\xdf\xf1'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155911"}'
2025-01-17 15:18:31.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155911"}'
2025-01-17 15:18:31.564 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 16 waiting for seq. number 39960
2025-01-17 15:18:31.645 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-17 15:18:31.715 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Success: connected to: 192.168.86.36
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:18:31.716 DEBUG (SyncWorker_1) [custom_components.localtuya.fan] Fan current_oscillating : True
2025-01-17 15:18:31.717 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:18:31.718 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_2 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 16 TuyaMessage(seqno=39960, cmd=16, retcode=0, payload=b'>|D\x1bA\\\xf3e\x97XU\xaa\x9f\xbd&\rv\x18Q@\x13\x97),IW`\x94\x88\xff\xa4J\xe9\xdc\x00 s\xdf+\xc3J3\xf1q\xe0J\xb0\x9e\xae\x7f\xbe\xef\xec\xde\xcd\x12$VKk\xe2\xd8\xa3Z', crc=b'x-\x86\x08\x7fVr<\x0c0.\\;5\xe9)\xc66!\xd2p\xd4\xbe\x1f\xf1"~>\xb8\xa4\xe6\xf8', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39960
2025-01-17 15:18:31.730 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Success: connected to: 192.168.86.30
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  (DP 3) - Not restoring as restore on reconnect is disabled for this entity and the entity has an initial status or it is not a passive entity
2025-01-17 15:18:31.731 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Started keep alive loop.
2025-01-17 15:18:31.732 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:31.732 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:39.742 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155919,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:39.744 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155919,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:39.745 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39961, cmd=13, retcode=0, payload=b'', crc=b'\x9c\xd4\xe3\xee\x0c\xa8\x8d\x12@\x07\xdb\xbe6\xea?(\xe1\xc2\x91G\xf0\xc0\xf4i\x95@ZBtOn\xcd', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39961
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39961 self.seqno=39962
2025-01-17 15:18:39.792 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39961
2025-01-17 15:18:39.793 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:40.732 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:40.799 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39962, cmd=9, retcode=0, payload=b'', crc=b'7\x18W#m\xe0~\ti&\xb1 \xc8s\x99\xc37$]N\xf7\xa5\xdc\xec\xa3[\xdbQ#\x0b\x8c\x1f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:40.800 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:40.800 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39962
2025-01-17 15:18:41.720 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155921,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155921,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:41.722 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39963, cmd=13, retcode=0, payload=b'', crc=b'"q\rS\xd1\xb5\xf5\x11\xb6tA\xafU\xa4:\x9f\xba\r@\xe3$\xdd\xbe\xae\x93\x91\x88,\xa4\xe1o\xff', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39963
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39963 self.seqno=39964
2025-01-17 15:18:41.844 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39963
2025-01-17 15:18:41.845 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:43.594 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'3': True}
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155923,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:43.595 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155923,"data":{"dps":{"3":true}}}'
2025-01-17 15:18:43.596 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=39964, cmd=13, retcode=0, payload=b'', crc=b"\xd3\x86w\x10\x9a\xbf\x89\x9d\x14\xe7C!G`\x8b8\xce\x0e\x97\x0b\x8d\xe1'\x10\x9c\xc8b'w\xcd\x9a\xc0", crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=39964 self.seqno=39965
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 39964
2025-01-17 15:18:43.673 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:49.801 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39965, cmd=9, retcode=0, payload=b'', crc=b'V\xe18\xf8\x8de\x01\xbb\x19E\x84\xd8\x01_u\xcd\x94*M\xd1\xb7_xF\xc3)\x1a\x0fv\x82\xdd\xfe', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:49.917 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39965
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:58.918 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:18:58.919 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39966, cmd=9, retcode=0, payload=b'', crc=b'\x9e3\x8cH#\x08\xa7\xcbIp\x86\xf7\xc5\x8f\xaf\xa2\xd5`\x00\xdf\xe6\xc3\xcf`\x8b.A\xdeWn\xbd\x7f', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:18:59.031 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39966
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:08.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=39967, cmd=9, retcode=0, payload=b'', crc=b'Xr5B\xe8\x8a\xe5G\xb7S\xd8lV\xbf\xee6\xc0\x8f\xc0N\xfd\x82\xe4r\x19<\xdd\xd1\x04\xee\xe8\xa4', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:19:08.148 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 39967
2025-01-17 15:19:08.252 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 15:19:08.253 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Closing connection
2025-01-17 15:19:08.253 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Cleaning up session.
2025-01-17 15:19:08.263 INFO (MainThread) [custom_components.localtuya] Device eb2d92a6870c513122umtv removed.
2025-01-17 15:19:08.264 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Stopped heartbeat loop
2025-01-17 15:19:08.265 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Cleaning up session.
2025-01-17 15:19:08.265 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Stopped heartbeat loop
2025-01-17 15:19:08.265 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Connection lost: None
2025-01-17 15:19:08.265 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Cleaning up session.
2025-01-17 15:19:08.266 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [ebb...8mn - OmniBreeze Tower Fan 1] Connection lost: None
2025-01-17 15:19:08.266 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb1...xrv - OmniBreeze Tower Fan 2] Connection lost: None
2025-01-17 15:19:08.267 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [150...12e - Living Room Light] Connection lost: None
2025-01-17 15:19:08.267 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Closed connection
2025-01-17 15:19:08.267 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Closed connection
2025-01-17 15:19:08.267 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Closed connection
2025-01-17 15:19:08.267 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Closed connection
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:19:08.275 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:19:08.282 INFO (MainThread) [custom_components.localtuya] Setup completed
2025-01-17 15:19:08.299 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Trying to connect to: 192.168.86.35...
2025-01-17 15:19:08.300 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Trying to connect to: 192.168.86.36...
2025-01-17 15:19:08.300 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Trying to connect to: 192.168.86.33...
2025-01-17 15:19:08.496 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Success: connected to: 192.168.86.35
2025-01-17 15:19:08.578 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Success: connected to: 192.168.86.36
2025-01-17 15:19:08.579 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:19:08.579 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:19:08.579 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_oscillating : True
2025-01-17 15:19:08.580 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:19:08.581 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_2 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:19:08.683 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Success: connected to: 192.168.86.33
2025-01-17 15:19:08.685 DEBUG (SyncWorker_0) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:19:08.685 DEBUG (SyncWorker_0) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:19:08.685 DEBUG (SyncWorker_0) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 15:19:08.692 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_1 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:19:08.692 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:19:08.777 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-17 15:19:19.226 DEBUG (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Devices has been updated a minutes ago.
2025-01-17 15:19:31.791 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:19:31.791 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:19:31.791 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 3 waiting for seq. number -102
2025-01-17 15:19:32.017 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 4 TuyaMessage(seqno=11457, cmd=4, retcode=0, payload=b'\xdcG&\x8b\xa6\xdb\xc8\x90\x1b\x9b\xb5\x9fex]\x99>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\xef[\xd2\xbc>7\x03L\xcc\xca\xc48\x0e\xf1\x06\xf9\xcc\xa3\xec\x8e>Av;e\xeb5e\x9aU\xf4s', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Got key negotiation response
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] decrypted session key negotiation step 2: payload=b'e2f33b7039a9e54e9e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 5: b'R\xca\x05S\xd6b\x9ebG{\xc0)\xcd\x90\x82\xf0\x17\r\xed|\xc7ia\xf5\x04~7\xd8l\xc7\xc8L'
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Session key negotiate success! session key: b' O;[\x8dR\xcd\x01d{5sH\x0eO\xc0'
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.018 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.070 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 11458
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=11458, cmd=16, retcode=0, payload=b'\xf2\xab\xafq9\xc0\xc0:/\x97\x97\x13\xba\x8cimUP\x87\xb2g\x81\xc4\xd2\xe4\xb1^\x9b\x15J\x0b\x8e}\t\x83\x1c\xe5\xd2\xe3K\x86w8\xc2\x81\xd7\xe7\xece\xb2\xba\xf8\xc0\xf0\xf9E\xd8\xea\xdb\xcf\xbe\x90\xc2\xac', crc=b'\x10\xa1\x05\xb7\x12\xccF\xbc\x1ecu_\x06&\xe4\xaa\xad\xa8\xc7\xb9<\x8d\xdc\x83\x8e\\\x9c\xf1\xef\xa2$d', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 11458
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.124 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.125 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 11459
2025-01-17 15:19:32.236 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=11459, cmd=16, retcode=0, payload=b'\xf2\xab\xafq9\xc0\xc0:/\x97\x97\x13\xba\x8cimUP\x87\xb2g\x81\xc4\xd2\xe4\xb1^\x9b\x15J\x0b\x8e}\t\x83\x1c\xe5\xd2\xe3K\x86w8\xc2\x81\xd7\xe7\xece\xb2\xba\xf8\xc0\xf0\xf9E\xd8\xea\xdb\xcf\xbe\x90\xc2\xac', crc=b'\xac\n9F\xf0\xad\xcf\xf1\n[M\xaa\xb1\xe0}\x8f(L\xa8\x08]\x1d\xde\x89LZ\xc0\xad\x11\xe3[@', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:32.236 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 11459
2025-01-17 15:19:32.236 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:19:32.236 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:19:32.237 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.237 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.237 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 11460
2025-01-17 15:19:32.306 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=11460, cmd=16, retcode=0, payload=b'\xf2\xab\xafq9\xc0\xc0:/\x97\x97\x13\xba\x8cimUP\x87\xb2g\x81\xc4\xd2\xe4\xb1^\x9b\x15J\x0b\x8e}\t\x83\x1c\xe5\xd2\xe3K\x86w8\xc2\x81\xd7\xe7\xece\xb2\xba\xf8\xc0\xf0\xf9E\xd8\xea\xdb\xcf\xbe\x90\xc2\xac', crc=b'\x86\x17\xaa\xf3?\xa6\x8b\x08=\xe3\xe7\xfd\x90\x8d\xe1\xba\xfe\xc1\xaa~W\r^DT\xcf\xc2\x8di\xd6\xc0\x12', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:32.306 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 11460
2025-01-17 15:19:32.307 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:19:32.307 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:19:32.308 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.308 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155972"}'
2025-01-17 15:19:32.309 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Command 16 waiting for seq. number 11461
2025-01-17 15:19:32.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching message CMD 16 TuyaMessage(seqno=11461, cmd=16, retcode=0, payload=b'\xf2\xab\xafq9\xc0\xc0:/\x97\x97\x13\xba\x8cimUP\x87\xb2g\x81\xc4\xd2\xe4\xb1^\x9b\x15J\x0b\x8e}\t\x83\x1c\xe5\xd2\xe3K\x86w8\xc2\x81\xd7\xe7\xece\xb2\xba\xf8\xc0\xf0\xf9E\xd8\xea\xdb\xcf\xbe\x90\xc2\xac', crc=b'\xeb\xf0\x80\x90_\xb0\x8e$\xacJ[\xee\xe4\x84!\xb8\x15\t\xd94\xfa\xf5\t\x02\xb5\xef\x1a&\xcd\xcbCf', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:32.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Dispatching sequence number 11461
2025-01-17 15:19:32.445 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:19:32.445 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Detected DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:19:32.445 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Closing connection
2025-01-17 15:19:32.445 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:19:32.445 DEBUG (MainThread) [custom_components.localtuya.config_flow] [eb2...mtv - Garage door ] Total DPS: {'1': False, '2': 0, '3': False, '4': 10, '5': 600, '12': 'none'}
2025-01-17 15:19:32.447 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Connection lost: None
2025-01-17 15:19:32.447 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv] Cleaning up session.
2025-01-17 15:19:44.732 INFO (MainThread) [custom_components.localtuya] Unload completed
2025-01-17 15:19:44.735 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [ebb...8mn - OmniBreeze Tower Fan 1] Connection lost: None
2025-01-17 15:19:44.735 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb1...xrv - OmniBreeze Tower Fan 2] Connection lost: None
2025-01-17 15:19:44.735 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [150...12e - Living Room Light] Connection lost: None
2025-01-17 15:19:44.736 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Closed connection
2025-01-17 15:19:44.736 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Closed connection
2025-01-17 15:19:44.736 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Closed connection
2025-01-17 15:19:44.739 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Initialized cover []
2025-01-17 15:19:44.739 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Adding cover.garage_door with configuration: {'id': '1', 'entity_category': 'None', 'commands_set': 'open_close_stop', 'positioning_mode': 'none', 'position_inverted': False, 'span_time': 25.0, 'friendly_name': '', 'platform': 'cover'}
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Last State', 'OFF', 'ON']
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['Nature', 'Normal', 'Sleep']
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 3 - Total Display Options: 3
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Display Options Configured: ['10h', '11h', '12h', '1 Hour', '2 Hours', '3 Hours', '4 Hours', '5 Hours', '6 Hours', '7h', '8h', '9h', 'cancel']
2025-01-17 15:19:44.743 DEBUG (MainThread) [custom_components.localtuya.select] Total Raw Options: 13 - Total Display Options: 13
2025-01-17 15:19:44.748 INFO (MainThread) [custom_components.localtuya] Setup completed
2025-01-17 15:19:44.750 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Trying to connect to: 192.168.86.35...
2025-01-17 15:19:44.751 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Trying to connect to: 192.168.86.36...
2025-01-17 15:19:44.751 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Trying to connect to: 192.168.86.33...
2025-01-17 15:19:44.752 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Trying to connect to: 192.168.86.30...
2025-01-17 15:19:44.799 DEBUG (MainThread) [custom_components.localtuya.coordinator] [150...12e - Living Room Light] Success: connected to: 192.168.86.35
2025-01-17 15:19:44.804 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Retrieving initial state
2025-01-17 15:19:44.804 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] 3.4 or 3.5 device: negotiating a new session key
2025-01-17 15:19:44.804 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 3: b'0123456789abcdef'
2025-01-17 15:19:44.805 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 3 waiting for seq. number -102
2025-01-17 15:19:45.035 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb1...xrv - OmniBreeze Tower Fan 2] Success: connected to: 192.168.86.36
2025-01-17 15:19:45.036 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:19:45.036 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:19:45.036 DEBUG (SyncWorker_6) [custom_components.localtuya.fan] Fan current_oscillating : True
2025-01-17 15:19:45.036 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:19:45.037 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_2 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:19:45.125 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-17 15:19:45.131 DEBUG (MainThread) [custom_components.localtuya.coordinator] [ebb...8mn - OmniBreeze Tower Fan 1] Success: connected to: 192.168.86.33
2025-01-17 15:19:45.132 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.omnibreeze_tower_fan_1 (<class 'custom_components.localtuya.sensor.LocalTuyaSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('temperature') it is using; expected one of ['°F', 'K', '°C']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/xZetsubou/hass-localtuya/issues
2025-01-17 15:19:45.133 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 4 TuyaMessage(seqno=5212, cmd=4, retcode=0, payload=b'\x7f:\x98\xe5\xe6\x86\xd4\xb3\xbf\xa5N\x81lq,\xb7>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'$\x9f\x8f\x19\xc2\xd6\xb1\xfe\x17\x0e\xb3B\xd4\xfb\xf3\x9e\x93\x19j\xd7\xa0\xf5T)\x95\xf6.\x86\x8e\x87\xe1\xbf', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:45.133 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got key negotiation response
2025-01-17 15:19:45.133 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] decrypted session key negotiation step 2: payload=b'0e29692bfe98fc759e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-17 15:19:45.133 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 5: b"\xedk]\xf6\xa1\xc0\x8er\t\x81\xaaI\x8aW\xd4'\x9d\xa2\x8fL\x91Jf\x16(V*\x8a-\x18\xf4t"
2025-01-17 15:19:45.134 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Session key negotiate success! session key: b'n\xba\n\x85VAm\xb5JZ~$\x02\x15K\x11'
2025-01-17 15:19:45.134 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 10 (device type: v3.4) DPS: None
2025-01-17 15:19:45.134 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155985"}'
2025-01-17 15:19:45.134 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737155985"}'
2025-01-17 15:19:45.136 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_speed ranged_value_to_percentage: 4 from (1, 4)
2025-01-17 15:19:45.136 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_percentage: 100
2025-01-17 15:19:45.136 DEBUG (SyncWorker_4) [custom_components.localtuya.fan] Fan current_oscillating : False
2025-01-17 15:19:45.137 DEBUG (MainThread) [custom_components.localtuya.fan] Fan speed_count: 4
2025-01-17 15:19:45.185 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 16 waiting for seq. number 5213
2025-01-17 15:19:45.237 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 16 TuyaMessage(seqno=5213, cmd=16, retcode=0, payload=b'fC\xfcM\xa1\xac_\x9cEw\xb8z\xcck\x85V?\x91\xb21\x9a\x15G\x1d\xf3FB\xaf\x7f\x19\xaa\xaa3\x99\x9b\xd8n\xf4R\x81\x04\xe3\x8c\xb2\x92\x19\xfd0A\xe6Y\x99\xe0\xdf\xfer\x86+P\x15\x16\x9b\xff\xa5', crc=b'*\xff9\x14\xe7\xa0\xe2\xb5+\xae\x08\x9f\xee\x80\xf6\xb0\xe9\xbb\xcb\x1aV\x14\x16\x8f\xdc\xed\xdd@\xec;\x10\xbf', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:45.238 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 5213
2025-01-17 15:19:45.238 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"dps":{"1":false,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-17 15:19:45.238 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Success: connected to: 192.168.86.30
2025-01-17 15:19:45.238 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  (DP 1) - Not restoring as restore on reconnect is disabled for this entity and the entity has an initial status or it is not a passive entity
2025-01-17 15:19:45.238 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Started keep alive loop.
2025-01-17 15:19:45.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:19:45.239 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:19:51.503 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-17 15:19:51.504 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'1': True}
2025-01-17 15:19:51.504 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737155991,"data":{"dps":{"1":true}}}'
2025-01-17 15:19:51.504 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737155991,"data":{"dps":{"1":true}}}'
2025-01-17 15:19:51.505 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 5214
2025-01-17 15:19:51.578 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=5214, cmd=13, retcode=0, payload=b'', crc=b'\xe6_\xde\x8cm<s@\xf0\x18mE@\x81 \x94l6\x8aYBL\x14\xdd6Y\xac_C\xcc\x07v', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:51.578 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 5214
2025-01-17 15:19:51.578 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 5214
2025-01-17 15:19:51.578 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=5214 self.seqno=5215
2025-01-17 15:19:51.578 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 5214
2025-01-17 15:19:51.579 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:19:51.742 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=5215, cmd=8, retcode=0, payload=b'3P\xde\xfa\x8bs\x9f~M\xcb\xba\x04u{\x1b\x97\x178.\x99\xee0r\x18v@\xba\xb0\xac\xa4#\xdd\x8b+\x90\xabX\x80I\x1beB\xa1\x9f\xa2\xe8\x99\x9c()\xddA)\xe5\xaf\xdar\xd9&6\x82\xa6\x12|>\x81[\xd7u\xdf\x10\xe0\x10\x93j\xd9d\x13\xd3j', crc=b'\xef\xddPU\xf9D\xe4f*\xc6&\xb0\xec\xee\x1dT"\xf5\x92\x89\x8b\x90\xe9\xbf\xdb\x18\xfb\xb2\x06\x08`\x95', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:51.742 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 15:19:51.743 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737155992,"data":{"dps":{"1":true}}}'
2025-01-17 15:19:51.747 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 15:19:52.244 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=5216, cmd=8, retcode=0, payload=b'\x87\xd2\x07\x7fcG\xe3\x18X\x9f\xe6!\xf9\xdf\xba!\x178.\x99\xee0r\x18v@\xba\xb0\xac\xa4#\xdd\xbb\x921\x04\x93\xff2\xf0\xb4/\xe0\xe5\x08\xe9)\x81\xa9\xb3n|P\x15!\xd5[}\x058\x1d\xe4Z\xa9]\xaa\x10\xdf\xe7(\xe5\xb2\xb0\x1d\xea\xe5\xa5j\xb0\x90', crc=b'\xe3<l7\xfd\xe4\x163\x1b\xb8\xa4\x1e\xac-\x0b\x95\xb7\x10\xbc\xe3|\x8a\xba)\x93\xf0\x0c\x0c\x8a\x01\xa7\xa7', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:52.244 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 15:19:52.244 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737155993,"data":{"dps":{"3":true,"5":600}}}'
2025-01-17 15:19:52.246 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': True}
2025-01-17 15:19:54.239 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:19:54.239 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:54.240 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:19:54.240 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:19:54.324 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=5217, cmd=9, retcode=0, payload=b'', crc=b'Ln#\xbe^\xafO\x15\x18\x07v\x18/\xe9e\xa3\x97\x87\xeet\xdc\x88\xa6\xdd\xe7\x0eV\x1a\xf4P\x8e\x96', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:19:54.324 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:19:54.324 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 5217
2025-01-17 15:20:00.262 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=5218, cmd=8, retcode=0, payload=b'\xbe\xe1\x91[/:i\xb7\x1fp\x16\x05\x93\x08\xfeW\x178.\x99\xee0r\x18v@\xba\xb0\xac\xa4#\xdd\xbf\xa5\xf1\x12\xd6P\xb1\x9d\xc8zX\x8e\x81!\xd0\x1e\xce\xfaU\x06\x8eK\xecP\x02\xfa\xaf\x8bC\xe8\xcf\xab|\x94\x87\xb2\xd2\x99\xeb\x83\x03L\x93wi6\xac\x93', crc=b' g\x0e\xbf\xb9\xf1\xaf/\x1fL\xd0\xcb\x91\x7f,\xc8k\xc2!+\\\x16\xf4=3\x86v/\xac\xb5\x8f2', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:20:00.262 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 15:20:00.263 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737156001,"data":{"dps":{"1":false}}}'
2025-01-17 15:20:00.264 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:20:03.325 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:20:03.325 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:20:03.325 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:20:03.326 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:20:03.442 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=5219, cmd=9, retcode=0, payload=b'', crc=b'\xe1\xee\xb6\xe8\xc5+\xa7@\xd1\xf3\xdeh4\x19?\x02\xd7\xd366W#\xb5.\xb7A\xa9\x92`4\x1c\x03', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:20:03.442 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:20:03.443 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 5219
2025-01-17 15:20:07.071 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=5220, cmd=8, retcode=0, payload=b'\xd9c\xc6\xee\x02\t\x7f\x95H\x00[i\xc9\x8dX<\x178.\x99\xee0r\x18v@\xba\xb0\xac\xa4#\xdd\xe0F\xfd\xb9\x16\xab\x068(4\x1fcX\xd3F\xf1\x93\xd2bl\xf8\xb9\xdc\xe6\x0fC\xc4\x07\x00\x8f\xd2\xda\xa6\xa5\xeb\xd3t\xe4r@\xb0\xed\xdeQ\x93\x83\x16\x81T$%\x9f\xf3\x8f\xd0K6\x81Z}.\xc14\x19', crc=b'\xb5^\x80CIQ\x146\xa3\x9a\x12m\x9d\xc0\x08\x06]\xb1\xc6\xf4\x16\xae\x9b\x85\xb2\xd2\xc7y\xf3\xcf\xd7\x89', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:20:07.071 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-17 15:20:07.071 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737156008,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'
2025-01-17 15:20:07.073 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity  - Additional attributes: {'raw_state': False}
2025-01-17 15:20:12.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-17 15:20:12.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:20:12.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-17 15:20:12.444 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-17 15:20:12.550 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=5221, cmd=9, retcode=0, payload=b'', crc=b'b\x93\x95\xf5\x9e\xfc\xc3\x1a\x95\xfc\xf7\xdb<i\tB\x18\xd4`:P\x17\x91\xaa0\xde\xcf\x9df\x9d(I', crc_good=True, prefix=21930, iv=None)
2025-01-17 15:20:12.550 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-17 15:20:12.550 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 5221

@xZetsubou xZetsubou reopened this Jan 17, 2025
@xZetsubou
Copy link
Owner

Here are logs for DPID 3 (for adding the device and clicking on the open button, which doesn't seem trigger the door to open):

Try reconfigure the device and check the "position inverted" option.

@donaldkwong
Copy link
Author

Try reconfigure the device and check the "position inverted" option.

Same behavior (the button doesn't do anything). Here's the diagnostic for this device.

localtuya-01JHPZCGJGTFRBJY1GS78BRZ12-Garage door -b0cd8b7e5ad5a3ce7ba20da46c5ad83e (2).json

@xZetsubou
Copy link
Owner

DPID 3 is the correct DP for the current position field, but it seems I missed something since it doesn't update instantly and only update if garage fully closed.

@donaldkwong
Copy link
Author

Let me know if there is more data or testing I can help provide.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 18, 2025

I downgraded back to 2025.1 to do some debugging. I put some debug logging in status_updated() and noticed that _current_cover_position never changes from 0 in either Neither or Set Position mode when the door opens or closes. InTime Based mode, the position would change to 33 and stay there forever.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 18, 2025

If there is other information that I can log to help with this, please let me know. I'm pretty comfortable with Python. I'm just not at all familiar with the HA platform or set of APIs, though.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 18, 2025

Speaking of which, should I be using a specific positioning mode and set anything for the Current Position and Set Position options?

@xZetsubou
Copy link
Owner

Speaking of which, should I be using a specific positioning mode and set anything for the Current Position and Set Position options?

The current position should be 3 because this DP became "True" if garage is fully closed or vice versa not sure confirm it by fully close the garage and check status_updated() DP 3 would be "true" or "false", set position shall be left empty, as for position mode it will be ignored if the current position is boolean type.

To clarify this can be fixed by assigning is_closed to true or false for "current position" but this way "open/closing" state won't works. and the state of garage would be only close/open, I can see where is the issue and it's fixable.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 18, 2025

Is DP 3 above the same as data["dps"]["3"] in the deciphered data in the logs below?

2025-01-17 18:24:10.598 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737167051,"data":{"dps":{"1":false}}}'
2025-01-17 18:24:17.033 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737167058,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'

If so, then yes, it becomes false only when the door is fully closed.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 18, 2025

Oh, I just did more testing with 2025.1.1 and with the configuration below, the entity is working as expected! The buttons work and the states are properly updated (even the "Closed" state doesn't appear until the door is fully closed). It exactly matches the behavior of the Cloud version of the entity!

Image

@donaldkwong
Copy link
Author

Try with latest update, reconfigure is required since current position now support boolean state "DPID 3 for your garage"

I think I completely misunderstood this. I thought you meant that I should change the main DP ID to 3, not the Current Position.

edit: I think the issue that it's instantly return "closed" or "open" is still present can you confirm it?

Nope, with this change, the state doesn't change to "Closed" until the door is fully closed!

@xZetsubou
Copy link
Owner

Hello can you test this changes.

copy the code block below and replace it with everything in HA config -> custom_components/localtuya/cover.py then restart HA

cover.py

"""Platform to locally control Tuya-based cover devices."""

import asyncio
import logging
import time
from functools import partial

import voluptuous as vol
from homeassistant.components.cover import (
    ATTR_POSITION,
    DOMAIN,
    CoverEntityFeature,
    CoverEntity,
    DEVICE_CLASSES_SCHEMA,
)
from homeassistant.const import CONF_DEVICE_CLASS
from .config_flow import col_to_select
from .entity import LocalTuyaEntity, async_setup_entry
from .const import (
    CONF_COMMANDS_SET,
    CONF_CURRENT_POSITION_DP,
    CONF_POSITION_INVERTED,
    CONF_POSITIONING_MODE,
    CONF_SET_POSITION_DP,
    CONF_SPAN_TIME,
    CONF_STOP_SWITCH_DP,
)


# cover states.
STATE_OPENING = "opening"
STATE_CLOSING = "closing"
STATE_STOPPED = "stopped"
STATE_SET_CMD = "moving"
STATE_SET_OPENING = "set_opeing"
STATE_SET_CLOSING = "set_closing"

_LOGGER = logging.getLogger(__name__)


COVER_COMMANDS = {
    "Open, Close and Stop": "open_close_stop",
    "Open, Close and Continue": "open_close_continue",
    "ON, OFF and Stop": "on_off_stop",
    "fz, zz and Stop": "fz_zz_stop",
    "zz, fz and Stop": "zz_fz_stop",
    "1, 2 and 3": "1_2_3",
    "0, 1 and 2": "0_1_2",
}

MODE_NONE = "none"
MODE_SET_POSITION = "position"
MODE_TIME_BASED = "timed"
COVER_MODES = {
    "Neither": MODE_NONE,
    "Set Position": MODE_SET_POSITION,
    "Time Based": MODE_TIME_BASED,
}

COVER_TIMEOUT_TOLERANCE = 3.0

DEF_CMD_SET = list(COVER_COMMANDS.values())[0]
DEF_POS_MODE = list(COVER_MODES.values())[0]
DEFAULT_SPAN_TIME = 25.0


def flow_schema(dps):
    """Return schema used in config flow."""
    return {
        vol.Optional(CONF_COMMANDS_SET, default=DEF_CMD_SET): col_to_select(
            COVER_COMMANDS
        ),
        vol.Optional(CONF_POSITIONING_MODE, default=DEF_POS_MODE): col_to_select(
            COVER_MODES
        ),
        vol.Optional(CONF_CURRENT_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_SET_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_POSITION_INVERTED, default=False): bool,
        vol.Optional(CONF_SPAN_TIME, default=DEFAULT_SPAN_TIME): vol.All(
            vol.Coerce(float), vol.Range(min=1.0, max=300.0)
        ),
        vol.Optional(CONF_STOP_SWITCH_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
    }


class LocalTuyaCover(LocalTuyaEntity, CoverEntity):
    """Tuya cover device."""

    def __init__(self, device, config_entry, switchid, **kwargs):
        """Initialize a new LocalTuyaCover."""
        super().__init__(device, config_entry, switchid, _LOGGER, **kwargs)
        commands_set = DEF_CMD_SET
        if self.has_config(CONF_COMMANDS_SET):
            commands_set = self._config[CONF_COMMANDS_SET]
        self._open_cmd = commands_set.split("_")[0]
        self._close_cmd = commands_set.split("_")[1]
        self._stop_cmd = commands_set.split("_")[2]
        self._timer_start = time.time()
        self._state = self._stop_cmd
        self._previous_state = self._state
        self._current_cover_position = 0
        self._current_state_action = STATE_STOPPED  # Default.
        self._set_new_position = int | None
        self._stop_switch = self._config.get(CONF_STOP_SWITCH_DP, None)
        self._position_inverted = self._config.get(CONF_POSITION_INVERTED)
        self._current_task = None

    @property
    def supported_features(self):
        """Flag supported features."""
        supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
        if not isinstance(self._open_cmd, bool):
            supported_features |= CoverEntityFeature.STOP
            if self._config[CONF_POSITIONING_MODE] != MODE_NONE:
                supported_features |= CoverEntityFeature.SET_POSITION
        return supported_features

    @property
    def _current_state(self) -> str:
        """Return the current state of the cover."""
        state = self._current_state_action
        curr_pos = self._current_cover_position

        # Reset STATE when cover is fully closed or fully opened.
        if state in (STATE_CLOSING, STATE_OPENING) and curr_pos in (0, 100):
            return STATE_STOPPED
        if state in (STATE_SET_CLOSING, STATE_SET_OPENING):
            set_pos = self._set_new_position
            # Reset state whenn cover reached the position.
            if curr_pos - set_pos < 5 and curr_pos - set_pos >= -5:
                return STATE_STOPPED
        return self._current_state_action

    @property
    def current_cover_position(self):
        """Return current cover position in percent."""
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self._current_cover_position

    @property
    def is_opening(self):
        """Return if cover is opening."""
        return self._current_state in (STATE_OPENING, STATE_SET_OPENING)

    @property
    def is_closing(self):
        """Return if cover is closing."""
        return self._current_state in (STATE_CLOSING, STATE_SET_CLOSING)

    @property
    def is_closed(self):
        """Return if the cover is closed or not."""
        if isinstance(self._open_cmd, (bool, str)):
            return self._current_cover_position == 0
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self.current_cover_position == 0 and self._current_state == STATE_STOPPED

    async def async_set_cover_position(self, **kwargs):
        """Move the cover to a specific position."""
        # Update device values IF the device is moving at the moment.
        if self._current_state != STATE_STOPPED:
            await self.async_stop_cover()

        self.debug("Setting cover position: %r", kwargs[ATTR_POSITION])
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            newpos = float(kwargs[ATTR_POSITION])

            currpos = self.current_cover_position
            posdiff = abs(newpos - currpos)
            mydelay = posdiff / 100.0 * self._config[CONF_SPAN_TIME]
            if newpos > currpos:
                self.debug("Opening to %f: delay %f", newpos, mydelay)
                await self.async_open_cover(delay=mydelay)
                self.update_state(STATE_OPENING)
            else:
                self.debug("Closing to %f: delay %f", newpos, mydelay)
                await self.async_close_cover(delay=mydelay)
                self.update_state(STATE_CLOSING)
            self.debug("Done")

        elif self._config[CONF_POSITIONING_MODE] == MODE_SET_POSITION:
            converted_position = int(kwargs[ATTR_POSITION])
            if self._position_inverted:
                converted_position = 100 - converted_position
            if 0 <= converted_position <= 100 and self.has_config(CONF_SET_POSITION_DP):
                await self._device.set_dp(
                    converted_position, self._config[CONF_SET_POSITION_DP]
                )
            # Give it a moment, to make sure hass updated current pos.
            await asyncio.sleep(0.1)
            self.update_state(STATE_SET_CMD, int(kwargs[ATTR_POSITION]))

    async def async_stop_after_timeout(self, delay_sec):
        """Stop the cover if timeout (max movement span) occurred."""
        try:
            await asyncio.sleep(delay_sec)
            self._current_task = None
            await self.async_stop_cover()
        except asyncio.CancelledError:
            self._current_task = None

    async def async_open_cover(self, **kwargs):
        """Open the cover."""
        self.debug("Launching command %s to cover ", self._open_cmd)
        await self._device.set_dp(self._open_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_OPENING)

    async def async_close_cover(self, **kwargs):
        """Close cover."""
        self.debug("Launching command %s to cover ", self._close_cmd)
        await self._device.set_dp(self._close_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_CLOSING)

    async def async_stop_cover(self, **kwargs):
        """Stop the cover."""
        if self._current_task is not None:
            self._current_task.cancel()
        self.debug("Launching command %s to cover ", self._stop_cmd)
        command = {self._dp_id: self._stop_cmd}
        if self._stop_switch is not None:
            command[self._stop_switch] = True
        await self._device.set_dps(command)
        self.update_state(STATE_STOPPED)

    def status_restored(self, stored_state):
        """Restore the last stored cover status."""
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            stored_pos = stored_state.attributes.get("current_position")
            if stored_pos is not None:
                self._current_cover_position = stored_pos
                self.debug("Restored cover position %s", self._current_cover_position)

    def connection_made(self):
        super().connection_made()

        match self.dp_value(self._dp_id):
            case str() as i if i.isupper():
                self._open_cmd = self._open_cmd.upper()
                self._close_cmd = self._close_cmd.upper()
                self._stop_cmd = self._stop_cmd.upper()
            case bool():
                self._open_cmd = True
                self._close_cmd = False

    def status_updated(self):
        """Device status was updated."""
        self._previous_state = self._state
        self._state = self.dp_value(self._dp_id)

        if self.has_config(CONF_CURRENT_POSITION_DP):
            curr_pos = self.dp_value(CONF_CURRENT_POSITION_DP)
            if isinstance(curr_pos, (bool, str)):
                closed = curr_pos in (True, "fully_close")
                stopped = self._previous_state == self._state
                curr_pos = 0 if stopped and closed else (100 if stopped else 50)

            if self._position_inverted:
                curr_pos = 100 - curr_pos

            self._current_cover_position = curr_pos
        if (
            self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED
            and self._state != self._previous_state
        ):
            if self._previous_state != self._stop_cmd:
                # the state has changed, and the cover was moving
                time_diff = time.time() - self._timer_start
                pos_diff = round(time_diff / self._config[CONF_SPAN_TIME] * 100.0)
                if self._previous_state == self._close_cmd:
                    pos_diff = -pos_diff
                self._current_cover_position = min(
                    100, max(0, self._current_cover_position + pos_diff)
                )

                change = "stopped" if self._state == self._stop_cmd else "inverted"
                self.debug(
                    "Movement %s after %s sec., position difference %s",
                    change,
                    time_diff,
                    pos_diff,
                )

            # store the time of the last movement change
            self._timer_start = time.time()

        # Keep record in last_state as long as not during connection/re-connection,
        # as last state will be used to restore the previous state
        if (self._state is not None) and (not self._device.is_connecting):
            self._last_state = self._state

    def update_state(self, action, position=None):
        """Update cover current states."""
        state = self._current_state_action
        # using Commands.
        if position is None:
            self._current_state_action = action
        # Set position cmd, check if target position weither close or open
        if action == STATE_SET_CMD and position is not None:
            curr_pos = self.current_cover_position
            self._set_new_position = position
            pos_diff = position - curr_pos
            # Prevent stuck state when interrupted on middle of cmd
            if state == STATE_STOPPED:
                if pos_diff > 0:
                    self._current_state_action = STATE_SET_OPENING
                elif pos_diff < 0:
                    self._current_state_action = STATE_SET_CLOSING
            else:
                self._current_state_action = STATE_STOPPED
        # Write state data.
        self.async_write_ha_state()


async_setup_entry = partial(async_setup_entry, DOMAIN, LocalTuyaCover, flow_schema)

@donaldkwong
Copy link
Author

Yeah, but I won't be able to test until tomorrow.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 21, 2025

Just tested this out and it's much improved! I re-added the device using automatic entity creation. The buttons to open and close the door work correctly and the states are showing up correctly. Even the opening and closing states are now represented. Here's a quick video showing the entity card working:

Screen.Recording.2025-01-21.at.11.23.03.AM.mov

There's just one minor bug. When the device was first created, the entity was in an Open state even though the garage door was closed. Clicking on the close button and then on the open button got the state to sync up correctly and has been correct since then.

@donaldkwong
Copy link
Author

Oh, also looks like every time I restart HA, the entity goes back into an Open state even though the door is closed. I'm going to go back to 2025.1.1 for now.

@xZetsubou
Copy link
Owner

xZetsubou commented Jan 22, 2025

There's just one minor bug. When the device was first created, the entity was in an Open state even though the garage door was closed. Clicking on the close button and then on the open button got the state to sync up correctly and has been correct since then.

Have you check invert the set position from localtuya entity configuration, if checking it correct the issue I'll merge the changes.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 22, 2025

I just re-created the device and manually created the entity with the same config as above, but the entity still defaults to an Open state after creation and after restarting HA.

@donaldkwong
Copy link
Author

I went back to reconfigure it and tried both inverted on and off, but the state remains Open.

@donaldkwong
Copy link
Author

Here are some logs for when the device is added:

2025-01-21 16:24:23.291 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 4 TuyaMessage(seqno=44387, cmd=4, retcode=0, payload=b'\\a\x95Qth\x9fZ\x87U\xac\xd7\xc7\xcd@\x14>@W:\xd3\xc8\xcer||p\xfew\xde\xbd\xca\xf5-n\xa2!7\xfdp\x96d\x85\xc4\xf0\t\x02\xd8\xc2\xdf\xa7\xdeJ=\x85\xb1\xdb\x9am\xba#\xed\x83\x92', crc=b'\x95\x81|\x93s\xf8k\x86\xf6\xabgI\x1c\x05\xbb\xff)D\xce\xe6/\xb0\xab\x9f\x13\xe3\xd1\x9f+\xa6\x9cZ', crc_good=True, prefix=21930, iv=None)
2025-01-21 16:24:23.291 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got key negotiation response
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] decrypted session key negotiation step 2: payload=b'3982ed3188ec3a0f9e\x06\x1eJE\xab\xbbv\x9dkN\x8fHNv0\xab2`m\xf4\xe83l\xb1\xc7\x0e\xd3C\xd6I'
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 5: b'n\xae\xf2\x86I\x93\x8e\x01\x9e\xd3\x11Zn\teMO\x9e\xde>\xc4\x82\x01Y\xcc\xe7\x05\x89Q\xf3\x14\xaf'
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Session key negotiate success! session key: b'YO\x0c\x99)\xce\xd3\xe0w\xb02oc\x18\x0bu'
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 10 (device type: v3.4) DPS: None
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737505463"}'
2025-01-21 16:24:23.294 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 16: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv","uid":"eb2d92a6870c513122umtv","t":"1737505463"}'
2025-01-21 16:24:23.348 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 16 waiting for seq. number 44388
2025-01-21 16:24:23.404 INFO (MainThread) [custom_components.localtuya.core.cloud_api] [az1...UBl] Cloud API connection succeeded.
2025-01-21 16:24:23.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 16 TuyaMessage(seqno=44388, cmd=16, retcode=0, payload=b"\xcb'\xf8\x8e9o\x94\x93\xb5I\xcd\xc6\xced\xd0\x9b\xdc eIG\xdf*\xa0<\xd2\x96\x91y\xdd\xe9[sdA\xc1D5h\x9f\x03\xaa\x86&\xce\x8a\x94\xf8\xa2\xdc\xe3D\x0c.,U\x8b~\xf3'o\xc6l>", crc=b'\x07\xe8\xafBRR8\xa9L\xacP*\xc9<\xe9\xba\x14y\xf8f\xcel\x92\xf1\x85\x1f\xf6\xc0\x8691\xc5', crc_good=True, prefix=21930, iv=None)
2025-01-21 16:24:23.507 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 44388
2025-01-21 16:24:23.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"dps":{"1":true,"2":0,"3":false,"4":10,"5":600,"12":"none"}}'
2025-01-21 16:24:23.508 DEBUG (MainThread) [custom_components.localtuya.coordinator] [eb2...mtv - Garage door ] Success: connected to: 192.168.86.30
2025-01-21 16:24:23.508 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Garage Door (DP 1) - Not restoring as restore on reconnect is disabled for this entity and the entity has an initial status or it is not a passive entity
2025-01-21 16:24:23.508 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Started keep alive loop.
2025-01-21 16:24:23.509 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Garage Door - Additional attributes: {'raw_state': True}
2025-01-21 16:24:23.509 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Garage Door - Additional attributes: {'raw_state': True}
2025-01-21 16:24:32.510 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-21 16:24:32.510 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-21 16:24:32.510 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-21 16:24:32.511 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-21 16:24:32.603 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=44389, cmd=9, retcode=0, payload=b'', crc=b'e@a\x18\xd8\xa5m\xb1?@2\xdd7QB\x806\xe5\x0cs\xf0w0P\x9b\xad\x14\xbeY\xb0\xeeX', crc_good=True, prefix=21930, iv=None)
2025-01-21 16:24:32.603 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-21 16:24:32.603 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 44389

@xZetsubou
Copy link
Owner

I know what happen here Thanks for feedback.

@xZetsubou
Copy link
Owner

Can you test this.

cover.py

"""Platform to locally control Tuya-based cover devices."""

import asyncio
import logging
import time
from functools import partial

import voluptuous as vol
from homeassistant.components.cover import (
    ATTR_POSITION,
    DOMAIN,
    CoverEntityFeature,
    CoverEntity,
    DEVICE_CLASSES_SCHEMA,
)
from homeassistant.const import CONF_DEVICE_CLASS
from .config_flow import col_to_select
from .entity import LocalTuyaEntity, async_setup_entry
from .const import (
    CONF_COMMANDS_SET,
    CONF_CURRENT_POSITION_DP,
    CONF_POSITION_INVERTED,
    CONF_POSITIONING_MODE,
    CONF_SET_POSITION_DP,
    CONF_SPAN_TIME,
    CONF_STOP_SWITCH_DP,
)


# cover states.
STATE_OPENING = "opening"
STATE_CLOSING = "closing"
STATE_STOPPED = "stopped"
STATE_SET_CMD = "moving"
STATE_SET_OPENING = "set_opeing"
STATE_SET_CLOSING = "set_closing"

_LOGGER = logging.getLogger(__name__)


COVER_COMMANDS = {
    "Open, Close and Stop": "open_close_stop",
    "Open, Close and Continue": "open_close_continue",
    "ON, OFF and Stop": "on_off_stop",
    "fz, zz and Stop": "fz_zz_stop",
    "zz, fz and Stop": "zz_fz_stop",
    "1, 2 and 3": "1_2_3",
    "0, 1 and 2": "0_1_2",
}

MODE_NONE = "none"
MODE_SET_POSITION = "position"
MODE_TIME_BASED = "timed"
COVER_MODES = {
    "Neither": MODE_NONE,
    "Set Position": MODE_SET_POSITION,
    "Time Based": MODE_TIME_BASED,
}

COVER_TIMEOUT_TOLERANCE = 3.0

DEF_CMD_SET = list(COVER_COMMANDS.values())[0]
DEF_POS_MODE = list(COVER_MODES.values())[0]
DEFAULT_SPAN_TIME = 25.0


def flow_schema(dps):
    """Return schema used in config flow."""
    return {
        vol.Optional(CONF_COMMANDS_SET, default=DEF_CMD_SET): col_to_select(
            COVER_COMMANDS
        ),
        vol.Optional(CONF_POSITIONING_MODE, default=DEF_POS_MODE): col_to_select(
            COVER_MODES
        ),
        vol.Optional(CONF_CURRENT_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_SET_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_POSITION_INVERTED, default=False): bool,
        vol.Optional(CONF_SPAN_TIME, default=DEFAULT_SPAN_TIME): vol.All(
            vol.Coerce(float), vol.Range(min=1.0, max=300.0)
        ),
        vol.Optional(CONF_STOP_SWITCH_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
    }


class LocalTuyaCover(LocalTuyaEntity, CoverEntity):
    """Tuya cover device."""

    def __init__(self, device, config_entry, switchid, **kwargs):
        """Initialize a new LocalTuyaCover."""
        super().__init__(device, config_entry, switchid, _LOGGER, **kwargs)
        commands_set = DEF_CMD_SET
        if self.has_config(CONF_COMMANDS_SET):
            commands_set = self._config[CONF_COMMANDS_SET]
        self._open_cmd = commands_set.split("_")[0]
        self._close_cmd = commands_set.split("_")[1]
        self._stop_cmd = commands_set.split("_")[2]
        self._timer_start = time.time()
        self._state = None
        self._previous_state = None
        self._current_cover_position = 0
        self._current_state_action = STATE_STOPPED  # Default.
        self._set_new_position = int | None
        self._stop_switch = self._config.get(CONF_STOP_SWITCH_DP)
        self._position_inverted = self._config.get(CONF_POSITION_INVERTED)
        self._current_task = None

    @property
    def supported_features(self):
        """Flag supported features."""
        supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
        if not isinstance(self._open_cmd, bool):
            supported_features |= CoverEntityFeature.STOP
            if self._config[CONF_POSITIONING_MODE] != MODE_NONE:
                supported_features |= CoverEntityFeature.SET_POSITION
        return supported_features

    @property
    def _current_state(self) -> str:
        """Return the current state of the cover."""
        state = self._current_state_action
        curr_pos = self._current_cover_position

        # Reset STATE when cover is fully closed or fully opened.
        if (state == STATE_CLOSING and curr_pos == 0) or (
            state == STATE_OPENING and curr_pos == 100
        ):
            return STATE_STOPPED
        if state in (STATE_SET_CLOSING, STATE_SET_OPENING):
            set_pos = self._set_new_position
            # Reset state whenn cover reached the position.
            if curr_pos - set_pos < 5 and curr_pos - set_pos >= -5:
                return STATE_STOPPED

        return self._current_state_action

    @property
    def current_cover_position(self):
        """Return current cover position in percent."""
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self._current_cover_position

    @property
    def is_opening(self):
        """Return if cover is opening."""
        return self._current_state in (STATE_OPENING, STATE_SET_OPENING)

    @property
    def is_closing(self):
        """Return if cover is closing."""
        return self._current_state in (STATE_CLOSING, STATE_SET_CLOSING)

    @property
    def is_closed(self):
        """Return if the cover is closed or not."""
        if isinstance(self._open_cmd, (bool, str)):
            return self._current_cover_position == 0
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self.current_cover_position == 0 and self._current_state == STATE_STOPPED

    async def async_set_cover_position(self, **kwargs):
        """Move the cover to a specific position."""
        # Update device values IF the device is moving at the moment.
        if self._current_state != STATE_STOPPED:
            await self.async_stop_cover()

        self.debug("Setting cover position: %r", kwargs[ATTR_POSITION])
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            newpos = float(kwargs[ATTR_POSITION])

            currpos = self.current_cover_position
            posdiff = abs(newpos - currpos)
            mydelay = posdiff / 100.0 * self._config[CONF_SPAN_TIME]
            if newpos > currpos:
                self.debug("Opening to %f: delay %f", newpos, mydelay)
                await self.async_open_cover(delay=mydelay)
                self.update_state(STATE_OPENING)
            else:
                self.debug("Closing to %f: delay %f", newpos, mydelay)
                await self.async_close_cover(delay=mydelay)
                self.update_state(STATE_CLOSING)
            self.debug("Done")

        elif self._config[CONF_POSITIONING_MODE] == MODE_SET_POSITION:
            converted_position = int(kwargs[ATTR_POSITION])
            if self._position_inverted:
                converted_position = 100 - converted_position
            if 0 <= converted_position <= 100 and self.has_config(CONF_SET_POSITION_DP):
                await self._device.set_dp(
                    converted_position, self._config[CONF_SET_POSITION_DP]
                )
            # Give it a moment, to make sure hass updated current pos.
            await asyncio.sleep(0.1)
            self.update_state(STATE_SET_CMD, int(kwargs[ATTR_POSITION]))

    async def async_stop_after_timeout(self, delay_sec):
        """Stop the cover if timeout (max movement span) occurred."""
        try:
            await asyncio.sleep(delay_sec)
            self._current_task = None
            await self.async_stop_cover()
        except asyncio.CancelledError:
            self._current_task = None

    async def async_open_cover(self, **kwargs):
        """Open the cover."""
        self.debug("Launching command %s to cover ", self._open_cmd)
        await self._device.set_dp(self._open_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_OPENING)

    async def async_close_cover(self, **kwargs):
        """Close cover."""
        self.debug("Launching command %s to cover ", self._close_cmd)
        await self._device.set_dp(self._close_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_CLOSING)

    async def async_stop_cover(self, **kwargs):
        """Stop the cover."""
        if self._current_task is not None:
            self._current_task.cancel()
        self.debug("Launching command %s to cover ", self._stop_cmd)
        command = {self._dp_id: self._stop_cmd}
        if self._stop_switch is not None:
            command[self._stop_switch] = True
        await self._device.set_dps(command)
        self.update_state(STATE_STOPPED)

    def status_restored(self, stored_state):
        """Restore the last stored cover status."""
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            stored_pos = stored_state.attributes.get("current_position")
            if stored_pos is not None:
                self._current_cover_position = stored_pos
                self.debug("Restored cover position %s", self._current_cover_position)

    def connection_made(self):
        super().connection_made()

        match self.dp_value(self._dp_id):
            case str() as i if i.isupper():
                self._open_cmd = self._open_cmd.upper()
                self._close_cmd = self._close_cmd.upper()
                self._stop_cmd = self._stop_cmd.upper()
            case bool():
                self._open_cmd = True
                self._close_cmd = False

    def status_updated(self):
        """Device status was updated."""
        self._previous_state = self._state
        self._state = self.dp_value(self._dp_id)

        if self.has_config(CONF_CURRENT_POSITION_DP):
            curr_pos = self.dp_value(CONF_CURRENT_POSITION_DP)
            if isinstance(curr_pos, (bool, str)):
                closed = curr_pos in (True, "fully_close")
                stopped = (
                    self._previous_state is None or self._previous_state == self._state
                )
                curr_pos = 0 if stopped and closed else (100 if stopped else 50)

            if self._position_inverted:
                curr_pos = 100 - curr_pos

            self._current_cover_position = curr_pos

        if (
            self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED
            and self._state != self._previous_state
        ):
            if self._previous_state != self._stop_cmd:
                # the state has changed, and the cover was moving
                time_diff = time.time() - self._timer_start
                pos_diff = round(time_diff / self._config[CONF_SPAN_TIME] * 100.0)
                if self._previous_state == self._close_cmd:
                    pos_diff = -pos_diff
                self._current_cover_position = min(
                    100, max(0, self._current_cover_position + pos_diff)
                )

                change = "stopped" if self._state == self._stop_cmd else "inverted"
                self.debug(
                    "Movement %s after %s sec., position difference %s",
                    change,
                    time_diff,
                    pos_diff,
                )

            # store the time of the last movement change
            self._timer_start = time.time()

        # Keep record in last_state as long as not during connection/re-connection,
        # as last state will be used to restore the previous state
        if (self._state is not None) and (not self._device.is_connecting):
            self._last_state = self._state

    def update_state(self, action, position=None):
        """Update cover current states."""
        state = self._current_state_action
        # using Commands.
        if position is None:
            self._current_state_action = action
        # Set position cmd, check if target position weither close or open
        if action == STATE_SET_CMD and position is not None:
            curr_pos = self.current_cover_position
            self._set_new_position = position
            pos_diff = position - curr_pos
            # Prevent stuck state when interrupted on middle of cmd
            if state == STATE_STOPPED:
                if pos_diff > 0:
                    self._current_state_action = STATE_SET_OPENING
                elif pos_diff < 0:
                    self._current_state_action = STATE_SET_CLOSING
            else:
                self._current_state_action = STATE_STOPPED
        # Write state data.
        self.async_write_ha_state()


async_setup_entry = partial(async_setup_entry, DOMAIN, LocalTuyaCover, flow_schema)

@donaldkwong
Copy link
Author

Re-created the device using automatic entity creation and it works perfectly! The initial state is correctly reflected. I even restarted HA while the door was open and when HA came back up, the door was correctly in the Open state. The buttons work perfectly and all four states (Open, Opening, Closing, and Closed) all work correctly. Thanks for fixing everything!

xZetsubou added a commit that referenced this issue Jan 22, 2025
@xZetsubou xZetsubou added the master/next-release Fixed in master branch, Will be ready in the next release label Jan 22, 2025
@donaldkwong
Copy link
Author

donaldkwong commented Jan 22, 2025

Just noticed a weird issue this morning. Opening and closing the door with the HA entity's buttons works fine. However, opening and closing the door with the physical door controls is off. When I close the garage door with the physical switch, the entity goes into Opening state and then stays there. I'll have to play around with it some more later today.

@donaldkwong
Copy link
Author

donaldkwong commented Jan 22, 2025

Yeah, definitely some weird behavior. Operating the door with the entity buttons work perfectly fine. However, operating the door with the physical garage door button seems inverted. Here's a video showing the entity state through that process:

Screen.Recording.2025-01-22.at.10.59.41.AM.mov

At 1s and 11s, I'm opening and closing the door with the entity button and that works fine. At 27s, I'm opening the door with the physical button and the entity enters a Closing state. At 38s, I'm closing the door with the physical button and the state doesn't change, until the door completely closes and becomes Closed. I've seen another time when closing the door with the physical button makes the entity go into Opening and it remains there.

This is with the inverted option checked. I tried again with the option unchecked and it's even worse (the states are always wrong).

@donaldkwong
Copy link
Author

Here are the logs for that entire test (opening and closing with the entity buttons and then opening and closing with the physical button):

2025-01-22 11:01:04.040 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command True to cover 
2025-01-22 11:01:04.041 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'1': True}
2025-01-22 11:01:04.041 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737572464,"data":{"dps":{"1":true}}}'
2025-01-22 11:01:04.041 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737572464,"data":{"dps":{"1":true}}}'
2025-01-22 11:01:04.041 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 10880
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=10880, cmd=13, retcode=0, payload=b'', crc=b'\xf0g\xf9\xee%1Lx\x95\x91\x88\x87\x12\xce(\xf3D\xc2=\n\x92\xb8\xa6\xdc\xa5\x08\x16Vy*T\xe8', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 10880
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 10880
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=10880 self.seqno=10881
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 10880
2025-01-22 11:01:04.131 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': False}
2025-01-22 11:01:04.305 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10881, cmd=8, retcode=0, payload=b'2\x91\xe5T\xa5j\\M\xd5\x86\x92\xc2q\xac\x8b\xd0\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9b\xff\xc4h\xfdH\xc1\xad\xc5\xad\x83#K\xb2Zbg9\xa8\x90\xd8\xae\xd6V\xf9\x12\xed\xd5\xf7\x10\xab\x1d\x8a\xbd\xfc\xe2\xe9\xaew\xc6\xe2\x9as\xa34\x9e-\xb2\xea', crc=b'\xbe\x9a@Is\xe8\x99\x19\x16\xe8 \xfa\x01\x02\xa6\x8d\xaa<$\xd5\xe9\x12\xd1[\xeaRgc\xcd\x1es\xc3', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:04.305 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:04.305 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572464,"data":{"dps":{"1":true}}}'
2025-01-22 11:01:04.307 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': True}
2025-01-22 11:01:04.781 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10882, cmd=8, retcode=0, payload=b"(\x026\xfe\xb0\xcb\x90\x99N\x0b#\x9f\x97<{i\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9b\xffi6)\x9b\xe0\xbf\xdb\xef\xb4O_51f\tI\xb3lI\xaf\x19\xc0J\xb2\xbf\xff\x12\x15?e\xc0\x12\x0fC\xa5\xef\x11h9\x1b\xd0'B\x9fA\xee\x1c", crc=b'\x08\xed`\x1b\xfeO\xedc\xea\xc8\x00\x10\x90\x1fB%\xda\xf2i\xa3\xad\xe2\xbb\x19\xddO\xaf\x01!5H\x1c', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:04.781 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:04.782 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572465,"data":{"dps":{"3":true,"5":600}}}'
2025-01-22 11:01:04.782 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': True}
2025-01-22 11:01:07.901 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:07.901 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:07.901 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:07.902 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:08.016 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10883, cmd=9, retcode=0, payload=b'', crc=b'\xf3Ea\x04(o\x07\x05\xc9\x8ce\xeb\xb8R\x843\x94\xb9\x90\x1c\xbbUu\xc0\xc9.\xbcV\x8a$\xf3\x18', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:08.016 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:08.016 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10883
2025-01-22 11:01:15.092 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Launching command False to cover 
2025-01-22 11:01:15.093 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 7 (device type: v3.4) DPS: {'1': False}
2025-01-22 11:01:15.094 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"protocol":5,"t":1737572475,"data":{"dps":{"1":false}}}'
2025-01-22 11:01:15.094 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 13: b'3.4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{"protocol":5,"t":1737572475,"data":{"dps":{"1":false}}}'
2025-01-22 11:01:15.094 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 13 waiting for seq. number 10884
2025-01-22 11:01:15.190 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 13 TuyaMessage(seqno=10884, cmd=13, retcode=0, payload=b'', crc=b'v\xac\xf5\xe0R\'\xb86D\x12\xc1\xdc\xd8\x1d\x8d\xd9hj\xed\x99\x02\x11\x89\xdb\x97\t\xd2"\x13\x07h\xc1', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:15.191 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching sequence number 10884
2025-01-22 11:01:15.191 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got ACK message for command 13: ignoring it 10884
2025-01-22 11:01:15.191 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got update ack message update seqno only. msg.seqno=10884 self.seqno=10885
2025-01-22 11:01:15.191 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 13: ignoring: 10884
2025-01-22 11:01:15.191 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': True}
2025-01-22 11:01:15.377 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10885, cmd=8, retcode=0, payload=b"C\x11y\x1bE\xdf\x8cX-|\xcb3\n\xb3\xda\x05\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9b\xcaZT\x99CUJ8\x13\xc8\xd2\xa3\xb3\xde'\xc5c\xbb\x88J1\xd2\x1d\x0ek;\rEJ\x15\xbfqY\xeb\xc6fJ\x9b\x8cR\x06\xec\x9c=\xec,\x9f2", crc=b'\x04\x13\xf8\xc96\xa8\xa2f\xc6@4F\x86\x15[\xdf\xe6khA\xe1\xa8\xda\x02\x8c\xc5\x87\x1b\xcd\xd3j*', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:15.377 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:15.377 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572475,"data":{"dps":{"1":false}}}'
2025-01-22 11:01:15.378 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': False}
2025-01-22 11:01:17.016 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:17.017 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:17.017 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:17.017 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:17.130 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10886, cmd=9, retcode=0, payload=b'', crc=b"\x06?\xc7\xb7\xa8\x0c\xc1X\xdf@\xf7\xef\x16V\x0fd\x83\xc0\xec\xa7\xcf/'5\xd7\xa9\xfc\xa4\xcae\x83\xf0", crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:17.130 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:17.131 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10886
2025-01-22 11:01:22.206 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10887, cmd=8, retcode=0, payload=b'R\x88il\xcc\x9c\x9c\x1a\x87\x93\xa2\xc2\xc2\x18\xbe_\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9b1\x84Er\xc4\x8a\xf9\xadq\xcd\x06\xf6Q\xd5pC\x8f\x10\x19\xea\xdb\x03&`\xf5i\xa8\x08f\xff@5\xf2k7\xb4-\xf4\xa0\xd1c\x15U\x07.\xac\xc3\x94.\xdd\xd1f\xfca\x89^\xafg.RH>g\xef', crc=b'\xeb9\xf8\xe5\x86\x0c4\xc2\xa5|\xb3b\x95G\x05<m\xe0\xf5\x00\xc9\x99q\xd8d{\x05\xacW\x87\x00\xce', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:22.206 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:22.206 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572482,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'
2025-01-22 11:01:22.208 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': False}
2025-01-22 11:01:26.132 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:26.132 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:26.132 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:26.133 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:26.242 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10888, cmd=9, retcode=0, payload=b'', crc=b'\x04\xa1\xb2\x9c\xa6\xc2\x04\x12\xa0\x1f\xcb\xd0\xc0\x1dn\xe2\xaf\x01\xcb\xacB\xd5\x1d=\xbf%>\x1f\xc6\xb0\x01\xa9', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:26.242 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:26.242 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10888
2025-01-22 11:01:31.282 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10889, cmd=8, retcode=0, payload=b"\x8a\xdc\xc0C\x1aO\x0f\xfc\x08oO\x16\xc6\xcd\xa1M\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9bc\x11\\\xf5\x04!!\xb4S\x05t\xf0\x91V\x9eUI\xb3lI\xaf\x19\xc0J\xb2\xbf\xff\x12\x15?e\xc0\x12\x0fC\xa5\xef\x11h9\x1b\xd0'B\x9fA\xee\x1c", crc=b'\xfbA\xca\xa9\x04\xa7\xce\xb6o[e\x0eeO\xe8\x1d\x03\x02_\xc9\xe0H\xadyOv`AT\xb2\x12~', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:31.282 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:31.282 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572491,"data":{"dps":{"3":true,"5":600}}}'
2025-01-22 11:01:31.284 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': False}
2025-01-22 11:01:35.243 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:35.243 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:35.243 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:35.244 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:35.365 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10890, cmd=9, retcode=0, payload=b'', crc=b'\xe9\xd6?\xe0\xea[\xb9\x90\xdf\xc4\x9f\xffC\x11\xfes)\x91+\x85\xd7x\x85\xd8?\x0e\xab`\xc9E\x1al', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:35.365 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:35.365 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10890
2025-01-22 11:01:44.366 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:44.366 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:44.366 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:44.367 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:44.467 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10891, cmd=9, retcode=0, payload=b'', crc=b'E\xac\xaf1\xeb\xdc\x1d\xc6F\xa5\xb8\n\x10\x18\x8c\xe8\\\x91\xf1)t\xca\xc7\xe5\x8c\x044|=\x13\xde\xdf', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:44.467 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:44.467 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10891
2025-01-22 11:01:47.283 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 8 TuyaMessage(seqno=10892, cmd=8, retcode=0, payload=b"\xd6\x8a\xa9\xaa\xdd\x90\xfc\xe2\xfb\x90\x06\x871rU\xa0\xd7\x0f\x08P\xeb\xd5p\xd9D\xe1\xb7\xc9\xd9sr\x9b\xd2o=\x88\xe39r\x81\xe8\xd0\xe1E'>\xf8\x82\x8f\x10\x19\xea\xdb\x03&`\xf5i\xa8\x08f\xff@5\xf2k7\xb4-\xf4\xa0\xd1c\x15U\x07.\xac\xc3\x94.\xdd\xd1f\xfca\x89^\xafg.RH>g\xef", crc=b'\xc9\x08\xc7\xd1\xcc\x02\x03\xdc\xddV\xaaG\xc8\x1f\xe5\x81\x15\xc3Bl\xda\x9f|\xc6c"&\x013\xa6\xdc\x03', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:47.283 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got status update
2025-01-22 11:01:47.284 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Deciphered data = '{"protocol":4,"t":1737572507,"data":{"dps":{"3":false,"5":600,"12":"none"}}}'
2025-01-22 11:01:47.285 DEBUG (MainThread) [custom_components.localtuya.cover] [eb2...mtv - Garage door ] Entity Door - Additional attributes: {'raw_state': False}
2025-01-22 11:01:53.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending command 9 (device type: v3.4) DPS: None
2025-01-22 11:01:53.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Sending payload: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:53.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] final payload for cmd 9: b'{"gwId":"eb2d92a6870c513122umtv","devId":"eb2d92a6870c513122umtv"}'
2025-01-22 11:01:53.469 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Command 9 waiting for seq. number -100
2025-01-22 11:01:53.588 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Dispatching message CMD 9 TuyaMessage(seqno=10893, cmd=9, retcode=0, payload=b'', crc=b'\xc4%\xb6\x91\x84bC\xd2\x8c\x94\x04\xb10\x0e\xb7\tu\x8e\x89\xdb]F\x07\x86}\xe0\xbf.\xfb\x96\x83\x88', crc_good=True, prefix=21930, iv=None)
2025-01-22 11:01:53.588 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] Got heartbeat response
2025-01-22 11:01:53.589 DEBUG (MainThread) [custom_components.localtuya.core.pytuya] [eb2...mtv - Garage door ] ACK received for command 9: ignoring: 10893

@donaldkwong
Copy link
Author

Tested 2005.1.1 again and it didn't have this state disconnect with the physical button. The entity correctly showed Open and Closed when the door was opened and closed with the physical button.

@xZetsubou
Copy link
Owner

The issue is that the garage doesn't support opening/closing it's only supports open/closed, try this.

cover.py

"""Platform to locally control Tuya-based cover devices."""

import asyncio
import logging
import time
from functools import partial

import voluptuous as vol
from homeassistant.components.cover import (
    ATTR_POSITION,
    DOMAIN,
    CoverEntityFeature,
    CoverEntity,
    DEVICE_CLASSES_SCHEMA,
)
from homeassistant.const import CONF_DEVICE_CLASS
from .config_flow import col_to_select
from .entity import LocalTuyaEntity, async_setup_entry
from .const import (
    CONF_COMMANDS_SET,
    CONF_CURRENT_POSITION_DP,
    CONF_POSITION_INVERTED,
    CONF_POSITIONING_MODE,
    CONF_SET_POSITION_DP,
    CONF_SPAN_TIME,
    CONF_STOP_SWITCH_DP,
)


# cover states.
STATE_OPENING = "opening"
STATE_CLOSING = "closing"
STATE_STOPPED = "stopped"
STATE_SET_CMD = "moving"
STATE_SET_OPENING = "set_opeing"
STATE_SET_CLOSING = "set_closing"

_LOGGER = logging.getLogger(__name__)


COVER_COMMANDS = {
    "Open, Close and Stop": "open_close_stop",
    "Open, Close and Continue": "open_close_continue",
    "ON, OFF and Stop": "on_off_stop",
    "fz, zz and Stop": "fz_zz_stop",
    "zz, fz and Stop": "zz_fz_stop",
    "1, 2 and 3": "1_2_3",
    "0, 1 and 2": "0_1_2",
}

MODE_NONE = "none"
MODE_SET_POSITION = "position"
MODE_TIME_BASED = "timed"
COVER_MODES = {
    "Neither": MODE_NONE,
    "Set Position": MODE_SET_POSITION,
    "Time Based": MODE_TIME_BASED,
}

COVER_TIMEOUT_TOLERANCE = 3.0

DEF_CMD_SET = list(COVER_COMMANDS.values())[0]
DEF_POS_MODE = list(COVER_MODES.values())[0]
DEFAULT_SPAN_TIME = 25.0


def flow_schema(dps):
    """Return schema used in config flow."""
    return {
        vol.Optional(CONF_COMMANDS_SET, default=DEF_CMD_SET): col_to_select(
            COVER_COMMANDS
        ),
        vol.Optional(CONF_POSITIONING_MODE, default=DEF_POS_MODE): col_to_select(
            COVER_MODES
        ),
        vol.Optional(CONF_CURRENT_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_SET_POSITION_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_POSITION_INVERTED, default=False): bool,
        vol.Optional(CONF_SPAN_TIME, default=DEFAULT_SPAN_TIME): vol.All(
            vol.Coerce(float), vol.Range(min=1.0, max=300.0)
        ),
        vol.Optional(CONF_STOP_SWITCH_DP): col_to_select(dps, is_dps=True),
        vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
    }


class LocalTuyaCover(LocalTuyaEntity, CoverEntity):
    """Tuya cover device."""

    def __init__(self, device, config_entry, switchid, **kwargs):
        """Initialize a new LocalTuyaCover."""
        super().__init__(device, config_entry, switchid, _LOGGER, **kwargs)
        commands_set = DEF_CMD_SET
        if self.has_config(CONF_COMMANDS_SET):
            commands_set = self._config[CONF_COMMANDS_SET]
        self._open_cmd = commands_set.split("_")[0]
        self._close_cmd = commands_set.split("_")[1]
        self._stop_cmd = commands_set.split("_")[2]
        self._timer_start = time.time()
        self._state = None
        self._previous_state = None
        self._current_cover_position = 0
        self._current_state_action = STATE_STOPPED  # Default.
        self._set_new_position = int | None
        self._stop_switch = self._config.get(CONF_STOP_SWITCH_DP)
        self._position_inverted = self._config.get(CONF_POSITION_INVERTED)
        self._current_task = None

    @property
    def supported_features(self):
        """Flag supported features."""
        supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
        if not isinstance(self._open_cmd, bool):
            supported_features |= CoverEntityFeature.STOP
            if self._config[CONF_POSITIONING_MODE] != MODE_NONE:
                supported_features |= CoverEntityFeature.SET_POSITION
        return supported_features

    @property
    def _current_state(self) -> str:
        """Return the current state of the cover."""
        state = self._current_state_action
        curr_pos = self._current_cover_position

        # Reset STATE when cover is fully closed or fully opened.
        if (state == STATE_CLOSING and curr_pos == 0) or (
            state == STATE_OPENING and curr_pos == 100
        ):
            self._current_state_action = STATE_STOPPED
        if state in (STATE_SET_CLOSING, STATE_SET_OPENING):
            set_pos = self._set_new_position
            # Reset state whenn cover reached the position.
            if curr_pos - set_pos < 5 and curr_pos - set_pos >= -5:
                self._current_state_action = STATE_STOPPED

        return self._current_state_action

    @property
    def current_cover_position(self):
        """Return current cover position in percent."""
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self._current_cover_position

    @property
    def is_opening(self):
        """Return if cover is opening."""
        return self._current_state in (STATE_OPENING, STATE_SET_OPENING)

    @property
    def is_closing(self):
        """Return if cover is closing."""
        return self._current_state in (STATE_CLOSING, STATE_SET_CLOSING)

    @property
    def is_closed(self):
        """Return if the cover is closed or not."""
        if isinstance(self._open_cmd, (bool, str)):
            return self._current_cover_position == 0
        if self._config[CONF_POSITIONING_MODE] == MODE_NONE:
            return None
        return self.current_cover_position == 0 and self._current_state == STATE_STOPPED

    async def async_set_cover_position(self, **kwargs):
        """Move the cover to a specific position."""
        # Update device values IF the device is moving at the moment.
        if self._current_state != STATE_STOPPED:
            await self.async_stop_cover()

        self.debug("Setting cover position: %r", kwargs[ATTR_POSITION])
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            newpos = float(kwargs[ATTR_POSITION])

            currpos = self.current_cover_position
            posdiff = abs(newpos - currpos)
            mydelay = posdiff / 100.0 * self._config[CONF_SPAN_TIME]
            if newpos > currpos:
                self.debug("Opening to %f: delay %f", newpos, mydelay)
                await self.async_open_cover(delay=mydelay)
                self.update_state(STATE_OPENING)
            else:
                self.debug("Closing to %f: delay %f", newpos, mydelay)
                await self.async_close_cover(delay=mydelay)
                self.update_state(STATE_CLOSING)
            self.debug("Done")

        elif self._config[CONF_POSITIONING_MODE] == MODE_SET_POSITION:
            converted_position = int(kwargs[ATTR_POSITION])
            if self._position_inverted:
                converted_position = 100 - converted_position
            if 0 <= converted_position <= 100 and self.has_config(CONF_SET_POSITION_DP):
                await self._device.set_dp(
                    converted_position, self._config[CONF_SET_POSITION_DP]
                )
            # Give it a moment, to make sure hass updated current pos.
            await asyncio.sleep(0.1)
            self.update_state(STATE_SET_CMD, int(kwargs[ATTR_POSITION]))

    async def async_stop_after_timeout(self, delay_sec):
        """Stop the cover if timeout (max movement span) occurred."""
        try:
            await asyncio.sleep(delay_sec)
            self._current_task = None
            await self.async_stop_cover()
        except asyncio.CancelledError:
            self._current_task = None

    async def async_open_cover(self, **kwargs):
        """Open the cover."""
        self.debug("Launching command %s to cover ", self._open_cmd)
        await self._device.set_dp(self._open_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_OPENING)

    async def async_close_cover(self, **kwargs):
        """Close cover."""
        self.debug("Launching command %s to cover ", self._close_cmd)
        await self._device.set_dp(self._close_cmd, self._dp_id)
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            if self._current_task is not None:
                self._current_task.cancel()
            # for timed positioning, stop the cover after a full opening timespan
            # instead of waiting the internal timeout
            self._current_task = self.hass.async_create_task(
                self.async_stop_after_timeout(
                    kwargs.get(
                        "delay", self._config[CONF_SPAN_TIME] + COVER_TIMEOUT_TOLERANCE
                    )
                )
            )
        self.update_state(STATE_CLOSING)

    async def async_stop_cover(self, **kwargs):
        """Stop the cover."""
        if self._current_task is not None:
            self._current_task.cancel()
        self.debug("Launching command %s to cover ", self._stop_cmd)
        command = {self._dp_id: self._stop_cmd}
        if self._stop_switch is not None:
            command[self._stop_switch] = True
        await self._device.set_dps(command)
        self.update_state(STATE_STOPPED)

    def status_restored(self, stored_state):
        """Restore the last stored cover status."""
        if self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED:
            stored_pos = stored_state.attributes.get("current_position")
            if stored_pos is not None:
                self._current_cover_position = stored_pos
                self.debug("Restored cover position %s", self._current_cover_position)

    def connection_made(self):
        super().connection_made()

        match self.dp_value(self._dp_id):
            case str() as i if i.isupper():
                self._open_cmd = self._open_cmd.upper()
                self._close_cmd = self._close_cmd.upper()
                self._stop_cmd = self._stop_cmd.upper()
            case bool():
                self._open_cmd = True
                self._close_cmd = False

    def status_updated(self):
        """Device status was updated."""
        self._previous_state = self._state
        self._state = self.dp_value(self._dp_id)

        if self.has_config(CONF_CURRENT_POSITION_DP):
            curr_pos = self.dp_value(CONF_CURRENT_POSITION_DP)
            if isinstance(curr_pos, (bool, str)):
                closed = curr_pos in (True, "fully_close")
                stopped = (
                    self._previous_state is None or self._previous_state == self._state
                )
                curr_pos = 0 if stopped and closed else (100 if stopped else 50)

            if self._position_inverted:
                curr_pos = 100 - curr_pos

            self._current_cover_position = curr_pos

        if (
            self._config[CONF_POSITIONING_MODE] == MODE_TIME_BASED
            and self._state != self._previous_state
        ):
            if self._previous_state != self._stop_cmd:
                # the state has changed, and the cover was moving
                time_diff = time.time() - self._timer_start
                pos_diff = round(time_diff / self._config[CONF_SPAN_TIME] * 100.0)
                if self._previous_state == self._close_cmd:
                    pos_diff = -pos_diff
                self._current_cover_position = min(
                    100, max(0, self._current_cover_position + pos_diff)
                )

                change = "stopped" if self._state == self._stop_cmd else "inverted"
                self.debug(
                    "Movement %s after %s sec., position difference %s",
                    change,
                    time_diff,
                    pos_diff,
                )

            # store the time of the last movement change
            self._timer_start = time.time()

        # Keep record in last_state as long as not during connection/re-connection,
        # as last state will be used to restore the previous state
        if (self._state is not None) and (not self._device.is_connecting):
            self._last_state = self._state

    def update_state(self, action, position=None):
        """Update cover current states."""
        if (state := self._current_state_action) == action:
            return

        # using Commands.
        if position is None:
            self._current_state_action = action
        # Set position cmd, check if target position weither close or open
        if action == STATE_SET_CMD and position is not None:
            curr_pos = self.current_cover_position
            self._set_new_position = position
            pos_diff = position - curr_pos
            # Prevent stuck state when interrupted on middle of cmd
            if state == STATE_STOPPED:
                if pos_diff > 0:
                    self._current_state_action = STATE_SET_OPENING
                elif pos_diff < 0:
                    self._current_state_action = STATE_SET_CLOSING
            else:
                self._current_state_action = STATE_STOPPED
        # Write state data.
        self.schedule_update_ha_state()


async_setup_entry = partial(async_setup_entry, DOMAIN, LocalTuyaCover, flow_schema)

@donaldkwong
Copy link
Author

donaldkwong commented Jan 22, 2025

That last change worked! The door states are now in sync when using the physical button and the HA entity buttons still work correctly. Thanks for the quick fix!

@donaldkwong
Copy link
Author

Been using this the past week and it's been really solid. I think these changes can be merged into main for the next release. Thanks!

@donaldkwong
Copy link
Author

donaldkwong commented Jan 29, 2025

I'm not sure what happened, but the entity card changed today all of a sudden and the button controls don't work anymore. I'm still using your custom cover.py from above and haven't changed anything. I've tried deleting and re-creating the device, but it's still the same. The only change I can think of is that I updated HACS itself, but I don't think that should change LocalTuya.

Image

@xZetsubou
Copy link
Owner

Well, this shouldn't affect localtuya , but try using cover services or ha native entity card instead of custom cards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working master/next-release Fixed in master branch, Will be ready in the next release
Projects
None yet
Development

No branches or pull requests

2 participants