In some previous posts, I first set up Bluetooth on the Beaglebone Black and then set up Node-Red to convert the Bluetooth data to MQTT messages. In this third post, I'll be using OpenHAB to receive the MQTT messages, process them and use them for notifications, trending, etc ...
OpenHAB
Installation
The installation of Java and OpenHAB is already covered in detail in one of my posts here on element14. The post can be found here: [AirCare] InTheAir - Week 5: openHAB and MQTT
In order to use OpenHAB with the SensorTag, different items, sitemap, rules, etc ... will be created though. You'll find them in the next paragraphs.
Configuration
Items
From Node-RED, all data is being published to the same topic, so in OpenHAB a master item has been defined to subscribe to the appropriate topic.
Other items have been defined in addition to the master item. They will be assigned with values parsed from the master item, categorising the data in different types such as temperature, humidity, buttons, etc ...
The items file contains the following:
debian@beaglebone:~$ cat /opt/openhab/configurations/items/sensortag.items
Group All
String SensorTag "SensorTag Raw Data [%s]" <sensortag> (All) {mqtt="<[eclipseIot:fvan-sensortag:state:default]"}
Number SensorTag_Temperature_Ambient "SensorTag Ambient Temperature [%.1f °C]" <sensortag> (All)
String SensorTag_Temperature_Object "SensorTag Object Temperature [%s °C]" <sensortag> (All)
String SensorTag_Humidity "SensorTag Humidity [%s %%RH]" <sensortag> (All)
String SensorTag_Pressure "SensorTag Pressure [%s hPa]" <sensortag> (All)
String SensorTag_Keys_1 "SensorTag Key #1 [MAP(bool.map):%s]" <sensortag> (All)
String SensorTag_Keys_2 "SensorTag Key #2 [MAP(bool.map):%s]" <sensortag> (All)
Number Chart_Period "Chart Period"
The screenshot below demonstrates the initial tests, comparing Node-RED's output to OpenHAB's input. A limiter was set in place to prevent flooding of data, limiting to 6 messages per minute per sensor used.
Sitemaps
The sitemaps file is used to arrange the different items visually, in certain (sub)categories, even including charts. In this example, a chart has been defined for the ambient temperature item, with three possible display periods: hour, day, week.
debian@beaglebone:~$ cat /opt/openhab/configurations/sitemaps/sensortag.sitemap
sitemap sensortag label="SensorTag" {
Frame {
Text item=SensorTag
}
Frame {
Text item=SensorTag_Temperature_Ambient {
Frame {
Text item=SensorTag_Temperature_Ambient
}
Frame {
Switch item=Chart_Period label="Chart Period" mappings=[0="Hour", 1="Day", 2="Week"]
Chart item=SensorTag_Temperature_Ambient period=h refresh=10000 visibility=[Chart_Period==0, Chart_Period=="Uninitialized"]
Chart item=SensorTag_Temperature_Ambient period=D refresh=10000 visibility=[Chart_Period==1]
Chart item=SensorTag_Temperature_Ambient period=W refresh=10000 visibility=[Chart_Period==2]
}
}
Text item=SensorTag_Temperature_Object
Text item=SensorTag_Pressure
Text item=SensorTag_Humidity
Text item=SensorTag_Keys_1
Text item=SensorTag_Keys_2
}
}
The result is the following:
Rules
Rules can be used to trigger actions based on certain events. In this particular case, two rules have been defined:
- Categorise data
- Temperature alarm
The first rule is triggered when the master item defined in the items file is updated to a new value. The rule then parses the content in order to categorise it and assign the contents to the item representing the correct sensor. Using some simple string operations, the useful content is extracted from the incoming data.
The second rule demonstrates the use of notifications using Prowl. For testing purposes, I have a notification triggered when the temperature is lower than 50°C. Obviously, this would need to be set to more realistic values, but it is a quick way of verifying the notification mechanism works.
To know more about notifications in OpenHAB using Prowl, be sure to check out the following post: http://www.element14.com/community/community/design-challenges/forget-me-not/blog/2014/10/20/cats-forgetmenot--final#jiv…
debian@beaglebone:~$ cat /opt/openhab/configurations/rules/sensortag.rules
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.lang.Math
import java.lang.Double
import java.lang.String
var Timer temperature_alarm = null
rule "Categorise data"
when
Item SensorTag changed
then
var state = SensorTag.state.toString()
var output = ""
if(state.contains("ambient")) {
output = state.substring(state.indexOf('"ambient":')+10,state.indexOf('}'))
SensorTag_Temperature_Ambient.postUpdate(output)
output = state.substring(state.indexOf('"object":')+9,state.indexOf(','))
SensorTag_Temperature_Object.postUpdate(output)
}
else if(state.contains("pressure")) {
output = state.substring(state.indexOf(':')+1,state.indexOf('}'))
SensorTag_Pressure.postUpdate(output)
}
else if(state.contains("humidity")) {
output = state.substring(state.indexOf('"humidity":')+11,state.indexOf('}'))
SensorTag_Humidity.postUpdate(output)
}
else if(state.contains("right")) {
output = state.substring(state.indexOf('"right":')+8,state.indexOf('}'))
SensorTag_Keys_1.postUpdate(output)
output = state.substring(state.indexOf('"left":')+7,state.indexOf(','))
SensorTag_Keys_2.postUpdate(output)
}
end
rule "Temperature alarm"
when
Item SensorTag_Temperature_Ambient changed
then
var state = SensorTag_Temperature_Ambient.state as DecimalType
if(state < 50.0) {
if(temperature_alarm == null) {
pushNotification("<api key>","Ambient temperature", "too low: " + state)
temperature_alarm = createTimer(now.plusMinutes(1)) [|
temperature_alarm.cancel
temperature_alarm = null
]
}
}
end
Here's a screenshot demonstrating the data being categorised properly:
And some screenshot of the notifications being received on my phone:
Transform
It is also possible to transform the data in the visualisation layer of OpenHAB. For example, the buttons return a true/false state. More meaningful would be to have the state reported as pressed or released.
By creating a bool.map file in the transform folder and reference it in the items file, this can be done quickly. The file contains one translation per line. In the GUI, "true" will be replaced by "pressed" and "false" by "released". The "-=-" is there to avoid OpenHAB reporting translation errors when no data has been received yet.
debian@beaglebone:~$ cat /opt/openhab/configurations/transform/bool.map -=- true=pressed false=released
Persistence
Finally, persistence is what defines which data to store and with which type of storage (MySQL, RRD4J, ...). Persistence is required when using charts.
debian@beaglebone:~$ cat /opt/openhab/configurations/persistence/rrd4j.persist
Strategies {
everyMinute : "0 * * * * ?"
everyHour : "0 0 * * * ?"
everyDay : "0 0 0 * * ?"
default = everyChange
}
Items {
* : strategy = everyChange, everyMinute, restoreOnStartup
}
Conclusion
This concludes this short series of post on how to retrieve data from a SensorTag via Bluetooth, convert it to MQTT using Node-RED and persist/monitor/trend it using OpenHAB.





Top Comments