22
- August
2020
Posted By : Dave Hartburn
ThingsBoard: Setting up mail alerts

As well as graphing, wouldn’t it be useful if ThingsBoard could send a mail alert when a particular parameter for a device goes above/blow a threshold, or when telemetry has not been received for a period of time?

Such things are possible, the following walks through the required configuration steps.

Set up a test device and client

It is easier if we can control the values being sent to ensure this works, so set up a test client and a script to populate it with data.

  • Login to ThingsBoard and go to Devices
  • Add new device
  • Call it TestDevice and give it a device type of GenericTest
    • This is where the ThingsBoard GUI can be frustrating. If you try to type GenericTest, it will attempt to match an existing type and keep overtyping what you are writing. It can be easier to type your new type in another window then cut and paste the whole string in one go.
  • Copy the access token then open the Latest Telemetry tab
  • Paste your server details and access token into the script below and run. You should see the Telemetry update.
#!/bin/bash
# ThingsBoard Telemetry Test

ACTOK='blahblahblah'
# Insert your server and port number
SRV='thingsboardserver.x.y:port'

BASE=45		# Base value
VARI=5		# +- variance around the base value
NAME='soilPC'	# Name of the key we are simulating
SL=5		# Number of seconds sleep between data

RANGE=$((VARI*2))	# Range of numbers

if [ "x$1" != "x" ] ; then                                                                                                  BASE=$1                                                                                           fi                                                                                                         

echo $BASE $VARI $SL $RANGE

while true; do
	# Get random number
	r=$((RANDOM % RANGE))
	# Add to base value - variance
	v=$((BASE-VARI+r))
	
	echo Sending $v
	curl -v -X POST -d "{\"$NAME\": $v}" http://${SRV}/api/v1/${ACTOK}/telemetry --header  "Content-Type:application/json"
	sleep $SL
done

The above script will send telemetry every 5 seconds. It will be +/- 5 around the base value 45. It gives slightly more interesting test data. A single parameter will override the base value to give a quick way of triggering alerts.

Configure mail sending

You must have an account with a mail provider to be able to send mail from

  • Login to ThingsBoard with the sysadmin account. This is different to your ‘everyday’ account where you can set up devices.
  • Go to Settings->Outgoing Mail
  • Enter details of your outgoing mail account and mail provider
  • Click ‘Send Test Mail’
  • If a test mail is received, click ‘Save’

Alert when a value is above/below a threshold

Generating alerts in ThingsBoard is performed using Rule Chains, these are powerful ways of acting on data, but can be difficult to understand at first. Before following this section, it is worth at least a skim read of ThingsBoard Rule Engine. I followed the Create and Clear Alarms tutorial, making changes to suit.

The following example alerts when the soil moisture (soilPC) on a particular device type drops below 30 percent. The rule chain looks like:

  • In Rule Chains, add a new rule chain with the name test device thresholds.
  • Open that chain, it will already have an input node.
  • Ensure the data from the telemetry message is available in the meta data for our use
    • Add a transformation filter
    • Name: Add soilPC to metadata
    • In the script, before the return line, add metadata.soilPC = msg.soilPC;
    • Join this to input
  • Filter on the threshold
    • Add a filter script
    • Name: Soil PC low
    • Filter: return msg.soilPC < 30
    • Join it to the transformation script with type ‘Success’
  • Add a Create Alarm action:
    • Name: Raise Soil Low Alarm
    • Alarm type: SoilLow
    • Propagate selected
    • Alarm severity: Critical
    • The function counts the number of times the alarm is triggered and adds to the metadata
    • When done, join to the filter script with type True
var details = {};
details.soilPC = msg.soilPC;

