Sunday, 2 July 2017

DRONE: Ublox Neo M8N GPS + SP Racing F3 Wiring

I have been toying with adding GPS to my quadcopter and after doing some research I went ahead and purchased the Mini Ublox M8N Neo GPS Receiver from banggood.

The banggood site has a few different options for different flight controllers, but the SP racing version doesn't come with a compass. I have the Eachine version of the SP racing board that didn't come with a compass, barometer or altimeter so I bought the APM version and decided I would replace the connectors to suit my board.

The SP Racing F3 manual says that the connectors are JST-XH but I ordered a few and was disappointed to discover they were the wrong ones for my Eachine version of the SP racing board.
After ordering a few types, I discovered the type on my board are the JST-SH 1.0mm (at least for the 4 pin ports).

I found out the hard way that the little piece of paper that comes with the device is misleading.
I was expecting that I would need to cross TX/RX from the GPS device when connecting to the FC, so I wired based on that and got stuck for a while trying to work out why my device wouldn't connect to my FC. It took me a while to realise that I should have been following the diagram below from the banggood website.


Once I fixed this the device connected immediately and functioned as expected. By default my device was working at 9600 baud.

Tuesday, 20 June 2017

HOME AUTOMATION: Google Home Assistant + Say a simple phrase with a number + openHAB

I've spent a bit of time integrating IR blasters in to my openHAB setup to gain control of my TV and AC. I was able to get simple functions working with the basic "Say a simple phrase" but this wasn't cutting it for something like controlling the volume of the TV so I've written a script that executes a command a given number of times based on the "Say a simple phrase with a number" action in IFTTT. This way I can say "Turn up the TV volume by 10".

 #!/bin/sh  
 # execute the command multiple times based on command line argument  
 for i in $(seq 1 $1); do  
  python /home/openhabian/addons/BlackBeanControl/BlackBeanControl.py -c LG_TV_V$  
 done  

I put my scripts in the /etc/openhab2/scripts folder.
You will need to create a thing/item combination that uses the Exec binding as I've done here.
To test the command is working as expected use the command:

 bash /etc/openhab2/scripts/tv_lounge_volume_down.sh 5  

If everything went well you should see your command executed 5 times. Pair this with my instructions on connecting openHAB with the Google Home Assistant and you should be set.

For reference this is what my applet looks like at the command end.


HOME AUTOMATION: Voice control with Google Home + IFTTT + myopenHAB

Recently I purchased a Google Home Assistant and it's been a lot of fun to play with the native features like shopping lists, reminds and Chromecast control I was really excited to dig in to getting the Home Assistant tied in to my openHAB setup. While the HA does not native support openHAB, it does support IFTTT and now openHAB also has added support for IFTTT through myopenHAB.
I followed the steps below to get my setup working.


Install the "openHAB Cloud Connector" Add-on

I've already covered this in a previous post, make sure myopenHAB is set up correctly and ensure you have exposed the items you want to connect with your HA.

Note: I've seen it take up to 36 hours for settings updated from the cloud connect plugin to appear in the IFTTT actions menu


IFTTT Integration

Register for IFTTT and create a custom applet by selecting the "My Applets" link

IFTTT home page



Create a new applet and click on the blue "+ this" button. This was confusing to me at first because I don't think it looks much like a link/button.

Select "New Applet"

Click the "+ this" button


Filter the available connections by typing "google" and select the "Google Assistant" service.
There are a number of options to choose from with the Google Assistant service, the simplest applet would use the "Say a simple phrase" function.



It's important to think about the various ways you might want to say the command you wish to execute. I've had to change a number of my applets because what I thought was natural when making the applet didn't roll off the tongue when I was sitting on the couch.


Next thing to do is to set the "that" part of IFTTT by clicking the "+ that" button and filtering the services for openHAB. Once the openHAB service is selected there is only one action, so no place to go wrong here.



Now select the item that was exposed through the openhab Cloud Connector Add-on. Once again, if your items aren't showing up you may need to give it more time to be updated. I've seen it take up t 36 hours.


That's it! Finish off the applet creation, give it a few seconds and test it out.

Sunday, 4 June 2017

HOME AUTOMATION: Using the Black Bean RM Mini 3 with openHAB

While there are a number of options out there for controlling infrared appliances like your TV and Air conditioner from your smartphone, none have come in at the price point of the Broadlink Black Bean RM Mini 3. I purchased 3 of the units from gearbest on flash sale for 12.89USD each with plans to use them only with the Broadlink app.

The app got old pretty quick so I started to dig in to openHAB integration. While there isn't an official openHAB binding for the devices there are a few python libraries out there for controlling the black bean. Combine those python scripts with the Exec binding and we can roll our own openHAB solution.


Requirements



Python Library Setup

Go ahead and configure the RM Mini devices per the Broadlink instructions, then set a static IP on your router for each of the devices. We need to do this because the python control script reference the device by IP address. 

Install the python-broadlink library and test the basic functions to ensure the library is working. 
 cd ~/addons/  
 git clone https://github.com/mjg59/python-broadlink.git  
 cd python-broadlink  
 python setup.py build  
 python setup.py install  

Test the installation by running python in the command line and testing a few of the functions in the readme:
 python  
 >>> import broadlink  
 >>> print broadlink.discover(timeout=5)  
 [<broadlink.rm instance at 0x7661XXXX>, <broadlink.rm instance at 0x7661XXXX>, <broadlink.rm instance at 0x7661XXXX>]  
 >>> quit()  

