Pi-Mote
Overview
Pi-Mote [1]is a simple wireless controller, dedicated to the Raspberry Pi computer, and Energenie ENER002 RF controlled mains sockets.
It is an extremely simple, transmit only, open loop system controlled by six GPIO pins in "out" mode on the Raspberry Pi.
It plugs directly into a Raspberry Pi computer, and is powered from the Pi.
Its power output is +12 dBm at 433.92Mhz (ISIM band). It draws 27 mA from the Pi's supply.
It is presently available as a bundle with two sockets at marginally less than £20, or can be purchased as a stand alone item at less than £10. Both prices are inclusive of UK VAT, postage and packaging.
It takes the form of a small L shaped PCB 35mm x 35mm bounding dimensions with a dead ended connector that takes up all the pins on a model B Pi's GPIO connector. It fits a model B+ and leaves the additional GPIOs on the B+ accessible.
There is no mechanical attachment to the Pi, it is simply supported by the connector it is plugged in to.
When installed the board sits inside the perimeter of the Raspberry Pi PCB, so is compatible with Pi cases that leave the space above the Pi unobstructed.
Note than many cases such as the popular Pibow case do not leave this space free, and would not be compatible with the Pi-Mote without major alteration.
There is a built in aerial on the board that allows operation of the Energenie Sockets at moderate range and a via in the board that allows the addition of a 165mm wire aerial that substantially increases the radial distance at which the sockets can operate with reasonable reliability.
Operational Considerations
As this system is open loop, there is no means to tell from the Pi that the commands sent have been acted on by the sockets. Thus, any application that uses this system needs to be tolerant of occasional missed commands.
In some applications this is a tolerable limitation, say for simulating house occupancy, but for any application that requires that operations are carried out in a strict sequence, the Pi-Mote would only be suitable if feedback can be obtained from outside the Pi-Mote system. For example, if the room is equipped with illumination monitoring, then that could be used to confirm that a socket on command to turn on a lamp, has actually been acted on.
This is true for any open loop system, not just the Pi-Mote.
Range of reliable operation and load considerations
The reliability of operation of the controls is generally good within moderate range of the Pi-Mote.
I have had sockets operating quite reliably at distances of 10M and more through solid brick internal walls, using the supplementary aerial.
A point to consider is the load you wish to control with the Pi-Mote. I was disappointed in some initial testing, using an old table lamp fitted with an old style high efficiency lamp as the test load. The lamp would turn on, but not switch off. It turned out that the problem was that the lamp was in direct line between the Pi-Mote and the socket, and the lamp radiated significant RF both by direct radiation and back up it's mains cable, and as soon as it was turned on it was washing out the control signals from the Pi-Mote.
Again this is not peculiar to the Pi-Mote, all low power wireless based systems are vulnerable to some extent.
Giving attention to it's limitations however, this is a very simple and effective system.
Operational controls
The Pi-Mote internally consists of two sub-systems, the encoder and the modulator.
The encoder builds a frame for transmission, comprising a fixed bit pattern specific to the particular Pi-Mote and a dynamic pattern of four bits that can be directly controlled by the Pi.
The modulator takes that bit pattern and encodes it onto the wireless output. The modulator loops through that bit pattern continuously while it is enabled.
Two GPIOs control the modulator:
- One GPIO enables and disables (keys) the modulator.
- One GPIO sets the coding scheme used by the modulator.
Two schemes are available, ASK and FSK, but all the sample code provided by Energenie uses ASK. Essentially this GPIO can be set and left at that setting.
(fixme - do ENER002 sockets react to FSK signalling?)
The remaining GPIOs control a four bit control/address interface to the encoder.
The four bits that are applied to the encoder are an on/off signal to the sockets and a three bit control/address code to select a specific socket.
There are eight possible bit patterns for those three bits.
All 4 bits held zero (address and on/off) and held in that state for a period is a reset command to the encoder and forces it into a known state.
The four bits are then set to the required address and on/off state, and held stable for a period to allow the encoder output to stabilise.
The modulator is then keyed up and begins looping through the bits of the encoder output.
The modulator is keyed up for, at minimum, one pass through the encoder output pattern. In practice, control can be made more reliable by looping through that pattern a number of times since repeated commands at the socket have no effect after one has been actioned.
In a noisy environment, which this wireless band definitely is, there is a reasonable possibility of the command being corrupted, especially towards the limit of the system range.
However, in most cases the corruption will change some of the address bits, making the command not match the socket address and thus get ignored.
Since this is a bit pattern with 20+ bits, the chance that only one of those bits is flipped to corrupt the command to a valid but wrong command for the socket, (the on/off bit only flipped and only in the last command sent) is much smaller than the probability that the corruption will affect somewhere else in the pattern and cause the command to be ignored. So, sending the command repeatedly improves the chance of the correct command getting through.
There is also the possibility that some of the other bits transmitted, over which the Pi has no control, are check bits to guard against accepting corrupted commands, but I have seen nothing in the documents to suggest that Energenie have adopted this approach. As this set up is compatible with the existing design of Energenie socket, it is constrained by whatever design features the sockets support.
After a reasonable period of repeating the code, the modulator is keyed off and the command cycle is complete.
Sync sockets
Holding down the button on the front of the ENER002 socket until the LED flashes a burst of short flashes puts the socket into "waiting for sync" mode. It then slow blinks the LED until it is synced at which point the LED goes out. While in sync mode it adopts (but does not act on) the first address that it receives. It makes no difference if the command is on or off.
After it is synced it answers commands normally.
Note, this means that if you want to sync a socket, it is advisable to ensure that Domoticz is not going to issue competing commands.
Address codes
Energenie document six bit patterns of the available eight bit patterns.
Four are socket addresses for the advertised four banks of sockets that the Pi-Mote can officially address. One is an "all on/all off" command that turns all sockets on or off. One is the "reset" command for the encoder.
Experiment has proved that it is possible to sync sockets to the two undocumented addresses. Sockets on these addresses also respond to the "all on/all off" commands. Why Energenie do not document these codes I'm not clear, possibly they wish to reserve them for other products.
It is also possible to sync a socket to address 000, by using the "on" command for socket 000.
However, trying to individually turn that socket off fails, since the command simply resets the encoder and never makes it out to air.
Such a socket will respond to the "all off" command and stay in that state until either an individual "on" command (which is 1000 so does not reset the encoder and does make it to air) or an "all on" command.
Code
To work with Domoticz the control code needs to operate as the default pi user.
Manipulating GPIO pins is usually a privileged task. However, the Linux GPIO driver allows us to "export" GPIO pins in a fashion such that ordinary users can manipulate them.
There are nice libraries that provide indirect access to the pins on the Pi GPIO connector face that maintain compatibility of output physical pin number on the Pi across Pi versions and provide access from various languages. It is probably possible to access the GPIO export mechanism via those libraries however, I've not found out how yet.
This code does not make use of any of that, it uses simple bash scripts to bit bang explicit GPIO pins.
This code will thus work, and has been tested, on a Raspberry Pi model Bv2 and B+. Because the GPIO allocation changed between Raspberry Pi model Bv1 and v2 this code will need translation to run on the earlier version Pi.
This code is in two parts. The first is a run once setup that needs root access to do its work.
I run this code from /etc/rc.local once at startup. There is no reason why this code should need to be efficient, so the lack of comments is simply laziness on my part that I keep meaning to fix.
To understand this code you need to understand the Unix convention that everything is a file.
We are making changes in the /sys "filesystem" which is not a real filesystem, in the sense that it's contents do not appear on any physical storage on the system. It's really an interface into the Linux kernel by which we can talk to the kernel about objects we want to control. Thus it has to be set up anew each time the Pi is booted, since it all vanishes into non existence as soon as the kernel shuts down.
The /sys file hierarchy is more recent than the /proc file hierarchy, and the developers are attempting to ensure that each file in /sys contains one and one only item.
Items are grouped by directory, not gathered into files.
Bash Code to Set Up GPIO
We need to control six GPIO pins.
We want to allow ordinary users to change the state of those pins
To do this we write (with root priv) a GPIO number into the "export" file in /sys/class/gpio.
The kernel responds by creating a new directory in that folder, named for the gpio we asked to export. In that directory the kernel puts the set of files that describe the exported GPIO.
We want all the GPIO pins to be outputs, so we set the permissions on the "direction" file so an ordinary user can write it, then as an ordinary user put "out" in it, which causes the kernel to set the matching GPIOs direction to out. Then being meanies and not wanting the hoi polloi to mess with it, we set it back to root only modify. We could have simply modified it as root, but hey ho this works.
However, we do want any old pleb, including Domoticz, to be able to waggle the exported pins. That is, they need to be able to change the contents of the "value" files. So we set permissions for those files to rw for group gpio (alright not any old pleb, just plebs in group gpio) hence the 6 (read and write flags) in the second digit (the group permissions) in the fifth line of the code below.
(If you look at the ownership of the files that the kernel generates in response to our export command, they are owned root group gpio. The pi user is a member of group gpio. Domoticz runs as user pi and can thus change the values of those bits.)
We repeat the same set up for all six GPIOs of interest.
Boring really as they are all the same. That's it, setup done, no need to visit this setup again until the next boot.
If you play with this to see what happens, if you write the gpio number into the unexport file, poof, the gpio directory and everything within it disappears. You, of course, would then have to run this file before your commands to the Pi-Mote will work.
Code follows:
sudo sh -c 'echo 17 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio17/direction echo out > /sys/class/gpio/gpio17/direction sudo chmod 744 /sys/class/gpio/gpio17/direction sudo chmod 764 /sys/class/gpio/gpio17/value
sudo sh -c 'echo 27 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio27/direction echo out > /sys/class/gpio/gpio27/direction sudo chmod 744 /sys/class/gpio/gpio27/direction sudo chmod 764 /sys/class/gpio/gpio27/value
sudo sh -c 'echo 22 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio22/direction echo out > /sys/class/gpio/gpio22/direction sudo chmods 744 /sys/class/gpio/gpio22/direction sudo chmod 764 /sys/class/gpio/gpio22/value
sudo sh -c 'echo 23 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio23/direction echo out > /sys/class/gpio/gpio23/direction sudo chmod 744 /sys/class/gpio/gpio23/direction sudo chmod 764 /sys/class/gpio/gpio23/value
sudo sh -c 'echo 24 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio24/direction echo out > /sys/class/gpio/gpio24/direction sudo chmod 744 /sys/class/gpio/gpio24/direction sudo chmod 764 /sys/class/gpio/gpio24/value
sudo sh -c 'echo 25 > /sys/class/gpio/export' sudo chmod 764 /sys/class/gpio/gpio25/direction echo out > /sys/class/gpio/gpio25/direction sudo chmod 744 /sys/class/gpio/gpio25/direction sudo chmod 764 /sys/class/gpio/gpio25/value
Bash Scripts to Control The Switches
For the actual code to control the sockets, I've done the obvious thing and written minimal bash scripts to do the bit bashing described above. So I have 10 files that differ in small ways to turn things on and off.
Called imaginativley sock1on.sh sock2on.sh sockallon.sh sock1off.sh and so on.
Each does what it says on the tin when executed by an unprivileged user at the command line. I could write a clever bash script that takes address and state as parameters, but I only ever want to operate one of the paths through the script at one time, and a straight on bash script with less than a twenty lines, with no control structure, no argument parsing, no call outs except to wait commands, is pretty damn lightweight.
The first block of six "echo 0 >" keys the modulator off, sets the mode to ASK and resets the encoder.
The second block of "echo 1 >" (in this case) sets address 1 (negative logic - dont ask me why)
The last line of that block sets the socket on (positive logic - again don't shoot the messenger)
The "echo 1 > /sys/class/gpio/gpio25/value" keys up the modulator.
Wait a bit and set it back to 0 key it off again.
Job done!
sock1on.sh:
\#!/bin/sh
echo 0 > /sys/class/gpio/gpio17/value
echo 0 > /sys/class/gpio/gpio22/value
echo 0 > /sys/class/gpio/gpio23/value
echo 0 > /sys/class/gpio/gpio27/value
echo 0 > /sys/class/gpio/gpio25/value
echo 0 > /sys/class/gpio/gpio24/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio17/value
echo 1 > /sys/class/gpio/gpio22/value
echo 1 > /sys/class/gpio/gpio23/value
echo 1 > /sys/class/gpio/gpio27/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio25/value
sleep 0.5
echo 0 > /sys/class/gpio/gpio25/value
The second is very similar with the subtle change to gpio27 to 0 to call for socket off.
sock1off.sh
\#!/bin/sh
echo 0 > /sys/class/gpio/gpio17/value
echo 0 > /sys/class/gpio/gpio22/value
echo 0 > /sys/class/gpio/gpio23/value
echo 0 > /sys/class/gpio/gpio27/value
echo 0 > /sys/class/gpio/gpio25/value
echo 0 > /sys/class/gpio/gpio24/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio17/value
echo 1 > /sys/class/gpio/gpio22/value
echo 1 > /sys/class/gpio/gpio23/value
echo 0 > /sys/class/gpio/gpio27/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio25/value
sleep 0.5
echo 0 > /sys/class/gpio/gpio25/value
I store those files in the pi user home directory.
To invoke from Domoticz I set the socket off and on scripts to script://home/pi/sock1off.sh and script://home/pi/sock1on.sh