if (metadata.prevAlarmDetails) {
    var prevDetails = JSON.parse(metadata.prevAlarmDetails);
    details.count = prevDetails.count + 1;
} else {
    details.count = 1;
}
return details;
  • Create a ‘to email’ transformation
    • Name: Mail Soil Warning
    • Set the from and to address
    • Subject: Device ${deviceName} soil moisture low
    • Body: Device ${deviceName} reporting soil moisture low, currently at ${soilPC}%
    • Join to Create Alarm with type ‘Created’
  • Add the external type ‘Send Mail’
    • Name: SendMail
    • Use system SMTP settings
    • Join to email transformation with type ‘Success’.
  • Add a ‘Clear Alarm’ action
    • Name: Clear Soil Low Alarm
    • In the function, before the return, add details.clearedSoil = msg.soilPC;
    • Alarm Type: SoilLow
    • Add to the ‘soil PC low’ filter script with type ‘False’
  • Create a ‘to email’ transformation
    • Name: Cleared Soil Warning
    • Set the from and to address
    • Subject: Device ${deviceName} soil moisture alert cleared
    • Body: Device ${deviceName} now reporting soil moisture at ${soilPC}%, alarm cleared
    • Join to Clear Alarm with type ‘Cleared’
    • Link to the same SendMail function we created for the alarm creation

The new rule chain will not be triggered unless it is linked from the root rule chain. There are a number of ways to do this. I prefer to filter on device type, then if a number of devices share the same data keys (e.g. temperature), the wrong devices to not trigger the wrong rule chain.

  • Open the Root Rule Chain
  • Create a filter switch
    • Name: DeviceTypeSwitch
    • Function: return metadata.deviceType
    • This produces the output of each type of DeviceType used when receiving telemetry.
    • Link this to the existing ‘Save Timeseries’ with type ‘Success’
    • This will save data as normal, then look at processing it.
  • Add the new rule chain we just created.
  • Join it to the new filter switch with a label that matches the device type being used, e.g. SoilSensor
  • Save and await mails, using the test script to trigger alerts.
  • If the process is not working, ‘Debug Mode’ can be turned on on any device to view events. Remember to remove debugging when finished.

Alert on no telemetry received

Has your device stopped working for some reason? You need to know ASAP, so configure ThingsBoard to send a mail. Based on the Thingsboard Inactivity Tutorial. The default time out is 10 minutes. I changed this to 1 hour by editing the thingsboard.yml file, changing defaultInactivityTimeoutInSec and restarting.

The following rule chain will be created:

  • Create a test device and make sure you can send telemetry to it, as above.
  • Under the device, go to Attributes, select server attributes and click + to add
    • Create a attribute inactivityTimeout of type integer and enter the timeout in ms.
    • For testing, make this short.
  • Create a new rule chain, called ‘Inactivity Alerts’
  • Add a filter switch:
    • Name: DeviceTypeSwitch
    • Function: return metadata.deviceType;
    • Join to the input.
    • This will return the device type for any inactive device. We can either pick different actions for a each device type or just feed all the ones we want into the next stage.
  • We need the inactivity time available to the mail sending later in the chain. This data must be copied from the message to the metadata.
    • Create a transformation script
      • Name: Add Inactivity Time To Metadata
      • Transform:
var tdiff = msg.lastInactivityAlarmTime-msg.lastActivityTime;
var tmin = Math.round(Math.floor(tdiff/1000)/60, 1);
metadata.inactiveMin = tmin;
metadata.moo = 12;
return {msg: msg, metadata: metadata, msgType: msgType};
  • Join the script to the device switch, creating a label for any device type to monitor inactivity for.
  • Add a ‘message type switch’
    • Join to transformation script with type ‘Success’
  • Add a create alarm node:
    • Name: Inactivity Alarm
    • Alarm Type: Inactivity Alarm
    • Select Propagate
    • Join to SwitchMessageType with ‘Inactivity Event’
  • Create a ‘to email’ transformation:
    • Name: Mail inactivity
    • Set to and from addresses
    • Subject: Device ${deviceName} inactivity
    • Body: Device ${deviceName} has been inactive for ${inactiveMin} minutes
    • Join to ‘create alarm’ with type ‘Created’
  • Add send mail external node and join it to the email transformation with Success
  • Create a clear alarm node:
    • Name: Clear Inactivity
    • Alarm Type: Inactivity Alarm
    • Join to SwitchMessageType with ‘Activity Event’
  • Add a ‘to email’ transformation:
    • Name: Mail device recovery
    • Set to and from addresses
    • Subject: Device ${deviceName} recovery
    • Body: Device ${deviceName} has returned to service and posted telemetry
    • Join to ‘clear alarm’ with type Cleared
    • Join output to the send email node with type Success
  • In the Root Rule Chain, add the new rule chain as a node
    • Join it to the Message Type Switch with Activity Events and Inactivity Events

Comments

Leave a Reply