MySensors ethernet 2.2.0 problem with control node switches



  • Hi
    I am beginner… Yesterday i installed Haspbian on my RPI3 and start configuration…Home Assistant version 0.63.3
    I also connect radio RFM69HW to GPIO on raspberry and start compile and build MySensors Gateway based on ETHERNET. Finally i finished it and connect MySensors Gateway to Home Assistant by ethernet.

    Configuration mysensors gatway looks like:

    mysensors:
    gateways:

    • device: '127.0.0.1’
      persistence_file: '/home/homeassistant/.homeassistant/mysensors.json’
      tcp_port: 5003
      optimistic: false
      persistence: true

    Then i connected node Mysenors based on Arduino MIni Pro with connected relay.
    Sketch uploaded to node looks like:

    /*
    Relay with button sketch
    modified to work with no uplink
    to gateway and try to maintain sync to controller
    */
    
    #define MY_DEBUG // Enable debug prints to serial monitor
    
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW
    #define RFM69_868MH
    #define MY_RFM69_NEW_DRIVER
    
    //#define MY_NODE_ID 203 // Node id defaults to AUTO (tries to fetch id from controller)
    
    #define MY_TRANSPORT_WAIT_READY_MS 5000 //set how long to wait for transport ready in milliseconds
    
    #define MY_REPEATER_FEATURE // Enabled repeater feature for this node
    
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN 5 // Arduino Digital I/O pin number for relay
    #define BUTTON_PIN 3 // Arduino Digital I/O pin number for button
    #define CHILD_ID 1 // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce();
    int oldValue = 0;
    bool uplinkAvailable = true;
    bool state = false;
    bool requestState;
    bool firstStart = true;
    unsigned long uplinkCheckTime ; // holder for uplink checks
    unsigned long uplinkCheckPeriod = 30*1000; // time between checks for uplink in milliseconds
    unsigned long returnWait = 1000; // how long to wait for return from controller in milliseconds… adjust as needed
    unsigned long oldTime = 0;
    unsigned long newTime = 0;
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup(){
    pinMode(BUTTON_PIN, INPUT_PULLUP); // Setup the button pin, Activate internal pull-up
    
    debouncer.attach(BUTTON_PIN); // After setting up the button, setup debouncer
    debouncer.interval(5);
    
    pinMode(RELAY_PIN, OUTPUT); // set relay pin in output mode
    digitalWrite(RELAY_PIN, RELAY_OFF); // Make sure relay is off when starting up
    }
    
    void presentation() {
    // Send the sketch version information to the gateway and Controller
    sendSketchInfo(“1xRelay & Button”, “2.2.0”);
    
    // Register all sensors to gw (they will be created as child devices)
    present(CHILD_ID, S_BINARY);
    }
    
    void loop(){
    if (firstStart) { // this code is only run once at startup
    Serial.println(“First run started”);
    requestTime(); // get time from controller
    wait (returnWait); // delay to allow time to return
    if (oldTime == 0){ // check to see if there was a return from the time request
    Serial.println(“uplink not available”);
    uplinkAvailable = false; // no uplink established
    uplinkCheckTime = millis();
    }
    else{
    Serial.println(“uplink available”);
    request( CHILD_ID, V_STATUS); // get status of switch on controller
    wait (returnWait); //wait needed to allow request to return from controller
    Serial.print("controller state — ");
    Serial.println(requestState);
    if (requestState != state) { // check that controller is corectly showing the current relay state
    send(msg.set(state), false); // notify controller of current state
    }
    }
    firstStart = false; // set firstStart flag false to prevent code from running again
    }
    
    debouncer.update();
    int value = debouncer.read(); // Get the update value
    if (value != oldValue && value == 0) { // check for new button push
    state = !state; // Toggle the state
    digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF); // switch the relay to the new state
    requestTime();
    wait (returnWait); // delay to allow time to return
    if (oldTime != newTime){ // if times are different then uplink is available
    send(msg.set(state), false);
    oldTime = newTime;
    }
    else{ // if times are the same no uplink is available
    Serial.println(“uplink not available”);
    uplinkAvailable = false; // no uplink available, set flag false
    uplinkCheckTime = millis(); // start the timer from now
    }
    
    }
    oldValue = value;
    
    if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) { // test to see if function should be called
    uplinkCheck(); // call uplink checking function
    }
    
    }
    
    /-------------------start of functions--------------------------/
    
    void receive(const MyMessage &message) {
    if (message.type == V_STATUS) { // check to see if incoming message is for a switch
    switch (message.getCommand()) { // message.getCommand will give us the command type of the incomming message
    case C_SET: //message is a set command from controller to update relay state
    state = message.getBool(); // get the new state
    digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF); // switch relay to new state
    uplinkAvailable = true; // uplink established
    /---- Write some debug info----/
    Serial.print(“Incoming change for sensor:”);
    Serial.print(message.sensor);
    Serial.print(", New status: ");
    Serial.println(message.getBool());
    break;
    case C_REQ: // message is a returning request from controller
    requestState = message.getBool(); // update requestState with returning state
    break;
    }
    }
    }
    
    void uplinkCheck() {
    requestTime();
    wait (returnWait); // wait for time return… this may need to be varied for your system
    if (oldTime != newTime){
    Serial.println(“uplink re-established”);
    request( CHILD_ID, V_STATUS);
    wait (returnWait); //wait needed to allow request to return from controller
    if (requestState != state) { // check that controller is corectly showing the current relay state
    send(msg.set(state), false); // notify controller of current state no ack
    uplinkAvailable = true; // uplink established
    oldTime = newTime;
    }
    }
    uplinkCheckTime = millis(); // reset the checktime
    Serial.println(“uplinkchecktime reset”);
    }
    
    void receiveTime(unsigned long time)
    {
    if (firstStart){
    oldTime = time;
    newTime = time;
    }
    else{
    newTime = time;
    }
    Serial.print("time received---- " );
    Serial.println(time);
    }```
    
    All based on library 2.2.0 MySensors.
    
    After that i found in Home Assistant node and add friendly name and add to my one of group. But after boot Home Assistant i can by frontend only one change status relay… Example set ON, but when i try OFF it not working and button for one secund go to OFF and again go to ON.
    When change by pin wire on Arduino Mini Pro status always change ok. But only not work by frontend. Only one i can change.
    
    On my old Domoticz all works ok.
    
    Next problem is also with test controller. When i change relay to ON , then ex reboot gateway MySensor and when gateway is rebooting i change by wire pin status relay , it is not refresh on frontend HA. Still show status ON before reboot gateway. But on domoticz works ok and status after reboot gateway was refreshed and show correct status OFF.
    
    Please help me…

  • Plugin Developer

    Please edit your post and put the sketch within code blocks so it's readable.



  • ok corrected


  • Plugin Developer

    You need to feedback and send the changed state to home assistant, after writing the new state to the pin, in the receive function. Otherwise home assistant thinks that the message to change state did not reach the node, and returns to the old state.



  • @martinhjelmare

    Can you explaine me more. Sorry i am begginer user and i dont know how ? Please

    Or please correct it in my sketch...please


  • Plugin Developer

    Add the following line in the receive function eg after the call to digitalWrite.

    send(msg.set(state));
    


  • Hi
    Ok i add this and now sketch look like:

    /*
       Relay with button sketch
       modified to work with no uplink
       to gateway and try to maintain sync to controller
    */
    
    
    #define MY_DEBUG                               // Enable debug prints to serial monitor
    
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW
    #define RFM69_868MH
    #define MY_RFM69_NEW_DRIVER
    
    //#define MY_NODE_ID 203                       // Node id defaults to AUTO (tries to fetch id from controller) 
    
    #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
    
    #define MY_REPEATER_FEATURE                    // Enabled repeater feature for this node
    
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN  5      // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
    #define CHILD_ID 1        // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce();
    int oldValue = 0;
    bool uplinkAvailable = true;
    bool state = false;
    bool requestState;
    bool firstStart = true;
    unsigned long uplinkCheckTime ;                // holder for uplink checks
    unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
    unsigned long returnWait = 1000;               // how long to wait for return from controller in milliseconds.. adjust as needed
    unsigned long oldTime = 0;
    unsigned long newTime = 0;
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup(){
      pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
      
      debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
      debouncer.interval(5);
    
      pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
      digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("1xRelay & Button", "2.2.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID, S_BINARY);
    }
    
    
    void loop(){
      if (firstStart) {                            // this code is only run once at startup
        Serial.println("First run started");
        requestTime();                             // get time from controller
        wait (returnWait);                         // delay to allow time to return
        if (oldTime == 0){                         // check to see if there was a return from the time request
          Serial.println("uplink not available");
          uplinkAvailable = false;                 // no uplink established
          uplinkCheckTime = millis();
        }
         else{
          Serial.println("uplink available");
          request( CHILD_ID, V_STATUS);            // get status of switch on controller
          wait (returnWait);                       //wait needed to allow request to return from controller
          Serial.print("controller state --- ");
          Serial.println(requestState);
          if (requestState != state) {             // check that controller is corectly showing the current relay state
            send(msg.set(state), false);           // notify controller of current state
          } 
         }   
      firstStart = false;                                          // set firstStart flag false to prevent code from running again
     }
    
      debouncer.update();
      int value = debouncer.read();                               // Get the update value
      if (value != oldValue && value == 0) {                      // check for new button push
        state =  !state;                                          // Toggle the state
        digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
        requestTime();
        wait (returnWait);                                               // delay to allow time to return
        if (oldTime != newTime){                                  // if times are different then uplink is available
          send(msg.set(state), false);
          oldTime = newTime;
        }
        else{                                                    // if times are the same no uplink is available
         Serial.println("uplink not available");
          uplinkAvailable = false;                                // no uplink available, set flag false
          uplinkCheckTime = millis();                             // start the timer from now
        }
    
      }
      oldValue = value;
     
      if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
        uplinkCheck();                                                                  // call uplink checking function
      }
    
    }
    
    /*-------------------start of functions--------------------------*/
    
    void receive(const MyMessage &message) {
      if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
        switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
          case C_SET:                                                   //message is a set command  from controller to update relay state
            state = message.getBool();                                  // get the new state
            digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
            send(msg.set(state));
            uplinkAvailable = true;                                     //  uplink established
            /*---- Write some debug info----*/
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
            break;
          case C_REQ:                                               // message is a returning request from controller
            requestState = message.getBool();                       // update requestState with returning state
            break;
        }
      }
    }
    
    void uplinkCheck() {
        requestTime();
        wait (returnWait);                       // wait for time return.. this may need to be varied for your system
       if (oldTime != newTime){
         Serial.println("uplink re-established");
         request( CHILD_ID, V_STATUS);
         wait (returnWait);                        //wait needed to allow request to return from controller
        if (requestState != state) {              // check that controller is corectly showing the current relay state
          send(msg.set(state), false);            // notify controller of current state no ack
          uplinkAvailable = true;                 //  uplink established
          oldTime = newTime;
        }
      }
      uplinkCheckTime = millis();                // reset the checktime
      Serial.println("uplinkchecktime reset");
    }
    
    
    void receiveTime(unsigned long time)
    {
      if (firstStart){
        oldTime = time;
        newTime = time;
      }
      else{
      newTime = time;
    }
      Serial.print("time received---- " );
      Serial.println(time);
    }
    

    Now works ok but another problem. Ex When i enable relay and then reboot my RPI with Home Assistant and under reboot i manual change state relay by put pin to GND, then after run RPI with Home Assistant , it come back to previus state relay. Again set my relay as ENABLE.
    Is any chance to change it to after start HA he check state relay and setup in home assistant actual phisicaly state relay... not remembered before reboot ?

    And next problem... When node has relay ENABLE and power lost, then power come back relay again to ENABLE. But i want to RELAY always after power lost and power come back to relay go to DISABLE.


  • Mod

    Set the relay state in setup function?



  • @gohan
    Can you explaine me more because I am beginner and I don't know how?

    It is in "void setup" ?
    And what is command for setup state?


  • Mod

    add

    send(msg.set(RELAY_OFF), false);           // notify controller to show off state
    

    at end of setup function and see if you get the result you want



  • @gohan
    But it is for only show state off or also physical change state relay to off?

    void setup(){
    pinMode(BUTTON_PIN, INPUT_PULLUP); // Setup the button pin, Activate internal pull-up
    
    debouncer.attach(BUTTON_PIN); // After setting up the button, setup debouncer
    debouncer.interval(5);
    
    pinMode(RELAY_PIN, OUTPUT); // set relay pin in output mode
    digitalWrite(RELAY_PIN, RELAY_OFF); // Make sure relay is off when starting up
    send(msg.set(RELAY_OFF), false);           // notify controller to show off state
    }
    

    This is OK code?



  • @gohan said in MySensors ethernet 2.2.0 problem with control node switches:

    send(msg.set(RELAY_OFF), false); // notify controller to show off state

    ok looks that is ok but please give me a time i test it more.


 

346
Online

7.6k
Users

8.5k
Topics

91.2k
Posts