smartHomeHub / SmartIR

Integration for Home Assistant to control climate, TV and fan devices via IR/RF controllers (Broadlink, Xiaomi, MQTT, LOOKin, ESPHome)
MIT License
1.99k stars 986 forks source link

Tuya Zigbee Blaster ZS06 #1084

Open TEF2one opened 1 year ago

TEF2one commented 1 year ago

Following on #873, the Tuya Zigbee Blaster ZS06 is getting more and more popular, so could it get some official support? According to a previous post, it can actually work once the commands are encapsulated. I can now confirm it does work using the below example but could I request that smartIR accept json command so we wouln't have to escape all the double quotes:

{
   "manufacturer":"Inspire",
   "supportedModels":[
      "Aruba"
   ],
   "supportedController":"MQTT",
   "commandsEncoding":"Raw",
   "speed":[
      "low",
      "medium",
      "high"
   ],
   "commands":{
      "off": "{\"ir_code_to_send\": \"AwgF6QFAAwN3AQgFQAMASCAHQANAC0ADQAtAA4ALBd8cCAXpAUADA0gBCAVAA0AXAggF6SAN4AsDQC9AIQHpAUAFwC/ABwMIBekBQAtAA4AfQC8B6QFAAwNIAQgFgBMECAVIAWogAwMIBQgFgBcBSAGADwFIAeADL8ATAQgFgDcDagUIBcAvBAgFSAFqIAPgAy9AE+AFAwEIBUAvQCcBCAVAAwF3AeAZLwN3AQgFQCuAA+ABL+AFFwEIBUAPAwgF6QFAC0ADQA8BSAHgES8FSAEIBQgFQC8LagVIAQgFSAEIBUgB\"}",
      "default":{
         "low": "{\"ir_code_to_send\": \"A/kE7QFAAwNLAfkEQAMAdKAHQAtAA+AFDwWYGvkE7QFAAwNLAfkEwBsC+QTtIA3gCwPgES9AP+ADAwX5BO0B+QTgFS/Ab0A3AfkE4AkvQBdAAwP5BO0BQAfgAQMHdgX5BO0B+QTgBV8ASyARQAMD+QTtAUAH4AMDBfkE7QH5BA==\"}",
         "medium": "{\"ir_code_to_send\": \"AwsF5wFAAwRPAQsFeiADQAfAA+ADD0ALB3oBcRoLBecBQAPAI0AHAwsF5wHgDQPgDS9AM+ADAwB6ID1ADwELBeABL8ATQAfAA0AjwANAEwELBeABL8AX4BMHAQsFQC8DIAILBeADLwRvBU8BC+AMAwELBUAvAOcgHQHnAeAPI+ACFwIFCwU=\"}",
         "high": "{\"ir_code_to_send\": \"AwsF5wFAAwRPAQsFeiADQAfAA+ADD0ALB3oBcRoLBecBQAPAI0AHAwsF5wHgDQPgDS9AM+ADAwB6ID1ADwELBeABL8ATQAfAA0AjwANAEwELBeABL8AX4BMHAQsFQC8DIAILBeADLwRvBU8BC+AMAwELBUAvAOcgHQHnAeAPI+ACFwIFCwU=\"}"
      }
   }

}

Home Assistant version Home Assistant 2023.7.1 Supervisor 2023.07.1 Operating System 10.3 Frontend 20230705.1 - latest

SmartIR version 1.17.7

SmartIR configuration

fan:
  - platform: smartir
    name: Office
    unique_id: office
    device_code: 1240
    controller_data: remote.office_rm4
  - platform: smartir
    name: Office Z
    unique_id: office_z
    device_code: 1241
    controller_data: zigbee2mqtt/Office Blaster/set

Describe the bug

Tuya Zigbee Blaster ZS06 device unsupported through MQTT

Debug log


2023-07-09 20:00:40.984 WARNING (SyncWorker_1) [homeassistant.loader] We found a custom integration smartir 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
2023-07-09 20:02:38.719 WARNING (MainThread) [homeassistant.helpers.entity] Entity fan.office_z (<class 'custom_components.smartir.fan.SmartIRFan'>) is using self.async_update_ha_state(), without enabling force_update. Instead it should use self.async_write_ha_state(), please report it to the custom integration author.
TEF2one commented 1 year ago

