Wow I havenāt been able to pay attention to this topic for a while. Iām really looking forward to trying out the commands and openssl implementation @Smwoodward! And Iām gonna take a look at the python script - it could replace node-red @mzac!
One thing I spent many hours doing is making my sensor creation much more dynamic. Iām now using MQTT and taking advantage of HAās autodiscovery. After defining my zone id and mapping them to names, I get sensors in HA immediately. So Iāve moved my automation into YAML in HA now.
I defined my zones (all I have are a few doors) in the āInitialize zone ids and namesā Setup step. Itās in javascript but super simple - just a list you can update for your zones.
I use the add-on MQTT broker so my MQTT setup is really simple.
[
{
"id": "cbfaf013.0e5e",
"type": "tab",
"label": "Monitor QolSys Panel",
"disabled": false,
"info": ""
},
{
"id": "a92cf1.8c434b1",
"type": "inject",
"z": "cbfaf013.0e5e",
"name": "go",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 90,
"y": 100,
"wires": [
[
"df1b46c2.dc0748",
"7593a9f9.4b4dc8"
]
]
},
{
"id": "df1b46c2.dc0748",
"type": "exec",
"z": "cbfaf013.0e5e",
"command": "curl -kN --http0.9 https://192.168.10.34:12345",
"addpay": true,
"append": "",
"useSpawn": "true",
"timer": "",
"oldrc": false,
"name": "curl",
"x": 210,
"y": 300,
"wires": [
[
"1f5ac981.6ccdde",
"1edaf367.8f44ed"
],
[
"f17d89c8.de8bf"
],
[
"cf10d274.0242e",
"5fe3eb4d.3d8c04"
]
]
},
{
"id": "cf10d274.0242e",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "return (exit) codes",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1130,
"y": 380,
"wires": []
},
{
"id": "1f5ac981.6ccdde",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "activity events and updates",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1060,
"y": 300,
"wires": []
},
{
"id": "f17d89c8.de8bf",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "Just outputs the curl progress, not the actual output",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1060,
"y": 340,
"wires": []
},
{
"id": "8cb8b681.b122f8",
"type": "status",
"z": "cbfaf013.0e5e",
"name": "",
"scope": [
"df1b46c2.dc0748"
],
"x": 160,
"y": 560,
"wires": [
[
"aff08d86.5d518",
"938d4ef0.68605"
]
]
},
{
"id": "aff08d86.5d518",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "pid",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 310,
"y": 580,
"wires": []
},
{
"id": "1edaf367.8f44ed",
"type": "switch",
"z": "cbfaf013.0e5e",
"name": "Ignore ACK",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "ACK",
"vt": "str"
},
{
"t": "cont",
"v": "ZONE_UPDATE",
"vt": "str"
},
{
"t": "cont",
"v": "ZONE_ACTIVE",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 4,
"x": 190,
"y": 400,
"wires": [
[],
[
"9a07870e.d047d8"
],
[
"9a07870e.d047d8"
],
[
"29d0c5a8.b1b4ea"
]
]
},
{
"id": "9a07870e.d047d8",
"type": "json",
"z": "cbfaf013.0e5e",
"name": "convert update to json",
"property": "payload",
"action": "",
"pretty": true,
"x": 400,
"y": 400,
"wires": [
[
"9c24717d.c5031",
"59822226.0248cc"
]
]
},
{
"id": "9c24717d.c5031",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "converted json",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1080,
"y": 460,
"wires": []
},
{
"id": "938d4ef0.68605",
"type": "change",
"z": "cbfaf013.0e5e",
"name": "get pid",
"rules": [
{
"t": "set",
"p": "pid",
"pt": "flow",
"to": "$split($lookup(status, \"text\"),\":\")[1]",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 300,
"y": 520,
"wires": [
[
"50203a30.d5c0a4"
]
]
},
{
"id": "50203a30.d5c0a4",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "$flowContext(\"pid\")\t",
"targetType": "jsonata",
"statusVal": "$flowContext(\"pid\")\t",
"statusType": "auto",
"x": 480,
"y": 520,
"wires": []
},
{
"id": "5fe3eb4d.3d8c04",
"type": "switch",
"z": "cbfaf013.0e5e",
"name": "Check and restart",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$lookup(payload, \"code\")=56",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 470,
"y": 360,
"wires": [
[
"bf874de4.ef135"
]
]
},
{
"id": "bf874de4.ef135",
"type": "delay",
"z": "cbfaf013.0e5e",
"name": "",
"pauseType": "delay",
"timeout": "10",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 660,
"y": 360,
"wires": [
[
"df1b46c2.dc0748"
]
]
},
{
"id": "20c47d1f.7e57d2",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "mqtt out",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 720,
"y": 460,
"wires": []
},
{
"id": "a272ddf7.56ba6",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "Zone id to zone name mapping",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "$flowContext(\"zones\")",
"statusType": "auto",
"x": 1050,
"y": 20,
"wires": []
},
{
"id": "7593a9f9.4b4dc8",
"type": "function",
"z": "cbfaf013.0e5e",
"name": "initialize zone ids and names",
"func": "var zones = flow.get(\"zones\")\nmsg.payload = zones\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "// Code added here will be run once\n// whenever the node is deployed.\n\nclass door_window {\n constructor(zoneid, entity_id=\"\", name, device_class=\"door\", state=\"Closed\") {\n this.state = state\n this.id = zoneid\n this.name = name\n this.device_class = device_class\n this.entity_id = entity_id\n this.payload_on = \"Open\"\n this.payload_off = \"Closed\"\n this.config_topic = \"homeassistant/binary_sensor/\" + entity_id + \"/config\"\n this.state_topic = \"mqtt_states/binary_sensor/\" + entity_id + \"/state\" \n }\n \n}\n\nvar zones = []\nzones[1] = new door_window(1, \"front_door\", \"Front Door\")\nzones[2] = new door_window(2, \"trash_gate\", \"Trash Gate\")\nzones[3] = new door_window(3, \"neela_s_garage_entry\", \"Neela's Garage Entry\")\nzones[4] = new door_window(4, \"roopesh_s_garage_entry\", \"Roopesh's Garage Entry\")\nzones[6] = new door_window(6, \"great_room_slider\", \"Great Room Slider\")\nzones[7] = new door_window(7, \"garage_side_door\", \"Garage Side Door\")\n\nflow.set(\"zones\", zones)\n",
"finalize": "",
"x": 360,
"y": 60,
"wires": [
[
"a272ddf7.56ba6",
"4e0e16a3.7cd0f8"
]
]
},
{
"id": "29d0c5a8.b1b4ea",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "Unknown events",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 170,
"y": 460,
"wires": []
},
{
"id": "59822226.0248cc",
"type": "function",
"z": "cbfaf013.0e5e",
"name": "Build MQTT Update Payload",
"func": "var zid = msg.payload[\"zone\"][\"zone_id\"]\nvar zones = flow.get(\"zones\")\nvar state_topic = zones[zid].state_topic\nvar state = msg.payload[\"zone\"][\"status\"]\n\nmsg.payload = state\nmsg.topic = state_topic\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 460,
"y": 460,
"wires": [
[
"7a8a7809.26cf68",
"20c47d1f.7e57d2"
]
]
},
{
"id": "4e0e16a3.7cd0f8",
"type": "array-loop",
"z": "cbfaf013.0e5e",
"name": "loop zones",
"key": "al4e0e16a37cd0f8",
"keyType": "msg",
"reset": true,
"resetValue": "value-null",
"array": "zones",
"arrayType": "flow",
"x": 650,
"y": 80,
"wires": [
[
"89ebb812.5ea3a8"
],
[
"a51867e3.622258"
]
]
},
{
"id": "89ebb812.5ea3a8",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "All HA Init'd",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 990,
"y": 80,
"wires": []
},
{
"id": "a51867e3.622258",
"type": "switch",
"z": "cbfaf013.0e5e",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nnull"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 430,
"y": 200,
"wires": [
[
"48744f25.dce7a"
],
[
"4e0e16a3.7cd0f8"
]
]
},
{
"id": "3f8da6fc.a7238a",
"type": "catch",
"z": "cbfaf013.0e5e",
"name": "",
"scope": null,
"uncaught": false,
"x": 540,
"y": 580,
"wires": [
[
"cd788dfe.d978"
]
]
},
{
"id": "cd788dfe.d978",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 710,
"y": 580,
"wires": []
},
{
"id": "dfd2c176.68a0e",
"type": "debug",
"z": "cbfaf013.0e5e",
"name": "Initialized in HA",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 160,
"wires": []
},
{
"id": "1534a5cd.807cea",
"type": "mqtt out",
"z": "cbfaf013.0e5e",
"name": "",
"topic": "",
"qos": "",
"retain": "",
"broker": "b1167957.68aa08",
"x": 930,
"y": 220,
"wires": []
},
{
"id": "48744f25.dce7a",
"type": "function",
"z": "cbfaf013.0e5e",
"name": "Build MQTT topic and payload",
"func": "var topic = \"\"\nvar type = msg.payload[\"type\"]\nvar entity_id = msg.payload[\"entity_id\"]\nvar name = msg.payload[\"name\"]\nvar device_class = msg.payload[\"device_class\"]\nvar state_topic = msg.payload[\"state_topic\"]\nvar config_topic = msg.payload[\"config_topic\"]\nvar payload_on = msg.payload[\"payload_on\"]\nvar payload_off = msg.payload[\"payload_off\"]\nvar config_msg = {\n \"name\": name,\n \"device_class\": device_class,\n \"state_topic\": state_topic,\n \"payload_on\": payload_on,\n \"payload_off\": payload_off\n}\n\nmsg.topic = config_topic\n\nmsg.payload = config_msg\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 690,
"y": 200,
"wires": [
[
"dfd2c176.68a0e",
"4e0e16a3.7cd0f8",
"1534a5cd.807cea"
]
]
},
{
"id": "7a8a7809.26cf68",
"type": "mqtt out",
"z": "cbfaf013.0e5e",
"name": "",
"topic": "",
"qos": "",
"retain": "",
"broker": "b1167957.68aa08",
"x": 710,
"y": 500,
"wires": []
},
{
"id": "b1167957.68aa08",
"type": "mqtt-broker",
"name": "HA MQTT",
"broker": "127.0.0.1",
"port": "1883",
"clientid": "",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
}
]
If it wasnāt nearly 1AM I would be implementing the openssl and/or python solutions .
Also, FWIW, I nearly never have to reboot my panel. Every so often node-redās curl would fail (dunno why) so I built in a restart if it fails.