Make the picture taken from Tuya Smart Video Doorbell available in HA

Feature request for the Tuya integration Tuya - Home Assistant
I have a battery powered Tuya Smart Video Doorbell with has PIR sensor on it, which wakes up the camera when it detects presence, takes picture/video and then the camera goes to sleep (not responding even to ping).
I then get notification in the Smart Life / Tuya app. The notification contains a picture taken from the camera.
If this picture can be made available in homeassistant somehow, it would be very useful, because currently the tuya integration does not work well with this doorbell camera - it wakes it up too often, and drains the battery - as described in Tuya integration keeps smart doorbell camera awake Ā· Issue #60837 Ā· home-assistant/core Ā· GitHub

Same Idea here, have tried to add this to an automation and make the picture available in the media library. Unfortunately hassio in containers and did not manage to have the correct way to store it in the correct directory

I managed to do something similar with automation - take picture and store it when HA detects the camera is awake via ping sensor, but unfortunately it makes the mentioned issue worse, because it makes the camera stay awake even longer.
Also, there was too much delay between a person standing in front of the doorbell and the picture being taken - because it takes several seconds to wake up the camera, then it takes several seconds for the PING sensor to detect the camera is awake, and then another several seconds to take the picture from HA. So not really viable solution.
We need access to the picture that the camera takes and sends to Tuya. This way we wonā€™t have to wake up the camera, because the picture is stored somewhere on the tuya servers.

Some time ago I was fooling around in the Tuya api explorer, and it looked like it might be possible to extract this image - when I try the ā€œGet device statusā€ function using the device id of the camera, thereā€™s ā€œmovement_detect_picā€ field in the response, and itā€™s value is some base64 encoded json, which looks this way:

{"v":"3.0","bucket":"ty-eu-storage30","files":[["/555455-18709973-ylsda70cecbcc17af30b/detect/1638478699.jpeg","1a54e0f1b0f94582"]]}

I have no idea how to reconstruct or access the actual picture url. But Iā€™m sure itā€™s possible :slight_smile:
Honestly, this will be a lot more useful to me, than any other functions the integration provides for this camera.

I wanted to have a picture from a cctv camera when the doorbell is pushed, have to explore this more and try to understand how you store this in the right directory in a docker environment

This should be doable for Tuya smart doorbells. HA receives a base64-encoded URL which is visible in the logs under status.doorbell_pic. The URL is for some Amazon storage bucket somewhere, and the image is only available for a couple of hours.

{
        "name": "VIRONE HILIT video door phone",
        "model": "VDP-65",
        "category": "sp",
        "product_id": "**redacted**",
        "product_name": "VIRONE HILIT video door phone",
        "online": true,
        "sub": false,
        "time_zone": "+02:00",
        "active_time": "2022-07-23T13:27:51+00:00",
        "create_time": "2022-07-23T13:27:51+00:00",
        "update_time": "2022-07-23T13:27:55+00:00",
        "function": {
          "record_switch": {
            "type": "Boolean",
            "value": {}
          },
          "ipc_smart_action": {
            "type": "Enum",
            "value": {
              "range": [
                "0",
                "1",
                "2",
                "3"
              ]
            }
          }
        },
        "status_range": {
          "doorbell_active": {
            "type": "String",
            "value": {
              "maxlen": 255
            }
          },
          "record_switch": {
            "type": "Boolean",
            "value": {}
          },
          "doorbell_pic": {
            "type": "Raw",
            "value": {}
          }
        },
        "status": {
          "doorbell_active": "",
          "record_switch": false,
          "doorbell_pic": ā€œ**BASE64_ENCODED_URL**ā€
        },
        "home_assistant": {
          "name": "VIRONE HILIT video door phone",
          "name_by_user": null,
          "disabled": false,
          "disabled_by": null,
          "entities": [
            {
              "disabled": false,
              "disabled_by": null,
              "entity_category": "config",
              "device_class": null,
              "original_device_class": null,
              "icon": null,
              "original_icon": "mdi:record-rec",
              "unit_of_measurement": null,
              "state": {
                "entity_id": "switch.virone_hilit_video_door_phone_video_recording",
                "state": "off",
                "attributes": {
                  "icon": "mdi:record-rec",
                  "friendly_name": "VIRONE HILIT video door phone Video Recording"
                },
                "last_changed": "2022-09-05T03:51:04.159768+00:00",
                "last_updated": "2022-09-05T03:51:04.159768+00:00"
              }
            },
            {
              "disabled": false,
              "disabled_by": null,
              "entity_category": null,
              "device_class": null,
              "original_device_class": null,
              "icon": null,
              "original_icon": null,
              "unit_of_measurement": null,
              "state": {
                "entity_id": "camera.virone_hilit_video_door_phone",
                "state": "idle",
                "attributes": {
                  "access_token": ā€œ**redacted**ā€,
                  "model_name": "VIRONE HILIT video door phone",
                  "brand": "Tuya",
                  "frontend_stream_type": "hls",
                  "entity_picture": "**REDACTED**",
                  "friendly_name": "VIRONE HILIT video door phone",
                  "supported_features": 2
                },
                "last_changed": "2022-09-05T03:51:04.160309+00:00",
                "last_updated": "2022-09-05T08:18:34.718030+00:00"
              }
            }
          ]
        }
      },

