MYS Library Startup Control ? After()? OnRegistration()?


  • Plugin Developer

    In v2.0+ (I dont remember if it was the same in 1.5), there seems to be a sort of pseudo multitasking sequence happening in background when Mysensors.h is included in the sketch.

    One of the consequence is that setup() function occurs at the "same" time as the Mysensor launch/presentation/registration process.

    I discovered a before() function, which permits to be sure to launch instructions BEFORE launching MYS, but I did not discovered any after() function wich would allow me to send MyMessages only ONCE the init with the gateway has been completed :
    I mean after the "init complete, id=xx, parent=0, distance=1, registration=1"

    So the questions are :

    1. What is the recommended way to launch (setup) code only ONCE the node is registered at the gateway, ie for sensing state of initial values. Is there some sort of after() function, or OnRegistered() function ?

    2. Is there some documentation (expect reverse engineering the big MYS library) to understand all the steps that are happening in the background, when launching the library as a node.

    3. It seems that since v2.0 , if the node is unable to find a gateway (ie the GW is too far, or offline) the sketch no longer launch... is there any mechanism to controls this behaviour (ie start anyway, being able to determine is the registration was successfull or not, and if not periodically try to register) ?

    Thank you


  • Hero Member

    @soif said:

    So the questions are :

    1. What is the recommended way to launch (setup) code only ONCE the node is registered at the gateway, ie for sensing state of initial values. Is there some sort of after() function, or OnRegistered() function ?

    A simple way would be to add a bit of code to the start of the loop

    int executeOnce = 0;
    
    void setup()
    { }
    
    void loop()
    {
    
    if (executeOnce == 0) {
    
        // Put code here to be executed once at startup
    
       }
        executeOnce = 1;
      }
    
    }
    

    In MySensors V2.1 you can also use isTransportReady() to check if the uplink has been completed

    if (isTransportReady()) {               // check if transport is available
         /*--- put code here to be executed when transport ready----- */
    }        
    

    Perhaps you could combine the two methods

    1. It seems that since v2.0 , if the node is unable to find a gateway (ie the GW is too far, or offline) the sketch no longer launch... is there any mechanism to controls this behaviour (ie start anyway, being able to determine is the registration was successfull or not, and if not periodically try to register) ?

    Yes in 2.1 MY_TRANSPORT_WAIT_READY_MS will do what you want. Have a look at this post for a bit of info on how it works.


  • Plugin Developer

    hi @Boots33

    Thank you for your really helpful answer! :-D

    Following your guidelines, I've succeeded to send MyMessages after registration is completed. Here is the code :

    boolean executeOnce = false;
    
    void setup(){ }
    
    void loop(){
     if ( ! executeOnce  && isTransportReady() ) {
        // code here to be executed once at startup
       // ...
        executeOnce = true;
     }
    }
    

    Regarding 3), here is the behaviour I would like to build:

    • Start MYsensors library
    • if startup registration works, continue to loop
    • if startup registration fails before 5s, continue to the loop
    • every 15 min try to register to the GW (either if initially failed, or if transport have dropped later)

    I've read the helpfull topic you have linked, and started to guess from reading the MyConfig.h : Is this simple code, the right one to act like I wish

    #define MY_TRANSPORT_WAIT_READY_MS 5000
    #define MY_TRANSPORT_SANITY_CHECK
    // already set as default
    //#define MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS (15*60*1000ul)
    

    Obviously, in the loop, I always have to send MyMessages, with the ACK parameter set to false, to NOT wait for ACK replies whenever the GW is not available, right?

    Cheers


  • Hero Member

    @soif said:

    Regarding 3), here is the behaviour I would like to build:

    Start MYsensors library
    if startup registration works, continue to loop
    if startup registration fails before 5s, continue to the loop

    You have those covered with your new code :)

    every 15 min try to register to the GW (either if initially failed, or if transport have dropped later)
    I've read the helpfull topic you have linked, and started to guess from reading the MyConfig.h : Is this simple code, the right one to act like I wish

    #define MY_TRANSPORT_WAIT_READY_MS 5000
    #define MY_TRANSPORT_SANITY_CHECK
    // already set as default
    //#define MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS (15601000ul)

    I am not sure as to how MY_TRANSPORT_SANITY_CHECK works. Reading MyConfig.h as you have done it does appear that it is only set to on for gateways and repeater nodes. so that would mean if your node is not a repeater then yes you would need to set it as you have done above.

    @tekka did say in the other post that if the timeout for MY_TRANSPORT_WAIT_READY_MS is reached without an uplink established the node will continue to try and connect so maybe MY_TRANSPORT_SANITY_CHECK is not needed. Perhaps tekka can set us right on this.

    Obviously, in the loop, I always have to send MyMessages, with the ACK parameter set to false, to NOT wait for ACK replies whenever the GW is not available, right?

    I think that will depend on what you are trying to do. Certainly you will not get an ack back if your uplink is not available, but your message will not be sent anyway so without transport available you may not want to send the message at all.

    Keep in mind that all of these transport checks only confirm that you have a connection to the gateway not all the way to the controller.


  • Admin

    @Boots33 @soif

    Setting MY_TRANSPORT_SANITY_CHECK enables regular radio HW checks (i.e. verify radio register settings), the check interval is set via MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS. This check is solely HW-based and does not verify uplink status or similar.

    To achieve what @soif talked about, this may be an approach:

    #define MY_TRANSPORT_WAIT_READY_MS (5*1000ul)
    #define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (15*60*1000ul)
    

    MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE defines the transport re-init interval, if radio is non-functional and/or uplink check failed.



  • @tekka

    to follow up on this: I am trying to build a robust network so for my battery nodes I need to limit the parent finding to save some energy. These two defines work very well.
    #define MY_TRANSPORT_STATE_RETRIES 2 works also, but when I try to use #define MY_TRANSPORT_MAX_TSM_FAILURES 1 the counter still goes up to 7 before the extended failure mode is entered with the longer wait period.

    Am I doing something wrong, or is this broken in some way?


  • Admin

    @DavidZH You have to change the setting here (it is by design not configurable in the user sketch): https://github.com/mysensors/MySensors/blob/development/core/MyTransport.h#L164



  • @tekka

    Found it! I added a #ifndef so I do not have to change it every time I program a node (and forget at what setting it is the next time....).


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.