Tuya LOCAL with energy monitoring and without tuya-convert

As promissed, I am sharing my experience with local connection to various different brand smart sockets, all connected to Tuya cloud.
Currently I use:

They all work perfectly with TuyaSmart and Smart Life application and work also without the issues with official Tuya integration for HomeAssistant https://www.home-assistant.io/integrations/tuya/
The problem is, that this option controls sockets via cloud and does not support power monitoring.

*edit: You may try the node-red solution described in the following posts, but I have found easier solution described in post #9

The best alternative probably is tuya-convert https://github.com/M4dmartig4n/tuya-convert
But… the process is not so easy and some of the devices can not be flashed due the different chipset.

Subzero79 did the great work creating node-red node for controlling tuya devices locally https://github.com/subzero79/node-red-contrib-tuya-local
Unfortunatelly guy at the end flashed all of his devices to Tasmota and project is not supported anymore and also instructions are not easy to follow. To help you to avoid spending nights googling, I promissed to make also to people with less programming knowledge (like me) with the instructions.


1. installation
Since this is non listed node, you can not find it under Manage palettes, but you have to add github path into Node-red addon Config under Supervisor in HomeAssistant


Annotation 2020-02-21 223122

Then install simple node red testing flow

 [{"id":"115ada30.1743c6","type":"tuya-local","z":"8e8fe68f.ac31b8","devName":"socket1","devIp":"[](https://l.messenger.com/l.php?u=http%3A%2F%2F10.10.4.81%2F&h=AT0X9xm4qucefdoIV38PMf4Fd_aJOtaJlktH7OEzSRctpjoC8g7oPv9inRCidzQgiGYlfM5C_t2M7hzj6Kis67numEh8LYLQ_I0SKRTBv67PY26OXINE2el5nHXhkNyZD1E)","devId":"82180707adcfa6743a","devKey":"d189ad7b927d1dac","protocolVer":"3.3","x":550,"y":400,"wires":[["88349073.f9906"]]},{"id":"f21e12d7.a9512","type":"inject","z":"8e8fe68f.ac31b8","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":460,"wires":[["115ada30.1743c6"]]},{"id":"19a51c7b.2203e4","type":"inject","z":"8e8fe68f.ac31b8","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":500,"wires":[["115ada30.1743c6"]]},{"id":"88349073.f9906","type":"debug","z":"8e8fe68f.ac31b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":400,"wires":[]},{"id":"797d431a.95651c","type":"inject","z":"8e8fe68f.ac31b8","name":"{\"set\": true, \"dps\" : 1}","topic":"","payload":"{\"set\": true, \"dps\" : 1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":310,"y":420,"wires":[["115ada30.1743c6"]]},{"id":"90a67db.6f94d8","type":"inject","z":"8e8fe68f.ac31b8","name":"request","topic":"","payload":"request","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":340,"wires":[["115ada30.1743c6"]]},{"id":"8d81b2e6.7d0b4","type":"inject","z":"8e8fe68f.ac31b8","name":"disconnect","topic":"disconnect","payload":"disconnect","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":340,"y":300,"wires":[["115ada30.1743c6"]]},{"id":"b1231ec7.fadc6","type":"inject","z":"8e8fe68f.ac31b8","name":"connect ","topic":"","payload":"connect","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":260,"wires":[["115ada30.1743c6"]]},{"id":"e23704b.8e613f8","type":"inject","z":"8e8fe68f.ac31b8","name":"{\"set\": false, \"dps\" : 1}","topic":"","payload":"{\"set\": false, \"dps\" : 1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":300,"y":380,"wires":[["115ada30.1743c6"]]},{"id":"778d17d6.8d4d28","type":"inject","z":"8e8fe68f.ac31b8","name":"","topic":"","payload":"toggle","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":540,"wires":[["115ada30.1743c6"]]}]

2. Node red configuration

2.1 For each tuya device you need Device IP, Device ID and Device key.

Device IP you could find in router settings our using network discovery tools like Fing https://play.google.com/store/apps/details?id=com.overlook.android.fing