The above confirms that the library found 3 devices on my network.


Now that we have confirmed the python-broadlink library is working, install the blackbeancontrol library:
 cd ~/addons/  
 git clone https://github.com/davorf/BlackBeanControl  
 cd BlackBeanControl  

Test the library is working as expected by first configuring a default unit in the BlackBeanControl.ini and then attempting to learn a command. If the command argument name exists then it will be executed by the device, otherwise it will put the device in to the leaning state and wait to lean the command and save it for future use:
 python BlackBeanControl.py -c LG_TV_Vol_Down

If everything went to plan you should have seen the device go in to learning mode, learn the command, then if running the same command again you should have seen the command executed.
Next step is to pair this python script with the exec binding to enable control from openHAB.


openHAB Setup

Depending on how you would like to control your RM Mini from openHAB there are a few ways to configure your items and sitemap. I've previously written up a few examples on this topic.

Typically I want my IR devices to function like a push button remote so I use items and rules to create my buttons (as opposed to things and items with the exec binding).

Item
String TV_GF_Power "TV Power"

Rules
 rule "LG TV Power"  
 when  
     Item TV_GF_Power received update  
 then  
     executeCommandLine("python /home/openhabian/addons/BlackBeanControl/BlackBeanControl.py -c LG_TV_Power -d Lounge", 1000)  
 end  

Sitemap
Switch item=TV_GF_Power mappings=[OFF="Power"]  

Friday, 2 June 2017

HOME AUTOMATION: openHAB and myopenhab - Accessing your openHAB installation from the web

I've been thinking about the best way to access my openHAB installation from outside my network for a little while, but I've always been worried about the safety of exposing my network to the world so I never did it. Luckily though the folks at openHAB have created a free way to access your openHAB installation via the web without having to deal with port forwarding, firewalls and VPNs, This service is called myopenHAB.

My main reasons for enabling this feature is for integration with cloud services like IFTTT, which I am using for integration with the Google Home Assistant. I'll share more on that topic in another post.


Plugin Installation

Log in to your local openHAB installation and navigate to the PaperUI interfact, From here navigate to the Add-ons tab and search for "openHAB Cloud Connector" in the MISC page of add-ons.


Installation takes while so be patient. It took around 20 minutes on my Raspberry Pi 3.
While we are waiting for the add-on to install we will get our myopenHAB account setup and ready for action.

myopenHAB Account Setup

Navigate to the myopenHAB website and then make your way to the registration page. Create your account and be sure to verify your account once created. You will be sent a verification email to the registered email address, follow the links to confirm your account. If you don't do this you may end up stuck with your device only ever showing "Offline" even if you have everything configured correctly.
Once you have setup you account check back in to your openHAB add-on installation. Once it is complete we need to grab a couple of auto-generated strings to link our openHAB add-on installation to the cloud service. We need to grab the UUID and Secret that were generated by the openHAB Cloud add-in and add them to our account:


Use the following commands to view your UUID and Secret from the command line:
 nano /var/lib/openhab2/uuid  
 nano /var/lib/openhab2/openhabcloud/secret  

Once these settings have been added to myopenHAB if everything was done right you should see your device come online. If not, there are a few things that could have gone wrong that I'll cover in the troubleshooting section below.


Add-on Configuration

With the add-on installed the last thing we need to do is enable remote access of our device and exposing items to 3rd party services like IFTTT
openHAB Cloud add-on configuration


Add the items you would like to be exposed to external services like IFTTT here by selecting the items from the drop down box and save your configuration.

If it has all worked you should now be able to navigate to the myopenHAB page, login and then follow the links to your openHAB dashboard.

myopenHAB logged in


Troubleshooting

I ran in to a few issues when connecting my openHAB installation to the myopenHAB cloud service:

  1. I had missed a character off the secret. 
  2. I was running an old version of oracle java. I fixed this by simply doing an apt-get update then apt-get upgrade followed by a reboot. There is also another issue with open-jdk that is described in this post

HOME AUTOMATION: openHAB exec2 binding

Since I started with openHAB I've been annoyed that it's not super simple to execute a script with a button press. There is an openHAB2 binding called the "Exec" binding that allows us to do exactly this, but the use of it is a mess in my opinion. The official documentation doesn't really give many good examples of how it can be used and trying to find a good example in the forums is hard because there is a openHAB1 and openHAB2 version of the binding that are used differently.

The first useful bit of information I came across was github repo XML definition of the Thing type.
This gives an explanation of what the various parameters and what they do.

Another bit of info that may be useful is how the different elements required for the Exec binding to work tie together:
    One Thing tied to a command we want to run
          Multiple Items for each Thing (input, output, exit, run, lastexecution)
              A sitemap that displays any Items we want to interact with

Armed with this info lets take a look at a few examples of using the Exec binding:


Example 1

This example executes a python command when the defined button changes states. It does not resend the command if the button is in the OFF state and it is turned OFF again.

Thing:

 Thing exec:command:TV_GF_Vol_Up "TV" [ command="python /home/openhabian/addons/BlackBeanControl/BlackBeanControl.py -c LG_TV_Vol_Up -d Lounge", timeout=15, interval=0, autorun=true ]  
 Thing exec:command:TV_GF_Vol_Down "TV" [ command="python /home/openhabian/addons/BlackBeanControl/BlackBeanControl.py -c LG_TV_Vol_Down -d Lounge", timeout=15, interval=0, autorun=true ]  

