Make node look for new/better parent without restarting



  • Hi

    In my MySensors network I have a ESP8288 MQTT gateway and two repeaters and a number of sensor nodes. One of these are a button-node that I like to move around in my house. This means that sometimes I move it from one end of the house to the other, so it can no longer connect to the parent node it used to use. I know how to request an acknowledgement in the send method so I can resend the button-press-message, but is there a way to "give up" a parent node after a number of failed transmissions, and broadcast for a new one?

    I know I can do this by pulling the battery and restarting the node, but I'd rather it just do it by itself 🙂


  • Mod

    @henrik-nielsen welcome to the forum!
    I am not sure, but I think calling transportCheckUplink(true) before sending the message will verify connection to the gateway, and establish new parent if needed. Could you try it?



  • It sort of works, I get a ping and a missing pong:

    (254 is button node, 252 is repeater I turned off after the button node was started up)

    64442 TSF:PNG:SEND,TO=252
    64479 !TSF:MSG:SEND,254-254-252-252,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=NACK:1
    66488 TSF:CKU:FAIL
    

    But no looking for a new parent.

    I tried calling some functions I thought sounded like they would help me, without really knowing. I guess it is not functions that a user like me really should use?:

    if ( !transportCheckUplink() ) {
      stParentTransition();
      while ( isTransportSearchingParent() ) {
        stParentUpdate();
      }
    }
    

    This starts what appears to be a new parent search, but it never completes:

    151171 TSF:MSG:SEND,254-254-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    153180 !TSM:FPAR:NO REPLY
    153182 TSM:FPAR
    153219 TSF:MSG:SEND,254-254-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    155228 !TSM:FPAR:NO REPLY
    155230 TSM:FPAR
    155267 TSF:MSG:SEND,254-254-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    157276 !TSM:FPAR:NO REPLY
    157278 TSM:FPAR
    157315 TSF:MSG:SEND,254-254-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    159324 !TSM:FPAR:FAIL
    159326 TSM:FAIL:CNT=7
    159328 TSM:FAIL:DIS
    159330 TSF:TDI:TSL
    161333 !TSM:FPAR:NO REPLY
    161335 TSM:FPAR
    

    At this point I have started my repeater again, and I think it should also find either the gateway or another node.


  • Mod

    @henrik-nielsen nice work. I am not sure about the internal functions. Pinging @tekka, maybe he can assist.



  • I guess another way would be like this:

    if ( !transportCheckUplink() ) {
       asm volatile ("  jmp 0"); // CRASH, BURN AND RESET
     }
    

    It does the trick ... though it really bothers my developer-heart 😉


  • Admin

    @henrik-nielsen By default, a new parent it searched after 5 (regular node) or 10 (repeater) failed uplink transmissions - alternatively, you can be more restrictive, by setting MY_TRANSPORT_MAX_TX_FAILURES to anything smaller.



  • @henrik-nielsen said in Make node look for new/better parent without restarting:

    n my MySensors network I have a ESP8288 MQTT gateway and two repeaters and a number of sensor nodes. One of these are a button-node that I like to move around in my house. This means that sometimes I move it from one end of the house to the other, so it can no longer connect to the parent node it used to use. I know how to request an acknowledgement in the send method so I can resend the button-press-message, but is there a way to "give up" a parent node after a number of failed transmissions, and broadcast for a new one?
    I know I can do this by pulling the battery and restarting the node, but I'd rather it just do it by itself

    It's part of my code, ... roughly so

    void check_parent() {
      _transportSM.findingParentNode = true;
      CORE_DEBUG(PSTR("MyS: SEND FIND PARENT REQUEST, WAIT RESPONSE\n"));
      tx_led ();
      _sendRoute(build(_msg, 255, NODE_SENSOR_ID, 3, 7).set(""));
      wait(2000, 3, 8);
      if (_msg.sensor == 255) {
        if (mGetCommand(_msg) == 3) {
          if (_msg.type == 8) {
            Ack_FP = 1;
            CORE_DEBUG(PSTR("MyS: PARENT RESPONSE FOUND\n"));
          }
        }
      }
      if (Ack_FP == 1) {
        CORE_DEBUG(PSTR("MyS: FIND PARENT PROCESS\n"));
        rx_led ();
        Ack_FP = 0;
        transportSwitchSM(stParent);
        flag_nogateway_mode = 0;
        flag_find_parent_process = 1;
        CORE_DEBUG(PSTR("MyS: STANDART TRANSPORT MODE IS RESTORED\n"));
      } else {
        bc_led ();
        _transportSM.findingParentNode = false;
        CORE_DEBUG(PSTR("MyS: PARENT RESPONSE NOT FOUND\n"));
        _transportSM.failedUplinkTransmissions = 0;
        fp_timer = millis();
      }
    }
    


  • Sorry I haven't gotten back to you, been a busy week.

    The MY_TRANSPORT_MAX_TX_FAILURES seems to do the job perfectly, I adjusted it down to 1 for the node, and resend the message a couple of times if it fails.

    Thank you for your support 🙂

    Also thanks to berkseo, your code also works for me, but I do prefer the built in way now that I know of it. Less code for me to write and maintain 🙂


 

306
Online

7.8k
Users

8.7k
Topics

93.0k
Posts