MySensors development notes 2.0.x
Supported controller backhaul transport types and allowed features (towards controller)
Type | TCP | UDP | Static IP | DHCP | MQTT Client |
ESP8266 | X | X | X | X | X |
W5100 | X | X | X | X | X |
ENC28j60 | X | X | |||
Serial | N/A | N/A | N/A | N/A | N/A |
NRF24L01+ | N/A | N/A | N/A | N/A | N/A |
RFM69 | N/A | N/A | N/A | N/A | N/A |
All gateway variants supports an optional sub network of 254 nodes. The gateway itself can also act as a node with directly attached sensors.
Supported forward link transport types and allowed features
Type | OTA FW Update | Signing | Encryption | ||
NRF24L01+ | X | X | X | ||
RFM69 | X | X | X | ||
RS232/RS485 | ? | ? | ? |
Hoperf Radio module selection chart
Features | High power | Footprint | Footprint compatible | Frequency | Size | Notes | |
RFM69HW | RFM69 | Yes RX : 16mA TX : 16-130mA | W | RFM69W | 433-915Mhz | 19,7x20 | |
RFM69HCW | CW | RFM95/96/97/98W | 16x16 | ||||
RFM69W | No RX : 16mA TX : 16-45mA | W | RFM69HW | 19,7x20 | |||
RFM69CW | CW | 16x16 | |||||
RFM95W | Not mysensors compatible yet | Yes RX : 10,8-12mA TX : 20-120mA | W | RFM69HCW | 868-915Mhz | 16x16 | Spreading factor : 6-12 |
RFM96W | 433-470Mhz | Spreading factor : 6-9 | |||||
RFM97W | 868-915Mhz | Spreading factor : 6-12 | |||||
RFM98W | 433-470Mhz | Spreading factor : 6-12 |
Add the following to activate NRF-radio support
#define MY_RADIO_NRF24
Remove MySensor constructor
MySensors gw;
Remove MySensors setup() call
gw.setup(....);
If node expects incoming messages, add the following function to handle data:
void receive(const MyMessage &msg) {}
Move present() and sendSketchInfo() from setup() to a new function called presentation().
void presentation() {
sendSketchInfo(...)
present(...);
}
If you’re using static ids , add:
#define MY_NODE_ID xx
If static parent node is used, add:
#define MY_PARENT_NODE_ID xx
If you want node to be a repeater, add
#define MY_REPEATER_FEATURE
If you need to reconfigure your CE/CS Pins (not needed if NRF is connected to default pins)
#define MY_RF24_CE_PIN 9
#define MY_RF24_CS_PIN 10
Remove all “gw.” before MySensors library calls.
If node requests time using requestTime(), remove callback argument define define the following function to handle time response:
void receiveTime(unsigned long ts) {
}
Make sure to include MySensor.h after any configuration defines.
Split out two new repos and keep git-history from the old Arduino-project
https://help.github.com/articles/splitting-a-subfolder-out-into-a-new-repository/
http://stackoverflow.com/questions/359424/detach-subdirectory-into-separate-git-repository
Arduino (old repo transformed a bit[a][b][c][d])
examples
<all examples here>
MySensors (submodule pointing to MySensors) ← NOTE
keywords.txt
README.md
MySensors.h ← Only includes MySensors/MyConfig.h and core/MySensors.h
library.json
library.properties
MySensors (new repo[e])
README.md
MySensors.h ← The old MySensors.h
MyConfig.h
Version.h
MyCapabilities.h
MyEepromAddresses.h
MyMainDefault.cpp
MyMainESP8266.cpp
MyMessage.cpp
MyMessage.h
MySensorCore.cpp
MySensorCore.h
MyPrivateConfig.h.sample
driver
AES
AltSoftSerial
ATSHA204
…
gateway
MyGatewayTransport.cpp
MyGatewayTransport.h
MyGatewayTransportEthernet.cpp
MyGatewayTransportMQTTClient.cpp
MyGatewayTransportSerial.cpp
hw
MyHw.h
MyHwATMega328.cpp
MyHwATMega328.h
MyHwESP8266.cpp
MyHwESP8266.h
MyHwSAMD.cpp
MyHwSAMD.h
button
MyInclusionMode.cpp
MyInclusionMode.h
led
MyLeds.cpp
MyLeds.h
protocol
MyProtocol.h
MyProtocolMySensors.cpp
signing
MySigning.cpp
MySigning.h
MySigningAtsha204.cpp
MySigningAtsha204Soft.cpp
transport
MyTransport.cpp
MyTransport.h
MyTransportNRF24.cpp
MyTransportRFM69.cpp
MyTransportRS485.cpp
MySensors Hardware AVR (new repo : ArduinoHwAVR)
README.md
… <board files>
MySensors Hardware SAMD (new repo: ArduinoHwSAMD)
README.md
… <board files>
MySensors Hardware
README.md
package_mysensors.org_index.json
<packages of the above two repositories>
Arduino Support Libraries (new repo)
Adafruit_BMP085
Adafruit_FONA_Library
Adafruit_NeoPixel
BH1750
Bounce2
DHT
DS3232RTC
DallasTemperature
DigitalIO
EmonLib
Encoder
GSM-GPRS-GPS-Shield-GSMSHIELD
HeatpumpIR
IRLib
InterruptChain
LiquidCrystal
LowPower
MAX6675
MsTimer2
MySensors (Submodule to Arduino) ← NOTE
NewPing
NewRemoteSwitch
OneWire
Oregon
PN532
PN532_I2C
PWF_AS3935_Lightning_Sensor
PinChangeInt
PubSubClient
RemoteSensor
RemoteSwitch
RunningAverage
SFE_BMP180
SI7021
SPIFlash
SimpleTimer
Time
Timer
TinyGPSPlus
UIPEthernet
UTFT
UTFT_Buttons
UTouch
readme.txt
sha204
The new version has some added functionality from a controller plugin developers perspective.
I_HEARTBEAT - New potential message sent from node to say “I’m alive”. You can use this as a ping message by sending a I_HEARTBEAT to a node. Node replies with I_HEARTBEAT_RESPONSE and an incremental integer as payload.
I_PRESENTATION - Send this to a node if controller wants to request presentation messages again after startup. This also triggers a configuration request from node.
I_DISCOVER / I_DISCOVER_RESPONSE
Controller broadcasts I_DISCOVER <page nr> to request all present, i.e. actively listening nodes. Nodes reply with I_DISCOVER_RESPONSE containing the requested page nr. If no or invalid page nr is requested, page 0 will be returned.
Forwarding: Repeater node only forwards broadcasted I_DISCOVER (i.e. destination = 0xFF)
pages, fix assignment 0 - 4, i.e. these pages always exist
Page | Description |
0 | Parent node id |
1 | general |
2 | architecture |
3 | uplink transport |
4 | bootloader |
n | depending on PAGE_TYPE_ID |
PAGE_TYPE_ID, page types (max 16)
ID | Description |
0 | fast discovery |
1 | general information about node, platform-independent |
2 | architecture information (freq, voltage, etc.) |
3 | bootloader information (vers, etc.) |
4 | transport (config, freq, encryption, signing, etc.) |
5 | periphery (flash, eeprom, security chip) |
n | ... |
MY_HWID, architecture ID (max 16)
MY_HWID | Description |
0000 | unknown |
0001 | AVR |
0010 | ESP8266 |
0011 | SAMD |
0100 | Raspberry |
0101 | RTL8710 |
0110 | nRF24LE1 (experimental, limited) |
xxxx | ...beaglebone, Intel Galileo, Cortex M3? Future platforms? |
I_DISCOVER_RESPONSE - PAYLOAD
2 bytes general header, send in every I_DISCOVER_RESPONSE payload:
payload header
Byte | Bit | Len | Description |
1 | 0..4 | 5 | Page |
1 | 5..7 | 3 | Protocol version |
2 | 0..3 | 4 | PAGE_TYPE_ID |
2 | 4..7 | 4 | MY_HWID |
page: fast discovery
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..7 | 8 | Parent node ID |
page: general information
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..4 | 5 | total # pages defined (max 31) |
3 | 5..7 | 3 | total # transports defined (max 7) |
4 | 0..3 | 4 | Node type, bits (0=sensors attached, 1=repeater, 2=gateway, 3=bridge) |
4 | 4..7 | 4 | Power type, bits (0=PSU, 1=battery, 2=solar, 3=reserved) e.g. PSU with backup = 0011, solar with battery = 0110 |
5 | 0..7 | 8 | Parent ID |
6 | 0..7 | 8 | Distance to GW |
7 | 0 | 1 | OTA FW feature (MY_OTA_FIRMWARE_FEATURE) |
7 | 1 | 1 | OTA reset allowed (MY_DISABLE_REMOTE_RESET) |
7 | 2 | 1 | Sleeping node (MY_SLEEPING_NODE/automatic?) |
7 | 3..7 | 5 | reserved |
8 | 0..32 | 32 | Heartbeat counter (incremental) ⇒ eventually redundant, value can be requested via I_HEARTBEAT |
9 | |||
10 | |||
11 | |||
12 | 0..15 | 16 | FW type (EEPROM) |
13 | |||
14 | 0..15 | 16 | FW version (EEPROM) |
15 | |||
16 | 0..15 | 16 | FW blocks (EEPROM) |
17 | |||
18 | 0..15 | 16 | FW CRC (EEPROM) |
19 |
0xFF = not defined/error
page: architecture information - AVR (platform specific definitions)
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..23 | 24 | Device signature (e.g. AT328p=0x1E950F, AT2560 = 0x1E9801, etc.) |
4 | |||
5 | |||
6 | 0..3 | 4 | MCUSR, reset cause, i.e. PORF, EXTRF, BORF, WDRF |
6 | 4..7 | 4 | CLKPR, clock prescaler, 2^0-2^8 |
7 | 0..15 | 16 | actual voltage in mV |
8 | |||
9 | 0..15 | 16 | actual frequency in 1/10Mhz |
10 | |||
11 | 0..7 | 8 | Low fuse |
12 | 0..7 | 8 | Lock fuse |
13 | 0..7 | 8 | Extended fuse |
14 | 0..7 | 8 | High fuse |
15 | 0..15 | 16 | Free RAM |
16 |
0xFF = not defined/error
page: architecture information - SAMD(platform specific definitions)
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..7 | 8 | tbd |
4 | 0..7 | 8 | tbd |
5 | 0..7 | 8 | tbd |
0xFF = not defined/error
page: architecture information - ESP8266 (platform specific definitions)
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..31 | 32 | CPU ID |
4 | |||
5 | |||
6 | |||
7 | 0..31 | 32 | Flash ID |
8 | |||
9 | |||
10 | |||
11 | 0..15 | 16 | actual frequency in 1/10Mhz |
12 | |||
13 | 0..15 | 16 | actual voltage in mV |
14 |
0xFF = not defined/error
page: bootloader information
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..7 | 8 | Bootloader type, 0=None, 1=MYSBootloader, 2=Dualoptiboot |
4 | 0..7 | 8 | Version major |
5 | 0..7 | 8 | Version minor |
6 | 0..15 | 16 | CRC bootloader |
7 |
0xFF = not defined/error
page: transport
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..3 | 4 | Transport type, 0=Unknown, 1=NRF24L01+, 2=RFM69, 3=RS232, 4=RS485, 5=TCP (max. 16) |
3 | 4 | 1 | Transport direction (0=to parent/GW/controller, 1=to child nodes) |
3 | 5..7 | 3 | reserved |
4 | 0 | 1 | Signing enabled (this node is capable of signing messages) |
4 | 1 | 1 | Signing required (this node will reject any unsigned message sent to it) |
4 | 2 | 1 | Whitelisting enabled (sender has to salt serial to the signature of messages to this node) |
4 | 3..7 | 5 | reserved |
5 | 0..2 | 3 | Encryption 0=none, 1=AES, 2=reserved, 3=reserved |
5 | 3..7 | 5 | reserved |
6 | 0..7 | 8 | Data rate |
7 | 0..7 | 8 | Tx power, dBm
|
8 | 0..15 | 16 | RF channel / frequency / TCP port |
9 | |||
10 | 0..7 | 8 | Base address 1 / IP |
11 | 0..7 | 8 | Base address 2 / IP |
12 | 0..7 | 8 | Base address 3 / IP |
13 | 0..7 | 8 | Base address 4 / IP |
14 | 0..7 | 8 | reserved |
0xFF = not defined/error
page: periphery
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..7 | 8 | periphery type, 0=NVRAM, 1=security chip, etc. |
4 | 0..7 | 8 | ID / size - tbd |
5 | 0..7 | 8 | ID / size - tbd |
6 | 0..7 | 8 | ... |
0xFF = not defined/error
page: discover - idea stage
Byte | Bit | Len | Description |
1 | 0..7 | 8 | Header byte 1 |
2 | 0..7 | 8 | Header byte 2 |
3 | 0..7 | 8 | nodes in surrounding |
4 | 0..7 | 8 | nodeid1 (0xFF = not defined) |
5 | 0..7 | 8 | lowest Tx power (dBm) to reach
|
6 | 0..7 | 8 | nodeid2 |
7 | 0..7 | 8 | lowest Tx power |
... | 0..7 | 8 | ... |
0xFF = not defined/error
Bootloader writes to EEPROM:
EEPROM_RESET_CAUSE_ADDRESS 1 Byte AVR: MCUSR
EEPROM_BOOTLOADER_MAJOR 1 Byte
EEPORM_BOOTLOADER_MINOR 1 Byte
0xFF = not defined/error
Extend usage of EEPROM for configuration-sensitive setups
I_LOG_MESSAGE - extension
Enhancement FW OTA updates
2 new ST_STREAM types:
ST_FIRMWARE_VALIDATION_REQUEST
⇒ request sha256 digest of newly transmitted FW for validation
ST_FIRMWARE_VALIDATION_RESPONSE
⇒ signed sha256 digest to validate FW transfer and activate sketch
ST_FIRMWARE_RESPONSE
MQTT - BREAKING CHANGE - The MySensors library now has build in MQTT client gateway but the mqtt-topic has changed a bit from the previous provided MQTT example. The new MQTT topic resembles the serial protocol which mean just numeral values in topic - no string VARs - this saves space and future maintenance.
MY_MQTT_PUBLISH_TOPIC_PREFIX/NODE-ID/SENSOR-ID/CMD-TYPE/ACK-FLAG/SUB-TYPE
Example outgoing topic (with default prefix) :
mygateway1-out/1/2/2/0/1
Example topic for sending data to your sensor network (with default prefix) :
mygateway1-in/1/2/2/0/1
This also means a controller can (and should) answer the id-requests and time requests via the MQTT broker just like it is handled for the serial protocol today. Ack messages from sensors is also supported.
New sensor types
S_INFO - LCD text device / Simple information device on controller, V_TEXT
S_GAS - Gas meter, V_FLOW, V_VOLUME
S_GPS - GPS Sensor, V_POSITION
New variables
V_CUSTOM - Custom messages used for controller
V_TEXT - S_INFO. Text message to display on LCD or controller device
r/inter node specific commands, preferably using S_CUSTOM device type.
V_POSITION - GPS position and altitude. Payload: latitude;longitude;altitude(m). E.g. "55.722526;13.017972;18"
TBD: There is a lot of boilerplate code in sensors sketches. Like checking if it is time to send in new sensor data based on time or change. Alexander earlier proposed that we could have a few helper-classes for a few standard scenarios[f].
The base classes could be something like:
Sender - sends data every X seconds or on change, interrupt driven, binary/analog values.
Receiver - handles incoming data
Clock - scheduled sending (based on RTC)
We could then provide a register method of these (with a few different implementations), like this:
Sender x = new BinarySender(pin, sendOnChange, throttling);
gw.register(x, <sensorType>, <sensorId>);
Where logic could be handled by process() in the background...
Possible variants..
AnalogSender(pin,....)
GenericSensor(callbackForFetchingDataFromSensor, sendOnChange, minSendInterval)
PWMReceiver(controlPin, transformerForIncomingDataCallback)
BinaryReceiver(controlPin, transformForIncomingDataCallback);
...
…
WE have one board on the wild; the SenseBender. We have also now defined (but not publicly announced) the MYSX connector which offer the ability to dock daughterboards to newer MySensors boards (not yet in the wild). The connector defines unique signal names for all its io and it would be convenient to be able to use these names in the sketches and libraries (we could define signal names for all other MySensors specific io as well like radio interfaces).
The Arduino IDE supports a board specific header for the board selected when compiling.
By extending this header for at least our own boards with the MYSX signal definitions (and possibly other signals) the board selection can be used to manage most hw specific deltas.
By including MyConfig.h in the board header (if that is possible) or the opposite (include board header in MyConfig.h) we could provide overridable defaults for all io.
Update: probably we skip MYSX definitions in MyConfig.h alltogether. A sketch compiled for a board that does not natively support MYSX will have to define the mappings itself if it wants to use them (as the library cannot possibly know the mapping on a generic board).
Now available (and should be improved) on documentation branch. Jenkins provide visualization of the most current doxygen results and also displays any doxygen related warnings.
Signing test framework
We have test sketches for security related features that at least ensures the library compile with these features enabled in Arduino/libraries/MySensors/tests/Arduino/sketches/
MySensors debug logs, >= 2.0.1
Format:
[!]SYSTEM:[SUB SYSTEM:]MESSAGE
Systems:
Short | Description | File |
MCO | MySensors core | MySensorsCore.cpp |
TSM | Transport state machine | MyTransport.cpp |
TSF | Transport support function | MyTransport.cpp |
RF24 | RF24 driver | RF24.cpp |
RFM69 | RFM69 driver | RFM69.cpp |
SIG | Signing backend | MySigning.cpp |
... |
Log messages:
E | SYS | SUB | Message | Comment |
| MCO | BGN | INIT %s,CP=%s,LIB=%s | Core initialization, capabilities (CP), library version (VER) |
| MCO | BGN | INIT OK,ID=%d,PAR=%d,DIS=%d,REG=%d | Core initialized, parent ID (PAR), distance to GW (DIS), registration (REG) |
| MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter) |
! | MCO | BGN | TSP FAIL | Transport initialization failed |
| MCO | REG | REQ | Registration request |
| MCO | REG | NOT NEEDED | No registration needed (i.e. GW) |
! | MCO | SND | NODE NOT REG | Node is not registered, cannot send message |
| MCO | PIM | NODE REG=%d | Registration response received, registration status (REG) |
| MCO | PIM | ROUTE N=%d,R=%d | Routing table, messages to node (N) are routed via node (R ) |
| MCO | NLK | NODE LOCKED. UNLOCK: GND PIN %d AND RESET | Node locked during booting, see signing chapter for additional information |
TSM | INIT | Transition to stInit state | ||
TSM | INIT | STATID,ID=%d | Node ID (ID) is static | |
TSM | INIT | TSP OK | Transport device configured and fully operational | |
TSM | INIT | GW MODE | Node is set up as GW, thus omitting ID and findParent states | |
! | TSM | INIT | TSP FAIL | Transport device initialization failed |
TSM | FPAR | Transition to stParent state | ||
TSM | FPAR | STATP=%d | Static parent (STATP) set, skip finding parent | |
TSM | FPAR | OK | Parent node identified | |
! | TSM | FPAR | NO REPLY | No potential parents replied to find parent request, retry |
! | TSM | FPAR | FAIL | Finding parent failed, go to failure state |
TSM | ID | Transition to stID state | ||
TSM | ID | OK,ID=%d | Node ID (ID) is valid | |
TSM | ID | REQ | Request node ID from controller | |
! | TSM | ID | FAIL,ID=%d | ID verification failed, ID (ID) invalid |
TSM | UPL | Transition to stUplink state | ||
TSM | UPL | OK | Uplink OK, GW returned ping | |
! | TSM | UPL | FAIL | Uplink check failed, i.e. GW could not be pinged |
TSM | READY | Transition to stReady, i.e. transport is ready and fully operational | ||
! | TSM | READY | UPL FAIL,SNP | Too many failed uplink transmissions, search new parent |
! | TSM | READY | FAIL,STATP | Too many failed uplink transmissions, no SNP, static parent enforced |
TSM | FAILURE | Transition to stFailure state | ||
TSM | FAILURE | PDT | Power-down transport | |
TSM | FAILURE | RE-INIT | Attempt to re-initialize transport | |
TSF | CHKUPL | OK | Uplink OK | |
TSF | CHKUPL | OK,FCTRL | Uplink OK, flood control prevents pinging GW in too short intervals | |
TSF | CHKUPL | DGWC,O=%d,N=%d | Checking uplink revealed a changed network topology, old distance (O), new distance (N) | |
TSF | CHKUPL | FAIL | No reply received when checking uplink | |
TSF | ASID | OK,ID=%d | Node ID (ID) assigned | |
TSF | PING | SEND,TO=%d | Send ping to destination (TO) | |
TSF | MSG | ACK REQ | ACK message requested | |
TSF | MSG | ACK | ACK message, do not proceed but forward to callback | |
TSF | MSG | FPAR RES,ID=%d,D=%d | Response to find parent received from node (ID) with distance (D) to GW | |
TSF | MSG | FPAR PREF FOUND | Preferred parent found | |
TSF | MSG | FPAR OK,ID=%d,D=%d | Find parent response from node (ID) is valid, distance (D) to GW | |
TSF | MSG | FPAR INACTIVE | Find parent response received, but no find parent request active, skip response | |
TSF | MSG | FPAR REQ,ID=%d | Find parent request from node (ID) | |
TSF | MSG | PINGED,ID=%d,HP=%d | Node pinged by node (ID) with (HP) hops | |
TSF | MSG | PONG RECV,HP=%d | Pinged node replied with (HP) hops | |
TSF | MSG | BC | Broadcast message received | |
TSF | MSG | GWL OK | Link to GW ok | |
TSF | MSG | FWD BC MSG | Controlled broadcast message forwarding | |
TSF | MSG | REL MSG | Relay message | |
TSF | MSG | REL PxNG,HP=%d | Relay PING/PONG message, increment hop counter (HP) | |
TSF | SANCHK | OK | Sanity check passed. This ensures radio functionality and automatically attempts to re-initialize in case of failure | |
TSF | CRT | OK | Clearing routing table successful | |
! | TSF | ASID | FAIL,ID=%d | Assigned ID (ID) is invalid, e.g. 0 (GATEWAY) |
! | TSF | ROUTE | FPAR ACTIVE | Finding parent active, message not sent |
! | TSF | ROUTE | DST %d UNKNOWN | Routing for destination (DST) unknown, send message to parent |
! | TSF | SEND | TNR | Transport not ready, message cannot be sent |
! | TSF | MSG | PVER,%d!=%d | Message protocol version mismatch |
! | TSF | MSG | SIGN VERIFY FAIL | Signing verification failed |
! | TSF | MSG | REL MSG,NORP | Node received a message for relaying, but node is not a repeater, message skipped |
! | TSF | MSG | SIGN FAIL | Signing message failed |
! | TSF | MSG | GWL FAIL | GW uplink failed |
! | TSF | SANCHK | FAIL | Sanity check failed, attempt to re-initialize radio |
Idea stage, MySensors 3.0.0
[a]Can't see the benefit of splitting this into two repos.. Mysensors Core should be a standalone library, that you could import into arduino (using library manager) and then compile one of the sketches..
[b]Hm, yes. If we can expect other architecture be able to handle the structures enforced by the arduino library manager
[c]So this is made, because we envision that we will jump on another IDE wagon at some point in time? (That is, making it independent of arduino build environment?)
[d]At least it is my vision :) If we do a refactoring, it could pay off to not paint ourself into the Arduino IDE corner
[e]Can this repo build stand alone, perhaps with a simple sketch?
[f]I've partially implemented something similar to this (prior to reading this document) here ( https://github.com/brahmafear/MySensors_Node ). Please contact me with any suggestions.