ryanjohnsontv / node-red-contrib-ha-inovelli-manager

Nodes for easily managing scenes, parameters, and notifications of Inovelli switches paired through various Home Assistant integrations
MIT License
15 stars 3 forks source link

Multiple entity/node IDs #31

Closed sstarcher closed 2 years ago

sstarcher commented 2 years ago

I'm using Home Assistant and ZwaveJS2QMTT. Whenever I put multiple values in for node/entity ID I get the following.

Example Node ID "27,1" Entity ID "light.bedroom_fan_lights,light.other"

The output becomes json that looks like

{
  "payload": ...
  entity_id: "light.bedroom_fan_lights, light.other"
}

I was expecting it to map the Node ID to the Entity ID in the comma-separated list. Am I misunderstanding how this is supposed to work?

ryanjohnsontv commented 2 years ago

ZWaveJS only accepts the entity id when making service calls, so any values set in the node ID field are ignored. The Node ID field is only applicable for the deprecated “zwave” integration and Open Z-Wave.

sstarcher commented 2 years ago

Thanks, so with that understanding if I wanted to control multiple switches with this integration would the best way be as follows.

Event -> Inovelli Scene Manager (per light) -> dynamic call function using {{ entity_id}}

I was trying to do this without multiple Inovelli Scene Managers and it also looks like your LED manager does not support a dynamic entity_id so I would need to instead use a service call function?

ryanjohnsontv commented 2 years ago

Ah I apologize, I misunderstood! For the scene manager it reads the node ID from the event message, and uses that to filter message to the proper output. So in your case you could fill the node ID field with your switch node IDs, and that will pass along messages for those nodes. Then you can use a function node connected to each output to route each node ID to a service call (ie. Node 3 turns on light.living_room & Node 4 turns light.bedroom for the single click up button).

The entity_id field for the scene manager node just appends it to the event message so you don’t have to clarify the same entity ID on each corresponding function/service node. For instance if you have one scene manager node for each switch and want each button click to behave the same way you can send the outputs of each scene manager node to the same {domain: “light”, service: “turn_on”, entity_id: {{msg.entity_id}}} message.

sstarcher commented 2 years ago

Got ya, so that sounds about identical to what I'm doing just with the switch at a different location.

If I'm following you are recommending

Event -> Scene Manager(With NodeID Passthrough) -> function|switch -> call service vs Event -> Switch -> Scene Manager(Multiple) -> call service

Thanks that answers my question.

sstarcher commented 2 years ago

It would be a fairly large usability upgrade to have an option for the scene manager to take a comma-separated list of nodeIDs and entityIDs. It would allow the user to either ditch a function or a switch/set combo.

ryanjohnsontv commented 2 years ago

Here are a few examples you can import that might help:

[{"id":"4515879418145fc4","type":"server-events","z":"978218e1.644ff8","name":"Z-Wave JS Scenes","server":"7931a4b6.dc7fbc","version":1,"event_type":"zwave_js_value_notification","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":150,"y":1180,"wires":[["09572a2dd11e1b5b"]]},{"id":"09572a2dd11e1b5b","type":"inovelli-scene-manager","z":"978218e1.644ff8","name":"Living Room/Hallway Switch","nodeid":"28,37","entityid":"","zwave":"zwave_js","switchtype":"LZW31","outputs":15,"labels":["Tap Up on Light Paddle 1x","Tap Up on Light Paddle 2x","Tap Up on Light Paddle 3x","Tap Up on Light Paddle 4x","Tap Up on Light Paddle 5x","Hold Up on Light Paddle","Release Up on Light Paddle","Tap Down on Light Paddle 1x","Tap Down on Light Paddle 2x","Tap Down on Light Paddle 3x","Tap Down on Light Paddle 4x","Tap Down on Light Paddle 5x","Hold Down on Light Paddle","Release Down on Light Paddle","Tap Config Button"],"passthrough":false,"x":400,"y":1180,"wires":[["55c090eebbec55d9"],["8d33955c72bef135"],["9cf4461cecb989f5"],[],[],[],[],["44097d796b2f4947"],["0cb17a65ea66488b"],["6223d97e68fa9b58"],[],[],[],[],[]]},{"id":"55c090eebbec55d9","type":"function","z":"978218e1.644ff8","name":"Light Up 1x","func":"//const node_id = parseInt(msg.payload.event.node_id);\nconst ha = global.get('homeassistant').homeAssistant.states;\nvar kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.hallway_light_1,light.hallway_light_2\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_on\",\n    data:{\n        entity_id,\n        brightness_pct:100,\n        kelvin,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":1060,"wires":[["2923fbb9d1736d37"]]},{"id":"2923fbb9d1736d37","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":755,"y":1060,"wires":[]},{"id":"44097d796b2f4947","type":"function","z":"978218e1.644ff8","name":"Light Down 1x","func":"//const node_id = parseInt(msg.payload.event.node_id);\n//const ha = global.get('homeassistant').homeAssistant.states;\n//var kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.hallway_light_1,light.hallway_light_2\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_off\",\n    data:{\n        entity_id,\n        //brightness_pct:20,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1180,"wires":[["93b31c90c4ef6a43"]]},{"id":"93b31c90c4ef6a43","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":755,"y":1180,"wires":[]},{"id":"8d33955c72bef135","type":"function","z":"978218e1.644ff8","name":"Light Up 2x","func":"//const node_id = parseInt(msg.payload.event.node_id);\n//const ha = global.get('homeassistant').homeAssistant.states;\n//var kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.living_room_lights\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_on\",\n    data:{\n        entity_id,\n        brightness_pct:100,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":850,"y":1080,"wires":[["4b24de7dfe087061"]]},{"id":"4b24de7dfe087061","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":975,"y":1080,"wires":[]},{"id":"0cb17a65ea66488b","type":"function","z":"978218e1.644ff8","name":"Light Down 2x","func":"//const node_id = parseInt(msg.payload.event.node_id);\n//const ha = global.get('homeassistant').homeAssistant.states;\n//var kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.living_room_lights\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_off\",\n    data:{\n        entity_id,\n        //brightness_pct:20,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":1200,"wires":[["86b2605972575072"]]},{"id":"86b2605972575072","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":975,"y":1200,"wires":[]},{"id":"9cf4461cecb989f5","type":"function","z":"978218e1.644ff8","name":"Light Up 3x","func":"//const node_id = parseInt(msg.payload.event.node_id);\n//const ha = global.get('homeassistant').homeAssistant.states;\n//var kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.living_room_lights,light.hallway_lights\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_on\",\n    data:{\n        entity_id,\n        brightness_pct:100,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":1100,"wires":[["01285b0d51feae26"]]},{"id":"01285b0d51feae26","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":755,"y":1100,"wires":[]},{"id":"6223d97e68fa9b58","type":"function","z":"978218e1.644ff8","name":"Light Down 3x","func":"//const node_id = parseInt(msg.payload.event.node_id);\n//const ha = global.get('homeassistant').homeAssistant.states;\n//var kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\n//var effect;\nconst entity_id = \"light.living_room_lights,light.hallway_lights\"\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_off\",\n    data:{\n        entity_id,\n        //brightness_pct:100,\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1220,"wires":[["21df96ae4cdfc9fb"]]},{"id":"21df96ae4cdfc9fb","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":755,"y":1220,"wires":[]},{"id":"7931a4b6.dc7fbc","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
[{"id":"bbd106384dd79366","type":"server-events","z":"978218e1.644ff8","name":"Z-Wave JS Scenes","server":"7931a4b6.dc7fbc","version":1,"event_type":"zwave_js_value_notification","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":150,"y":1500,"wires":[["2689c8c1007e84e1"]]},{"id":"2689c8c1007e84e1","type":"inovelli-scene-manager","z":"978218e1.644ff8","name":"Closets","nodeid":"29,31,48","entityid":"","zwave":"zwave_js","switchtype":"LZW31","outputs":15,"labels":["Tap Up on Light Paddle 1x","Tap Up on Light Paddle 2x","Tap Up on Light Paddle 3x","Tap Up on Light Paddle 4x","Tap Up on Light Paddle 5x","Hold Up on Light Paddle","Release Up on Light Paddle","Tap Down on Light Paddle 1x","Tap Down on Light Paddle 2x","Tap Down on Light Paddle 3x","Tap Down on Light Paddle 4x","Tap Down on Light Paddle 5x","Hold Down on Light Paddle","Release Down on Light Paddle","Tap Config Button"],"passthrough":false,"x":340,"y":1500,"wires":[["1c5b6843ce161e0f"],["a70c439d5ed71fcd"],[],[],[],[],[],["a0c64200b4d6c3cc"],[],[],[],[],[],[],[]]},{"id":"1c5b6843ce161e0f","type":"function","z":"978218e1.644ff8","name":"Light Up 1x","func":"const node_id = parseInt(msg.payload.event.node_id);\nconst ha = global.get('homeassistant').homeAssistant.states;\nvar kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\nvar effect;\nconst entityDict = {\n    29: \"light.office_closet_light\",\n    31: \"light.guest_bedroom_closet_light\",\n    48: \"light.bedroom_closet_light\",\n}\nconst entity_id = entityDict[node_id];\nif (entity_id){\n    node.send({payload:{\n        domain:\"light\",\n        service:\"turn_on\",\n        data:{\n            entity_id,\n            brightness_pct:100,\n            ...kelvin,\n            ...effect\n        }\n    }});\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":1380,"wires":[["d67581889c405c12"]]},{"id":"d67581889c405c12","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":655,"y":1380,"wires":[]},{"id":"861d7fdeb8b0b3c9","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":655,"y":1500,"wires":[]},{"id":"a0c64200b4d6c3cc","type":"function","z":"978218e1.644ff8","d":true,"name":"Light Down 1x","func":"const node_id = parseInt(msg.payload.event.node_id);\nconst ha = global.get('homeassistant').homeAssistant.states;\nvar kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\nvar effect;\nconst entityDict = {\n    29: \"light.office_closet_light\",\n    31: \"light.guest_bedroom_closet_light\",\n    48: \"light.bedroom_closet_light\",\n}\nconst entity_id = entityDict[node_id];\nif (entity_id){\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_off\",\n    data:{\n        entity_id,\n    }\n}});\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":1500,"wires":[["861d7fdeb8b0b3c9"]]},{"id":"a70c439d5ed71fcd","type":"function","z":"978218e1.644ff8","name":"Light Up 2x","func":"const node_id = parseInt(msg.payload.event.node_id);\nconst ha = global.get('homeassistant').homeAssistant.states;\nvar kelvin = parseInt(ha[\"input_number.color_temperature\"].state);\nvar effect;\nconst entityDict = {\n    29: \"light.office_closet_light\",\n    31: \"light.guest_bedroom_closet_light\",\n    48: \"light.bedroom_closet_light\",\n}\nconst entity_id = entityDict[node_id];\nnode.send({payload:{\n    domain:\"light\",\n    service:\"turn_on\",\n    data:{\n        entity_id,\n        brightness_pct:10,\n        ...kelvin,\n        ...effect\n    }\n}});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":1420,"wires":[["aeecacd21f1ed5ef"]]},{"id":"aeecacd21f1ed5ef","type":"link out","z":"978218e1.644ff8","name":"","links":["9ebecd1a.ddbba","fca1ac8c.cb636","5ba1f0f7e896daca"],"x":655,"y":1420,"wires":[]},{"id":"7931a4b6.dc7fbc","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
sstarcher commented 2 years ago

Your second option certainly is more like what I'm doing. I'm essentially doing the same thing you are, but with minimal work in the functions.

Screen Shot 2022-01-24 at 6 14 29 AM

sstarcher commented 2 years ago

The switch contains the ID mapping and the set after that is setting the entity id.

sstarcher commented 2 years ago

Your second example in your link would be great to add to your existing list of examples in github.

ryanjohnsontv commented 2 years ago

Would you benefit from having some sort of node ID/entity ID grouping table like this in the scene manager?

image

I personally like having a dedicated JSON object with my Z-Wave info so I can update everything in one place for all my function nodes, but of course not everyone would want to do it this way and the table pairing might be more beneficial.

image
sstarcher commented 2 years ago

I can see having them all in one place can provide benefit, but in all of my automation, I have never needed to map nodeIDs to entityIDs until using the scene manager. For someone like myself, it would be beneficial if scene manager had that function since it gets nodeIDs from the events.