I also noticed the IR codes for RM4 do not work with ZS06 even when using the correct file format... Given I have both, I defined a flow in NodeRed which is able to read any Broadlink Base64 codes file and convert/re-learn commands with ZS06 to generate new MQTT Raw code files. I could share the flow on demand or provide some ZS06 commands files if there are some interest...

MarcoZ76 commented 1 year ago

I also noticed the IR codes for RM4 do not work with ZS06 even when using the correct file format... Given I have both, I defined a flow in NodeRed which is able to read any Broadlink Base64 codes file and convert/re-learn commands with ZS06 to generate new MQTT Raw code files. I could share the flow on demand or provide some ZS06 commands files if there are some interest...

Could you share with me the flow for NodeRed? Thanks in advance

TEF2one commented 1 year ago

share with me the flow for NodeRed Here is what I have done so far, it's in 2 part the first extract all RM4 codes and replay them to teach the ZS06 and store the result in a CSV. Sometime some codes are missing so I have to run multple time on manually replay the missing codes. Then there is a quick converter that take the CSV and replace the learned code from an Broadlink doc converting it to a MQTT. image

[{"id":"9c23481e17746023","type":"file in","z":"b7998df890ce76f5","name":"Dest","filename":"/data/ha/codes/climate/1124.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":860,"wires":[["3c74da852ee4d13e"]]},{"id":"a7fd69f6d8f938b7","type":"inject","z":"b7998df890ce76f5","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":75,"y":880,"wires":[["9c23481e17746023","32023e0b79768de7"]],"l":false},{"id":"32023e0b79768de7","type":"file in","z":"b7998df890ce76f5","name":"Src","filename":"/data/ha/ir_code_ac_up.csv","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":900,"wires":[["3c74da852ee4d13e"]]},{"id":"3c74da852ee4d13e","type":"join","z":"b7998df890ce76f5","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"filename","joiner":",","joinerType":"str","accumulate":false,"timeout":"1","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":310,"y":880,"wires":[["aefe37416b3ce75b"]]},{"id":"aefe37416b3ce75b","type":"function","z":"b7998df890ce76f5","name":"parse","func":"const src = msg.payload;\nconst codes = parseCMD(src[isJson(src[0]) ? 1 : 0]);\nvar payload = JSON.parse(src[isJson(src[0])? 0 : 1]);\n\nudpateCMD(payload.commands, codes);\n\npayload.supportedController = \"MQTT\";\npayload.commandsEncoding = \"Raw\";\nmsg.payload = JSON.stringify(payload, null, 3);\nreturn msg;\n\n\nfunction udpateCMD(obj, cmd,prefix) {\n    prefix = prefix === undefined ? \"\" : prefix + \".\";\n    for (const k in obj) {\n        let v = obj[k];\n        if (typeof v === 'string' || v instanceof String) {\n            if (cmd.hasOwnProperty(prefix + k)) {\n                obj[k] = JSON.stringify({ ir_code_to_send: cmd[prefix + k] });\n            }else{\n                obj[k] = JSON.stringify({ ir_code_to_send: \"\" });\n            }\n        } else if(typeof v === 'object' && v !== null){\n            udpateCMD(obj[k], cmd, prefix + k);\n        }\n    }\n};\n\nfunction parseCMD(data, delimiter = ',') {\n    var map = new Object();\n    data = data\n        .slice(data.indexOf('\\n') + 1)\n        .split('\\n').map(v => {\n            const arr = v.split(delimiter);\n            if (arr.hasOwnProperty(2)) {\n                map[arr[1]] = arr[2];\n            }\n        });;\n    return map;\n};\n\nfunction encode(code) {\n    return JSON.stringify({ ir_code_to_send: code });\n}\nfunction isJson(str) {\n    try {\n        JSON.parse(str);\n    } catch (e) {\n        return false;\n    }\n    return true;\n}\nfunction csvToArray(str, delimiter = \",\") {\n    let array = str.split(\"\\\\r\\\\n\").map(function (line) {\n        return line.split(delimiter);\n    });\n\n    return array;\n}\nfunction CSVToJSON(data, delimiter = ','){\n    const titles = data.slice(0, data.indexOf('\\n')).split(delimiter);\n    return data\n        .slice(data.indexOf('\\n') + 1)\n        .split('\\n')\n        .map(v => {\n            const values = v.split(delimiter);\n            return titles.reduce(\n                (obj, title, index) => ((obj[title] = values[index]), obj),\n                {}\n            );\n        });\n};\n/*\nfor (const property in object) {\n    console.log(`${property}: ${object[property]}`);\n}\n*/\n//Object.values(animals).forEach(val => console.log(val));","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":880,"wires":[["f0008d2e6611cb68"]]},{"id":"f0008d2e6611cb68","type":"file","z":"b7998df890ce76f5","name":"Log","filename":"/data/ha/ir_codes.json","filenameType":"str","appendNewline":false,"createDir":false,"overwriteFile":"true","encoding":"none","x":590,"y":880,"wires":[["91a7b887f11ea946"]]},{"id":"91a7b887f11ea946","type":"debug","z":"b7998df890ce76f5","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":730,"y":880,"wires":[]},{"id":"7ed8ce32d57268ed","type":"inject","z":"b7998df890ce76f5","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":780,"wires":[["6a073749e4ebcb7f"]],"l":false},{"id":"c2c8045800223dd7","type":"group","z":"b7998df890ce76f5","name":"Covert SmartIr RM4 to ZS06","style":{"label":true},"nodes":["507a1ad555f8cf50","4fc5e2bbafd8efa0","43409397257f8e34","919071a27b8ec4d5","9198590c62f199cd","27b3cf4e0e4e340c","7ffb6262ef272467","77940daabc33296e","6687c91fb16fab29","afc7849272fc5590","deab06de0e53f081","c3074cf9a1021870","95d786911f0aaa53","eee196a1932ce952","41ef85dffa09612f","89f3de66fe8a1f19","0197f6a2ec029258","2b1b046b324202e0","cd0d3dcff7b1524e","15ec1eb773ebeac2","d05213882f8a597d","dcd9f2274b7ba955","685c00c55eb2b8a0","b31e93ef23ce44dd","b4561199d3f2db8c","ef7f66db1d630edb","ef9ccc686da68143","d5414260fedf7acd","e1bc3ab056cf684b","7cb92a52d69d1a1d","3fa36aaa406e9dd9","003f6678b4b7927a","6a073749e4ebcb7f"],"x":34,"y":459,"w":1352,"h":362},{"id":"507a1ad555f8cf50","type":"mqtt in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Listen","topic":"zigbee2mqtt/Guest Blaster","qos":"0","datatype":"auto-detect","broker":"7c05f96914c79996","nl":false,"rap":true,"rh":0,"inputs":0,"x":610,"y":720,"wires":[["919071a27b8ec4d5"]]},{"id":"4fc5e2bbafd8efa0","type":"file","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Log","filename":"/data/ha/ir_code.csv","filenameType":"str","appendNewline":false,"createDir":false,"overwriteFile":"false","encoding":"none","x":1310,"y":740,"wires":[[]]},{"id":"43409397257f8e34","type":"csv","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","sep":",","hdrin":"","hdrout":"once","multi":"one","ret":"\\n","temp":"time,command,code","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":1170,"y":740,"wires":[["4fc5e2bbafd8efa0"]]},{"id":"919071a27b8ec4d5","type":"rbe","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload.learned_ir_code","topi":"topic","x":750,"y":720,"wires":[["89f3de66fe8a1f19"]]},{"id":"9198590c62f199cd","type":"api-call-service","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"RM4","server":"8093ca4.46eb138","version":5,"debugenabled":false,"domain":"remote","service":"send_command","areaId":[],"deviceId":[],"entityId":["remote.guest_rm4"],"data":"{\"command\":\"b64: \"& payload}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":890,"y":600,"wires":[[]]},{"id":"27b3cf4e0e4e340c","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"AC Down","filename":"/data/ha/codes/climate/1084.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":180,"y":500,"wires":[["6687c91fb16fab29"]]},{"id":"7ffb6262ef272467","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":540,"wires":[["77940daabc33296e"]],"l":false},{"id":"77940daabc33296e","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"AC Up","filename":"/data/ha/codes/climate/1124.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":540,"wires":[["6687c91fb16fab29"]]},{"id":"6687c91fb16fab29","type":"function","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"parse","func":"var obj = JSON.parse(msg.payload);\nvar table = flattenObject(obj.commands);\nvar date = new Date();\nmsg = [{ payload: table }, { reset: true, payload: { time: date.toISOString(), command: msg.filename } }];\nreturn msg;\n\n\n/*\nsetTimeout(function () {\n    console.log(\"Executed after 1 second\");\n}, 1000);\n*/\n\nfunction payload(postion, payload) {\n    const msg = new Array(node.outputCount);\n    msg[postion] = { payload: payload };\n    return msg;\n}\n\nfunction flattenObject(ob) {\n    var toReturn = {};\n\n    for (var i in ob) {\n        if (!ob.hasOwnProperty(i)) continue;\n\n        if ((typeof ob[i]) == 'object' && ob[i] !== null) {\n            var flatObject = flattenObject(ob[i]);\n            for (var x in flatObject) {\n                if (!flatObject.hasOwnProperty(x)) continue;\n\n                toReturn[i + '.' + x] = flatObject[x];\n            }\n        } else {\n            toReturn[i] = ob[i];\n        }\n    }\n    return toReturn;\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":740,"wires":[["eee196a1932ce952"],["43409397257f8e34"]]},{"id":"afc7849272fc5590","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Fan","filename":"/data/ha/codes/fan/1240.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":580,"wires":[["6687c91fb16fab29"]]},{"id":"deab06de0e53f081","type":"mqtt out","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"ZS06","topic":"zigbee2mqtt/Guest Blaster/set","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"7c05f96914c79996","x":890,"y":560,"wires":[]},{"id":"c3074cf9a1021870","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learn","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"learn_ir_code\": \"ON\"}","payloadType":"json","x":750,"y":560,"wires":[["deab06de0e53f081"]]},{"id":"95d786911f0aaa53","type":"delay","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"limit","pauseType":"rate","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"3","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":610,"y":680,"wires":[["2b1b046b324202e0","3fa36aaa406e9dd9","003f6678b4b7927a"]]},{"id":"eee196a1932ce952","type":"split","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":680,"wires":[["95d786911f0aaa53"]]},{"id":"41ef85dffa09612f","type":"join","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":",","joinerType":"str","accumulate":false,"timeout":"3","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1030,"y":720,"wires":[["43409397257f8e34","0197f6a2ec029258"]]},{"id":"89f3de66fe8a1f19","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Code","rules":[{"t":"set","p":"topic","pt":"msg","to":"code","tot":"str"},{"t":"move","p":"payload.learned_ir_code","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"complete","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":720,"wires":[["41ef85dffa09612f"]]},{"id":"0197f6a2ec029258","type":"debug","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learned","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":680,"wires":[]},{"id":"2b1b046b324202e0","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Time","rules":[{"t":"set","p":"topic","pt":"msg","to":"time","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"$now()","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":640,"wires":[["41ef85dffa09612f"]]},{"id":"cd0d3dcff7b1524e","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Test","props":[{"p":"payload.ir_code_to_send","v":"C9kEvgHZBPgBhwHZBEAJ4AsDAPjgABsFhxzZBL4BQAMBvgFABYADAdkEQAkAh6ANQAvAAwCH4AwvwB0F2QS+AYcBQAWAAwL4AYcgLweHAdkEvgG+AUAF4AUDA9kEvgGAHUAJQAMAhyAvAb4BQAMBhwFABYADAPggB0ADA9kE+AHgAxcCvgGH4AAvBL4B2QSHIAPgAwcD2QS+AUATQAMBvgFAAwCH4AQvAb4B4AUDBdkEvgG+AUAFwAPgAS8BhwGAEwD44AIHAdkE4AEXAL4gFwL4AYegXwGHAUAPA4cB2QRAB8ADA9kEvgHgBRMAh6AvIAkAAUAF4AEDQA8B2QQgUQIB2QTgARcAh+AILwSHAdkEvqADAdkEgC8JhwHZBIcB2QSHAQ==","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":750,"y":520,"wires":[["deab06de0e53f081"]]},{"id":"15ec1eb773ebeac2","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Matrix","filename":"/data/ha/codes/media_player/1500.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":620,"wires":[["6687c91fb16fab29"]]},{"id":"d05213882f8a597d","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"TV","filename":"/data/ha/codes/media_player/1480.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":660,"wires":[["6687c91fb16fab29"]]},{"id":"dcd9f2274b7ba955","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Projector","filename":"/data/ha/codes/media_player/1361.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":180,"y":700,"wires":[["6687c91fb16fab29"]]},{"id":"685c00c55eb2b8a0","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Sound","filename":"/data/ha/codes/media_player/1044.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":740,"wires":[["6687c91fb16fab29"]]},{"id":"b31e93ef23ce44dd","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":500,"wires":[["27b3cf4e0e4e340c"]],"l":false},{"id":"b4561199d3f2db8c","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":580,"wires":[["afc7849272fc5590"]],"l":false},{"id":"ef7f66db1d630edb","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":620,"wires":[["15ec1eb773ebeac2"]],"l":false},{"id":"ef9ccc686da68143","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":660,"wires":[["d05213882f8a597d"]],"l":false},{"id":"d5414260fedf7acd","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":700,"wires":[["dcd9f2274b7ba955"]],"l":false},{"id":"e1bc3ab056cf684b","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":740,"wires":[["685c00c55eb2b8a0"]],"l":false},{"id":"7cb92a52d69d1a1d","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Reset","props":[{"p":"reset","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":470,"y":640,"wires":[["95d786911f0aaa53"]]},{"id":"3fa36aaa406e9dd9","type":"trigger","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learn","op1":"{\"learn_ir_code\": \"ON\"}","op2":"","op1type":"json","op2type":"pay","duration":"300","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":750,"y":600,"wires":[["deab06de0e53f081"],["9198590c62f199cd"]]},{"id":"003f6678b4b7927a","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Cmd","rules":[{"t":"set","p":"topic","pt":"msg","to":"command","tot":"str"},{"t":"move","p":"parts.key","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":680,"wires":[["41ef85dffa09612f"]]},{"id":"6a073749e4ebcb7f","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Misc","filename":"/data/ha/ir_codes_todo.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":780,"wires":[["6687c91fb16fab29"]]},{"id":"7c05f96914c79996","type":"mqtt-broker","name":"MQTT","broker":"192.168.50.105","port":"1883","clientid":"NodeRed","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"8093ca4.46eb138","type":"server","name":"HA nodered","version":5,"addon":false,"rejectUnauthorizedCerts":false,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
MarcoZ76 commented 1 year ago

share with me the flow for NodeRed Here is what I have done so far, it's in 2 part the first extract all RM4 codes and replay them to teach the ZS06 and store the result in a CSV. Sometime some codes are missing so I have to run multple time on manually replay the missing codes. Then there is a quick converter that take the CSV and replace the learned code from an Broadlink doc converting it to a MQTT. image

[{"id":"9c23481e17746023","type":"file in","z":"b7998df890ce76f5","name":"Dest","filename":"/data/ha/codes/climate/1124.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":860,"wires":[["3c74da852ee4d13e"]]},{"id":"a7fd69f6d8f938b7","type":"inject","z":"b7998df890ce76f5","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":75,"y":880,"wires":[["9c23481e17746023","32023e0b79768de7"]],"l":false},{"id":"32023e0b79768de7","type":"file in","z":"b7998df890ce76f5","name":"Src","filename":"/data/ha/ir_code_ac_up.csv","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":900,"wires":[["3c74da852ee4d13e"]]},{"id":"3c74da852ee4d13e","type":"join","z":"b7998df890ce76f5","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"filename","joiner":",","joinerType":"str","accumulate":false,"timeout":"1","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":310,"y":880,"wires":[["aefe37416b3ce75b"]]},{"id":"aefe37416b3ce75b","type":"function","z":"b7998df890ce76f5","name":"parse","func":"const src = msg.payload;\nconst codes = parseCMD(src[isJson(src[0]) ? 1 : 0]);\nvar payload = JSON.parse(src[isJson(src[0])? 0 : 1]);\n\nudpateCMD(payload.commands, codes);\n\npayload.supportedController = \"MQTT\";\npayload.commandsEncoding = \"Raw\";\nmsg.payload = JSON.stringify(payload, null, 3);\nreturn msg;\n\n\nfunction udpateCMD(obj, cmd,prefix) {\n    prefix = prefix === undefined ? \"\" : prefix + \".\";\n    for (const k in obj) {\n        let v = obj[k];\n        if (typeof v === 'string' || v instanceof String) {\n            if (cmd.hasOwnProperty(prefix + k)) {\n                obj[k] = JSON.stringify({ ir_code_to_send: cmd[prefix + k] });\n            }else{\n                obj[k] = JSON.stringify({ ir_code_to_send: \"\" });\n            }\n        } else if(typeof v === 'object' && v !== null){\n            udpateCMD(obj[k], cmd, prefix + k);\n        }\n    }\n};\n\nfunction parseCMD(data, delimiter = ',') {\n    var map = new Object();\n    data = data\n        .slice(data.indexOf('\\n') + 1)\n        .split('\\n').map(v => {\n            const arr = v.split(delimiter);\n            if (arr.hasOwnProperty(2)) {\n                map[arr[1]] = arr[2];\n            }\n        });;\n    return map;\n};\n\nfunction encode(code) {\n    return JSON.stringify({ ir_code_to_send: code });\n}\nfunction isJson(str) {\n    try {\n        JSON.parse(str);\n    } catch (e) {\n        return false;\n    }\n    return true;\n}\nfunction csvToArray(str, delimiter = \",\") {\n    let array = str.split(\"\\\\r\\\\n\").map(function (line) {\n        return line.split(delimiter);\n    });\n\n    return array;\n}\nfunction CSVToJSON(data, delimiter = ','){\n    const titles = data.slice(0, data.indexOf('\\n')).split(delimiter);\n    return data\n        .slice(data.indexOf('\\n') + 1)\n        .split('\\n')\n        .map(v => {\n            const values = v.split(delimiter);\n            return titles.reduce(\n                (obj, title, index) => ((obj[title] = values[index]), obj),\n                {}\n            );\n        });\n};\n/*\nfor (const property in object) {\n    console.log(`${property}: ${object[property]}`);\n}\n*/\n//Object.values(animals).forEach(val => console.log(val));","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":880,"wires":[["f0008d2e6611cb68"]]},{"id":"f0008d2e6611cb68","type":"file","z":"b7998df890ce76f5","name":"Log","filename":"/data/ha/ir_codes.json","filenameType":"str","appendNewline":false,"createDir":false,"overwriteFile":"true","encoding":"none","x":590,"y":880,"wires":[["91a7b887f11ea946"]]},{"id":"91a7b887f11ea946","type":"debug","z":"b7998df890ce76f5","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":730,"y":880,"wires":[]},{"id":"7ed8ce32d57268ed","type":"inject","z":"b7998df890ce76f5","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":780,"wires":[["6a073749e4ebcb7f"]],"l":false},{"id":"c2c8045800223dd7","type":"group","z":"b7998df890ce76f5","name":"Covert SmartIr RM4 to ZS06","style":{"label":true},"nodes":["507a1ad555f8cf50","4fc5e2bbafd8efa0","43409397257f8e34","919071a27b8ec4d5","9198590c62f199cd","27b3cf4e0e4e340c","7ffb6262ef272467","77940daabc33296e","6687c91fb16fab29","afc7849272fc5590","deab06de0e53f081","c3074cf9a1021870","95d786911f0aaa53","eee196a1932ce952","41ef85dffa09612f","89f3de66fe8a1f19","0197f6a2ec029258","2b1b046b324202e0","cd0d3dcff7b1524e","15ec1eb773ebeac2","d05213882f8a597d","dcd9f2274b7ba955","685c00c55eb2b8a0","b31e93ef23ce44dd","b4561199d3f2db8c","ef7f66db1d630edb","ef9ccc686da68143","d5414260fedf7acd","e1bc3ab056cf684b","7cb92a52d69d1a1d","3fa36aaa406e9dd9","003f6678b4b7927a","6a073749e4ebcb7f"],"x":34,"y":459,"w":1352,"h":362},{"id":"507a1ad555f8cf50","type":"mqtt in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Listen","topic":"zigbee2mqtt/Guest Blaster","qos":"0","datatype":"auto-detect","broker":"7c05f96914c79996","nl":false,"rap":true,"rh":0,"inputs":0,"x":610,"y":720,"wires":[["919071a27b8ec4d5"]]},{"id":"4fc5e2bbafd8efa0","type":"file","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Log","filename":"/data/ha/ir_code.csv","filenameType":"str","appendNewline":false,"createDir":false,"overwriteFile":"false","encoding":"none","x":1310,"y":740,"wires":[[]]},{"id":"43409397257f8e34","type":"csv","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","sep":",","hdrin":"","hdrout":"once","multi":"one","ret":"\\n","temp":"time,command,code","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":1170,"y":740,"wires":[["4fc5e2bbafd8efa0"]]},{"id":"919071a27b8ec4d5","type":"rbe","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload.learned_ir_code","topi":"topic","x":750,"y":720,"wires":[["89f3de66fe8a1f19"]]},{"id":"9198590c62f199cd","type":"api-call-service","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"RM4","server":"8093ca4.46eb138","version":5,"debugenabled":false,"domain":"remote","service":"send_command","areaId":[],"deviceId":[],"entityId":["remote.guest_rm4"],"data":"{\"command\":\"b64: \"& payload}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":890,"y":600,"wires":[[]]},{"id":"27b3cf4e0e4e340c","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"AC Down","filename":"/data/ha/codes/climate/1084.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":180,"y":500,"wires":[["6687c91fb16fab29"]]},{"id":"7ffb6262ef272467","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":540,"wires":[["77940daabc33296e"]],"l":false},{"id":"77940daabc33296e","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"AC Up","filename":"/data/ha/codes/climate/1124.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":540,"wires":[["6687c91fb16fab29"]]},{"id":"6687c91fb16fab29","type":"function","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"parse","func":"var obj = JSON.parse(msg.payload);\nvar table = flattenObject(obj.commands);\nvar date = new Date();\nmsg = [{ payload: table }, { reset: true, payload: { time: date.toISOString(), command: msg.filename } }];\nreturn msg;\n\n\n/*\nsetTimeout(function () {\n    console.log(\"Executed after 1 second\");\n}, 1000);\n*/\n\nfunction payload(postion, payload) {\n    const msg = new Array(node.outputCount);\n    msg[postion] = { payload: payload };\n    return msg;\n}\n\nfunction flattenObject(ob) {\n    var toReturn = {};\n\n    for (var i in ob) {\n        if (!ob.hasOwnProperty(i)) continue;\n\n        if ((typeof ob[i]) == 'object' && ob[i] !== null) {\n            var flatObject = flattenObject(ob[i]);\n            for (var x in flatObject) {\n                if (!flatObject.hasOwnProperty(x)) continue;\n\n                toReturn[i + '.' + x] = flatObject[x];\n            }\n        } else {\n            toReturn[i] = ob[i];\n        }\n    }\n    return toReturn;\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":740,"wires":[["eee196a1932ce952"],["43409397257f8e34"]]},{"id":"afc7849272fc5590","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Fan","filename":"/data/ha/codes/fan/1240.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":580,"wires":[["6687c91fb16fab29"]]},{"id":"deab06de0e53f081","type":"mqtt out","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"ZS06","topic":"zigbee2mqtt/Guest Blaster/set","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"7c05f96914c79996","x":890,"y":560,"wires":[]},{"id":"c3074cf9a1021870","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learn","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"learn_ir_code\": \"ON\"}","payloadType":"json","x":750,"y":560,"wires":[["deab06de0e53f081"]]},{"id":"95d786911f0aaa53","type":"delay","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"limit","pauseType":"rate","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"3","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":610,"y":680,"wires":[["2b1b046b324202e0","3fa36aaa406e9dd9","003f6678b4b7927a"]]},{"id":"eee196a1932ce952","type":"split","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":680,"wires":[["95d786911f0aaa53"]]},{"id":"41ef85dffa09612f","type":"join","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":",","joinerType":"str","accumulate":false,"timeout":"3","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1030,"y":720,"wires":[["43409397257f8e34","0197f6a2ec029258"]]},{"id":"89f3de66fe8a1f19","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Code","rules":[{"t":"set","p":"topic","pt":"msg","to":"code","tot":"str"},{"t":"move","p":"payload.learned_ir_code","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"complete","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":720,"wires":[["41ef85dffa09612f"]]},{"id":"0197f6a2ec029258","type":"debug","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learned","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":680,"wires":[]},{"id":"2b1b046b324202e0","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Time","rules":[{"t":"set","p":"topic","pt":"msg","to":"time","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"$now()","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":640,"wires":[["41ef85dffa09612f"]]},{"id":"cd0d3dcff7b1524e","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Test","props":[{"p":"payload.ir_code_to_send","v":"C9kEvgHZBPgBhwHZBEAJ4AsDAPjgABsFhxzZBL4BQAMBvgFABYADAdkEQAkAh6ANQAvAAwCH4AwvwB0F2QS+AYcBQAWAAwL4AYcgLweHAdkEvgG+AUAF4AUDA9kEvgGAHUAJQAMAhyAvAb4BQAMBhwFABYADAPggB0ADA9kE+AHgAxcCvgGH4AAvBL4B2QSHIAPgAwcD2QS+AUATQAMBvgFAAwCH4AQvAb4B4AUDBdkEvgG+AUAFwAPgAS8BhwGAEwD44AIHAdkE4AEXAL4gFwL4AYegXwGHAUAPA4cB2QRAB8ADA9kEvgHgBRMAh6AvIAkAAUAF4AEDQA8B2QQgUQIB2QTgARcAh+AILwSHAdkEvqADAdkEgC8JhwHZBIcB2QSHAQ==","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":750,"y":520,"wires":[["deab06de0e53f081"]]},{"id":"15ec1eb773ebeac2","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Matrix","filename":"/data/ha/codes/media_player/1500.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":620,"wires":[["6687c91fb16fab29"]]},{"id":"d05213882f8a597d","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"TV","filename":"/data/ha/codes/media_player/1480.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":660,"wires":[["6687c91fb16fab29"]]},{"id":"dcd9f2274b7ba955","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Projector","filename":"/data/ha/codes/media_player/1361.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":180,"y":700,"wires":[["6687c91fb16fab29"]]},{"id":"685c00c55eb2b8a0","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Sound","filename":"/data/ha/codes/media_player/1044.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":740,"wires":[["6687c91fb16fab29"]]},{"id":"b31e93ef23ce44dd","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":500,"wires":[["27b3cf4e0e4e340c"]],"l":false},{"id":"b4561199d3f2db8c","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":580,"wires":[["afc7849272fc5590"]],"l":false},{"id":"ef7f66db1d630edb","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":620,"wires":[["15ec1eb773ebeac2"]],"l":false},{"id":"ef9ccc686da68143","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":660,"wires":[["d05213882f8a597d"]],"l":false},{"id":"d5414260fedf7acd","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":700,"wires":[["dcd9f2274b7ba955"]],"l":false},{"id":"e1bc3ab056cf684b","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":95,"y":740,"wires":[["685c00c55eb2b8a0"]],"l":false},{"id":"7cb92a52d69d1a1d","type":"inject","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Reset","props":[{"p":"reset","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":470,"y":640,"wires":[["95d786911f0aaa53"]]},{"id":"3fa36aaa406e9dd9","type":"trigger","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Learn","op1":"{\"learn_ir_code\": \"ON\"}","op2":"","op1type":"json","op2type":"pay","duration":"300","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":750,"y":600,"wires":[["deab06de0e53f081"],["9198590c62f199cd"]]},{"id":"003f6678b4b7927a","type":"change","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Cmd","rules":[{"t":"set","p":"topic","pt":"msg","to":"command","tot":"str"},{"t":"move","p":"parts.key","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":890,"y":680,"wires":[["41ef85dffa09612f"]]},{"id":"6a073749e4ebcb7f","type":"file in","z":"b7998df890ce76f5","g":"c2c8045800223dd7","name":"Misc","filename":"/data/ha/ir_codes_todo.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":170,"y":780,"wires":[["6687c91fb16fab29"]]},{"id":"7c05f96914c79996","type":"mqtt-broker","name":"MQTT","broker":"192.168.50.105","port":"1883","clientid":"NodeRed","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"8093ca4.46eb138","type":"server","name":"HA nodered","version":5,"addon":false,"rejectUnauthorizedCerts":false,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Thanks! I will try to learn NodeRed and use your flow! Best Regards

TEF2one commented 1 year ago

I will try to learn NodeRed

There isn't much to learn, mostly drag and drop functions. But JavaScript is quite helpful for more complex situation.

You may however, need to install missing nodes from the palette. it's another way to extend nodered capabilities For example the RM4 node is from a Home Asssitant ndoes collection simplifying the interaction with HA. (Confer node-red-contrib-home-assistant-websocket in the palette)

Note: you will need to update the references in the blue, purple & brown notes which respectively point to RM4, ZS06 and files.

I recommend processing only one config file at a time to avoid mixing the command between devices and reset the command file each time for the same reason.

BenJamesAndo commented 1 year ago

I wonder whether it'd be possible to use this with ZHA instead of zigbee2mqtt? I'm using my Tuya Zigbee Blaster with ZHA and it works great.

I've come up with a slightly workable hackaround solution. Use an automation that listens for a MQTT topic and payload. Then trigger the IR signal with the ZHA cluster command. It means a new automation for every single payload which corresponds to the commands in the json file.

An improved version would be to use an MQTT sensor and store the payload in the sensor and then trigger the IR command with the sensor value. That way only one automation is needed. However, sensor states are limited to 255 characters and I couldn't figure out how to store an MQTT payload in a sensors attribute. All this effort makes me think I should just switch to zigbee2mqtt haha.