On my case, I am not receiving any state for doorbell_pic, it is not exposed through MQTT, marked as binary but I can alarm_message attribute and it is in base64. If I decode it, I can see the event type ipc_doorbell or ipc_movement and s3 bucket address. but, I could not reach out to exact file with s3 bucket information.

Hi, iā€™m not using home assistant but am developing my own domotics management tool. I noticed this question on how to get the doorbell_pic from tuya service bus message.

I got this working through some article i found on the iot tuya developer pages, which describes the ā€˜encryptionā€™ of the messages. Just check the demo pulsar project (message queue consumer), for DecryptByAes Get Push Messages by Pulsar (C# SDK)-Tuya IoT Development Platform-Tuya Developer

I managed to get a (working) image url of my doorbell (attention, it is only valid for a limited period of time).

How to store in home assistant or things, i donā€™t know, i store it locally in my own sql db

I hope this helps someone.

And maybe someone can help me: i have the message queue listener up and running, but when someone rings my doorbell, i only get the ā€˜doorbell_picā€™ notification once in a while, any idea ? However, in my smart life app, i can see all pictures of all people ringing my doorbell

I tried this (the python version of the example - Get Push Messages by Pulsar (Python SDK)-Tuya IoT Development Platform-Tuya Developer), but the data I can get with it is more or less the same I get from the API - it contains the same movement_detect_pic and alarm_message data I was already able to get. Something like this after base64 decoding:

{"v":"3.0","bucket":"ty-eu-storage30","files":[["/555455-18709973-ylsda70cecbcc17af30b/detect/1638478699.jpeg","1a54e0f1b0f94582"]]}

The contents of the message when someone rings the doorbell are a bit different, but the problem is the same - the value of the ā€œalarm_messageā€ can be base64 decoded to something like this:

{"v":"3.0","files":[{"data":"1c660cc9e0cc914b57dfcbfc228374029edb76815475801099cf33f6aa1bd150a1153e61f756bda2e18949ee47ae2e73a93bfcb21b266fccdd1840a87ee7535c49dfff4440d0a21b92d040538be97d709a9f68759bbfa489c07bef8722cad996aa1a89a6aee0d78a7bf64351633136f1","keyId":"default","iv":"c6974bc7d7079637257222c28e425a21"}],"cmd":"ipc_doorbell","type":"image"}

How do you get the correct url of the picture?
Can you provide an example how you do it?

Hi, Just receive a battery tuya doorbell for christmas. I read a lot about it and how much is a Headaches.

I have a some question :

1: Instead of asking for the feature of the picture, why just ask for a better power management ? like awake the camera only if I check the feedā€¦ ( bonus tell me when the camera is awake so i can take a screenshot of the movement )

2: Do you guys check on the side of LocalTuya ( custom integration ) it doesā€™nt seam to be working but you are searching for a longer time than me may be you saw something i didā€™nt see

3: At this point I donā€™t mind to keep the doorbell plug into wall outlet and just use it as wireless camera but my issue is the camera feed is too random ā€¦ almost always not working iā€™m i the only one ?

thanks

EDIT : i think I found what you need: Every time the doorbell detect motion it become idle then unavailable ā€¦ so if you do an automation that look like that you should receive a notification with the image :

alias: TestDoorbell
description: ""
trigger:
  - platform: state
    entity_id:
      - camera.porrte_avant
    to: idle
condition: []
action:
  - service: camera.snapshot
    data:
      filename: /config/www/snapshots/test.jpg
    target:
      entity_id: camera.porrte_avant
  - service: notify.mobile_app_djjfj
    data:
      message: Test DoorBell
      data:
        image: https://YOURIP/local/snapshots/test.jpg
mode: single

Unfortunately this image is not the image that the camera took when it detected the motion (and not the one from the notification in SmartLife / Tuya app). Hence - itā€™s delayed, because it takes some time for the camera to initially wake on movement, then it takes some time for the tuya integration to realize that the camera is awake, and then it takes even more time to take the snapshot.
And I think itā€™s critical to get the very first snapshot - as soon as the camera wakes up, otherwise it might and will miss some important ā€œactionā€ in front of the door.
Btw, regarding detecting when the camera is awake (i.e. when there is motion) - Iā€™m using a faster method with a ping command, emulating motion sensor. Itā€™s fast - no more than 1 second delay after the camera awakes:

binary_sensor:
  - platform: command_line
    name: "Motion - Door"
    command: 'ping -W 1 -c 1 THE_CAMERA_IP > /dev/null 2>&1 && echo on || echo off'
    device_class: motion
    payload_on: "on"
    payload_off: "off"
    scan_interval: 1
1 Like

Hey,

Iā€™ve been wondering for a long time how to download the image taken by my crappy video intercom (itā€™s one of the worst things I bought that was supposed to be smart). I found an option to capture a message containing a picture. Itā€™s the same photo thatā€™s in the official Tuya app. I used Node-RED installed in HA for this, because you can simulate messages and debug the whole process accurately.

In Node-RED I used this plugin ( node-red-contrib-tuya-smart-device (node) - Node-RED ) In Node-RED you can install it by clicking on Settings ā†’ Palette ā†’ Install ā†’ and search for ā€œnode-red-contrib-tuya-smart-deviceā€

Import the code that is below:

[{"id":"0f190a2bca60a4be","type":"tuya-smart-device","z":"8ad639860cb6690f","deviceName":"Dorbell parter","disableAutoStart":false,"deviceId":"","deviceKey":"","storeAsCreds":false,"deviceIp":"10.0.1.50","retryTimeout":1000,"findTimeout":10000,"tuyaVersion":"3.3","eventMode":"event-both","credentials":{"secretConfig":"{}"},"x":340,"y":480,"wires":[["5afadc8ea527fdf3","8938329798814a30"],[]]},{"id":"5afadc8ea527fdf3","type":"function","z":"8ad639860cb6690f","name":"Add timestamp to LOG","func":"var now = new Date();\n// Create formatted time\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar time = yyyy + \"-\" + mm + \"-\" + dd + \" \" + hh + \":\" + mmm + \":\" + ss;\n\nmsg.payload = { Time: time, Message: msg.payload }\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":480,"wires":[["a25ea003dfe40c1b"]]},{"id":"a25ea003dfe40c1b","type":"file","z":"8ad639860cb6690f","name":"Save all commands send by dorbell in /share/logs/parter.log","filename":"/share/logs/parter.log","filenameType":"str","appendNewline":true,"createDir":true,"overwriteFile":"false","encoding":"none","x":960,"y":480,"wires":[[]]},{"id":"1286683668fb701f","type":"base64","z":"8ad639860cb6690f","name":"Decode base64 adress","action":"b64","property":"payload","x":1030,"y":560,"wires":[["0b9c9d503cf1a34a"]]},{"id":"710cf8f19245a997","type":"inject","z":"8ad639860cb6690f","name":"Fake message","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"data\":{\"dps\":{\"154\":\"aHR0cHM6Ly9yZWdpb3dlYmNhbS5kZS9maWxlYWRtaW4vdXNlcl91cGxvYWQvMDFfc3RvcmNoX2tpcmNoemFydGVuMjAyMS5qcGc/dmVyPTE2MzkzMDIyNjYzNDk=\"},\"t\":1664969089},\"deviceId\":\"bfd52cb7f15a171ef3qznk\",\"deviceName\":\"Dorbell pietro\"}","payloadType":"json","x":360,"y":560,"wires":[["8938329798814a30"]]},{"id":"8938329798814a30","type":"switch","z":"8ad639860cb6690f","name":"If contains picture","property":"payload.data.dps","propertyType":"msg","rules":[{"t":"hask","v":"154","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":560,"wires":[["49ff43949c4ef580"],[]]},{"id":"49ff43949c4ef580","type":"change","z":"8ad639860cb6690f","name":"Extract base64 adress","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.data.dps[\"154\"]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":560,"wires":[["1286683668fb701f"]]},{"id":"45dc7a80ee0db931","type":"file","z":"8ad639860cb6690f","name":"Write file","filename":"filename","filenameType":"msg","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":840,"y":640,"wires":[["74cae47ba499b0ac"]]},{"id":"b5a8447904c662d5","type":"function","z":"8ad639860cb6690f","name":"Set file name","func":"var now = new Date();\n// Create formatted time\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\n\n// file path with / at the end\nvar path = \"/media/Parter/\";                     // This is the path\nvar fileName = \"Dorbell_Parter_\" + yyyy + \"_\" + mm + \"_\" + dd + \"-\" + hh + \"_\" + mmm + \"_\" + ss + \".jpg\";     // file name\nvar pathWithLocal = \"/media/local/Parter/\" // Need to add /local/ to path for notify\n//node.warn(now);\n//msg.filename = `/share/logs/test.jpg`\n\nmsg.filename = path + fileName;\nmsg.filename2 = pathWithLocal + fileName;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":640,"wires":[["45dc7a80ee0db931"]]},{"id":"8049a89b539eb455","type":"http request","z":"8ad639860cb6690f","name":"HTTP request","method":"use","ret":"bin","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":520,"y":640,"wires":[["b5a8447904c662d5"]]},{"id":"0b9c9d503cf1a34a","type":"change","z":"8ad639860cb6690f","name":"Payload to URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"method","pt":"msg","to":"get","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":640,"wires":[["8049a89b539eb455"]]},{"id":"7642b2b6835a4e61","type":"tuya-smart-device","z":"8ad639860cb6690f","deviceName":"Dorbell pietro","disableAutoStart":false,"deviceId":"","deviceKey":"","storeAsCreds":false,"deviceIp":"10.0.1.51","retryTimeout":1000,"findTimeout":10000,"tuyaVersion":"3.3","eventMode":"event-both","credentials":{"secretConfig":"{}"},"x":350,"y":820,"wires":[["7b321904fe0af295","27138d1448befa47"],[]]},{"id":"cc076642764c123e","type":"file","z":"8ad639860cb6690f","name":"Save all commands send by dorbell in /share/logs/pietro.log","filename":"/share/logs/pietro.log","filenameType":"str","appendNewline":true,"createDir":true,"overwriteFile":"false","encoding":"none","x":960,"y":820,"wires":[[]]},{"id":"7b321904fe0af295","type":"function","z":"8ad639860cb6690f","name":"Add timestamp to LOG","func":"var now = new Date();\n// Create formatted time\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar time = yyyy + \"-\" + mm + \"-\" + dd + \" \" + hh + \":\" + mmm + \":\" + ss;\n\nmsg.payload = { Time: time, Message: msg.payload }\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":820,"wires":[["cc076642764c123e"]]},{"id":"43a86da92e358c4d","type":"base64","z":"8ad639860cb6690f","name":"Decode base64 adress","action":"b64","property":"payload","x":1030,"y":900,"wires":[["ce17f74d19a20be1"]]},{"id":"931fd56e0ecdcad9","type":"inject","z":"8ad639860cb6690f","name":"Fake message","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"data\":{\"dps\":{\"154\":\"aHR0cHM6Ly9yZWdpb3dlYmNhbS5kZS9maWxlYWRtaW4vdXNlcl91cGxvYWQvMDFfc3RvcmNoX2tpcmNoemFydGVuMjAyMS5qcGc/dmVyPTE2MzkzMDIyNjYzNDk=\"},\"t\":1664969089},\"deviceId\":\"bfd52cb7f15a171ef3qznk\",\"deviceName\":\"Dorbell pietro\"}","payloadType":"json","x":360,"y":900,"wires":[["27138d1448befa47"]]},{"id":"27138d1448befa47","type":"switch","z":"8ad639860cb6690f","name":"If contains picture","property":"payload.data.dps","propertyType":"msg","rules":[{"t":"hask","v":"154","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":900,"wires":[["1e7bc8ea60e2b55c"],[]]},{"id":"1e7bc8ea60e2b55c","type":"change","z":"8ad639860cb6690f","name":"Extract base64 adress","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.data.dps[\"154\"]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":900,"wires":[["43a86da92e358c4d"]]},{"id":"e372f3b41528dc38","type":"file","z":"8ad639860cb6690f","name":"Write file","filename":"filename","filenameType":"msg","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":840,"y":980,"wires":[["2262904dd9aedfef"]]},{"id":"c8ca7efa2c8f033c","type":"function","z":"8ad639860cb6690f","name":"Set file name","func":"var now = new Date();\n// Create formatted time\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\n\n// file path with / at the end\nvar path = \"/media/Pietro/\";                     // This is the path\nvar fileName = \"Dorbell_Pietro_\" + yyyy + \"_\" + mm + \"_\" + dd + \"-\" + hh + \"_\" + mmm + \"_\" + ss + \".jpg\";     // file name\nvar pathWithLocal = \"/media/local/Pietro/\" // Need to add /local/ to path for notify\n\nmsg.filename = path + fileName;\nmsg.filename2 = pathWithLocal + fileName;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":980,"wires":[["e372f3b41528dc38"]]},{"id":"ca1df8d17e7e2c27","type":"http request","z":"8ad639860cb6690f","name":"HTTP request","method":"use","ret":"bin","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":520,"y":980,"wires":[["c8ca7efa2c8f033c"]]},{"id":"ce17f74d19a20be1","type":"change","z":"8ad639860cb6690f","name":"Payload to URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"method","pt":"msg","to":"get","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":980,"wires":[["ca1df8d17e7e2c27"]]},{"id":"252fe9520b79ef56","type":"api-call-service","z":"8ad639860cb6690f","name":"Notify","server":"32589209.0c3ffe","version":5,"debugenabled":true,"domain":"notify","service":"mobile_app_telefonadrian","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":640,"wires":[[]]},{"id":"74cae47ba499b0ac","type":"delay","z":"8ad639860cb6690f","name":"Delay 1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":980,"y":640,"wires":[["05fa85fd24f29686"]]},{"id":"05fa85fd24f29686","type":"function","z":"8ad639860cb6690f","name":"Build message","func":"msg.payload =\n{\n    \"data\":\n    {\n        \"title\": \"Ktoś dzwoni!\",\n        \"message\": \"Ktoś dobija się do domu! (zjęcie z parteru)\",\n        \"data\":\n        {\n            \"ttl\": 0,\n            \"priority\": \"high\",\n            \"icon_url\": msg.filename2,\n            \"color\": \"green\",\n            \"image\": msg.filename2,\n            \"sticky\": \"true\",\n        }\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1140,"y":640,"wires":[["252fe9520b79ef56","f4c7478e2a586590"]]},{"id":"2be6e90b7f5673df","type":"api-call-service","z":"8ad639860cb6690f","name":"Notify","server":"32589209.0c3ffe","version":5,"debugenabled":true,"domain":"notify","service":"mobile_app_telefonadrian","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":980,"wires":[[]]},{"id":"2262904dd9aedfef","type":"delay","z":"8ad639860cb6690f","name":"Delay 1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":980,"y":980,"wires":[["56aed77283525840"]]},{"id":"56aed77283525840","type":"function","z":"8ad639860cb6690f","name":"Build message","func":"msg.payload =\n{\n    \"data\":\n    {\n        \"title\": \"Ktoś dzwoni!\",\n        \"message\": \"Ktoś dobija się do domu! (zjęcie z piętra)\",\n        \"data\":\n        {\n            \"ttl\": 0,\n            \"priority\": \"high\",\n            \"icon_url\": msg.filename2,\n            \"color\": \"green\",\n            \"image\": msg.filename2,\n            \"sticky\": \"true\",\n        }\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1140,"y":980,"wires":[["2be6e90b7f5673df","23a73e15a77f75ab"]]},{"id":"f4c7478e2a586590","type":"api-call-service","z":"8ad639860cb6690f","name":"Notify","server":"32589209.0c3ffe","version":5,"debugenabled":true,"domain":"notify","service":"mobile_app_sm_a505fn","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":700,"wires":[[]]},{"id":"23a73e15a77f75ab","type":"api-call-service","z":"8ad639860cb6690f","name":"Notify","server":"32589209.0c3ffe","version":5,"debugenabled":true,"domain":"notify","service":"mobile_app_sm_a505fn","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":1040,"wires":[[]]},{"id":"32589209.0c3ffe","type":"server","name":"Home Assistant","version":4,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m"}]

It contains the process of saving all the messages sent by each device (I have two monitors so I created two copies). In addition, the pictures are saved in a folder. And at the very end a notification is sent to the phone.

In order for everything to work you need to enter ā€œDevice Virtual IDā€, " Device Key" and ā€œIP adressā€.

You can easily check the Device Virtual ID in TuyaIOT.

Device Key is also in TuyaIOT but is a little harder to get. You need to go to ā€œApi Explorerā€ on the TuyaIOT website and search for ā€œGet Device Informationā€. It should be under ā€œGeneral Device Capabilitiesā€ ā†’ ā€œGeneral device managementā€ ā†’ ā€œGet Device Informationā€.

Now you need to paste the ā€œDevice IDā€ there and press Submit Request. If your device responds you should get the device information, and in the ā€œā€œlocal_keyā€:ā€ line is your Device Key.

I spent a few hours on it but for about two months now everything has been working properly.

5 Likes

Thanks for sharing, with this approach, you are extracting the message or photo?

A message containing an encrypted link to the image. The image is uploaded by dorbell to the tuya server and is available for download for one minute. I uploaded the whole process in the picture in the previous post.

1 Like

Can you share the node details of decode, payload, url generation etc? I can quickly come up with a custom tuya camera integration to take care of this inside home assistant

1 Like
{"data":{"dps":{"110":1},"t":xxxxxx},"deviceId":"xxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"109":"15586432|1347888|14238544"},"t":xxxxxxx},"deviceId":"xxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"117":0},"t":xxxxxxx},"deviceId":"xxxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"231":"{\"cc\":1,\"chs\":[{\"id\":1,\"n\":\"channel 1\"},{\"id\":2,\"n\":\"channel 2\"},{\"id\":3,\"n\":\"channel 3\"},{\"id\":4,\"n\":\"channel 4\"}]}"},"t":xxxxxx},"deviceId":"xxxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"154":"aHR0cHM6Ly90eS1ldS1zdG9yYWdlMzAtcGljLnMzLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tL2ZmMzU2Yi0zNDczNTc3NS1ia2R6OWM5OTNhN2QzYWVkMjI3Yy9kZXRlY3QvMTY3MjI0MjA0OS5qcGVnP1gtQW16LVNlY3VyaXR5LVRva2VuPUZ3b0daWEl2WVhkekVCRWFERzIydm1oUU1pMTBEcE9QUmlLRkFnbkxzYzJXMHlBNlBGUm9xUjg4UEFjWk5xVXgxU1I4aVcwNGhKJTJCT05PZ0ZKN3pDRUl2WXhHaHFQQUxiNU1sJTJGQ1lQTWR1cWIyUVFMVk4xRnNQMnQ2a3BxeXlWZ3NUbmhPc2I2OWh0UzltYlo4WDQ2QVVGaVNyMFlNSU9ucjduOFFxZnJVekZtbzcxNzlyd1RpUVZ2bVhzMXJNT090ckxqVE5mb3M3d2MxNzlTM3lRa3VaVjRacUNpZ0IlMkJ1V3gxeTVCZmVoSk1rV3hPcHJNUG43dldNUTJoV2VzdkVHMG1GZDIyM0ZwRU1kcnRQdjc3UVZZc2tCczQlMkZDRGk1UzhNYXN5VyUyRlFqaGFtOVNVSFl1aWJVczQ2R0lvaG9iRTI1SUxsaUFMYWlnS1dIU3pyeDVJNWZiWmMlMkZzbkVTQXhCc3NPSXJCZ1BPRmNGUTJadU52SXFXNk1mVHA2Umw5MXFTaUN4N0dkQmpJcGpTY0d0bU5XRHRYWG1nSWdtSmEyd3YwcnpETUFEczElMkJoNzdReXRIbno5dGhWMSUyQnQwdXNGdE04JTNEJlgtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QVNJQVVUUE1VSkpKNUdBWkRFUDYlMkYyMDIyMTIyOCUyRmV1LWNlbnRyYWwtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyMjEyMjhUMTU0MDUyWiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZidWNrZXQ9dHktZXUtc3RvcmFnZTMwLXBpYyZ2PTEuMCZYLUFtei1TaWduYXR1cmU9MjY4Y2M5N2YyMTFjMmNlYmE0NDFlYTBlMmQxNWExYTQ0ZmFmZmQzYjZiZjY1YmExMjlhMjgzNTM4MTA3YTk5OQ=="},"t":xxxxx},"deviceId":"xxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"154":"aHR0cHM6Ly90eS1ldS1zdG9yYWdlMzAtcGljLnMzLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tL2ZmMzU2Yi0zNDczNTc3NS1ia2R6OWM5OTNhN2QzYWVkMjI3Yy9kZXRlY3QvMTY3MjMyOTM1My5qcGVnP1gtQW16LVNlY3VyaXR5LVRva2VuPUZ3b0daWEl2WVhkekVDa2FETzBLT3dmMUZOSGxKS2Izd0NLRkFxYUR6RWZlWUlnNFVoZUxFTnFiRGo3R1hIYXVrcGNpUzI3dXRuSmJuQ3kwTFd2QnFORXRsc2lqMGF1MktXVHIydEw0R0RtZ1lRMU5jN1pnVFdCWU9VNjdGS01wSVBkSjdzcWhkTFdjVjIxZmxpeGxZTnQ3cXlRaDk4Y2Vlejl3c0dBQyUyQldycjcyaDcxQ3AlMkZwUkJtZkxTaWp3enVma1diRlpvSEtPdlMyRGM1QzFvcTdBUllyRTU5dW1kdDNSMU5qTU92Wmd6WWRNdTJpdE85QW5oOE5EMWklMkIwNm4lMkYlMkY3ZjVlejExQzl4MzV0eTk2UUxKTGgwZkZuaGtiS1pmQUp2UTVLMzQ4ZjBNUnc3OUY2alJPb0hVYTVUWCUyRkh0c1diZ3RqdkxWV09Ra0NRUURPeEVadzBNMzlsZjBpS0tCMkN3SHpNbWJRVnVRJTJCSktDWFNKOCUyQkxueUtrRnpZYzJ3U2lJOGJhZEJqSXBUTFBZYTBDOExLQ2pNTzBRekZocXhvRk12a0RpayUyQlRuc0ptb29KcmdvVnhpVGE2YlB6VGVFUDAlM0QmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BU0lBVVRQTVVKSkpSU1RGUlBWQSUyRjIwMjIxMjI5JTJGZXUtY2VudHJhbC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIyMTIyOVQxNTU1NTZaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmJ1Y2tldD10eS1ldS1zdG9yYWdlMzAtcGljJnY9MS4wJlgtQW16LVNpZ25hdHVyZT1kMGYyMWQ4ZjY1NDcxODczYzgxNGJlYTVlMTZlNmIzNDU3MWY1MWNiMjIxMzg2YjM2MjEzOTE3ZmE3Nzc5YzIx"},"t":xxxxxx},"deviceId":"xxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"154":"aHR0cHM6Ly90eS1ldS1zdG9yYWdlMzAtcGljLnMzLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tL2ZmMzU2Yi0zNDczNTc3NS1ia2R6OWM5OTNhN2QzYWVkMjI3Yy9kZXRlY3QvMTY3MjQ3OTQxNi5qcGVnP1gtQW16LVNlY3VyaXR5LVRva2VuPUZ3b0daWEl2WVhkekVGTWFETkc3UjJFbDE2cFlOWFloWlNLRkFpRHF2anNWRXN3dTBnckZIWXVZODZYY1l4NWdLJTJGTU9MdlE1Q2ZyYTY3bUQlMkY5dEhwcGx5WWlZOXYyMHU2SGRZbFRVRnEyUFhic0dNVkt3SDJDMjZNSDh1b1pZTVNOaVhZZXVYOXd0bUpPeDZIbVZ2bTl3NnplQTBhWUVUc0tzek9ESkJINkhwdCUyRkxCcGdaNHZKS2xzelp2S1hVSlBhczZycXV0OTBpWmUwNWRhN1VweVolMkZJSHRTWmhKRlRSRUMwZ2JGS1VGbDFnbGlnRW1aT1pPM2pWbURuZWpzMnZBNmNqTkI2RHppNCUyQlVKTmlRSHQ2OXNWYlZxWHhoOWtwdzN2ZEN2RXhZRmUxdmolMkZ1SFBXODA3cEJaWTFuZHpuRFN2eiUyRnRxMXpJc05JalZnUUtldEczMkRFVERjdmRrNkxiOUtiVmszdVFYTlFRUzBrMVFjWVNNc0dIaVhVTWY2NnlpMmhjQ2RCaklwJTJGQnllaEhzWE14VnluaGRpUm0xV1J6WXdGTUxDTzUlMkZKMVpuWmdqeVJFa2VYaDNDbnY1TFUwcmslM0QmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BU0lBVVRQTVVKSkpTNEpXNEc0UiUyRjIwMjIxMjMxJTJGZXUtY2VudHJhbC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIyMTIzMVQwOTM2NThaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmJ1Y2tldD10eS1ldS1zdG9yYWdlMzAtcGljJnY9MS4wJlgtQW16LVNpZ25hdHVyZT1iNjk3YWFhODE4MDExYzhmNGIyODU4NmY4ZDhiODFhMGNjNjNhMjI0MWFlYWJlODNmYWYwNjNlYzkzYjdlYzRj"},"t":xxxxxx},"deviceId":"xxxxxxxx","deviceName":"Dorbell parter"}}
{"data":{"dps":{"154":"aHR0cHM6Ly9yZWdpb3dlYmNhbS5kZS9maWxlYWRtaW4vdXNlcl91cGxvYWQvMDFfc3RvcmNoX2tpcmNoemFydGVuMjAyMS5qcGc/dmVyPTE2MzkzMDIyNjYzNDk="},"t":xxxxxx},"deviceId":"xxxxxx","deviceName":"Dorbell pietro"}

This is how the data sent automatically by doorbell looks like. When the doorbell button is activated, a command with the header ā€œ154ā€ is sent. I check if the message has this header.

If it does, the function decodes the address and we get a normal Internet address containing the image.

I donā€™t have anything to show because all these functions are built into Node-RED. Download it and check it yourself if you want.

3 Likes

Thanks, will do this weekend and share my findings

2 Likes

Any luck? :slight_smile:

2 Likes

iā€™m. interested too

1 Like

Is the problem solved?
i want to buy a Tuya doorbell

Is there any update? I also have a Tuya doorbell powered with battery.