Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Description: This function is for use with Home Assistant and Node-Red. It will
- // turn on a specified light and set it to a specified color in the event of an
- // Internet outage. Upon re-connecting, the function will return the light to its
- // original state. Note that in order to operate properly, the specified light
- // must be locally controlled and not cloud controlled.
- // Input for this function is a Ping node. Tested with a target identified, automatic
- // protocol, timed mode, and an interval of 30 seconds.
- // For testing purposes, the target IP was set as a WiFi light bulb. To simulate an
- // outage, power was turned off to the light. When power was turned back on, the
- // re-connect portion would excute.
- // This function node requires three outputs. These outputs should allow for
- // expanded functionality outside the scope of this function node.
- // -the first output is for the failure path; payload = number of ping failures
- // -the second output is for the operational path; payload = ping response time
- // -the third output connects to an empty call service node for the notification.
- // payload sends the necessary variables in the event of an outage and re-connection.
- // Bug: function will sometimes throw a ReferenceError: local is not defined
- // Reason: not sure. seems random. mostly noticed when forcing scripts to restart.
- // Fix: unknown. tried a couple different ways to define local and they all did
- // the same thing.
- // Bug: During an outage, if the light's state or attributes are changed, the
- // function will still return it back to how it was before the outage was reported.
- // Reason: The light's state and attributes are stored prior to an outage. It does
- // not check if the state has changed during the outage.
- // Fix: None yet. Maybe checking during the outage to see if the current
- // state/attributes matches the outage state/attributes?
- // Note: The function does have a variable for the time of failure but it is not
- // used for anything yet. Maybe it will get added to the HA log in the future.
- //20211009 - Added node.status message
- // This is the entity that will be used for notification of an outage and
- // setting previous state.
- var entity = "light.hallway";
- //This is the color the light will change to during an outage.
- var rgb_out = [255,0,0];
- // This sets how many consecutive ping failures can occur before triggering the
- // outage notification.
- var max_allowed_ping_failures = 2;
- // This function stores the current state of the entity (on/off). If the entity is
- // on, it will also stores the entity's attributes. These values will be used when
- // returning the entity to its previous state once the internet has re-connected.
- function set_entity_previous() {
- local.previous_state = ha.state;
- if (local.previous_state === "on") //Store entity's attributes if state is on
- {
- local.previous_attributes = ha.attributes;
- } else {
- local.previous_attributes = null
- }
- }
- // Initialize variables
- const ha = global.get('homeassistant').homeAssistant.states[entity]
- const messages = new Array(node.outputCount) // Create an array same length as there are outputs
- const msg0 = {payload:"", topic:"MSG0"};
- const msg1 = {payload:"", topic:"MSG1"};
- const msg2 = {payload:"", data:"", topic:"MSG2"};
- // Establish variables if they do not exist and set default value
- if (typeof local !== undefined) { local = global.get('data') || {}; }
- if (local.ping_failure_count===undefined) { local.ping_failure_count = 0; }
- if (local.ping_failure_time===undefined) { local.ping_failure_time = 0; }
- // Establish standard payload to be passed to service call node
- msg2.payload = {domain: "light", service: "turn_on",
- data: {
- entity_id: entity, }
- };
- // The Ping node will return false if it does not receive a response.
- // Otherwise, it will return a time in ms.
- if (msg.payload === false) // Ping response failed
- {
- node.status({fill:"red",shape:"ring",text:"disconnected"});
- local.ping_failure_count++;
- // Has max_allowed_ping_failures occured? Indicate outage.
- if (local.ping_failure_count === max_allowed_ping_failures)
- {
- if (local.previous_state === "on" || local.previous_state === "off") { set_entity_previous(); }
- local.ping_failure_time = Date.now(); //Creates timestamp variable in seconds; not used yet
- msg2.payload.data.rgb_color = rgb_out;
- messages[2] = msg2; // Send service call payload to output
- }
- msg0.payload = local.ping_failure_count;
- global.set('data',local);
- messages[0] = msg0; // Send ping failure count to output
- } else { // Ping response good
- node.status({fill:"green",shape:"dot",text:"connected"});
- // Has the internet re-connected following an outage?
- if (local.ping_failure_count >= max_allowed_ping_failures)
- {
- //Return light to its previous state
- if (local.previous_state === "on")
- {
- msg2.payload.data.brightness = local.previous_attributes.brightness;
- // Was light in color mode or RGB mode since both cannot be passed in the same payload?
- if (local.previous_attributes.rgb_color.toString() === '255,255,255') {
- msg2.payload.data.color_temp = local.previous_attributes.color_temp;
- } else {
- msg2.payload.data.rgb_color = local.previous_attributes.rgb_color;
- }
- } else { // Light's previous state was off
- msg2.payload.service = "turn_off";
- }
- messages[2] = msg2; // Send service call payload to output
- }
- local.ping_failure_count = 0; // Reset/maintain ping failure count to zero
- set_entity_previous(); // Store entity's current state
- msg1.payload = msg.payload;
- global.set('data',local);
- messages[1] = msg1; // Send response time to output
- }
- return messages;
Advertisement
Add Comment
Please, Sign In to add comment