Item:

 String TV_GF_OnOff "TV" { channel="exec:command:TV_GF_OnOff:input" }  
 String TV_GF_OnOff_Output "TV" { channel="exec:command:TV_GF_OnOff:output" }  
 Switch TV_GF_OnOff_Running "TV" { channel="exec:command:TV_GF_OnOff:run" }  
 Number TV_GF_OnOff_ExitValue "TV" { channel="exec:command:TV_GF_OnOff:exit" }  
 DateTime TV_GF_OnOff_LastExec "TV" { channel="exec:command:TV_GF_OnOff:lastexecution" }  

 String TV_GF_Vol_Up "TV" { channel="exec:command:TV_GF_Vol_Up:input"}  
 String TV_GF_Vol_Up_Output "TV" { channel="exec:command:TV_GF_Vol_Up:output"}  
 Switch TV_GF_Vol_Up_Running "TV" { channel="exec:command:TV_GF_Vol_Up:run"}  
 Number TV_GF_Vol_Up_ExitValue "TV" { channel="exec:command:TV_GF_Vol_Up:exit" }  
 DateTime TV_GF_Vol_Up_LastExec "TV" { channel="exec:command:TV_GF_Vol_Up:lastexecution" }  

 String TV_GF_Vol_Down "TV" { channel="exec:command:TV_GF_Vol_Down:input"}  
 String TV_GF_Vol_Down_Output "TV" { channel="exec:command:TV_GF_Vol_Down:output"}  
 Switch TV_GF_Vol_Down_Running "TV" { channel="exec:command:TV_GF_Vol_Down:run"}  
 Number TV_GF_Vol_Down_ExitValue "TV" { channel="exec:command:TV_GF_Vol_Down:exit" }  
 DateTime TV_GF_Vol_Down_LastExec "TV" { channel="exec:command:TV_GF_Vol_Down:lastexecution" }  

Sitemap:

 Switch item=TV_GF_Vol_Up label="Volume Up" mappings=[OFF="+", ON="+"]  
 Switch item=TV_GF_Vol_Down label="Volume Down" mappings=[OFF="-", ON="-"]  



Example 2

In this example we will create a single button that runs a python script each time the button is pressed.

Things:

Not needed as we will be executing the commands from within the rules we create.

Items:

This example creates a virtual item that is not tied to a Thing.
 String TV_GF_Power "TV Power"

Rules:

 rule "LG TV Power"  
 when  
     Item TV_GF_Power received update  
 then  
     executeCommandLine("python /home/openhabian/addons/BlackBeanControl/BlackBeanControl.py -c LG_TV_Power -d Lounge", 1000)  
 end  

Sitemaps:

 Switch item=TV_GF_Power mappings=[OFF="Power"]  


I've also found the following forum examples useful in developing my Exec scripts and functions.
Online example 1Online example 2

Sunday, 16 April 2017

HOME AUTOMATION: Teptron Move control from OpenHAB

I've previously explored how to control the bluetooth version of Teptron Move from a linux PC (or Raspberry Pi) with the built in Bluetooth adapter. While it's interesting to be able to do this from the Linux commands line it's not particularly practical for use in a home automation system. In this post

I'll explain how to integrate those controls with openHAB for more practical use.


OpenHAB Binding Configuration

In order to run a linux script from within openHAB we need to first install the "Exec Binding".

Exec Binding Installation


There are a few examples on how to configure the exec binding but none of the examples worked for me. I ended up following this post to get the right combination of Things/Items/Sitemaps working to give the following result:


I'll go in to some more detail below on how I configured my Things/Items/Sitemap to get the units working.


There are a few peculiarities in working with the Bluetooth version of the Teptron Move with the command line functions. I've noticed the following inconsistencies:

  • Sometimes the device does not respond and the command reports an error
  • Other times the device responds and accepts the commands but does not move
  • The time between receiving the accepted response and the device moving varies from immediate to ~5 seconds

I've tried a number of workarounds for this but so far I've had the most success with simply just retrying the command multiple times, but this has the issue of pausing the unit motion when the second/third command is resent. I'm not ready to give up on this one just yet, but I'm fast running out of ideas.


Move Control Script

Create a new script in the in the openHAB scripts folder:
 sudo nano /etc/openhab/scripts/teptron_move_control.sh  

Copy the following lines in to the file and save the file:
 #!/bin/sh  
 RESPONSE=""  
   
 # execute the command multiple times  
 #for i in 1 2 3  
 for i in 1  
 do  
  RESPONSE="$(/home/openhabian/development/csrmesh/bin/csrmesh-cli move --pin 8888 --dest 43:c5:5b:04:00:06 --objid $1 --position $2)"  
  echo "Response: ${RESPONSE}"  
  sleep 1  
 done  
   

Now make the script executable with the command:
 chmod +x /etc/openhab/scripts/teptron_move_command.sh  

This script accepts two input arguments:
  1. The move unit we want to move
  2. The position to be moved to (0 to 255)
Test the command is working as expected, as an example use the command:
 /etc/openhab/scripts/teptron_move_command.sh 2 255  

This will command unit 2 to move to the fully opened position.

Things Configuration

