Interfacing Serial Devices

Sometimes you simply want to connect a microcontroller to the HAH and have some way of receiving and sending data from/to this device. The xap-serial process allows even the most basic micros to interoperate with the HAH. The micro simply sends an ASCII string to its UART. This UART is generally connected to the USB port on the HAH via a RS232 to USB cable. The string as sent from the micro should be CR/LF terminated. When a string is received by the xap-serial process, a corresponding xAP message is generated. The text of the string is included in the xAP message and is available to the hah_plugboard for further actioning.

In a similar way, an xAP message can cause text to be sent to the micro.

Enabling

xAP serial uses the /etc/xap.d/xap-serial.ini configuration file. There is only one option, opening and closing serial ports is done via the xAP schema protocol.

[serial]
enable=1
  • enable default 0. This attribute is examined by the /etc/init.d/xap startup script and determines if xap-serial will be started as a service when the HAH boots up.

xAP Serial Schema

A serial schema exists for this purpose which is implemented in the xap-serial daemon.

The schema has been extended slightly from that published on the xAP Automation web page so it's reproduced here as implemented on the HAH.

Unless otherwise stated, a name/value pair is assumed to be mandatory.

Class=Serial.Comms

Serial.Setup
{
Port=(e.g. /dev/ttyUSB0)
Baud=(bits per second e.g. 9600)
Stop=(1 | 2)
DataBits=( 5 | 6 | 7 | 8)
Parity=(none | even | odd)
Flow=(None | XOnXOff | Hardware)
}
Serial.Send
{
Port=(e.g. /dev/ttyUSB0)
Data=(Data to be sent on the serial port)
}
Serial.Close
{
Port=(e.g. /dev/ttyUSB0)
}
Serial.Received
{
Port=(e.g. /dev/ttyUSB0)
Data=(Data received on the serial port)
}

When sending a string to the HAH from your micro, just ensure that the string is terminated with a CR. This will trigger the production of a xAP message from xap-serial.

Serial.Error
{
text=
}

If you try to do something like opening a non-existent port, you will get a notification via a xAP message.

The data= key supports escaping so that you can send non-printable characters the following are supported:

Escape Sequence Hex Represents When
\a 0x07 Bell (alert)
\b 0x08 Backspace
\f 0x0c Form feed
\n 0x0a New line
\r 0x0d Carriage return
\t 0x09 Horizontal tab
\v 0x0b Vertical tab
\\ 0x5c Backslash
\ooo 0x## An octal bit pattern
\x## 0x## A Hexadecimal number build 307

Examples

xap-header
{
v=12
hop=1
uid=FF00DD00
class=serial.comms
source=dbzoo.test.demo
target=dbzoo.livebox.serial
}
serial.setup
{
port=/dev/ttyS0
baud=9600
stop=1
databits=8
parity=none
flow=none
}
xap-header
{
v=12
hop=1
uid=FF00DD00
class=serial.comms
source=dbzoo.test.demo
target=dbzoo.livebox.serial
}
Serial.Send
{
port=/dev/ttyUSB0
data=Hello world!
}

Note that the 'data' string can include C style escapes. e.g. \r gives a CR

A short tutorial

I have a little microcontroller project that works as an RF receiver. It can decode signals sent by the Bye Bye StandBy (BBSB) or HomeEasy (HE) range of RF handheld controllers, PIR units and switches. Note that any one receiver can be configured to decode either HE or BBSB, not both at the same time (a chip change is required to swap protocols).
5104201077_47002647e3.jpg

Currently, it simply outputs any received code to a serial port on the micro board. This is interesting, but on its own is not really of much practical use. What I’m looking to do is to have the BBSB sensors and switches fully interact with the other facilities that are controlled by my HAH.

For example, it would be handy to be able to identify a particular BBSB PIR being triggered and then activate a, HAH connected, RF mains socket to turn on a light.

So, in this note I’ll detail the steps required to do just that.

The micro that I’m using presents its serial data via an RS232 interface, at 19200baud. The output from the micro is pretty straightforward … an ASCII string which has the format <systemId>,<BBSB housecode>,<BBSB unitcode>,S<0 for off or 1 for on><CR/LF>. e.g. BBSB,A,2,S1

Since the HAH can work with a USB to serial adaptor, I’m going to use one of these to link the HAH to the micro. These adaptors can be found on eBay for a few dollars.

Before you connect the micro, just plug the USB adaptor into the USB port on the side of the HAH (the port next to the two pushbuttons).
usb and reset buttons
Now, telnet into the HAH and issue the ‘dmesg’ command. If the USB adaptor has been recognised, you should see something along the lines of …

hub.c: USB new device connect on bus1/1, assigned device number 2
usbserial.c: PL-2303 converter detected
usbserial.c: PL-2303 converter now attached to ttyUSB0 (or usb/tts/0 for devfs)

From this we can see that the adaptor is configured as /dev/ttyUSB0

If your USB to Serial adaptor isn't recognised, do drop me a note. The HAH supports Prolific and FTDI USB adaptors … these are by far the most common parts in use.

Now, connect the micro board to the RS232 end of the USB adaptor cable. Apply power to the micro board.

Check that the serial data is being received by the HAH by issuing the following command …

microcom  -s 19200 /dev/ttyUSB0

Activate a BBSB remote and you should see the data appear. If not, check that you don’t have any other process using the /dev/ttyUSB0 port (e.g. the HAH CurrentCost process). Also check that the transmitter is in range of the receiver. The BBSB transmitters don't seem to pump out a very strong signal, so experiment with the location of the Tx and Rx units.

