Alexa on the Raspberry Pi

2016-06-15 16.43.38

UPDATE June 16th 2016: I was wrong about Alexa not being able to access my UK Amazon account. It appears that my UK an USA accounts are linked, so when I said “Read my Kindle”, Alexa started reading me my current Kindle book. It did it at about one sentence every few minutes, with no obvious way to stop it, so it was not that useful. I still don’t think it can access Amazon Prime music. 

Also, although the Alexa app is not available in the UK, you can go to alexa.amazon.com and control things from there. In particular, it shows me my history of interactions with Alexa.

A couple of things that the alexa web site showed me I could do were shopping lists and to-do lists. They are quite fun, but you have to go to the alexa web site to delete things from them.

It also reminded me that I could get a voice remote for my Amazon Fire stick, so I have ordered one of those. Perhaps at some time I can use it for voice control of my home automation.

I still could not get any smart home devices to work with my Alexa setup. When I tried “Discover devices” on the alexa web site, it did not discover my Wemo devices, although they are supported.  I suspect an Amazon Echo would find them. I wonder if this could be added to the Raspberry Pi application. It needs to do a UPnP Wifi search. It would be possible for either the Raspberry Pi or my Amazon Fire stick to do this.

SECOND UPDATE: The Alexa app is more useful than I thought it would be, now that I have looked at what it can do on alexa.amazon.com. It will now read and update my Google Calendar, and I have added several skills so it tells me about Beer, Cricket and a few other things. It will play a lot of radio stations via TuneIn, which does not need an account.

Unfortunately you can only set US addresses for devices (even Amazon Fire TV or sticks). This means I can’t default locations for things like weather. However, the traffic update does allow UK addresses. Amazon are going to have to do a lot of work on this to make it truly international.

I thought I would try the instructions on Github for Alexa on the Raspberry Pi.

My Kitchen Raspberry Pi, which is a Pi 3 with a Touch Display, and a camera, microphone and speaker, seemed a good choice. (I have Raspberry Pis in most of my rooms).

It took several hours to set up.

Here is is telling me a joke:

To use an Alexa with your own device, you have to set up a developer account using a USA Amazon account, and do a lot of configuration of your own custom device and security profile on the developer site. This results in a device type, and an oauth2 client id and secret, which you then use to configure the Raspberry Pi application.

The Raspberry Pi application is odd. It uses a node.js server and a Java client. The node.js server seems to only be used for the oauth2 authentication.

You have to install node.js, a recent version of the Oracle Java JDK, Maven, VLC, and a few other things. You need self-signed certificates to access the applications. It is all very involved, and the instructions are not very good. It is not at all clear why VLC is installed, particularly as it is configured, and then the configuration is discarded.

The main problem with the instructions is that they are for a very specific old version of Raspbian, and are misleading for the latest Jessie release of Raspbian.

The resulting application is a bit difficult to use and very fragile. It does not have much useful error reporting.

It looks like you need to re-authenticate the application every time you reboot the Raspberry Pi, and authentication is a non-trivial process.

This video explains some of the difficulties of the instructions and the application. The author of the video was setting the application up on a Pi Zero, which has its own issues:

Is the application useful for someone in the UK, who can’t yet officially buy an Amazon Echo? Well, not really.

Its OK for asking about the weather (which defaults to Seattle, if you are not specific), telling jokes, and asking some general knowledge questions. But is is currently pretty useless for playing music, and doing home automation.

There are several issues for UK users:

  • It is not linked to your UK Amazon account, so it can’t read your Kindle books, or play your Amazon music.
  • The Alexa application that configures it for home automation, music etc. is not available in the UK
  • It seems to use iHeartRadio for internet radio and that is not available in the UK.

When the Amazon Echo is eventually available in the UK, and other countries, some of these issues should be fixed. It might then  be worth developing a more robust application, which is easier to configure and use.

 

Advertisements
Posted in Home automation, Raspberry PI | Tagged , , , , | Leave a comment

Controlling my house with texts

2016-04-07 12.50.45

I backed the Seeedstudio RePhone Kickstarter, and got the Create kit. I thought I would use it as a house SMS server, so that I can control my house with text messages when I am out. I can already control it via various means including MQTT messages, if I have an Internet connection. But sometimes you do not have an Internet connection.

As the RePhone does not have Wifi, I needed to use Bluetooth to send the commands to my home automation system. This needs a Bluetooth SPP server, and a Raspberry Pi 3 seems like the perfect server for that, as it has built-in Bluetooth.

I am not sure it is a very good use of the RePhone as it does not use its capability to control electronics, but the RePhone is a relatively cheap way to get this capability.

