See Mike's blog entry: http://mikestirling.co.uk/notes/fht8v-protocol/
Also: http://mikestirling.co.uk/2012/10/hacking-wireless-radiator-valves-with-gnuradio/
See Mike's follow-up and sample Arduino-friendly code: http://mikestirling.co.uk/2013/02/implementing-the-elv-fht-protocol-with-an-rfm23/
Also see: http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol and http://fhz4linux.info/tiki-index.php?page=FHT+protocol
The FHT valves use (a variant of?) the FS20 protocol for communication. This operates on a nominal frequency of 868.35 MHz using on-off keying. Bits are encoded as follows:
Each transmission starts with a preamble of 12 zero bits followed by a 1. Bytes are then sent MSb first followed by an even parity bit. An additional 400 us burst completes the transmission. (DHD20130212: send as a 0 not a 1; the latter does not work.)
Transmitted data may be either 5 or 6 bytes:
<HC1> <HC2> <ADDRESS> <COMMAND> [<EXTENSION>] <CHECKSUM>
The checksum is a simple sum of the preceding bytes plus 0xC, mod 256 (ie using the lsbyte). The extension byte is only present if bit 5 of the command is set.
Each transmission is sent twice with a gap of about 8.75 ms between the first and second transmissions. Transmissions must be sent at a precise interval synchronised with the valve receiver (s). The interval varies depending on the least significant 3 bits of HC2:
Period = 115 + 0.5 * (HC2 & 7) seconds
A synchronisation procedure is required between the controller and each independently addressed valve. This is described below.
HC1 and HC2 are configurable between 0 and 99 and correspond to the valve's C1 and C2 address values, which can be re-programmed over the air after pressing the button inside the battery compartment. ADDRESS is typically 0, which is a broadcast to all valves with the same HC1/HC2 pair. Each actuator can be programmed with a sub-address between 1 and 8, and a non-zero ADDRESS byte can be used to control a particular actuator individually. Information on the Internet suggests that a particular valve will accept only one command with matching HC1/HC2 per timeslot, so it is not possible to address multiple individual valves in any given 2 minute period (1 single valve or all valves in the group only).
The high nibble of the command byte defines some flag bits:
bit 7 - Indicates that this is a repeat transmission (the valves expect to see a message in every 2 minute frame or they assume loss of signal) bit 6 - Something to do with the optional base station. bit 5 - Extension bit present (always set for actuators). bit 4 - If set, sound a low battery warning if batteries are depleted
The low nibble defines a command as follows:
0 - Sync then set valve as specified in EXTENSION (see 6). Sent at the end of the sync sequence only. 1 - Valve fully open 2 - Valve fully closed 6 - Valve open to amount specified in EXTENSION. open % = <EXTENSION> * 100 / 255 8 - Offset adjustment. bit 7 is sign, rest is absolute value from 0 to 50 10 - Start descaling cycle then set valve as specified in EXTENSION (see 6) 12 - Sync countdown. Sent (twice) once per second. See below 14 - Test. Makes the actuator beep. 15 - Pairing. CHECK
To synchronise a controller and valve the controller must transmit a sync command on every second for two minutes. A down counter starting at 120 is sent on the extension byte of a command 12. The counter is sent in bits 7:1 with the LSB always set to 1. The last count to be sent is 3 (not 0). The first real transmission occurs 4 + 0.5 * (HC2 & 7) seconds later, after which the normal transmit period commences. For a controller communicating with multiple valves it must keep track of the next transmit time for each of the 8 possible time slots.
The example that Mike S gives in his blog at http://mikestirling.co.uk/notes/fht8v-protocol/ is synchronising with a valve having house code 10 04 then setting it to 50% open:
0A 04 00 2C F1 37 [SYNC(241)] - pause 1 second 0A 04 00 2C EF 35 [SYNC(239)] - pause 1 second 0A 04 00 2C ED 33 [SYNC(237)] - pause 1 second 0A 04 00 2C EB 31 [SYNC(235)] - pause 1 second ... 0A 04 00 2C 05 4B [SYNC(5)] - pause 1 second 0A 04 00 2C 03 49 [SYNC(3)] - pause 6 seconds 0A 04 00 20 00 3A [SYNC_END(0)] - pause 117 seconds 0A 04 00 26 80 C0 [SET(128)] - pause 117 seconds 0A 04 00 A6 80 40 [REPEAT SET(128)] - pause 117 seconds
DHD20130212: It seems that the sync process can be dispensed with if prepared to transmit the desired valve state at least once per second instead. Not efficient, but it is simple.
DHD20130120: I understand that the radio is only on for 1s every 2 minutes, which if so requires high (sub-second) transmission-to-transmission accuracy from anything managing the TRV (or brute-force command retransmissions at least once a second) implying an external clock/RTC, and a sophisticated control loop that can schedule other long tasks on a single thread without missing the slot to talk to the FHT8V
MS: Required resolution is half a second with an ideal accuracy of maybe 10 ms. The valves will resync on each message so long term accuracy is not critical. This is easily within the capabilities of any micro with a hardware timer. I will write up the details of the sync process later on.
DHD20130120: I'm contemplating one of a couple of hideous workrounds for the moment: either transmit more than once per second all the time (which may still be <10% radio duty cycle), or broadcast a burst of transmissions less than 1s apart up to or around where the 2 minute mark is estimated to be. I'm going to try to use an external RTC (on order) to try to keep the 2-minute spacing good, and then the burst-of-transmissions technique eventually. Dunno: still restructuring my control loop skeleton to allow something like this. the PICAXE is not made for precision timing, and the initial solution can be mains powered!
MS20130125: I now have a fully working implementation that can perform the initial sync and then update the valve position, sending the transmission automatically at the correct time. This is a useful step forward.
The next task will be to sync with multiple valves at the same time, for which I will need to get some more FHTs ordered. The sync protocol is addressed, so this may involve syncing with every single node separately unless I discover a way to do some sort of house-code broadcast.
(Also MS suggests that for my purposes to have an RFM22 behave like an RFM23 I should wire it up as fig 32b (RXANT to GPIO0, TXANT to GPIO1) and add 8-bit writes to GPIO 0 and 1 config of 0x15 and 0x12 respectively.)
DHD20130213: Succeeded with RFM23 (omitting $b,$15, $c,$12 register settings) and RFM22 (with them included) talking to FHT8V!
PJ20130212: The http://busware.de product CUL (has) some tricks for talking to multiple FHT8V valves by assigning each its own house code. Might be useful.
DHD20130214: On the bottom of my FHT8V-3 TRV is the note "RX: RX868SH-DV" which seems to refer to ELV's RX868SH-DV 868MHz super-het receiver module, eg see http://homematic-forum.de/forum/viewtopic.php?f=4&t=7834 (German), translated: http://translate.google.co.uk/translate?hl=en&sl=de&u=http://homematic-forum.de/forum/viewtopic.php%3Ff%3D4%26t%3D7834&prev=/search%3Fq%3Drx868sh-dv%26hl%3Den%26client%3Dfirefox-a%26hs%3D20H%26tbo%3Dd%26rls%3Dorg.mozilla:en-US:official&sa=X&ei=CbscUZKkNofAhAeD0oCQBg&ved=0CEEQ7gEwAQ
DHD20130228: I haven't been changing any 'repeat' bit (nor doing the sync yet, of course) and have not come unstuck: why not, do you think?
MS replied: I assume you have it clear. I guess it only matters for commands that actually do a one-shot operation, like the test command and the de-scale. If you just keep telling it to set the valve to the same place then it isn't going to take any action anyway.
After a lengthy period without receiving anything from the thermostat (maybe 1h or 2h), the TRV makes a tinkly sound and sets the valve to 30% open.