xap-serial is the name of the process that handles the transformation of serial data to and from xAP messages. By default, this process is not enabled. To enable it, we edit the /etc/xap-livebox.ini file. Search for the [serial] section and change ‘enabled=0’ to ‘enabled=1’. Save the file, then restart your HAH. You can also control the process from the HAH web UI, Automation/Assists tab.

xap-serial is configured via xAP messages. We must tell it the details of the connection that we are looking to work with.

The following message will do the trick …

xap-header
{
v=12
hop=1
uid=FF00DD00
class=serial.comms
source=dbzoo.test.demo
target=dbzoo.livebox.serial
}
serial.setup
{
port=/dev/ttyUSB0
baud=19200
stop=1
databits=8
parity=none
flow=none
}

Note that the 'port' setting is the same as that found in the 'dmesg' output.

Of course, we don’t expect to issue this startup message unless we have a Plugboard script in place to handle any input messages from xap-serial. So, we will embed the sending of this message into the overall Plugboard handler script (see function enable_serial, below).

The xap-plugboard is the rules and action engine at the heart of the HAH. It's the place where we put the 'glue' that inspects xAP messages and takes action when something of interest is spotted.

The default location for Plugboard scripts is /etc/plugboard
Save the following to a file called ‘sertest.lua’.

This code uses the plugboard V1 API and needs to be rewritten

-- Catch a PIR activation and turn on an RF mains switch
 
 function init()
    -- We register an interest in the messages from the xap-serial process
    -- Messages will be processed by the 'dosource' function.
    register_source('dbzoo.livebox.Serial', "dosource")
    --
    BBSB = "BBSB" --string to id the microcontroller system
    PIR1 = "A,1,S1" --string to id the unit sending the RF input
    -- turn on the serial handler by sending the appropriate xAP message
    enable_serial()
 end
 
 function dosource()
    -- Get the serial data from the xAP message
    theData = xapmsg_getvalue("Serial.Received","data");
    -- print(theData)
    if string.match(theData,BBSB) == BBSB then
      -- it's from the BBSB decoder
      if string.match(theData,PIR1) == PIR1 then
        -- it's from the unit of interest
        rfrelay_on()
      end
    end
 end
 
 function rfrelay_on()
    xap_send("xap-header\
    {\
    class=xAPBSC.cmd\
    target=dbzoo.livebox.1.Controller:rf.1\
    }\
    output.state.1\
    {\
    id=*\
    state=on\
    }\
    ")
    -- print("Relay on")
 end
 
function enable_serial()
   xap_send("xap-header\
    {\
    class=serial.comms\
    target=dbzoo.livebox.Serial\
    }\
    serial.setup\
    {\
    port=/dev/ttyUSB0\
    baud=19200\
    stop=1\
    databits=8\
    parity=none\
    flow=none\
    }\
    ")
  -- print("setup done")
end;

When the HAH boots, the Plugboard processes any and all .lua script files.

Use xAP Message Viewer to see the messages that are generated by the serially attached unit. However, note that whilst xfxViever has a nice UI, it isn't terribly good at spotting non-BSC messages. Fortunately, Brett has written a little 'xAP message viewer' application that runs directly on the HAH. It's called xap-snoop and it doesn't miss a thing! Just telnet in & type 'xap-snoop -h' to see how it can be used.

With this script loaded, you should be able to activate the BBSB sensor and see the xAP message from the RF microcontroller module appear. The Plugboard script will catch this message and action the RF mains socket that will turn on the light. If you would like the light to automatically turn off after a given period of time, you can use the script shown here.

Job done!

… and over to you.

My micro happened to decode RF reception down to ASCII strings. Your micro might do any number of cool things (read temperatures, humidity, light level, detect things going well [or badly], measure the speed of wind blowing, spot fridge doors left open, identify music being played too loud ….. ). The point is that you can now use xap-serial and a slight tweak to the script detailed above to notify/alert/action via the HAH.

Currently, two versions of the firmware. One supports Bye Bye Standby (BBSB) devices, the other supports Home Easy (HE) devices. Now available in the Shop.

Home Easy Receiver

HE devices tested and known to work:

Home Easy
HE100 Touchscreen Handheld controller
HE300 Handheld controller
HE303 Indoor PIR
HE305 Door contact switch
HE307 Single on/off wallswitch
HE308 Twin on/off wallswitch
HE312v2 Handheld controller

Note that the HE403 'Outdoor PIR' does not work with this decoder. It seems to use the BBSB (completely different) RF protocol.

Also note that the HE305 is especially good as it transmits on both an open (S1) and a close (S0).

The output format for the HE decoder is <Device Id>,<Housecode 'A'..'C'>,<Unit code '1'..'4'>,G<0 for no group/1 for group>,S<0 for off or 1 for on><CR/LF>. e.g. 4555555,A,2,G0,S1

Bye Bye Standby Receiver

Devices tested and known to work:

Bye Bye Standby
BBSBRCW Handheld controller
BBSBUSRC Handheld controller
BBSBMSW PIR
BBSBDSSingle on/off wallswitch
HE200Handheld controller
HE306Wireless Doorbell
HE403External PIR
Byron RS12/RS13External PIR


Note: The HE200/HE403/HE306 are branded as 'Home Easy' but actually transmit using the BBSB protocol.

The output format for the BBSB decoder is <systemId>,<BBSB housecode>,<BBSB unitcode>,S<0 for off or 1 for on><CR/LF>. e.g. BBSB,A,2,S1

In testing, it has been noted that occasionally the very first in a series of messages presents an incorrect housecode. However, subsequent transmissions are good. Easy enough to filter out in the script.


KevinT put his RF receiver into a nice enclosure … thanks to him for this picture.