Multiple sensor data in one message
I've been playing with mysensors for some days now and I can say that, for now, it is very well suited for my needs.
There are some parts that I had some trouble with though, and I would like to bring this up.
For now, I have used rfm69CW/HCW and some BMP280 sensors, but I plan to switch to HTU21d because I only need temperature/humidity for most of my room monitoring devices (haven't yet gotten the time to create a power profile for those yet, though).
For BMP280 (it was supposed to be a BME280 but it seems I got scammed again on Aliexpress) I have a good understanding of its power profile.
When sending humidity/baro/temperature/battery, I need to add a sleep(5-10) between sends otherwise it takes between 300ms-1000ms to send everything - I assume is some sort of collision (I've seen some discussions around this subject). If the sleeps are added, I get around 100ms for the RF activity. If sending a single data type, I get lower than 20ms for one send.
As the 100ms effectively doubles the time spent in the whole iteration comparing to a single message, I was wondering if there is any possibility to combine multiple sensor data in one message. 24 bytes seem more than enough for what I need. I have also looked through the code but it seems to me that messages can have only one sensor data. I am thinking that maybe a special new type could be used that causes the gateway to reconstruct multiple messages from that one if a certain structure is used. But I don't want to get too much into it without asking around if there is any plan for that (or maybe there's already something not obvious to me).
If there isn't and there's no plan for it, I would like to look into it when I get some time.
I have decided to implement this myself.
The code seems to work. I have added a new "MyBlob" object that can handle multiple sensor data in one message, as I wanted to keep the MyMessage.h header clean. I will probably add a pull request when I get the time to document it.
The usage is quite simpe:
#ifdef USE_BLOB MyMessage msgBlob(0, V_BLOB); #else MyMessage msgTEMPERATURE(CHILD_ID_TEMPERATURE, V_TEMP); MyMessage msgHUMIDITY(CHILD_ID_HUMIDITY, V_HUM); #endif
#ifdef USE_BLOB MyBlob blob(&msgBlob); blob.set(V_TEMP, CHILD_ID_TEMPERATURE , temperature, 1); blob.set(V_HUM, CHILD_ID_HUMIDITY, humidity, 1); blob.setBattery(batt_level); send(msgBlob); #else send(msgTEMPERATURE.set(temperature, 1)); wait(10); send(msgHUMIDITY.set(humidity, 1)); wait(10); sendBatteryLevel(batt_level); #endif
The sketch I have added uses Adafruit_HTU21DF.h, where I have also changed the delay() to sleep(),
I have the following results when reading and sending the data. The times I have are now:
T on: 23 avg: 31 min: 19 max: 443
T on: 95 avg: 108 min: 72 max: 510
On average, 31 ms vs 108 when sending temperature/humidity/battery ( I realize the battery level doesn't need to be sent too often, but still...)
Considering a 300mA CR2032 battery with a 5 minute update time, it can last a whole year.
There are probably other ways of packing up more data (e.g. one doesn't really need 5 bytes to send temperature information with one decimal precision, 3 bytes should be enough for environmental measurement) but that's another story.
.Some logs from the gateway in the generic case:
Feb 03 07:19:59 DEBUG RFM69:SAC:SEND ACK,TO=1,RSSI=-99 Feb 03 07:19:59 DEBUG RFM69:CSMA:RSSI=-102 Feb 03 07:19:59 DEBUG TSF:MSG:READ,1-1-0,s=0,c=1,t=0,pt=7,l=5,sg=0:17.2 Feb 03 07:19:59 DEBUG GWT:TPS:TOPIC=mysensors-out/1/0/1/0/0,MSG SENT Feb 03 07:19:59 DEBUG RFM69:SAC:SEND ACK,TO=1,RSSI=-91 Feb 03 07:19:59 DEBUG RFM69:CSMA:RSSI=-100 Feb 03 07:19:59 DEBUG TSF:MSG:READ,1-1-0,s=1,c=1,t=1,pt=7,l=5,sg=0:49.6 Feb 03 07:19:59 DEBUG GWT:TPS:TOPIC=mysensors-out/1/1/1/0/1,MSG SENT Feb 03 07:19:59 DEBUG RFM69:SAC:SEND ACK,TO=1,RSSI=-74 Feb 03 07:19:59 DEBUG RFM69:CSMA:RSSI=-97 Feb 03 07:19:59 DEBUG TSF:MSG:READ,1-1-0,s=255,c=3,t=0,pt=1,l=1,sg=0:0 Feb 03 07:19:59 DEBUG GWT:TPS:TOPIC=mysensors-out/1/255/3/0/0,MSG SENT
And in the "blob" case:
Feb 03 07:22:02 DEBUG RFM69:SAC:SEND ACK,TO=1,RSSI=-99 Feb 03 07:22:02 DEBUG RFM69:CSMA:RSSI=-99 Feb 03 07:22:02 DEBUG TSF:MSG:READ,1-1-0,s=0,c=1,t=57,pt=6,l=20,sg=0:E10000D4758A4101E1010140204D42012300FF00 Feb 03 07:22:02 DEBUG GWT:TPS:TOPIC=mysensors-out/1/0/1/0/0,MSG SENT Feb 03 07:22:02 DEBUG GWT:TPS:TOPIC=mysensors-out/1/1/1/0/1,MSG SENT Feb 03 07:22:02 DEBUG GWT:TPS:TOPIC=mysensors-out/1/255/3/0/0,MSG SENT
Let me know what you think. Eventually let me know what other parts I should touch, as I'm not that familiar with the whole code...
InTranceWeTrust last edited by
I personally use the Home Assistant controller. Do i have to make any changes to the controller itself to recognize V_BLOB messages ?
There should be no need for anything in the controller. The gateway will reconstruct different messages from the blob and send them one by one to the controller (as if they were passed individually), assuming the registration is done as in the "no blob" case. But one should be careful about how many messages fit in one block, the MyBlob.set() will return false if the desired message will not fit in the available space and in this case one should do a send() and then construct a new block. Probably a "reset()" API should be added to MyBlob to ease re-using it instead of constructing a new one....
I have added a pull request for this (#1515).