I program the RePhone using Arduino. This involved bringing my old Vista laptop back to life, as the drivers for the RePhone are only available on Windows, and not on Windows 10. The good set of example provided made programming it to process texts, talk to a Bluetooth server and write to the OLED screen easy.

I programmed the Bluetooth SPP server in Java, and again there are good examples for that. Getting Bluecove working on the Raspberry Pi 3 was a little tricky but not too hard.

The Bluetooth SPP server relays the text message commands to my HouseControl server running on a Raspberry Pi 2, and sends the replies back to the RePhone which currently just displays them on the screen.

So now I can do things like turn the lights on or the heating up, or talk to people in the house via text to speech.

I do not currently text the replies back, but that would be easy to add.

Here is the RePhone Arduino code:

#include <LBT.h>
#include <LBTClient.h>
#include <LGSM.h>
#include <LCheckSIM.h>
#include <LDisplay.h>

// Change to the name of your server
#define SPP_SVR "pi3"

LBTDeviceInfo info;
char *spaces = "                    ";

void setup()  
{
  Serial.begin(9600);
  Serial.println("House Client started");
  
  // Set up the LCD screen
  Lcd.init();
  Lcd.font_init();
  Lcd.back_light_level(50);
  Lcd.screen_set(0xffff00); // Yellow background
  
  // Set up SMS
  while(!LSMS.ready())
  {
    delay(1000);
  }
  Serial.println("SMS is ready");
  
  // Set up Bluetooth
  bool found = false;
  bool success = LBTClient.begin();
  if( !success )
  {
    Serial.println("Cannot start Bluetooth");
	Lcd.draw_font(10, 0, "Cannot start Bluetooth", 0xffff00, 0);
    delay(0xffffffff);
  }
  else
  {
    Serial.println("Bluetooth client started");
    // Look for the Bluetooth devices
    int num = LBTClient.scan(30);
    Serial.printf("Found %d devices\n", num);
    for (int i = 0; i < num; i++)
    {
      memset(&info, 0, sizeof(info));
      // See if it is the required server
      if (!LBTClient.getDeviceInfo(i, &info)) continue;
      Serial.printf("Found address: %02x:%02x:%02x:%02x:%02x:%02x name: %s\n", 
          info.address.nap[1], info.address.nap[0], info.address.uap, info.address.lap[2], info.address.lap[1], info.address.lap[0],
          info.name);
      if (0 == strcmp(info.name, SPP_SVR))
      {
        found = true;
        Serial.println("Server found");
        break;
	  }
    }
  }
  
  if( !found )
  {
    Serial.println("Server not found");
	Lcd.draw_font(10, 0, "Server not found", 0xffff00, 0);
    delay(0xffffffff);
  }
  
  Serial.println("Trying to connect\n");
  // Try to connect
  bool conn_result = LBTClient.connect(info.address);
  Serial.printf("Connect result: %d\n", conn_result);
 
  if( !conn_result )
  {
    Serial.println("Connect failed");
    Lcd.draw_font(10, 0, "Connect failed", 0xffff00, 0);
    delay(0xffffffff);
  }
  else
  {
    Serial.println("Connected to SPP Server");
    Lcd.draw_font(10, 0, "Connected", 0xffff00, 0);
  }
}
 
void loop()
{
  // Wait for SMS message
  if( LSMS.available() ) 
  {
    char cmd[50];
    char reply[32];
          
    // Get the command from the text message 
    LSMS.remoteContent(cmd, 50);
    Serial.print("Command:");
    Serial.println(cmd);
    Lcd.draw_font(10, 20, spaces, 0xffff00, 0);
    Lcd.draw_font(10, 20, cmd, 0xffff00, 0);
	Lcd.draw_font(10, 40, spaces, 0xffff00, 0);
	
	// Send the command to the SPP server, terminated by newline
    LBTClient.write(cmd, strlen(cmd));
    LBTClient.write((char *) "\n", 1);

    // Read reply from SPP server
    while(true)
    {
      if(LBTClient.available())
      {
        int len = LBTClient.readBytes(reply,32);
		reply[len] = 0;
        break;
      }
      delay(100);
    }
    Serial.printf("Reply: %s\n", reply);
    Lcd.draw_font(10, 40, reply, 0xffff00, 0);
  }
}

and here is the Raspberry Pi 3 Java code:

package net.geekgrandad.apps;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
  
import java.net.Socket;
import java.net.UnknownHostException;

import javax.bluetooth.*;
import javax.microedition.io.*;
  