Create a new .things file for the blinds:
 sudo nano /etc/openhab/things/blinds.things  

Add the following lines:
 Thing exec:command:Blinds_GF_Lounge_North "Blinds" [ command="bash /etc/openhab2/scripts/teptron_move_control.sh 1 %2$s", interval=0, autorun=true ]  
 Thing exec:command:Blinds_GF_Lounge_South "Blinds" [ command="bash /etc/openhab2/scripts/teptron_move_control.sh 2 %2$s", interval=0, autorun=true ]  

The important part of the command here is the  name of the Thing, in this case "Blinds_GF_Lounge_North" and "Blinds_GF_Lounge_South". These will need to match the name of the items we will create next.


Items Configuration

Next we must define items that will take the input from the sitemap and send it as a parameter to the exec binding and execute the script:

Create a new .items file:
 sudo nano /etc/openhab/items/blinds.items  

Add the following items:
 String Blinds_GF_Lounge_North_Command "Blinds" { channel="exec:command:Blinds_GF_Lounge_North:input", autoupdate="false" }  
 String Blinds_GF_Lounge_South_Command "Blinds" { channel="exec:command:Blinds_GF_Lounge_South:input", autoupdate="false" }  

Ensure the names of the defined items match the names of the things we defined previously.

Sitemap Configuration

We need to define a couple of switches with custom mapping to command the move units to the "Open" and "Close" positions:
 sudo nano /etc/openhab/sitemaps/default.sitemap  

Add the following lines where applicable:
 Switch item=Blinds_GF_Lounge_North_Command label="North Blinds" mappings=["255"="Open", "0"="Close"]  
 Switch item=Blinds_GF_Lounge_South_Command label="South Blinds" mappings=["255"="Open", "0"="Close"]  

If everything was working properly, pressing the buttons on the sitemap should command the move units to the open and closed positions.



Technically it should be possible to use a slider here to set the blind position, but I'm yet to work out how to do it.

Remember the following command is great to be able to debug any openHAB issues:
 tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log   

Saturday, 8 April 2017

ROBOTICS: Android App for Bluetooth Remote Control Robots

A while back I was tinkering with the MIT App Inventor project and wrote a little android app that would connect to a bluetooth device and send ASCII commands via a bluetooth serial connection. It turned out to be a really handy way to control my robots over bluetooth so I shared it and made a short youtube video showing how to use it. It's my most successful youtube video to date and I still get people asking for the codes.

Since then I taught myself to code for Android and rewrote the app with plans of releasing it on the app store, but never found the motivation to take it all the way. It's been a couple of years since I put any time in to active development of the app, so in the spirit of sharing the codes I've decided to upload my project to Github for anyone who is interested. To make it easier for use I've also included a compiled apk.


The App

Basically, the app connects to a bluetooth device and creates a serial connection and streams ASCII characters to and from the connected device. Typically the way I use this by assigning specific ASCII characters to buttons, then when coding my android project I interpret the ASCII characters and react based on the command.
Vertical Layout

Landscape Layout

Pair with Bluetooth device

Preferences and Help menu


The app also allows you to change the button labels as well as the characters being sent for each button.

The app requires a minimum of Android 4.0 and has been written to support a number of screen resolutions and configurations.

Features

Inverted button layout switches the position of the direction keys and action keys:





Receive commands from your robot with the Feedback Group scale scale bars. Commands need to be sent over serial in the format "SB1=XX" where XX is a number from 0 to 100.






Known Bugs

Pairing a new bluetooth device is clunky. I've had the most success in performing the pairing from within the settings menu first, then going back in to the app and connecting to the bluetooth device.

Monday, 3 April 2017

HOME AUTOMATION: ELK/NESS M1 Home Alarm Controller with OpenHAB over Serial

When I installed the NESS M1 home automation controller and home alarm I had plans of integrating it in to my overall setup. I purchased an M1XEP with plans of exposing the alarm control to the network but ran in to setup issues that I was never able to resolve.

When I installed my openHAB controller I looked for a binding for the NESS/ELK but was not able to find one. There are some active conversations on the forums but no available bindings, so I decided to try my hand at getting something going. I'm using a USB to Serial adaptor plugged from the serial port of my home alarm directly in to my Raspberry Pi running openHAB2.


OpenHAB Serial Binding

First thing to do is to install and configure the serial binding. I have already covered this in an older post.



Reading Zone States

The easiest thing to start with is to read the zone state from the NESS alarm controller. With serial configured this is simply a matter of reading the serial input data and interpreting the commands based on the well documented serial protocol for the controller.


Here are the files I have used to mirror the state of the motion sensors on my home alarm by reading the zone states:


alarm.items
 Switch AlarmUpdate  "Alarm Update"  { serial="/dev/ttyUSB0@115200" }  
 String AlarmMessage "Alarm Message" { serial="/dev/ttyUSB0@115200" }  
 Group gAlarm_PIR
 Contact Alarm_PIR_Zone1                                                (gAlarm_PIR)
 Contact Alarm_PIR_Zone2                                                (gAlarm_PIR)
 Contact Alarm_PIR_FF_MasterBedroom "Master Bedroom Motion Sensor [%s]" (gAlarm_PIR)
 Contact Alarm_PIR_Zone4                                                (gAlarm_PIR)
 Contact Alarm_PIR_Nursery "Nursery Motion Sensor [%s]"                 (gAlarm_PIR)
 Contact Alarm_PIR_FF_Stairs "Stairs Motion Sensor [%s]"                (gAlarm_PIR)
 Contact Alarm_PIR_GF_Lounge "Lounge Motion Sensor [%s]"                (gAlarm_PIR)
 Contact Alarm_PIR_GF_Stairs "Basement Stairs Motion Sensor [%s]"       (gAlarm_PIR)

