Wednesday, November 09, 2016

my.openhab.org REST API and Amazon Alexa Smart Home Skills

If you have an Amazon Echo with Alexa, and you make your own home automation devices, then you will no doubt want to interface the two together and have a powerful voice controlled home automation system.

Well, if you use OpenHAB then it's easy.

First follow the instructions to add my.openhab.org to your existing working openhab controller -
https://my.openhab.org/docs

Next, create an Alexa Smart Home Skill and link it to your Amazon account with LWA (Login.With.Amazon).
https://developer.amazon.com/edw/home.html#/skills/list

Alexa requires OAuth2.0 authentication with a service to function, but it was easier to link to LWA rather than try to work out the intricacies of my.openhab.org, seeing as I know my credentials anyway.
https://developer.amazon.com/lwa/sp/overview.html

After you have created an account with developer.amazon.com, follow the instructions here:

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/steps-to-create-a-smart-home-skill

In the AWS lambda function.lambda_handler (I used python, but you can use JavaScript or Java too), for the event namespaces below:

    if event['header']['namespace'] == 'Alexa.ConnectedHome.Discovery':
        return handleDiscovery(context, event)

    elif event['header']['namespace'] == 'Alexa.ConnectedHome.Control':
        return handleControl(context, event)

You will write the handleDiscovery and handleControl methods and return the following:

    return { 'header': header,
             'payload': payload
        }

Just define the header as shown in the example step-by-step skill adaptor example on the Amazon developer website and fill in your device details in the payload instead of the examples.

Now, the bit that you actually need to know.
How do you get the device details and states of your home automation devices through my.openhab.org and how do you control those devices?

When you ask Alexa to 'Discover devices', your handleDiscovery method will be called.

To get a list of all OpenHAB devices, make a GET request to :

https://<username:password@my.openhab.org/rest/items

To get just a known devices details do:
https://<username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling

To get just the state of a known device do:
https://<username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling/state

This will return an XML response similar to this:

<items>
<item>
<type>GroupItem</type>
<name>myopenhab</name>
<state>Undefined</state>
<link>https://my.openhab.org/rest/items/myopenhab</link>
</item>
<item>
<type>GroupItem</type>
<name>All</name>
<state>Undefined</state>
<link>https://my.openhab.org/rest/items/All</link>
</item>
<item>
<type>SwitchItem</type>
<name>Light_GF_Corridor_Ceiling</name>
<state>Uninitialized</state>
<link>https://my.openhab.org/rest/items/Light_GF_Corridor_Ceiling</link>
</item>
<item>
<type>NumberItem</type>
<name>Weather_Temperature</name>
<state>10</state>
<link>https://my.openhab.org/rest/items/Weather_Temperature</link>
</item>
</items>

In the handleDiscovery method, find the items like "SwitchItem" in the XML and add them to the payload by name to build your list of devices that Alexa can control using ON/OFF commands.
Just look at the Amazon example code to see what the payload should look like.

Then, when you ask Alexa to turn something on or off, your handleControl method will be called.
This is where you send the ON or OFF to your device in openHAB.

Make a POST request to the device's specific URL:

https://username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling

In the POST body, put the plain text command ON or OFF
Make sure you set the Content-Type header to 'text/plain' or it won't work.


In the URLs, if your my.openhab.org username or password has '@' or '.' characters in it, then be sure to escape them using %40 and %2E respectively, as mentioned in this wiki: 


Or, if you have issues with passing the credentials in the URL, then encode them as base64 and put them in the headers, like so in bold below:

Python example

import base64
post_data = "OFF"
post_header = { 'Content-Type' : 'text/plain' }
req = urllib2.Request(openhab_url, post_data, post_header)
base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
req.add_header("Authorization", "Basic %s" % base64string)
response = urllib2.urlopen(req)

That's it.

my.openhab.org REST API and Amazon Alexa Smart Home Skills

If you have an Amazon Echo with Alexa, and you make your own home automation devices, then you will no doubt want to interface the two together and have a powerful voice controlled home automation system.

Well, if you use OpenHAB then it's easy.

First follow the instructions to add my.openhab.org to your existing working openhab controller -
https://my.openhab.org/docs

Next, create an Alexa Smart Home Skill and link it to your Amazon account with LWA (Login.With.Amazon).
https://developer.amazon.com
Alexa requires OAuth2.0 authentication with a service to function, but it was easier to link to LWA rather than try to work out the intricacies of my.openhab.org, seeing as I know my credentials anyway.

In the AWS lambda function.lambda_handler (I used python, but you can use JavaScript or Java too), for the event namespaces below:

    if event['header']['namespace'] == 'Alexa.ConnectedHome.Discovery':
        return handleDiscovery(context, event)

    elif event['header']['namespace'] == 'Alexa.ConnectedHome.Control':
        return handleControl(context, event)

You will write the handleDiscovery and handleControl methods and return the following:

    return { 'header': header,
             'payload': payload
        }

Just define the header as shown in the example step-by-step skill adaptor example on the Amazon developer website and fill in your device details in the payload instead of the examples.

Now, the bit that you actually need to know.
How do you get the device details and states of your home automation devices through my.openhab.org and how do you control those devices?

When you ask Alexa to 'Discover devices', your handleDiscovery method will be called.

To get a list of all OpenHAB devices, make a GET request to :

https://<username:password@my.openhab.org/rest/items