/**
* Class that implements an SPP Server which accepts single line of
* message from an SPP client and sends a single line of response to the client.
*/
public class SPPServer {
    
    //start server
    private void startServer() throws IOException{
  
        //Create a UUID for SPP
        UUID uuid = new UUID("1101", true);
        //Create the servicve url
        String connectionString = "btspp://localhost:" + uuid +";name=Sample SPP Server";
        
        //open server url
        StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier)Connector.open( connectionString );
        
        //Wait for client connection
        System.out.println("\nServer Started. Waiting for clients to connect...");
        StreamConnection connection=streamConnNotifier.acceptAndOpen();
  
        RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
        System.out.println("Remote device address: "+dev.getBluetoothAddress());
        System.out.println("Remote device name: "+dev.getFriendlyName(true));
        
        //read string from spp client
        InputStream inStream=connection.openInputStream();
        BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
        
        OutputStream outStream=connection.openOutputStream();
        PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
        boolean connected = true;
        
        while (connected) {
	        String lineRead=bReader.readLine();
	        System.out.println(lineRead);
	        Socket sock = null;
	        String host = "192.168.0.100";
	        String ret = "No reply";
	        
			try {
				sock = new Socket(host, 50000);
			    PrintWriter out = new PrintWriter(sock.getOutputStream(),true);
			    BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
			    out.println(lineRead);
			    ret = in.readLine();
			    System.out.println("Reply is " + ret);
			    out.close();
			    in.close();
			    sock.close();
			    sock = null;
			} catch (UnknownHostException e1) {
				System.err.println("Unknown host");
				connected = false;
			} catch (IOException e1) {
				connected = false;
				System.err.println(e1);
				try {
					if (sock != null) sock.close();
				} catch (IOException e2) {
				}
			}
        
	        //send response to spp client
	
	        pWriter.write(ret);
	        pWriter.flush();
        }
	  
        pWriter.close();
        streamConnNotifier.close();
  
    }
  
  
    public static void main(String[] args) throws IOException {
        
        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println("Address: "+localDevice.getBluetoothAddress());
        System.out.println("Name: "+localDevice.getFriendlyName());
        
        SPPServer sampleSPPServer=new SPPServer();
        sampleSPPServer.startServer();
        
    }
}
Posted in Arduino, Home automation, Raspberry PI | Tagged , | Leave a comment

VGA and audio for Pi Zero

2016-03-26 11.56.06

I backed the Analog Expander Cap – for Raspberry Pi Zero Kickstarter campaign.

It was a lot of soldering, but it works and makes a very small PC that works with a VGA monitor.

I have only tried the VGA ad audio, not the composite output.

 

Posted in Electronics, Raspberry PI | Leave a comment

Flotilla

2015-12-06 09.57.38

I seem to be one of the first to get the Flotilla mini-kit from Kickstarter.

It consists of a hub that is connected to the Raspberry Pi, and then a set of modules can be connected to the hub via micro USB cables. The mini-kit comes with a 4-button touch sensor and a rainbow LED stick.

There is an application called Rockpool that lets you define connections between the inputs and outputs:

rockpool

Rockpool is a Javascript web application that talks to a flotilla daemon on the Raspberry Pi via Websockets.

It is easy connect to the same websocket using node-RED,  which allows me to link Flotilla to my home automation system.

Here is it telling me when a touch button is pressed:

flotilla-nodered

You send the Websocket a “ready” message and it starts sending back messages about the state of the modules. I am intercepting an update message for the”Touch” device, checking which button is pressed and then using my house control system to speak a message. I could just as easily use the buttons to switch devices in the house on or off.

Flotilla looks very promising; I will try it on my grandchildren to see how easy they find it to “program”.

There is also a python API, but this is being actively worked on, and may change.

There is an even easier interface coming called “Cookbook” with pre-defined “recipes” that should make it even easier for kids to start using it.

 

 

 

Posted in Electronics, Home automation | Tagged , | Leave a comment

MQTT Topic Hierarchy

topics

Here is my current MQTT topic hierarchy in a real-time updating web page, produced by Ben Hardill‘s MQTT Topic Hierarchy browser.

I need to sort a lot of things out. The data is sometimes correctly scaled, and sometimes not. The precision is variable.

I need to publish the status of my IAM devices as well as their power usage.

I need to publish the data from my two Wemo devices.

I could publish the status of my LWRF devices, but I do not know that accurately.

Some data like the emonPi power data is probably not sensibly associated with a specific room.

I also need to rationalise battery level data and add last updated fields to all the data.

I think I will also publish fitbit data to /people/lawrie.

