You need to remove one indent level (four spaces) and data seems to be misspelled (dati).
except Exception as e:
self.log.warning("Failed to get status: %s", e)
raise
self.log.debug ("Data:% s", data)
detected_dps.update(data["dps"])
Traceback (most recent call last):
File “/config/custom_components/localtuya/config_flow.py”, line 236, in async_step_basic_info
self.dps_strings = await validate_input(self.hass, user_input)
File “/config/custom_components/localtuya/config_flow.py”, line 172, in validate_input
detected_dps = await interface.detect_available_dps()
File “/config/custom_components/localtuya/pytuya/init.py”, line 440, in detect_available_dps
detected_dps.update(data[“dps”])
KeyError: ‘dps’
What’s printed on the line above, with “Data:”?
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] switching to dev_type type_0d
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Re-send status due to device type change (type_0a -> type_0d)
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0d)
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“devId”:“MyID”,“uid”:“MyID”,“t”:“1xxx4”,“dps”:{“1”:null,“2”:null,“3”:null,“4”:null,“5”:null,“6”:null,“7”:null,“8”:null,“9”:null,“10”:null}}’
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 2
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 2
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-06 19:44:14 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Data:{}
2020-10-06 19:44:14 ERROR (MainThread) [custom_components.localtuya.config_flow] Unexpected exception
Ok, so we get nothing. Last try to see if anything works. Try replacing the entire method with this:
async def detect_available_dps(self):
"""Return which datapoints are supported by the device."""
# type_0d devices need a sort of bruteforce querying in order to detect the
# list of available dps experience shows that the dps available are usually
# in the ranges [1-25] and [100-110] need to split the bruteforcing in
# different steps due to request payload limitation (max. length = 255)
detected_dps = {}
ranges = [(2, 11), (11, 21), (21, 31), (100, 111)]
for dps_range in ranges:
# dps 1 must always be sent, otherwise it might fail in case no dps is found
# in the requested range
self.dps_to_request = {"1": None}
self.add_dps_to_request(range(*dps_range))
try:
data = await self.status()
except Exception as e:
self.log.warning("Failed to get status: %s", e)
raise
if "dps" in data:
detected_dps.update(data["dps"])
if self.dev_type == "type_0a":
return detected_dps
self.log.debug("detected dps: %s", detected_dps)
return detected_dps
Hi @postlund,
thank you for all the time you give me.
I copied the code and this time it went ahead and I could choose the “switch” type, but I couldn’t enter the ID even manually.
This is the reported error:
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command heartbeat (device type: type_0a)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number -100
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0a)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“gwId”:“MyID”,“devId”:“MyID”}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 1
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Got heartbeat response
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 1
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’\xxx…xxx…xxx’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] switching to dev_type type_0d
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Re-send status due to device type change (type_0a -> type_0d)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0d)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“devId”:“MyID”,“uid”:“MyID”,“t”:“1xxx3”,“dps”:{“1”:null,“2”:null,“3”:null,“4”:null,“5”:null,“6”:null,“7”:null,“8”:null,“9”:null,“10”:null}}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 2
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 2
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0d)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“devId”:“MyID”,“uid”:“MyID”,“t”:“1xxx3”,“dps”:{“1”:null,“11”:null,“12”:null,“13”:null,“14”:null,“15”:null,“16”:null,“17”:null,“18”:null,“19”:null,“20”:null}}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 3
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 3
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0d)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“devId”:“MyID”,“uid”:“MyID”,“t”:“1xxx3”,“dps”:{“1”:null,“21”:null,“22”:null,“23”:null,“24”:null,“25”:null,“26”:null,“27”:null,“28”:null,“29”:null,“30”:null}}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 4
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 4
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Sending command status (device type: type_0d)
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Paylod: b’{“devId”:“MyID”,“uid”:“MyID”,“t”:“1xxx3”,“dps”:{“1”:null,“100”:null,“101”:null,“102”:null,“103”:null,“104”:null,“105”:null,“106”:null,“107”:null,“108”:null,“109”:null,“110”:null}}’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Waiting for sequence number 5
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Got status update
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Got status update
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Dispatching sequence number 5
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Got status update
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decode payload: b’’
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] Decrypted payload: {}
2020-10-07 00:30:03 DEBUG (MainThread) [custom_components.localtuya.pytuya] [MyID] detected dps: {}
My switch:
I’m trying to debug what’s happening on my tuya lights (nebula lights) after a power outage or after replugging it to an outlet. The localtuya was able to detect it’s unavailability and comes back once I plugged it in but with wrong state (light automatically turns on after plugging it) until I issue light.turn_off.
tuya-cli get fails with an error until the light.turn_off command:
~ $ tuya-cli get --ip 192.168.20.49 --id 'XXXXXXXX' --key 'XXXXX' --protocol-version 3.3 -a
events.js:174
throw er; // Unhandled 'error' event
^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('json obj data unvalid')
at TuyaDevice.emit (events.js:187:17)
at Socket.client.on.data (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/tuyapi/index.js:318:22)
at Socket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
Emitted 'error' event at:
at Socket.client.on.data (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/tuyapi/index.js:334:18)
at Socket.emit (events.js:198:13)
[... lines matching original stack trace ...]
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
Hi @postlund,
I don’t know if it is due to the change made, but I find all the “LocalTuya” lights on the “unavailable” state.
I try to restart Home Assistant to see if the problem persists.
Could it be a problem with modified pytuya?
Restarting Home Assistant the lights “LoaclTuya” are reachable
Hi thats super news. I can provide you screenshots from my SmartLife APP, thats not a problem. But where can I find the tuyadebug.tgz file? I dont know how to help you
@Alloc186, it’s right in the main page of LocalTuya repository:
As an alternative, you could try to add the device using the config flow, select any type of device (of course you won’t find climate yet) and post a screenshot of the drop-down menu containing the DPS indexes with their value, if it’s easier for you.
Let us know
Well call me a noob, but Im not really skilled in running scripts. I dont know how to make it without instructions.
Anyway, i tried it with config flow and seems really hopefully!!!
See the pics It found many IDs with right values.
I tried to associate them, at least some of them…
The first thing, Im using thermostat made by Hysen, Model: HY08-2.
ID1=True; is device ON/OFF
ID2=set temperature (in my case multiplied by 10)
ID3=current temperature (in my case multiplied by 10)
ID4= heating mode (manual, auto, holiday)
ID6= False; lock
ID12=0; ???
ID101=false; ???
ID102=false; is right now in heating state???
ID103=245; external floor temperature
ID104=30; Days in holiday mode
ID105=5; temperature to keep in holiday mode
ID106=true; ???
ID107=true; ???
ID108=true; ???
ID109=-15; Temp Calibration (*10)
ID110=5; Int temperature deadzone (*10)
ID111=1; Ext temperature deadzone
ID112=45; HighTemp protection
ID113=5; LowTemp protection
ID114=35; Max Temperature limit
ID115=5; Min Temperature limit
ID116=all;Internal temp sensor, External temp, or both to control heater
ID117=keep; Device state on power
ID118=2days; Seem to be auto program type 5+2days
Hi @Alloc186 , I created a first implementation of the climate class, you can find it at
It’s quite basic but somehow tailored on your device, even if I tried to keep it general.
I don’t really know how to handle the “holiday” mode (should probably use a combination of HVAC and Preset modes but it would be too tailored on your device), so currently only “manual” and “auto” are supported. External temperature is supposed to be obtained using a sensor apart (so you should create both a climate: and a sensor: entities.
Please give it a go and report feedback, bye!
22 = Brightness (Scale 10-1000) / 23 Color Temp (Scale 0-1000). DP ID 24 = Colour_data (Char type). You can check the ID on iot.tuya.com when you create a product:
Wow, great observation info. Now it should be easier to integrate it. Thank you!
Just tried it and I think its working fine. But I found strange thing, temperature values are halved. ID shows 230, in HA thermostat card is shown 115. real room temp is 23°C.
Did you select 0.5 as Precision? You should have set 0.1…
With 0.1 precision both temperatures are shown OK. But my thermostat supports only target_temp_step: 0.5 in reality. When I tried to change the set temp from HA it becomes unavailable for a while and nothing happens.
Ok I was having this doubt while writing the code but thought the step was 0.1 since the value was multiplied by 10 in the dps. I also thought this because my thermostat supports 0.1 steps… Anyway, I will separate the two options, please wait.
Hi Carlo,
little OT. Which chronothermostat do you recommend that integrates with home assistant and compatible with local tuya?
I am in Italy and I have the box “503”.
Thank you
PS @rospogrigio Which one do you have?