To get just a known devices details do:
https://<username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling

To get just the state of a known device do:
https://<username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling/state

This will return an XML response similar to this:

<items>
<item>
<type>GroupItem</type>
<name>myopenhab</name>
<state>Undefined</state>
<link>https://my.openhab.org/rest/items/myopenhab</link>
</item>
<item>
<type>GroupItem</type>
<name>All</name>
<state>Undefined</state>
<link>https://my.openhab.org/rest/items/All</link>
</item>
<item>
<type>SwitchItem</type>
<name>Light_GF_Corridor_Ceiling</name>
<state>Uninitialized</state>
<link>https://my.openhab.org/rest/items/Light_GF_Corridor_Ceiling</link>
</item>
<item>
<type>NumberItem</type>
<name>Weather_Temperature</name>
<state>10</state>
<link>https://my.openhab.org/rest/items/Weather_Temperature</link>
</item>
</items>

In the handleDiscovery method, find the items like "SwitchItem" in the XML and add them to the payload by name to build your list of devices that Alexa can control using ON/OFF commands.
Just look at the Amazon example code to see what the payload should look like.

Then, when you ask Alexa to turn something on or off, your handleControl method will be called.
This is where you send the ON or OFF to your device in openHAB.

curl --request POST --data 'OFF' --header "Content-Type:text/plain" --verbose
Make a POST request to the device's specific URL:

https://username:password@my.openhab.org/rest/items/Light_GF_Corridor_Ceiling

In the POST body, put the plain text command ON or OFF
Make sure you set the Content-Type header to 'text/plain' or it won't work.


In the URLs, if your my.openhab.org username or password has '@' or '.' characters in it, then be sure to escape them using %40 and %2E respectively, as mentioned in this wiki: 


That's it.

Sunday, October 02, 2016

How to create an Alexa Skill to talk to ThingSpeak for IoT control

If you are just experimenting with Alexa and your own homemade IoT devices, you may be using a cloud service such as ThingSpeak.
Here is a simple example of everything needed to enable your Amazon Echo or similar device to control your devices by talking directly to Alexa.

You can say things like:

Alexa, tell Smart Control to turn on the light
Alexa, ask Smart Control to switch the lamp off
Alexa, open Smart Control
 - light on

and so on.

You can find the code here on GitHub:

Monday, July 11, 2016

How To setup mDNS on Slackware

mDNS is tool for finding computers and services, such printers, shares, devices, etc. on your local network without having to set up DNS etc. first.

1. Download the Slackware mDNS package from here:
http://0pointer.de/lennart/projects/nss-mdns/

2. unzip the package:
gzip -d nss-mdns-0.10.tar.gz

Remember to substitute your packages version number in place of "0.10" if it is different.

3. unarchive the files into a directory:
tar -xvf nss-mdns-0.10.tar

Again, remember to substitute your own package version.

Now we need to configure the package for your Slackware system and then build it and install it.

4. Configure the package:
cd nss-mdns-0.10

./configure

Note, if you don't have Avahi, then you will need to use the mini mDNS stack like this:

./configure -enable-legacy

5. next build the package:

make

6. next install the package as root:

su
<enter your root password>

make install

7. Now we need to add some things to our /etc/nsswitch.conf file:
pico /etc/nsswitch.conf

change the line that start with the word "hosts:" to this:
hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4

This means look for a hostname in the hosts file, then if it ends in.local, try mDNS and give up if not found. If it didn't end in .local, try the normal DNS services and finally try mDNS.

Done. Now we can test it quickly by using the getent command:

getent <name>.local

replace <name> with the name of a service registered with an mDNSResponder (like a Windows PC with iTunes running on it).

This will return the IP address of the host.

If you have a firewall in your local network, set it up to allow UDP traffic to the the mDNS multicast address 224.0.0.251 on port 5353.

Monday, October 12, 2015

To Blog or not to blog



from Gmail
via IFTTT

Labels: ,

Monday, June 15, 2015

How to add an existing Xcode project to git

cd projectfolder/

find . | grep "UserInterfaceState.xcuserstate"

if the file exists add it to the .gitignore file

find . | grep "UserInterfaceState.xcuserstate" > .gitignore

check everything is OK

cat .gitignore

Initialise git

git init

Add all the files to git

git add .

Commit the files to git with a comment to say why

git commit - m "initial commit"

If you have git issues, you may need to install command line tools from Xcode preferences.

Thursday, May 07, 2015

Standards for Measuring Goodness and Frivolity

I found something the other day that brought back a lot of fun memories. A good friend of mine blogged an email conversation we once had. It had all started off with a very serious work related topic and ended up rather humorous (to us anyway, your mileage might vary).

Have a read for yourselves at https://niknewark.wordpress.com/2008/09/11/the_si_unit_for/

Monday, February 16, 2015

Possible discovery in 2015 of a new particle in physics

The world's largest atom-smasher could help physicists understand mysterious dark matter in the universe, and later this year it may offer a discovery even more fascinating than the Higgs-Boson, researchers say.

Read more at: http://phys.org/news/2015-02-discovery-particle-physics.html#jCp

'Cloud' over Mars leaves scientists baffled

Plumes seen reaching high above the surface of Mars are causing a stir among scientists studying the atmosphere on the Red Planet.

Read more at: http://phys.org/news/2015-02-cloud-mars-scientists-baffled.html#jCp