In last post, we looked how to dweet enocean sensor data from raspberry pi using Enocean-Py library and view it real time in your desktop using 'desk_viewer.py' script. In this post, we'll see how to dweet from enocean data from openHAB and also how to control your device from internet. With this step, we are stepping a little more towards the dream of 'internet of things'.
I have my enocean pi connected to my rPi and my rPi is having a working internet connection. What we are going to do is to wire two switches in openHAB which are controlled by enocean rocker switch and whenever they gets an update, they will post it to dweet.io. Also we'll create two switches which will take inputs from dweet.io and update the device status.
Wiring up things in openHAB
Rather than creating an entirely new openHAB configuration for this tutorial, I'll modify last week's configuration and add four new switches and for the moment disable the previously created enocean switches. Now the question is how to wire your openHAB dweet.io? So far we don't have any binding for dweet.io. Disappointed? No!! The answer lies in dweet.io's ridiculously simple API. You don't need any additional binding. What you all need is a way to request an url from web -- which can either be a request to post your status or a request to get new status. And there exists some binding in openHAB which can handle this neatly.
HTTP binding
If you want to let openHAB request an URL when special events occur or let it poll a given URL frequently, you can use this binding to make your day easier. It's very easy to update your status to web via http binding. But to update a device status from web, it's a little tricky. First we will look into the update to web part. To request an url upon an event, you just have to put this alongside your device configuration in openHAB.
{http:">[<command>:<httpmethod>:<url>]"}
Suppose you have an enocean rocker switch wired to a switch in openHAB( say the name of this switch is Dwitter0 ), now you can achieve both controlling from enocean rocker switch and update to web with just a simple line on items file.
Switch Dwitter0 (All) {enocean="{id=00:1A:34:82, eep=F6:02:01, channel=B}", http=">[ON:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch0?status=ON] >[OFF:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch0?status=OFF]"}
Here I'm referring my switch in dweet as myHome_device_dwitterSwitch0 and I'm requesting slightly different urls for ON-OFF events. It can't be simpler than this right?
For updating from dweet.io, the solution is a little tricky. While requesting a thing status in dweet.io, we'll be returned with a JSON datastructure like this.
{ "this":"succeeded", "by":"getting", "the":"dweets", "with":[ { "thing":"myHome_device_dwitterSwitch2", "created":"2014-09-10T11:38:49.955Z", "content":{ "status":"OFF" } } ] }
What we have to do is to extract the status part from the returned string. I used regular expressions for this, but I'm sure there will be some better method. ( Please let share with me if you know one ). I have to run this regex query on the returned string and magically it returns the status :
.*?status...(.+?)\".*
Now we have and idea of what to do to extract status from result, we can create a new switch in openHAB which will be updated from dweet.io. Just add this line to your items :
Switch Dwitter2 (All) {http="<[https://dweet.io/get/latest/dweet/for/myHome_device_dwitterSwitch2:10000:REGEX(.*?status...(.+?)\".*)]"}
Here I'm subscribed to dweet handle myHome_device_dwitterSwitch2 and is checking every 10 seconds.
The whole picture
With the basics covered, I'm putting how the enocean.items file will look now.
// enocean.items Group All Group model0_Weather (All) // EnOcean devices // Switch Rocker0 (All) {enocean="{id=00:1A:34:82, eep=F6:02:01, channel=B}"} // Switch Rocker1 (All) {enocean="{id=00:1A:34:82, eep=F6:02:01, channel=A}"} Switch Dwitter0 (All) {enocean="{id=00:1A:34:82, eep=F6:02:01, channel=B}", http=">[ON:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch0?status=ON] >[OFF:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch0?status=OFF]"} Switch Dwitter1 (All) {enocean="{id=00:1A:34:82, eep=F6:02:01, channel=A}", http=">[ON:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch1?status=ON] >[OFF:POST:http://dweet.io/dweet/for/myHome_device_dwitterSwitch0?status=OFF]"} Switch Dwitter2 (All) {http="<[https://dweet.io/get/latest/dweet/for/myHome_device_dwitterSwitch2:10000:REGEX(.*?status...(.+?)\".*)]"} Switch Dwitter3 (All) {http="<[https://dweet.io/get/latest/dweet/for/myHome_device_dwitterSwitch3:10000:REGEX(.*?status...(.+?)\".*)]"} Contact myWindow "Bay Window [MAP(en.map):%s]" <contact> (All) {enocean="{id=00:83:35:06, eep=D5:00:01, parameter=CONTACT_STATE}" } Number TempEnocean "Room Temperature [%.1f °C]" <temperature> (All) {enocean="{id=00:83:02:E5, eep=A5:02:05, parameter=TEMPERATURE}"} Group model0_Weather_Chart (model0_Weather) Number model0_Weather_Temperature "Outside Temperature [%.1f °C]" <temperature> (model0_Weather_Chart) { http="<[http://weather.yahooapis.com/forecastrss?w=2295424&u=c:60000:XSLT(yahoo_weather_temperature.xsl)]" } Number model0_Weather_Temp_Max "Todays Maximum [%.1f °C]" <temperature> (model0_Weather_Chart) Number model0_Weather_Temp_Min "Todays Minimum [%.1f °C]" <temperature> (model0_Weather_Chart) Number model0_Weather_Chart_Period "Chart Period" DateTime model0_Weather_LastUpdate "Last Update [%1$ta %1$tR]" <clock>
and my sitemap now looks like
// enocean.sitemap sitemap model0 label="Enocean Home" { Frame label="Enocean Devices" { // Switch item=Rocker0 label="Rocker 0 Channel B" // Switch item=Rocker1 label="Rocker 1 Channel A" Text item=TempEnocean valuecolor=[>25="orange",>15="green",>5="orange",<=5="blue"] Text item=myWindow } Frame label="Dweet.io Devices" { Switch item=Dwitter0 label="Dwitter Sender 0" Switch item=Dwitter1 label="Dwitter Sender 1" Switch item=Dwitter2 label="Dwitter Reciever 2" Switch item=Dwitter3 label="Dwitter Reciever 3" } Frame label="Weather" { Text item=model0_Weather_Temperature valuecolor=[model0_Weather_LastUpdate=="Uninitialized"="lightgray",model0_Weather_LastUpdate>90="lightgray",>25="orange",>15="green",>5="orange",<=5="blue"] { Frame { Text item=model0_Weather_Temp_Max valuecolor=[>25="orange",>15="green",>5="orange",<=5="blue"] Text item=model0_Weather_Temp_Min valuecolor=[>25="orange",>15="green",>5="orange",<=5="blue"] Text item=model0_Weather_LastUpdate valuecolor=[model0_Weather_LastUpdate>120="orange", model0_Weather_LastUpdate>300="red"] } Frame { Switch item=model0_Weather_Chart_Period label="Chart Period" mappings=[0="Hour", 1="Day", 2="Week"] Chart item=model0_Weather_Chart period=h refresh=600 visibility=[model0_Weather_Chart_Period==0, model0_Weather_Chart_Period=="Uninitialized"] Chart item=model0_Weather_Chart period=D refresh=3600 visibility=[model0_Weather_Chart_Period==1] Chart item=model0_Weather_Chart period=W refresh=3600 visibility=[model0_Weather_Chart_Period==2] } } } }
I've added four new switches to items and wired them as mentioned above.
If you want to check your openHAB site now, it should look like this :
Will this stuff work?
As now I'm claiming that this will do all the tasks of updating to and from dweet.io, it's time to put this to test. Testing will be of two parts -- testing the update from dweet.io and testing the update to dweet.io.
For testing update from dweet.io, what I'll do is post a new dweet in dweet,io play and check whether it got updated in my opanHAB. For testing update to dweet.io, what I'll do is use modified 'dweet_viewer.py' script for real time updates.
import json import dweepy def main(): # replace with your thing Id thingId = "myHome_device_dwitterSwitch0" print "\t\t*************************************************" print "\t\t** Forget Me Not 2014 - Dweet Viewer **" print "\t\t** by vish **" print "\t\t*************************************************" print "Listening to thing " + thingId + "\n" for dweetJSON in dweepy.listen_for_dweets_from( thingId ): if type(dweetJSON) is int: continue dweet = json.loads( dweetJSON ) timeStamp = dweet['created'] content = dweet['content'] for items in content.keys(): print "At " + timeStamp + " \"" + items + "\" updated to \"" + content[items] + "\""; if __name__ == "__main__": main()
The imperfection
Though I showed everything works fine, there is a slight problem. While trying to update device status from dweet,io, if such a device doesn't exist in dweet.io or in any condition where our regular expression fails to match, openhab is returning the whole string. This will cause the switch status to update to invalid states. This won't be a problem if you are running this script regularly. But dweet.io by itself will remove old non active things from it's database. In a case like using this for first time or after a long interval( of days ), this can cause a slight imperfection. But as soon as you sends a command from dweet.io, everything will become prefect again. Anybody have any fix for this, please let me know?
For the ease of replication, I'm sharing my openHAB configurations folder below.
Happy hacking,
vish