init.rules
 rule "Init"  
 when  
     System started  
 then  
     // let openHAB settle and give other rules the chance to fire  
     createTimer(now.plusSeconds(180)) [|  
         gAlarm_PIR?.members.forEach[g |  
             g.postUpdate(CLOSED)  
         ]  
 end  


alarm.rules
 import java.lang.Integer.*  
 val AlarmMemoryMessage = "AM"  
 val ZoneChangedMessage = "ZC"  
 val NetworkAdapterPing = "XK"  
 val ZoneStatusTable_NormalUnconfigured = "0"  
 val ZoneStatusTable_NormalOpen = "1"  
 val ZoneStatusTable_NormalEOL = "2"  
 val ZoneStatusTable_NormalShort = "3"  
 val ZoneStatusTable_TroubleOpen = "5"  
 val ZoneStatusTable_TroubleEOL = "6"  
 val ZoneStatusTable_TroubleShort = "7"  
 val ZoneStatusTable_ViolatedOpen = "9"  
 val ZoneStatusTable_ViolatedEOL = "A"  
 val ZoneStatusTable_ViolatedShort = "B"  
 val ZoneStatusTable_BypassedOpen = "D"  
 val ZoneStatusTable_BypassedEOL = "E"  
 val ZoneStatusTable_BypassedShort = "F"  
 rule "Interpret Alarm Command"  
 when  
     Item AlarmMessage received update  
 then  
     var lines = AlarmMessage.state.toString.split('\n')  
     lines.forEach[line |  
         if(line.length > 6) {  
             var messageLength = line.substring(0,2)  
             var commandType = line.substring(2,4)  
             var checksum = line.substring(line.length-3, line.length-1)  
             //logInfo("alarm", "Message:" + line + " Len:" + messageLength + " Command:" + commandType)  
             if(commandType == AlarmMemoryMessage) {  
                 var alarmMemoryAreas = line.substring(4, 12)  
             }  
             else if(commandType == ZoneChangedMessage) {  
                 else if(commandType == ZoneChangedMessage) {  
                 var int zoneNumber = Integer::parseInt(line.substring(4,7))  
                 var zoneStatus = line.substring(7,8)  
                 //logInfo("alarm", "Zone:" + zoneNumber + " Status:" + zoneStatus)  
                 //logInfo("alarm", "gAlarm_PIR:" + gAlarm_PIR.members.filter(g | g.name == "Alarm_PIR_GF_Lounge").toString)  
                 var zone = Alarm_PIR_GF_Lounge  
                 var state = CLOSED  
                 // case statement setting the zone item from the message received  
                 switch zoneNumber {  
                     case zoneNumber == 1 : zone = Alarm_PIR_Zone1  
                     case zoneNumber == 2 : zone = Alarm_PIR_Zone2  
                     case zoneNumber == 3 : zone = Alarm_PIR_FF_MasterBedroom  
                     case zoneNumber == 4 : zone = Alarm_PIR_Zone4  
                     case zoneNumber == 5 : zone = Alarm_PIR_FF_Nursery  
                     case zoneNumber == 6 : zone = Alarm_PIR_FF_Stairs  
                     case zoneNumber == 7 : zone = Alarm_PIR_GF_Lounge  
                     case zoneNumber == 8 : zone = Alarm_PIR_GF_Stairs  
                 }  
                 // set the state of the zone from the message received  
                 if(zoneStatus == ZoneStatusTable_NormalUnconfigured) {  
                     state = CLOSED  
                 }  
                 else if(zoneStatus == ZoneStatusTable_NormalOpen) {  
                     state = CLOSED  
                 }  
                 else if(zoneStatus == ZoneStatusTable_NormalEOL) {  
                     state = CLOSED  
                 }  
                 else if(zoneStatus == ZoneStatusTable_TroubleOpen) {  
                     state = OPEN  
                 }  
                 else if(zoneStatus == ZoneStatusTable_TroubleEOL) {  
                     state = OPEN  
                 }  
                 else if(zoneStatus == ZoneStatusTable_TroubleShort) {  
                     state = OPEN  
                 }  
                 else if(zoneStatus == ZoneStatusTable_ViolatedOpen) {\  
                     state = OPEN  
                 }  
                 else if(zoneStatus == ZoneStatusTable_ViolatedEOL) {  
                     state = OPEN  
                 }  
                 else if(zoneStatus == ZoneStatusTable_ViolatedShort) {  
                     state = OPEN  
                 }  
                 else {  
                     state = CLOSED  
                 }  
                 postUpdate(zone, state)  
             }  
             else if(commandType == NetworkAdapterPing) {  
             }  
             else {  
                 //logInfo("alarm", "No code match")  
             }  
         }  
     ]  
 end  


Add the following lines to your sitemap:
 Frame label="Ground Floor Stairs" {  
   Text item=Alarm_PIR_GF_Stairs icon="motion"  
 }  


Testing

View the sitemap and we should see the motion sensor updates coming through



Test the sitemap is working as expected with the command:
 tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log  

If everything is working as expected you should see updates coming through:
 ==> /var/log/openhab2/events.log <==  
 2017-04-03 13:44:24.818 [GroupItemStateChangedEvent] - gAlarm_PIR changed from CLOSED to UNDEF through Alarm_PIR_GF_Lounge  
 2017-04-03 13:44:28.191 [ItemStateChangedEvent   ] - AlarmMessage changed from 0AZC007900C2  
 1EAS000000000111111100000000000F  
 0CAM000000007F  
  to 0AZC007200C9  
 1EAS000000001111111100000000000E  
 0CAM000000007F  
 2017-04-03 13:46:26.579 [ItemStateChangedEvent   ] - Alarm_PIR_GF_Lounge changed from OPEN to CLOSED  


Update

There is a bug in openHAB2 that stops icon updates on the sitemap as the states are updated. It's documented here. The solution is to restart the OpenHAB server.

Monday, 27 March 2017

HOME AUTOMATION: OpenHAB2 Serial Binding on Raspberry Pi

I have always wanted to enable my home automation setup with per-room presence detection. With this in mind I purchased and installed an ELK/NESS home alarm with automation capability.

I haven't been able to find any decent OpenHAB binding for the alarm, and after recently giving up on getting my M1XEP serial to network box for my alarm working I've decided to try my hand at rolling my own serial solution. Here I'll discuss how I got the serial configuration up and running.

Installation

Install the binding from the configuration GUI


I'm using a USB to Serial adapter, but other serial devices should also show up as serial devices if they have been recognised by the kernel. You can check this with the command:
 dmesg  

Or to view messages relating to the serial port configuration use the command:
 dmesg | grep tty
This should tell you what port was assigned to your USB to Serial adapter, in my case ttyUSB0

Check which users have access to the serial port with the command:
 ll /dev/ttyUSB0  

Output should look something like:
 crw-rw---- 1 root dialout 188, 0 Mar 27 10:03 /dev/ttyUSB0  

You may need to add the default user to the dialout group:
 sudo adduser openhabian dialout  


It's a good time to check the serial connection to make sure it's working as expected. You can use the GNU screen command to view the serial port from the command line:
 screen /dev/ttyUSB0 115200  

The screen command won't exit with the typical commands like CTRL-X or CRTL-Z, to exit the screen command enter 'CTRL-a' then press '\', then hit 'Y' to exit the screen.

Now that we have the binding installed and confirmed the serial port is working as expected we can continue with the OpenHAB setup

OpenHAB2 Configuration 

I created and 'alarm.items' file to store alarm related configuration info:
 Switch AlarmUpdate "Alarm Update" { serial="/dev/ttyUSB0@115200" }  
 String AlarmMessage "Alarm Message" { serial="/dev/ttyUSB0@115200" }  

and a 'alarm.rules' file with the following:
 ule "Interpret Alarm Command"  
 when  
     Item AlarmMessage received update  
 then  
     logDebug("alarm", "Alarm message updated")  
 end  
   

Check everything is working with the command:
 tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log  

And you should see log messages like the following:
 2017-03-27 12:08:27.946 [ItemStateChangedEvent   ] - AlarmMessage changed from 0AZC007200C9  
 1EAS000000001111111100000000000E  
 0CAM000000007F  
  to 16XK2708212270117011006C  

Now that the serial binding is working we can move on to interpreting the data!

Monday, 13 March 2017

HOME AUTOMATION: MiLight/LimitlessLED/Easybulb OpenHAB Configuration

I've been thinking about wireless lighting control for a while now and tested out the space with the MiLight wireless controlled light bulbs.

My initial use case was focused around bulb dimming and while I realise I could have achieved this with a simple dimmer switch costing around 20 bucks from Bunnings, the cost of hiring an Electrician to come to wire a single switch would easily run be over $100. I know some people take to doing this themselves but you need to remember this is illegal in Australia.


The Research

The majority of my house is fitted with modern downlights that use the GU10 socket. This is a pretty common fitting type so the number of options is quite large. Here are a few of the options I considered:
  • MiLight/LimitlessLED/Easybulb - 15USD and around 10USD for a bridge
  • Phillips Hue - 4 wireless bulbs and a bridge at $399 or $89 per bulb
  • LiFX GU10 WiFi bulbs - 4 wireless downlights at $120 or $40 per bulb

As my main use case was brightness control I went for the MiLight bulbs that I bought from the LimitlessLED website.

While the cheapest, the MiLight bulbs have downside of no publishing their state when the lights are turned on.

This may not sound like a big deal, but after having used the bulbs in my home automation setup I can say that this limitation is quite annoying as there is no easy way to manage the state of the bulbs in your home automation setup. Unless you can see the lights left on you don't really know what state they are in, so the only useful feature when you are away is the blanket "All Off". It's not the worst but it's definitely not ideal.

The MiLight bulbs are not Wi-Fi, they use the a 2.4GHz wireless protocol that requires a Wi-Fi bridge to connect it to your home network. There are a few limitations with these Wi-Fi bridges and some folks have developed their own bridges that overcome these limitations, but I'm going to be sticking with the standard as the OpenHAB MiLight binding has been designed to work with this device.


Setting Up Your MiLight Bridge

Follow the MiLight instructions to set up your bridge to control the bulb groups in your house using the Android or iOS apps. Here are a few tips:
  • If you are using the Android app I've noticed it works much better on an old phone in airplane mode. The app experience on Android Nougat is horrible
  • Make sure you assign a static IP for your Wi-Fi bridge on your router
  • Once you have taught the bridge your light groups make a note so your don't forget which group was associated with each channel of the bridge
  • Each bridge can only control 4 groups of WW/CW and 4 groups of RGB/W bulbs
  • Each bridge has an "All Off" channel. Think about how many bridges you might want to make this function useful. In my setup I have 1 bridge per floor.


MiLight Wi-Fi Bridge with OpenHAB

I follow these steps to get my MiLight bulbs set up with my OpenHAB installation:
  • Navigate to the PaperUI page of your OpenHAB installation to configure you devices
PaperUI Configuration

  • Install the MiLight add-on 
MiLight Add-on

  • Navigate to the inbox and search for new devices
  • At this point you will see a number of devices listed under the MiLight services in the inbox 
    • 4 channels of WW/CW
    • 4 channels of RGB/W
    • 1 channel of WW/CW all off
    • 1 channel of RGB/W all off 
MiLight Bridge Channel
Now we need to add the devices be previously taught the Wi-Fi bridge in the setup step. This is done by clicking the check icon on the device we want to add, then follow the steps to add the device.

I followed the advice in the OpenHAB instructions and set the system to enable "Item Linking" to make the addition of Things easier.
Item Linking configuration


Once you have added the devices you plan to use the next thing to do is check they are working as expected via the configuration panel.

Testing Things in configuration panel


If your device's aren't working at this point you'll need to go back to the bridge setup step and make sure everything is working there. 


OpenHAB .items Configuration

With the devices now added as Things in your OpenHAB installation we need to add the bulbs as a .items file to get them running with our user interface.
Navigate to the items folder of the OpenHAB installation folder and create a new .items file:
 cd /etc/openhab2/items/  
 sudo nano lights.items  

Here we will add the devices we wish to use with our user interface. The MiLight binding gives some examples of how to configure the devices, but for quick reference this is how it's done.

  • Get the unique ID of the device you want to add from the Things banner of the Configuration panel. You need to click the Thing and view the available channels
Click the Thing you want to add to the .items file

Copy the channel you want to use

  • Add the ID to the item and give it a unique name. Here is an example:
 Switch Light_GF_Laundry_OnOff        {channel="milight:whiteLed:ACCF23508A5A:1:ledbrightness"}
 Switch Light_GF_Laundry_NightMode    {channel="milight:whiteLed:ACCF23508A5A:1:lednightmode"}
 Dimmer Light_GF_Laundry_Temperature  {channel="milight:whiteLed:ACCF23508A5A:1:ledtemperature"}
 Dimmer Light_GF_Laundry_Brightness   {channel="milight:whiteLed:ACCF23508A5A:1:ledbrightness"}

  • Repeat this process for all the devices you want to add, then move on to the sitemap
Note: the MiLight binding does not expose and on/off state for the bulbs, rather you need to define a switch for the brightness to control the on/off and a dimmer for the brightness adjustment both using the same channel



OpenHAB Sitemap Configuration

With the devices added to your items file now we can add them to your sitemap. This is the file that outlays the user interface for user interaction with the OpenHAB setup.

Navigate to the OpenHAB installation directory and then to the sitemap directory. If you are coming from a fresh installation you probably won't have anything in here other than a readme.txt file so you will also need to create a default.sitemap file.
 cd /etc/openhab2/sitemaps/  
 sudo nano default.sitemap  

We will start with a basic working sitemap to test the functions of the devices we just added.
 sitemap default label="Test Layout" {  
     Frame label="Laundry" {  
         Switch item=Light_GF_Laundry_OnOff label="On/Off"  
         Slider item=Light_GF_Laundry_Brightness label="Brightness"  
         Switch item=Light_GF_Laundry_NightMode label="Night Mode"  
     }  
 }  

And here is the output:

Sunday, 12 March 2017

HOME AUTOMATION: Teptron move control from Linux

UPDATE: this method does not appear to work with the latest Teptron Move firmware. The developer of csrmesh is looking in to the problem but there is no current solution for controlling the Teptron Move from anything other than the app.

My biggest pain point with the Teptron Move automated blinds device at the moment is the lack of app updates and any functionality other than just simply commanding the blinds from my phone. Because of this I have basically removed the devices from my blinds. You can read more about my issues with the device in an old post.

I recently started to think about how I could potentially expose the CSR bluetooth mesh that the Move uses to my wireless network. This would allow me to get the automation I'm looking for out of my OpenHAB controller. I came across a project on GitHub claiming to have reverse engineered the CSRMesh protocol for the Teptron Move and decided to give it a shot.

I did a little more digging and found some posts on the domoticz forums talking about how to integrate the linux script with the domoticz home automation solution to automated the Move units, so I decided to investigate the possibility of integrating the devices with my OpenHAB system.

Installing The Script

Git is not installed on the Ubuntu image for the Pine64. Install with the following commands:
 apt-get install git  

If it's the first time using git on your machine you need to:
  • Generate an rsa key 
  • Follow the Github instructions to add the rsa key to you github account
I also found this article useful to debug my problem.

If you don't follow these steps you will get the error:
 Permission denied (publickey).  
 fatal: Could not read from remote repository.  

Now create a new directory clone the csrmesh repository into that directory:
 mkdir Downloads  
 cd Downloads  
 git clone git@github.com:nkaminski/csrmesh.git  

Build and install the project:
 python setup.py build  
 sudo python setup.py install  

The script also needs the bluez software installed:
 sudo apt-get installed bluez  

If you are trouble getting your bluetooth running on an Raspberry Pi 3 with OpenHABian I have explained how I did it in an older post.


Bluetooth Setup

If your device doesn't support Bluetooth natively you will need to do some work with a USB Bluetooth adapter to get connected  to the Move units.

Insert the USB adapter in to the Pine64 and run the following command to check the device was recognised:
 dmesg  

 If the device was recognised by the linux kernel you should see an output something like this
 [449253.083342] input: Logitech Logitech BT Mini-Receiver as /devices/soc.0/1c1b000.ohci1-controller/usb4/4-1/4-1.2/4-1.2:1.0/input/input5  
 [449253.083769] hid-generic 0003:046D:C71B.0001: input: USB HID v1.11 Keyboard [Logitech Logitech BT Mini-Receiver] on usb-sunxi-ohci-1.2/input0  
 [449253.159418] usb 4-1.3: new full-speed USB device number 4 using sunxi-ohci  
 [449253.303636] input: Logitech Logitech BT Mini-Receiver as /devices/soc.0/1c1b000.ohci1-controller/usb4/4-1/4-1.3/4-1.3:1.0/input/input6  
 [449253.304398] hid-generic 0003:046D:C71C.0002: input,hiddev0: USB HID v1.11 Mouse [Logitech Logitech BT Mini-Receiver] on usb-sunxi-ohci-1.3/input0  
 [449253.581549] usb 4-1.1: new full-speed USB device number 5 using sunxi-ohci  
 [449253.750067] usbcore: registered new interface driver btusb  
 [449253.875233] Bluetooth: BNEP (Ethernet Emulation) ver 1.3  
 [449253.875245] Bluetooth: BNEP filters: protocol multicast  
 [449253.875282] Bluetooth: BNEP socket layer initialized  
 [470188.654809] sunxi-bt bt.28: set block: 0  
 [470188.654971] sunxi-bt bt.28: check bluetooth io_regulator voltage: 1800000  
 [470193.118153] sunxi-bt bt.28: block state already is 0  

We can now run one of the bluez commands to check if the bluetooth adapter was recognised and is available for us:
 hcitool dev  

If everything is in order with your setup you should see an output like the one below and you can continue on to the next section:
 ubuntu@pine64:~$ hcitool dev  
 Devices:  
     hci0  00:1F:20:51:CC:AA  

If you don't see any devices listed then you will have to do some work to enable the Bluetooth adapter. You should have a utility installed called rfkill that is used to enable and disable wireless devices. If it's not installed you can install it with the command:
 sudo apt-get install rfkill  

Run the following command to see your connection status:
 ubuntu@pine64:~$ rfkill list  
 0: sunxi-bt: Bluetooth  
     Soft blocked: Yes  
     Hard blocked: no  
 1: phy0: Wireless LAN  
     Soft blocked: no  
     Hard blocked: no  
 2: phy1: Wireless LAN  
     Soft blocked: no  
     Hard blocked: no  
 3: hci0: Bluetooth  
     Soft blocked: Yes  
     Hard blocked: no  

The following command will remove the soft block on the Bluetooth adapter:
 sudo rfkill unblock bluetooth  

Now run the "rfkill list" command again and you should see the soft block has been removed.

Success! The Bluetooth output has been enabled and we should be able to see available Bluetooth devices if we run the hcitool dev command again. We can confirm the device is working by scanning for available Bluetooth devices:
 hcitool scan  

The above command will scan for regular Bluetooth devices but will not be able to to see Low Energy (BLE) devices. In order to scan the available BLE devices we need to run the command:
 sudo hcitool lescan


Testing The Script

Typically we would do a hcitool scan to get a devices MAC address, but the csrmesh network doesn't allow us to do this (at least in my setup). I've connected to the CSRMesh network from my Windows laptop and used that connection to gather the device address to include in the script.
The address I grabbed from my PC was: BTHLE\Dev_43c55b040006

The Github documentation tells us to format the command in the following way:
 ./bin/csrmesh-cli move --pin 8888 --dest 43:c5:5b:04:00:06 --objid 1 --position 255  

You need to make sure you are running this command from within the csrmesh folder that was cloned earlier. If everything worked you should see your Move unit move to the set position and the output:
 Running: gatttool -b 43:c5:5b:04:00:06 --char-write-req -a 0x0021 -n 0fe2bd00809bb9d83b76b48585673a77b747ff  
 Characteristic value was written successfully  

Note: The only gotcha here is the pin for the Move units. Here you will need to remember the password you set to the CSRMesh network when you first set up your move unit. If like me you have forgotten this, perform a factory reset on the unit by removing the battery, hold down the stop key then re-insert the battery. The notification light on the bottom of the device should be on solid. Keep holding the stop key for at least 5 seconds at which point the device should be reset. In my experience you don't get any feedback that it has performed the reset. With the device having been factory reset you can restart the Android app and enter a new password.

The next step here is to now enable the device for use with OpenHAB.


UPDATE:
I've written a post on how to get this script working with openHAB here