How to find out if message was successfully delivered?



  • I did successfully build the Power Meter Pulse Sensor and use it with Domoticz.

    Next, I would like to have a LED on the sensor indicate whether messages are successfully delivered (e.g one blink) or not (e.g. three blinks).

    As far as I understand the ack should be set true while sending. E.g.

    gw.send(kwhMsg.set(kwh, 4)),true)
    

    However, I cannot figure out how to evaluate the result. I.e. if the destination node send ack back.


  • Contest Winner

    Hi @arraWX

    When you set the ack boolean to true while sending a message the gateway will return the message with the ACK bit set.

    So you have to handle this message with code like this

    setup ()
    {
       ... do stuff
    
       gw.begin(incomingMessage, AUTO, true);
    
      ... do more stuff
    }
    
    
    void incomingMessage(const MyMessage &message) {
      if (message.isAck()) {
          Serial.println("This is an ack from gateway");
          if (message.sensor == YOUR_KWH_SENSOR_ID) {
                 toggleLed();
          }
      }
    }
    


  • @arraWX
    I solved it by doing this, it is just a few rows from the sketch

    
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    ...
    void setup()
    gw.present(CHILD_ID_BATTERY, S_MULTIMETER);
    ...
    void loop()
    ...
    int sensorValue = analogRead(A0);
    float batteryVolt=sensorValue*(3.3/1023);
    resend((voltage_msg.set(batteryVolt, 3)), 10);
    
    void resend(MyMessage &msg, int repeats)
    {
      int repeat = 1;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (gw.send(msg)) {
          sendOK = true;
        } else {
          sendOK = false;
          Serial.print("Error ");
          Serial.println(repeat);
          repeatdelay += 500;
        } repeat++; delay(repeatdelay);
      }
    }
    
    

    which means, it will send batteryVolt with 3 decimals to Controller and try 10 times.
    If it doesn't get OK after 10 times it will not try again until it is time to send data next time.



  • @arraWX

    You could also use code like this:

    bool delivered = gw.send(kwhMsg.set(kwh, 4)),true);
    if !(delivered){
    // put code here to take corrective actions, ... 
    }
    

    BR,

    Boozz


  • Contest Winner

    @boozz and @flopp what you check here is that the message successfully was broadcast-ed to the next node.
    This can be either the gateway or a repeater node.

    With the reception of an acknowledge message you are sure that the original message was delivered at the gateway (and back).



  • @BartE
    Oh, then my check is just half way.

    I will test with your ACK, seems the best solution to confirm that it was sent OK


  • Contest Winner

    @flopp

    Here is a reliable delivery discussion with more information


  • Mod

    The reliable delivery stuff in MySensors is utterly confusing. In the discussion BartE linked to there is this post which suggested ways to prevent even more people from being confused by the documentation and code. Unfortunately, it turned out that 2 and 3 had already been done in the development version, but it is not available in the official documentation since the development version hasn't been made stable yet. Learning that all my hard work was in vain really pissed me off.

    I am really sorry that you also had to learn the hard way how this stuff works.



  • I have tested around now.

    Domoticz on RPi 3.5273
    Mysensors 1.5.1
    Arduino UNO(clone) NRF24+ with 100uF cap

    And what I see is that a acknowledge is working better if the value change since last time, strange.

    float temp=0;
    #include <SPI.h>
    #include <MySensor.h>  
    #define CHILD_ID_TEMP 1
    unsigned long SLEEP_TIME = 10000; // Sleep time between reads (in milliseconds)
    
    MySensor gw;
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    void setup()  
    { 
      gw.begin(incomingMessage, AUTO);
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo("Humidity", "9",true);
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_TEMP, S_TEMP,"def" ,true);  
    }
    
    void loop()      
    {  
    temp=temp+0.2;
    gw.send(msgTemp.set(temp, 1),true);
    gw.wait(SLEEP_TIME);
    }
    
    void incomingMessage(const MyMessage &message) {
      if (message.isAck()) {
          Serial.println("This is an ack from gateway");
          }
    }
    

    Debug output

    send: 22-22-4-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 22-22-4-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:4
    read: 0-4-22 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=22, parent=4, distance=2
    send: 22-22-4-0 s=255,c=3,t=11,pt=0,l=8,sg=0,st=ok:Humidity
    send: 22-22-4-0 s=255,c=3,t=12,pt=0,l=1,sg=0,st=ok:9
    send: 22-22-4-0 s=1,c=0,t=6,pt=0,l=3,sg=0,st=ok:def
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.2
    read: 0-4-22 s=255,c=3,t=11,pt=0,l=8,sg=0:Humidity
    read: 0-4-22 s=255,c=3,t=12,pt=0,l=1,sg=0:9
    read: 0-4-22 s=1,c=0,t=6,pt=0,l=3,sg=0:def
    This is an ack from gateway
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.2
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.4
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.4
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.6
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.6
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.8
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.8
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:1.0
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:1.0
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:1.2
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:1.2
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:1.4
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:1.4
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:1.6
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:1.6
    This is an ack from gateway
    

    Same value every send, same sketch but I removed temp=temp+0.2
    Debug output

    send: 22-22-4-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 22-22-4-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:4
    read: 0-4-22 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=22, parent=4, distance=2
    send: 22-22-4-0 s=255,c=3,t=11,pt=0,l=8,sg=0,st=ok:Humidity
    send: 22-22-4-0 s=255,c=3,t=12,pt=0,l=1,sg=0,st=ok:9
    send: 22-22-4-0 s=1,c=0,t=6,pt=0,l=3,sg=0,st=ok:def
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    read: 0-4-22 s=255,c=3,t=11,pt=0,l=8,sg=0:Humidity
    read: 0-4-22 s=255,c=3,t=12,pt=0,l=1,sg=0:9
    read: 0-4-22 s=1,c=0,t=6,pt=0,l=3,sg=0:def
    This is an ack from gateway
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.0
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.0
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.0
    This is an ack from gateway
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    send: 22-22-4-0 s=1,c=1,t=0,pt=7,l=5,sg=0,st=ok:0.0
    read: 0-4-22 s=1,c=1,t=0,pt=7,l=5,sg=0:0.0
    This is an ack from gateway
    
    


  • @BartE said:

    gw.begin(incomingMessage, AUTO, true);
    

    you can actually remove TRUE, that mean this is a Repeater Node



  • A big thanks to all of you! I learned a lot from your answers.

    For now I think that hardware ack is sufficient. I can now place a sensor in different locations and tell from its LED wether or not messages are recieved by the gateway (I have no repeater nodes yet).



  • @arraWX Can you given an example of a sketch you run with the LED logic in?



  • @Mark-Swift In the sensebender sketch I replaced

    gw.send(msgTemp.set(temperature,1));
    

    with

        if(gw.send(msgTemp.set(temperature,1)))
        {
          digitalWrite(LED_PIN,LOW);
        }
        else
        {
          digitalWrite(LED_PIN,HIGH);
        }
    

    LED is OFF if meassages are successfully delivered. LED turns ON if meassage delivery fails and stays ON until a new meassage is successfully delivered.

    Note that I use mysensors 1.5 as I did not yet update to mysensors 2.0. In 2.0 gw. is not needed


Log in to reply
 

Suggested Topics

  • 1
  • 1
  • 5
  • 3
  • 6
  • 3

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts