Skip navigation
2015

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.

Screen Shot 2015-07-17 at 21.14.59.png

 

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:

Screen Shot 2015-07-20 at 11.14.40.png

 

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:

Screen Shot 2015-09-12 at 12.42.15.png

 

And some screenshot of the notifications being received on my phone:

IMG_0017.PNGIMG_0019.PNG

 

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.