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();
        
    }
}
Advertisements
This entry was posted in Arduino, Home automation, Raspberry PI and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s