Response to Sensors with Email Alerts - Example Follow
This example walks through the formation of a flow-based solution to several requirements. The example uses several nodes without explanation. The nodes and associated help articles are list below.
- Set Resource node - See Mobius Core
- Mobius Flow Inject node - See Mobius Core
- Mobius Filter node - See (not written yet)
- Mytimeout - See https://flows.nodered.org/node/node-red-contrib-mytimeout
Knowledge of the following articles is recommended.
The space in question is a small room containing a single EnOcean Occupancy and Lux sensor. The door to the room features and an EnOcean Single Input Contact sensor to measure if the door is open or closed. The window below shows the setup configuration window within MobiusFlow.
Requirements
- An immediate email alert is to be sent whenever the door state changes. This includes closed to open and open to closed.
- An immediate email alert is to be sent whenever the lighting sate changes. This includes on to off and off to on.
- An email alert is to be sent if the light is left on for 30 minutes.
- An email alert is to be sent if the door is left open for 30 minutes.
- An email alert is any hardware that goes offline for 60 minutes or more.
Requirement 1 - Door State
Requirement: An immediate email alert is to be sent whenever the door state changes. This includes closed to open and open to closed.
This requires the reading of the state of the Single Contact Input sensor located on the door. This sensor has a URI of 000001/020/0033/0001. The following flow is used to satisfy this requirement.
The flow consists of a Mobius Inject node, a Mobius Filter node, a Get Resource node, a function node and a send email. It can be broken down into two stages. These stages are covered in the following sections.
Change Detection
The change in the door state is detected by using the Mobius Flow Inject node and the Mobius Filter node.
The Mobius Flow Inject node is used to detect any changes in the state of the Single Contact Input sensor located on the door of the room. If a change of state is detected, the node will inject a message into the flow. The configuration of properties for the Mobius Flow Inject node is shown below.
The Mobius Flow Injects a message into the Mobius Filter node. This Mobius Filter node filters any incoming messages allowing messages to pass only when the Contact State resource (resource 40) has changed. The configuration of properties for the Mobius Filter node is shown below.
The flow is now sufficient so any change to the Contact State of the Single Contact Input sensor will be detected and a message relayed.
Message Processing and Email
After the Mobius Filter node, messages are only received when the Contact state changes. This section focuses on the later stage of flow, shown below.
The next state is to fetch the actual value of this resource for later processing. This is done using the Get Resource node. The Get Resource node is set up to fetch the value of Contact State resource (URI - 000001/020/033/0001/40) whenever a message is received. The configuration of properties for the Get Resource node is shown below.
Output 1 of the Get Resource node is connected to the function node. Connecting to this output means the payload (msg.payload) of any messages leaving the Get Resource node will have a payload equal to the value of the Contact state resource.
The function node is necessary to prepare the message to a form where it can be emailed. The email node will send an email setting the subject equal to the topic of the message (msg.topic) and the content equal the payload of the message (msg.payload). The function node formats the message into this form prior to sending via email. The code within the function is shown below.
msg.topic="Alert!"
if (msg.payload===true){
msg.payload="Door Closed."
}
else {
msg.payload="Door Opened."
}
return msg;
Initially, the code sets the new topic of the message to read "Alert!". This will become the subject of the generated email. The code then checks to see if the message payload (Contact state of the door) is true. The Single Input Contact sensor will send a true reading if the door is closed. Due to this, the code will set the new payload of the message to say "Door Closed.". This will become the body of the email alert. Conversely, if the payload of the message is false, the code will set the new payload to read "Door Opened.".
After processing within the function node, the message is now ready to be emailed. The message reaches the send email node and is sent to the desired recipient.
Requirement 2 - Lighting State
An email alert is to be sent if the light is left on for 30 minutes.
This is similar to requirement 1 because an email alert is being sent based on the state of a single resource. The sensor which is used for this requirement is the Occupancy and Lux sensor which as a URI of 000001/020/0030/0001. This is more complex than requirement 1 because the lighting state is not returned as a simple true or false. It is instead returned from the Lux sensor (resource 41) with a value between 0lx to 1000lx.
The flow to satisfy requirement 2 is shown below.
The initial Mobius Flow Inject node, Mobius Filter node, and Get Resource node are used in the same manner as in requirement 1. They are used to respond to when the Lux level changes and ensure the outputted message payload is equal to the light level in lx. The configurations of properties for the three nodes are shown below.
Mobius Flow Inject:
Mobius Filter:
Get Resource:
Hysteresis Node
The Hysteresis node is used to detect when a value climbs above or descends below a given value. For the purpose of this example, we will assume the light in the room is on when the lighting level rises above approximately 110lx. The node is configured to send a message every time the light level rises above the 120lx mark or falls below the 100lx. The node by default sets the edge property of the message (msg.edge) to 'rising' or 'falling' depending on if the light level rises or falls past the defined thresholds. The configuration of properties for the hysteresis node is shown below.
Filters
The two function nodes, labeled risingFilter, and fallingFilter, are used to filter the messages into two different streams. These streams mark if the lux level has risen above the defined threshold i.e. the light is turning on, or the lux level has fallen below the defined threshold i.e. the light is turning off. The nodes check the state of the msg.edge property to see if the message marks a rising or falling event. The code for the two function nodes is shown below.
Rising Filter:
if (msg.edge==="rising"){
return msg;
}
Falling Filter:
if (msg.edge==="falling"){
return msg;
}
Both filters will only forward the message if msg.edge property is in the state they are checking for. This means they filter only rising or falling messages into their corresponding streams. The net effect of this is that the upper stream will only contain messages when the light is switch on and the lower stream will only contain messages when the light is switched off.
Final Formatting
The two streams are formatted ready to be sent by the email node. The code within the two function nodes is shown below.
Upper Stream:
msg.topic="Alert!";
msg.payload="Light switched on.";
return msg;
Lower Stream:
msg.topic="Alert!";
msg.payload="Light switched off.";
return msg;
In both streams, the topic of the message (msg.topic) is set to "Alert!" to become the subject line of the sent email. The upper stream will set the message payload of the message to read "Light switched on." and the lower stream will set the message payload to "Light switched off.". The messages are then sent to the email send node to alert the relevant recipient.
Requirement 3 - Light left On
An email alert is to be sent if the light is left on for 30 minutes.
This requirement is similar to requirement 2 because the actions that must be fulfilled are based on light level. The requirement uses the Lux level sensor filtering method already completed in requirement 2 and combines this with a timer to time how long the light has been on for.
Up to an including the nodes labeled risingFilter and fallingFilter, the flow is unchanged from requirement 2. At this point within the flow, a message will be sent by the node labelled risingFilter if the light is switched on, and a message will be sent by the fallingFilter if the light has been switched off.
Timing
The node labeled risingFilter is connected to the Mytimeout node. The Mytimeout node is a non-standard node-RED node. It can be added using the manage pallet option within node-RED. This option is outlined by the red box in the window below.
The Mytimeout node will start a pre-defined timer when it receives an incoming message. Once the timer has timed out, the node will output a message. During timing, the node has the ability for the timer to be reset or canceled based on further incoming messages. The node has been set up to time for 30 minutes (1800 seconds) before outputting a message. The configuration of properties for the Mytimeout node is shown below.
Timer stop
If the light has been left on, the Mytimeout node will have a running timer measuring a period of 30 minutes. If the light is switched off during this time, the timer running in the Mytimeout node must be canceled.
The change node connected to the fallingFilter node receives a message when the light is switched off. The Mytimeout node will cancel its running timer when it receives an incoming message where the payload of the message (msg.payload) is equal to 'cancel'. The change node used here sets the payload of the incoming message to 'cancel'. This, used with the fallingFilter function, has the net effect of canceling the timer in the Mytimeout node whenever the light switches off. The configuration of properties for the change node is shown below.
Final Formatting
If the light is left on for the full 30 minutes, the Mytimeout node timer will time out. This means the Mytimeout node will output a message with the payload (msg.payload) equal to 'off'. The final function node prepares the message to be emailed. The code in the function node is shown below.
if (msg.payload==="off"){
msg.topic="Escalation Alert!";
msg.payload="Light has been on for 30 minutes.";
return msg;
}
The first line of the function checks to see if the msg.payload is equal to 'off'. This is important because the Mytimeout node will also output messages when the timer is switched on. As an email alert is only required when the timer times out, this makes this check necessary. The remainder of the function sets the topic and payload of the outgoing message. These will become the subject and content respectively of the email to be sent. The function node is connected to the send the email node and the email is sent to the relevant recipient.
Requirement 4 - Door left Open
An email alert is to be sent if the door is left open for 30 minutes.
This requirement is similar to requirement 1 because it depends on the state of the Single Contact Input sensor. The flow below satisfies the requirement by using the same method as requirement 1 to collect the data and combines with a timer.
The Mobius Flow Inject node, Mobius Filter node and Get Resource node are used in the same manner as requirement 1. They have the net effect of outputting a message when the Contact state of the Single Input Contact sensor changes.
Timing
The change node is used to check to see if any incoming message shows the door has been closed. If this is not detected (i.e. the door is open), the change node will now output an unchanged message which will start the timer Mytimeout node. The Mytimeout node is set to time 30 minutes (1800 seconds). The configuration of properties of the Mytimeout node is shown below.
If Contact State resource (resource 40) will have a true value if the door closed. The change node is set to check if the payload of any incoming messages is true. If this is the case, the change node will change the payload of the message to 'cancel'. This has the net effect of canceling the timer every time the door is closed. The configuration of properties of the change is shown below.
Final Formatting
If the door is left open for more than 30 minutes, the timer of the Mytimeout node will time out and will output a message a result. The payload of this message will be set to 'off' to show the timer has timed out. The following function node will format the message in preparation to be emailed. The code of the function node is shown below.
if (msg.payload==="off"){
msg.topic="Escalation Alert!";
msg.payload="Door left open for 30 minutes.";
return msg;
}
The function works in the same manner as in requirement 3. The function checks if the incoming message is marking the timer has timed out, and if so it format and forward the message accordingly. The message is sent to the email send node where it is sent to the recipient.
Requirement 5 - Hardware offline
An email alert is to be sent if any hardware goes offline for 60 minutes or more.
The flow shown here shows the solution to this requirement focusing on a single device. The device chosen in this instance is the Single Input Contact device, URI 000001/020/0033/0001. The flow can be easily duplicated to include all devices following this. The solution flow is shown below.
The flow checks when the device was last updated and checks if this value was more than 60 minutes ago. If this is the case, the flow will output a message which is then processed and an email sent a result.
Time Check
The initial inject node is set to inject a message once every minute. This will cause the Get Resource node to check the Single Contact Input sensor every minute. The configuration of properties for the inject node is shown below.
The Get Resource node will check the Object Last Updated resource (resource 02) of the Single Contact Input sensor. Nominally, this resource will update every 30 minutes to show the sensor remains online. The Get Resource node is setup to set the payload of the outgoing message to equal the value of the Object Last Updates resource. The configuration of properties for this node is shown below.
The message is fed into the function node labeled timeCheck. This function checks if the payload of the message contains a time more than 60 minutes before the current time. The function code is shown below.
if (Date.now()-Date.parse(msg.payload)>=60000*60){
if (flow.get("alreadySent")===false){
msg.topic=null;
flow.set("alreadySent", true);
return msg;
}
}
The Date.now function fetched the current number of milliseconds elapsed since the 1st of January 1970. The Date.parse function converts the date in the payload of the message to a number of milliseconds elapsed since 1970. Taking this value away from the current time yields the number of milliseconds elapsed since the device was last online. If this value is more 60 minutes (60,000*60 milliseconds) this means the device has been offline for more than 60 minutes.
The variable called alreadySent is used to store whether or not an email alert has already been sent that day. This is because if the device goes offline, the flow will continue checking if the device is offline every subsequent minute. If this check was not performed, the flow would send the recipient and alert every single minute until the device is back online. The function checks if the alreadySent variable is false (i.e. an alert is yet to be sent). If so, an alert message is sent and the alreadySent variable is set to true so no further message can be sent. Note, the topic of the message is cleared for further formatting reasons, see the next section for further explanation.
The alreadySent variable will be reset to false at midnight every night by a separate flow. This means, if the device remains offline, the recipient will receive notifications once per day until the device is brought back online. The reset flow is shown below.
The inject node sends a message once at midnight every night. The reset function is shown below.
flow.set("alreadySent", false);
Message Formatting
Following the function node labeled time check, a Get Resource node is used to fetch the device name (resource 01) of the sensor which has gone offline. Due to the nature of the Get Resource node, if the topic of any incoming message is a valid URI, the node will use the URI in the topic instead of the URI configured within the node properties. This is not intended with this Get Resource node which is why topic of the message was cleared in the previous function node. The Get Resource node sets the payload of the message to the name of the device. The configuration of properties is shown below.
Finally, the message reaches the final function node which formats it ready to be sent via email. The code within the function is shown below.
msg.payload=msg.payload+" has been unresponsive for 60 minutes."
msg.topic="Escalation Alert!"
return msg;
The function sets the new payload of the message to equal the old payload of the message (the device name) in addition to 'has been unresponsive for 60 minutes'. This will become the body of the email alert. The topic is set to 'Escalation Alert!' which will become the subject of the sent message. The message is forwarded to the email node where it is sent to the recipient.
Combined Requirements
In the flow below, the requirements have been combined into a single flow. Please note, this takes advantage of some requirements sharing common sections of the flow. In this flow, Requirements 1 and 4 share their Mobius Inject, Mobius Filter and Get Resource nodes. The same is true for requirements 2 and 3 which also share their hysteresis and filter nodes. The final combined flow is shown below.
It can be challenging to view this flow and see the individual requirements within it. Below is the same flow but with the individual sections relating to each requirement highlighted.
Comments
0 comments
Please sign in to leave a comment.