Device ID can be found under Device information in your tuya application (use Smart Life https://play.google.com/store/apps/details?id=com.tuya.smartlife and not Tuya Smart )

The trickiest part here is to get Local key of the tuya devices. You can find a few different ways, none is straightforward. The 2 successfully tested are using HTTP sniffer and the one using rooted phone. I will focus instructions on option with rooted phone since this was the only one giving me 100% success.

I have installed Tuya Smart Life from the playstore link above and pair all your devices with your account. Then get rooted android mobile phone and install Smart Life v 3.3.0 (on newer versions it does not work since they changed the way data is stored)

Open the application and log in with the same account you used for pairing. Wait untill all devices appear.

Use Root explorer (or any other file explorer that can access root files).

Now navigate to


Find the file with the name like this:

preferences_global_key_<some chars and numbers>.xml 

Copy it to the computer and open with some text editor. I prefer Visual Studio Code since it is easier to find things or clean the file. But also notepad would work. You will get something like

Find your device by name or ID (key) and look for “localkey” in this example Local key is


Save it on a safe place (be careful that you will not copy also garbage in front or after the key).

Warning: if you remove the device from your application (account) or do the hard reset (holding button for 5s), the Local Key will change and you will have to repeat the procedure.
(ideas and screenshoots are from https://community.openhab.org/t/step-by-step-guide-for-adding-tuya-bulbs-wi-fi-smart-led-smart-life-app-to-oh2-using-tuya-mqtt-js-by-agentk/59371 )

2.2 Test node
Put settings into the tuya-local node in the simple testing flow from the previous post and test if you get the connection

do not have more flows with the same device, since api can connect only once. When you will do the real flow, you need to remove the device from test flow!


3. Create flow and publish tuya socket to HomeAssistant
Prerequisete is that you have MQTT working in HomeAssistant in order to publish the data to HA

Install this flow:

[{"id":"b40f19b3.81c0e8","type":"change","z":"d98cf64c.d7fed8","name":"set tuya_devices","rules":[{"t":"set","p":"tuya_devices","pt":"flow","to":"(\t   $s1          := \"switch_1\";\t   $s2          := \"switch_2\";\t   [\t       {\t           \"devId\"      : \"82180808c44f33a6743a\",\t           \"ip\"         : \"\",\t           \"name\"       : $s1\t       },\t       {\t           \"devId\"      : \"82180808c44f3387a0fe\",\t           \"ip\"         : \"\",\t           \"name\"       : $s2\t       }\t   ]\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":160,"wires":[[]]},{"id":"546e596.a25eea8","type":"inject","z":"d98cf64c.d7fed8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":150,"y":160,"wires":[["b40f19b3.81c0e8"]]},{"id":"bf85621d.da07d","type":"inject","z":"d98cf64c.d7fed8","name":"","topic":"","payload":"tuya_devices","payloadType":"flow","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":240,"wires":[["5795380.6f9a1c8"]]},{"id":"5795380.6f9a1c8","type":"split","z":"d98cf64c.d7fed8","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":290,"y":240,"wires":[["c1f88cc8.ad8e"]]},{"id":"c1f88cc8.ad8e","type":"change","z":"d98cf64c.d7fed8","name":"set mqtt devices","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t$topic_prefix := \"tuya\";\t$dev_name := payload.name;\t   {\t       \"platform\":\"mqtt\",\t       \"name\": $dev_name,\t       \"state_topic\":$topic_prefix & \"/\" & $dev_name & \"/status\",\t       \"value_template\": \"{{ value_json.state }}\",\t       \"command_topic\":$topic_prefix & \"/\" & $dev_name & \"/set\",\t       \"availability_topic\":$topic_prefix & \"/\" & $dev_name & \"/available\",\t       \"payload_available\":\"online\",\t       \"payload_not_available\":\"offline\",\t       \"json_attributes_topic\": $topic_prefix & \"/\" & $dev_name & \"/status\",\t       \"json_attributes_template\": \"{{ value_json.attributes | tojson }}\",\t       \"payload_on\":\"ON\",\t       \"payload_off\":\"OFF\",\t       \"optimistic\":false,\t       \"qos\":0,\t       \"retain\":false\t   }\t)","tot":"jsonata"},{"t":"set","p":"topic","pt":"msg","to":"\"homeassistant/switch/\" & payload.name & \"/config\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":240,"wires":[["879a9a27.016f58"]]},{"id":"879a9a27.016f58","type":"mqtt out","z":"d98cf64c.d7fed8","name":"","topic":"","qos":"","retain":"","broker":"7b9a492a.76f2c8","x":650,"y":240,"wires":[]},{"id":"a2e39ae1.1c8008","type":"tuya-local","z":"d98cf64c.d7fed8","devName":"switch_1","devIp":"","devId":"82180707c44f33a6743a","devKey":"df2ad2b927d1dac","protocolVer":"3.3","renameSchema":"","filterCB":"","x":660,"y":340,"wires":[["82d03748.37a7c8"]]},{"id":"743700a3.27eee","type":"mqtt in","z":"d98cf64c.d7fed8","name":"","topic":"tuya/+/set","qos":"2","datatype":"auto","broker":"7b9a492a.76f2c8","x":160,"y":380,"wires":[["74d7a3e9.b626cc"]]},{"id":"87ac07d9.edda68","type":"change","z":"d98cf64c.d7fed8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"data.available ? \"online\" : \"offline\"","tot":"jsonata"},{"t":"set","p":"topic","pt":"msg","to":"\"tuya/\" & data.name & \"/available\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":980,"y":400,"wires":[["7ee9b2f.05c694c"]]},{"id":"7ee9b2f.05c694c","type":"mqtt out","z":"d98cf64c.d7fed8","name":"","topic":"","qos":"","retain":"","broker":"7b9a492a.76f2c8","x":1190,"y":360,"wires":[]},{"id":"74d7a3e9.b626cc","type":"change","z":"d98cf64c.d7fed8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t$new_state := (payload = \"ON\") ? true : false; \t{ \"set\" : $new_state, \"dps\": 1 }\t)","tot":"jsonata"},{"t":"set","p":"topic","pt":"msg","to":"(\t$name:= $split(topic, \"/\")[1];\t   $tuya:= [\t       {\t           \"devId\":\"82180707c44f33a6743a\",\t           \"ip\":\"\",\t           \"localKey\":\"acb2ad7b927d1dac\",\t           \"name\":\"switch_1\",\t           \"state_t\":\"medion/switch_1\",\t           \"cmd_t\":\"medion/switch_1/set\",\t           \"attr_t\":\"medion/switch_1/attributes\",\t           \"avai_t\":\"medion/switch_1/available\",\t           \"entity_id\":\"switch.medion_switch_1_mqtt\"\t       },\t       {\t           \"devId\":\"82180707c44f3387a0fe\",\t           \"ip\":\"\",\t           \"localKey\":\"58c3558e3ca45c9e\",\t           \"name\":\"switch_2\",\t           \"state_t\":\"medion/switch_2\",\t           \"cmd_t\":\"medion/switch_2/set\",\t           \"attr_t\":\"medion/switch_2/attributes\",\t           \"avai_t\":\"medion/switch_2/available\",\t           \"entity_id\":\"switch.medion_switch_2_mqtt\"\t       }\t   ];\t$device := $filter($tuya, function($x) {\t    $x.name = $name\t});\t$device.ip\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":380,"wires":[["27fe737.1f92e8c"]]},{"id":"27fe737.1f92e8c","type":"switch","z":"d98cf64c.d7fed8","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"tuya_devices.0.ip","vt":"flow"},{"t":"eq","v":"tuya_devices.1.ip","vt":"flow"}],"checkall":"true","repair":false,"outputs":2,"x":470,"y":380,"wires":[["a2e39ae1.1c8008"],["4b43fc85.5c39a4"]]},{"id":"4d1e51e4.123a","type":"function","z":"d98cf64c.d7fed8","name":"","func":"const dps =  msg.payload.dps;\nlet state = null;\nlet power = null;\nlet voltage = null;\nlet current = null;\nif (\"1\" in dps) {\n    state = (dps['1']) ? \"ON\" : \"OFF\";\n}\n\nmsg.payload = {\n    state: state,\n    attributes: {power: \"0 W\",current:\"0 mA\",voltage:\"0 V\"}\n};\n\nif (\"19\" in dps) {\n    msg.payload.attributes.power = (dps['19']/10).toString() + \" W\";\n}\n\nif (\"20\" in dps) {\n    msg.payload.attributes.voltage = (dps['20'] /10).toString() + \" V\";\n}\n\nif (\"18\" in dps) {\n    msg.payload.attributes.current = (dps['18']).toString() + \" mA\";\n}\n\n\n\nif (msg.payload.state === null) {\n    delete msg.payload.state;\n}\n\nmsg.topic = \"tuya/\" + msg.data.name + \"/status\"\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":360,"wires":[["7ee9b2f.05c694c"]]},{"id":"3a1376d8.ad1c3a","type":"comment","z":"d98cf64c.d7fed8","name":"set device information","info":"","x":160,"y":100,"wires":[]},{"id":"ab82d464.f622c8","type":"comment","z":"d98cf64c.d7fed8","name":"set homeassistant discovery","info":"","x":180,"y":200,"wires":[]},{"id":"16e068de.061e07","type":"comment","z":"d98cf64c.d7fed8","name":"control-status","info":"","x":130,"y":320,"wires":[]},{"id":"4b43fc85.5c39a4","type":"tuya-local","z":"d98cf64c.d7fed8","devName":"switch_2","devIp":"","devId":"82180707c44f3387a0fe","devKey":"58c2568e3ca45c9e","protocolVer":"3.3","renameSchema":"","filterCB":"","x":660,"y":420,"wires":[["82d03748.37a7c8"]]},{"id":"82d03748.37a7c8","type":"function","z":"d98cf64c.d7fed8","name":"","func":"if (\"payload\" in msg) {\n    return [msg,msg];\n} else {\n    return [null,msg];\n}","outputs":2,"noerr":0,"x":800,"y":380,"wires":[["4d1e51e4.123a"],["87ac07d9.edda68"]]},{"id":"7b9a492a.76f2c8","type":"mqtt-broker","z":"","name":"hass","broker":"","port":"1883","clientid":"nr-docker","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

And configure it according to your data. Do not forget to configure MQTT IN and MQTT OUT with your MQTT settings (and password)
(I will add more detailed instructions next time)

4. Create sensors and switches
Put the following data into you HomeAssistant configuration.yaml and adjust it according to your data

  - platform: mqtt
    name: "Plug1"
    state_topic: "devices/tuya/plug1"
    value_template: "{{ value_json.dps['1'] }}"
    command_topic: "devices/tuya/plug1/trigger"
    payload_on: "true"
    payload_off: "false"
    state_on: "True"
    state_off: "False"
    optimistic: false
    qos: 0
    retain: true

  - platform: mqtt
    name: "Plug1_Power"
    state_topic: "devices/tuya/plug1"
    unit_of_measurement: W
    value_template: "{{ value_json.dps['19'] | multiply(0.1) | float(2) | round (2) }}"
  - platform: mqtt
    name: "Plug1_Current"
    state_topic: "devices/tuya/plug1"
    unit_of_measurement: mA
    value_template: "{{ value_json.dps['18'] | float(2) | round(2)  }}"
  - platform: mqtt
    name: "Plug1_Voltage"
    state_topic: "devices/tuya/plug1"
    unit_of_measurement: V
    value_template: "{{ value_json.dps['20'] | multiply(0.1) | float(2) | round (2) }}"

Add sensors and switches to lovelace and use the created entities in your automations and flows!

This looks really useful as I want to get my tuya smartplug to give me power usage not just be able to turn off and on which works fine for me in HA.
However since I have a standard install of HA I am getting lost even at the first step. Could you get a bit more explicit for people unfamiliar with the underlying linux world. I can see the folder config/node-red/ in file editor but where do I go from here.?

1 Like

sorry, I didn’t understand what exactly is your problem

@monaco to be honest I can’t remember. Stay safe.

How do you use your tuya switches now?

1 Like

I have found better and way easier solution!

Just be warned, instructions in repository are a bit confusing, you can not just copy code, since there is some inconsistency! But you may copy mine:


- platform: localtuya
  local_key: 1234567891234567
  device_id: 12345678912345671234
  name: tuya_g4
  friendly_name: tuya_g4
  protocol_version: 3.3
      name: tuya_g4
      friendly_name: G4 plug
      id: 1
      current: 4
      current_consumption: 5
      voltage: 6


- platform: template
      friendly_name: "G4 voltage"
      unit_of_measurement: 'V'
      value_template: "{{ states.switch.tuya_g4.attributes.voltage }}"
      friendly_name: "G4 current"
      unit_of_measurement: 'mA'
      value_template: "{{ states.switch.tuya_g4.attributes.current }}"
      friendly_name: "G4 current consumption"
      unit_of_measurement: 'W'
      value_template: "{{ states.switch.tuya_g4.attributes.current_consumption }}"

You may change all “friendly_name” but when you are changing “tuya_g4” under sw01, make sure that you will change also all instances for switch! I had some issues getting sensor data since in the instructions on repository for switch is name “tuya_01”, but in sensor was once “tuya-sw01” and in value template “sw01”.


@monaco I played with switches but really use tuya for a underfloor heating thermostat. The cloud based tuya integration has limited functionality and I wanted more. In particular the device a BHT-002 has an underfloor temp sensor and a room temp sensor. The underfloor one is not available in the tuya interface - only in the phone app (eg SmartLife).

I have combination. Some of my Tuya sockets are tasmotized and some of them are using the local tuya from my last update. Actually I do no see much difference between both options. Tasmotized send a bit more data, but on the other hand I can use stock ones also without running HA.

But anyway if someone will decide to flash Tasmota, I really suggest this tutorial https://www.digiblur.com/2020/01/tuya-convert-23-update-flash-tuya.html The whole procedure is very easy!

1 Like

I just bought my first Tuya flashed device (smart switch with energy monitoring). I read this thread and followed your advice to use the tutorial.

I must say for me at least this was not easy and took me around 8 hours to get through it start to finish with all the problems in between.

All of my problems came from the tuya-convert not downloading all the files it was supposed to but not realizing this and getting so far along and running into errors then googleing the errors and then going back and forth.

Eventually I worked out that all I had to do was delete the tuya-convert folder and redownload 3 times until there was no errors during the downloading and unpacking. Then errors stopped randomly appearing and I all the way to the end where I now have a Tuya smart plug with Tasmota installed.

1 Like

I’ve got mine working in that I can switch it on and off but the power values are just showing V, mA and W.

I think I skipped these steps below though. When I get home I’ll try and fix that part up and hopefully it will work. Tuya convert doesn’t work on the plugs I have and opening them up to flash is a pain Asni don’t have the security screwdriver bit it needs. A really strange trip groove one.

  1. Identify on your Home-Assistant logs (putting your logging into debug mode), the different attributes you want to handle by HA.
  2. Find in the switch.py file that part, and edit it for ID/DPS that is correct for your device.

If you have tuya-convert, I think you have selected the wrong template in Tasmota. They are really different even the plugs look the same. Just get the propper one from https://templates.blakadder.com/

I’m not using tasmota, I have the original firmware and am using the localtuya custom component you linked above.

I’m just at the step where i need to set the DPS but I can’t make sense of it.

    def device_state_attributes(self):
        attrs = {}
            attrs[ATTR_CURRENT] = "{}".format(self._status['dps'][self._attr_current])
            attrs[ATTR_CURRENT_CONSUMPTION] = "{}".format(self._status['dps'][self._attr_consumption]/10)
            attrs[ATTR_VOLTAGE] = "{}".format(self._status['dps'][self._attr_voltage]/10)
#            print('attrs[ATTR_CURRENT]: [{}]'.format(attrs[ATTR_CURRENT]))
#            print('attrs[ATTR_CURRENT_CONSUMPTION]: [{}]'.format(attrs[ATTR_CURRENT_CONSUMPTION]))
#            print('attrs[ATTR_VOLTAGE]: [{}]'.format(attrs[ATTR_VOLTAGE]))

The instructions say “Find in the switch.py file that part, and edit it for ID/DPS that is correct for your device.”
In my logs I found what looks to be the DPS values for my smart plug but not sure how to enter it. In my logs I have

DEBUG (SyncWorker_13) [custom_components.localtuya.pytuya] decrypted result='{"devId":"XXXXXXXXXXXXXXXXXXXXXXXXXX","dps":{"1":true,"9":0,"18":0,"19":0,"20":2451,"21":1,"22":604,"23":29911,"24":17310,"25":1200}}'

hopefully it makes a bit more sense to you than it does to me haha

This are your dps settings. Now you have to figure out which number is what.
I usualy compare values from tuya app.
Then you just replace bolded numbers with yours. I think you have
voltage: 20 but current and consumption depends what you have connected

name: tuya_g4
friendly_name: G4 plug
id: 1
current: 4
current_consumption: 5
voltage: 6

Ok I followed your advice so it looks like it is 18, 19 and 20.

Just checking do I need to put these values in the switch.py file as well? Like this:

    def device_state_attributes(self):
        attrs = {}
            attrs[ATTR_CURRENT] = "{}".format(self._status['dps']['18'][self._attr_current])
            attrs[ATTR_CURRENT_CONSUMPTION] = "{}".format(self._status['dps']['19'][self._attr_consumption]/10)
            attrs[ATTR_VOLTAGE] = "{}".format(self._status['dps']['20'][self._attr_voltage]/10)
#            print('attrs[ATTR_CURRENT]: [{}]'.format(attrs[ATTR_CURRENT]))
#            print('attrs[ATTR_CURRENT_CONSUMPTION]: [{}]'.format(attrs[ATTR_CURRENT_CONSUMPTION]))
#            print('attrs[ATTR_VOLTAGE]: [{}]'.format(attrs[ATTR_VOLTAGE]))

Or do I leave the switch.py file alone and just put the do’s values in the config.yaml like you explained above. On the git page it explains about modifying the switch.py which is why I’m now confused.

Really appreciate you taking the time to help me with this. It’s had me stumped for the best part of a week.

no, just leave switch.py alone.

I actually didn’t have even to look for logs or even open switch.py since I used first my initial proposal with nodered and got dps numbers there. So I can confirm you do not need to do anything else than just putting correct numbers to yaml.

Thanks mate put it back to normal and it’s now working with 18, 19, 20

1 Like

How do i find my DPS settings?
And this: host IP ,local_key, device_id ?

I got in my yaml:
default: debug

But I cant find “DPS” in logs.