   return result;
 }
 
-static void sendMessage () {
-  byte payload [3];
-  payload[0] = hex2bin(lastChars + 3);
-  payload[1] = hex2bin(lastChars + 5);
-  payload[2] = hex2bin(lastChars + 7);
+static void sendId (byte id) {
+  if (history[id].resends > 0) {
+    --history[id].resends;
 
-  if (shouldSend(payload)) {
+    byte payload [3];
+    payload[0] = id;
+    payload[1] = history[id].value;
+    payload[2] = history[id].value >> 8;
+
     while (!rf12_canSend())
       rf12_recvDone();
     rf12_sendStart(0, payload, sizeof payload);
+  }
+}
+
+static void sendIfChanged () {
+  byte id = hex2bin(lastChars+3);
+  word newval = hex2bin(lastChars+5) + (hex2bin(lastChars+7) << 8);
+
+  if (newval != history[id].value) {
+    history[id].value = newval;
+    history[id].resends = RESEND_COUNT;
+    sendId(id);
   }
 }
 

    // done, or invalid: clear the lastChars buffer
    lastFill = 0;
  }
}

/// Read out the OpenTherm gateway and relay readings using RFM12B.
/// @see http://jeelabs.org/2012/11/20/opentherm-relay/
/// @see http://jeelabs.org/2012/11/21/reducing-the-payload-size/
/// @see http://jeelabs.org/2012/11/22/reducing-the-packet-rate/
// 2012-11-11 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <JeeLib.h>

#define RESEND_COUNT 10   // send each new value out this often

// buffer to collect last data received
byte lastChars[9], lastFill;

MilliTimer resendTimer;   // fires once a second
byte resendCursor;        // cycles over all the history entries

// the last values received, one entry for each ID 0..255
struct { word value; byte resends; } history [256];

static byte hex2bin (const byte* hex) {
  byte result = (hex[0] - (hex[0] <= '9' ? 0 : 7)) << 4;
