Multiple sensor data in one message



  • Hi,

    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.

    Thanks,
    Constantin



  • I have decided to implement this myself.
    https://github.com/cpetra/MySensors
    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 
    

    and then:

      #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...

    Best Regards,
    Constantin



  • Sounds interesting.

    I personally use the Home Assistant controller. Do i have to make any changes to the controller itself to recognize V_BLOB messages ?



  • @InTranceWeTrust
    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).

    Best Regards,
    Constantin


Log in to reply
 

Suggested Topics

  • 90
  • 13
  • 2
  • 3
  • 3
  • 4

16
Online

11.4k
Users

11.1k
Topics

112.7k
Posts