The weather data is not really weather data as it comes from an indoor ESP8266 BMP180 sensor. I neee to put it in the right place in the hierarchy.

I need to add my letterbox sensor status.

Posted in Home automation | Tagged | Leave a comment

MQTT and Websockets

websockets

I have been experimenting with a new web site to control my house as the current one, written in PHP, is very slow as it gets data using TCP connections to HouseControl.

I wanted to get as much of the data from MQTT as possible. I experimented with a node.js web site, which read the MQTT data in the server and sent it to the browser in a refreshing page. This worked but the data was slightly out of date, and the page refresh flash was annoying.

So I need a Javascript-based web site to avoid these problems. The easiest way to do this was to use a version of the Mosquitto MQTT server, that supported Websockets. The 1.4 version supports it, but only if you build it with Websocket support. So I followed Martin Harizanov’s guide, and installed it on a Raspberry Pi 2. I had slight problem with this, as the service script gave a syntax error, and as I had lost the indentation, it was hard to diagnose, so I copied the one from my emonPi. Also, as the script puts things in /usr/local, not /usr, I had to run “ldconfig”, to update symbolic links.

The web app works well and data is updated in real time.

I configure the page with a json file, rooms.json on the server:

{
"Power":{
"emonhub/rx/5/values":{"Total": null},
"/house/rooms/first-floor/kitchen/dishwasher/power":{"Dish washer":null},
"/house/rooms/ground-floor/utility/washer/power":{"Washer":null},
"/house/rooms/ground-floor/utility/dryer/power":{"Dryer":null},
"/house/rooms/ground-floor/dining-room/games/power":{"Games":null}
},
"Utility room":{
"/weather/temperature":{"Temperature":null, "scale": 0.1},
"/weather/pressure":{"Pressure":null, "scale": 0.01}
},
"Kitchen":{
"/house/rooms/first-floor/kitchen/temperature":{"Temperature":null},
"/house/rooms/first-floor/kitchen/light-level":{"Light Level":null},
"/house/rooms/first-floor/kitchen/occupied":{"Occupied":null},
"/house/rooms/first-floor/kitchen/humidity":{"Humidity":null}
},
"Living Room":{
"/house/rooms/first-floor/living-room/front/temperature":{"Front temperature":null},
"/house/rooms/first-floor/living-room/back/temperature":{"Back temperature":null},
"/house/rooms/first-floor/living-room/front/light-level":{"Front Light Level":null},
"/house/rooms/first-floor/living-room/back/light-level":{"Back Light Level":null},
"/house/rooms/first-floor/living-room/front/occupied":{"Front Occupied":null},
"/house/rooms/first-floor/living-room/back/occupied":{"Back Occupied":null},
"/house/rooms/first-floor/living-room/couch/occupied":{"Couch Occupied":null}},
"Landing":{
"/house/rooms/second-floor/landing/temperature":{"Temperature":null},
"/house/rooms/second-floor/landing/lightlevel":{"Light Level":null},
"/house/rooms/second-floor/landing/occupied":{"Occupied":null}
},
"Bathroom":{
"/house/rooms/second-floor/bathroom/temperature":{"Temperature":null, "scale": 0.1}
},
"Second bedroom":{
"/house/rooms/second-floor/second-bedroom/temperature":{"Temperature":null,"scale": 0.1},
"/house/rooms/second-floor/second-bedroom/humidity":{"Humidity":null, "scale":0.1}
},
"Master bedroom":{
"/house/rooms/second-floor/master-bedroom/temperature":{"Temperature":null, "scale": 0.1},
"/house/rooms/second-floor/master-bedroom/light-level":{"Light level":null}
}
}

I could have easier configuration if I made more use of the topic hierarchy, e.g. show everything under /house/rooms, but the way I have things is more flexible and lets me choose which items to display.

Currently this web site only supports monitoring devices, not controlling them. I think I might add Websocket support to HouseControl, or I might do a node.js gateway that converts a Websocket to the tcp socket that HouseControl currently supports. HouseControl does support controlling things by publishing to MQTT, but you get no reply from that, and sometimes I need the reply.

Posted in Home automation | Tagged | 1 Comment

Couch Potato

potato

I have had a Jeenode force sensor under my couch for a while. I thought I would use it for some couch potato monitoring.

This node-red flow causes my house to say “Hello, couch potato” when anyone sits down on the sofa, and “Goodbye, couch potato” when they get up.

It uses the MQTT topic than emonHub publishes when it receives RF data from the couch sensor.

Posted in Home automation, Uncategorized | Leave a comment