I had added to my nodered the most recent not so binary presence detection (NSBPD): Making Home Assistant's Presence Detection not so Binary (Node-RED version). Worked well enough, but a constant solution I was trying to find was how to give my home, or rather, group of people, a status that would be similar to a group made of person entities (ie if one home and one not_home, shows as home, or if both not_home shows as away). Having something like this would assist in automatons that require all people to be Away or even Extended Away. My solution is as follows:
-
I created a new input_select (lts call it input_select.away for our purposes) with the same options as those in the NSBPD (Home, Just Arrived, Just Left, Away, Extended Away).
-
In NODERED I create an “events: state” node to listen to entity
^input_select\..*$
with Regex selected so anytime an input select is changed, this flow would trigger. The purpose is to capture any input select changes in the NSBPD flow. -
The events: state node flowed into a function node with the following:
//creates values for the states
var dict = {
"Home": 1,
"Just Arrived": 2,
"Just Left": 3,
"Away": 4,
"Extended Away": 5
}
//a function to be able to recall a key by its value
function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
//assigning values to persons based on their NSBPD status
var states = global.get('homeassistant.homeAssistant.states');
var P1 = dict[states["input_select.P1"].state];
var P2 = dict[states["input_select.P2"].state];
//Select the lowest value, convert the value to a status, and return that status
msg.payload = getKeyByValue(dict,Math.min(P1,P2));
return msg;
-
This function node then flows into a call service node, with input_select domain, select_option service, input_select.away entityId with {“option”:msg.payload} in the data field.
-
Now you can set automations based input_select.away which captures the whole home status instead of the binary HA status.
Nodered flow:
[{"id":"3bfe440f79fd38c0","type":"server-state-changed","z":"57b685e5ab28d75a","name":"Precise Away Change","server":"14701c3.a2c7564","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"^input_select\\.status.*$","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":120,"y":460,"wires":[["5779de89f3c3231e"]]},{"id":"5779de89f3c3231e","type":"function","z":"57b685e5ab28d75a","name":"Home Status","func":"var dict = {\n \"Home\": 1,\n \"Just Arrived\": 2,\n \"Just Left\": 3,\n \"Away\": 4,\n \"Extended Away\": 5\n}\n\nfunction getKeyByValue(object, value) {\n return Object.keys(object).find(key => object[key] === value);\n}\n\nvar states = global.get('homeassistant.homeAssistant.states');\nvar kristin = dict[states[\"input_select.status_kristin\"].state];\nvar zach = dict[states[\"input_select.status_zach\"].state];\n\nmsg.payload = getKeyByValue(dict,Math.min(zach,kristin));\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":460,"wires":[["08d51d50dc1f390c"]]},{"id":"08d51d50dc1f390c","type":"api-call-service","z":"57b685e5ab28d75a","name":"Away Mode","server":"14701c3.a2c7564","version":1,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.away","data":"{\"option\":msg.payload}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":530,"y":460,"wires":[[]]},{"id":"14701c3.a2c7564","type":"server","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]