Multi RF433 Switches Node



  • Hi.
    I'm trying sketching myself for 6 days and just gave up...
    I read all the Library API and Serial API and can't understand this line syntax "send(msg.set(value==HIGH ? 1 : 0));"
    What do those "?" ":" mean?

    Objective: Control 9 Livolo branded RF433 switches from home assistant through a mysensors node build with a chinese RFTX 433Mhz.

    Home Assistant demands mysensor's node send presentation and an initial value for all the child_id, so they use a "initialValueSent" variable to check if the gateway got those initial values and request this value to assure they were been sent in the loop section.

    I've got the livolo's library for mysensors and joined some sketches and got success controlling 1 switch with this:

    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #include <SPI.h>
    #include <MySensors.h>
    #include <livolo.h>
    
    #define CHILD_ID 1
    
    Livolo livolo(8);   //tx 433 in the dig 8 pin
    
    bool initialValueSent = false;
    
    MyMessage msg(CHILD_ID, V_LIGHT);
    
    void setup() {
      
    }
    
    void presentation()  {   
      sendSketchInfo("Livolo", "1.0");
      present(CHILD_ID, S_LIGHT);
    }
    
    void loop() {
      if (!initialValueSent) {
        int value = 0;
        Serial.println("Sending initial value");
        send(msg.set(value==HIGH ? 1 : 0)); // how to I know which child_id is sending this?
        Serial.println("Requesting initial value from controller");
        request(CHILD_ID, V_LIGHT);
        wait(2000, C_SET, V_LIGHT);
      }
    }
    
    void receive(const MyMessage &message) {
      if (message.type==V_LIGHT) {
         livolo.sendButton(6400, 120);
         if (!initialValueSent) {
           Serial.println("Receiving initial value from controller");
           initialValueSent = true;
         }
      }
       
    }
    

    I can change that livolo line
    livolo.sendButton(6400, 120);
    for another (remote control ID, and button ID) and control the other switches.

    I tryed changing a multi relay sketch but I can't understand and did not find anywhere explain the syntax of sending messages from different child_id and making different actions for different child_id received messages from the gateway.

    So I need to check if all 9 initial values were received and make a void receive with livolo.sendButton(REM_ID, BUT_ID) based on each switch.


  • Mod

    @OliverDog the ? Is called conditional operator. It is described here https://en.m.wikipedia.org/wiki/%3F:

    The RelayActuator example included with MySensors supports multiple relays. Documentation is provided inside that example and at https://www.mysensors.org/build/relay

    The child id for incoming messages is available through the message.sensor variable. You can use if clauses or a switch statement to do different things depending on the sensor id.

    Documentation on how to send data with different sensor id is available at https://www.mysensors.org/download/sensor_api_20#sending-data
    A node has one child id. Different relays use different sendor id, not different child id. Description of how a node works is available at https://www.mysensors.org/about/network

    Hope this helps you a few steps forward.



  • Thanks @mfalkvidd
    that ?: was killing my brain!! and I think I don't need conditional operator because the status need to be always off. It won't be 9 switches, but 9 momentary relays.

    I have already made a multi relay working, but my problem is not about creating and presenting 9 relays, but sending their initial status and confirming it was received by the gateway.

    I need to create 9 sensors (they won't send any data, just receive 9 different RF433 codes to reply), define an initial value for each one and confirm if the gateway got all those initial values before starting the receiving loop.

    And finally I need to config two types of received messages
    When receiving a initial value from gateway, I need to change initValSentX to true for each sensor.
    And when receiving a command from each virtual switch I need to reply a livolo.sendButton(REM_ID, BUT_ID) command.

    I think it is very simple but I can't figure out how coding it!
    Wrong way??

    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #include <SPI.h>
    #include <MySensors.h>
    #include <livolo.h>
    
    #define CHILD_ID 1
    
    Livolo livolo(8);
    
    bool initValSent1 = false;
    bool initValSent2 = false;
    bool initValSent3 = false;
    bool initValSent4 = false;
    bool initValSent5 = false;
    bool initValSent6 = false;
    bool initValSent7 = false;
    bool initValSent8 = false;
    bool initValSent9 = false;
    
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup() {
      
    }
    
    void presentation()  {   
      sendSketchInfo("Livolo", "1.0");
      for (int sensor=1; sensor<=9; sensor++) { 
        // (presents each sensor, S_BINARY type)
        present(sensor, S_BINARY);
      }
    }
    
    void loop() {
      if (!initValSent1) {
        int value1;
        Serial.println("Sending initial value for each sensor");
        send(msg.set(value1==0)); 
        Serial.println("Requesting initial value for each sensor");
        request(CHILD_ID, V_STATUS);
        wait(2000, C_SET, V_STATUS);
      }
      if (!initValSent2) {
        int value2;
        Serial.println("Sending initial value for each sensor");
        send(msg.set(value2==0));
        Serial.println("Requesting initial value for each sensor");
        request(CHILD_ID, V_STATUS);
        wait(2000, C_SET, V_STATUS);
      }
    // thought making 7 more like these.
    
    }
    
    void receive(const MyMessage &message) {
      if (message ACTION FROM THE VIRTUAL SWITCH ON THE CONTROLLER) {
         if message from sensor 1
           livolo.sendButton(6400, 120); // coded for each sensor
         if message from sensor 2
           livolo.sendButton(6400, #70); // coded for each sensor
         // make 7 more like this
      if (message INITIAL VALUE ANSWER FROM THE GATEWAY ) {
         if (!initValSent1) {
           Serial.println("Receiving initial value from controller");
           initValSent1 = true;
         }
         // make 7 more like this
      }
    }
    
    

  • Contest Winner

    @OliverDog Maybe this will work for you

    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #include <SPI.h>
    #include <MySensors.h>
    #include <livolo.h>
    
    #define CHILD_ID 1
    
    Livolo livolo(8);
    
    bool initValSent[]   = {false, false, false, false, false, false, false, false, false};
    int livoloSensCode[] = {120, 70, 1, 2, 3, 4, 5, 6, 7}; // Set correct livolo codes here
    
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup() {
      
    }
    
    void presentation()  {   
      sendSketchInfo("Livolo", "1.0");
      for (int sensor=1; sensor<=9; sensor++) { 
        // (presents each sensor, S_BINARY type)
        present(sensor, S_BINARY);
      }
    }
    
    void loop() {
      for (int sensor=1; sensor<=9; sensor++) { 
        if (!initValSent[sensor]) {
          msg.setSensor(sensor);
          send(msg.set(false)); 
          Serial.println("Requesting initial value for each sensor");
          request(sensor, V_STATUS);
          wait(2000, C_SET, V_STATUS);
        }
      }
    }
    
    void receive(const MyMessage &message) {
      switch (message.type) {
        case V_LIGHT:
           if (!initValSent[message.sensor]) {
              Serial.println("Receiving initial value from controller");
              initValSent[message.sensor] = true;
           } else {
              Serial.println("Receiving new value");
              livolo.sendButton(6400, livoloSensCode[message.sensor]); // coded for each sensor 
           }    
           break;
      }
    }
    
    


  • Nice @BartE
    Almost got it working...

    It keeps asking for the 9 sensor value and receiving the same value as a new value forever...

    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0



  • In fact, it apear it does not ask for the value, it only receives new value.
    Here is the entire Serial Monitor until the infinite loop:

    TSM:INIT
    TSM:RADIO:OK
    TSP:ASSIGNID:OK (ID=19)
    TSM:FPAR
    TSP:MSG:SEND 19-19-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=bc:
    TSP:MSG:READ 0-0-19 s=255,c=3,t=8,pt=1,l=1,sg=0:0
    TSP:MSG:FPAR RES (ID=0, dist=0)
    TSP:MSG:PAR OK (ID=0, dist=1)
    TSM:FPAR:OK
    TSM:ID
    TSM:CHKID:OK (ID=19)
    TSM:UPL
    TSP:PING:SEND (dest=0)
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=ok:1
    TSP:MSG:READ 0-0-19 s=255,c=3,t=25,pt=1,l=1,sg=0:1
    TSP:MSG:PONG RECV (hops=1)
    TSP:CHKUPL:OK
    TSM:UPL:OK
    TSM:READY
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100
    TSP:MSG:SEND 19-19-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=ok:2.0.0
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=ok:0
    TSP:MSG:READ 0-0-19 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=11,pt=0,l=6,sg=0,ft=0,st=ok:Livolo
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=ok:1.0
    TSP:MSG:SEND 19-19-0-0 s=1,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=2,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=3,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=4,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=5,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=6,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=7,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=8,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 19-19-0-0 s=9,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    Request registration...
    TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=ok:2
    TSP:MSG:READ 0-0-19 s=255,c=3,t=27,pt=1,l=1,sg=0:1
    Node registration=1
    Init complete, id=19, parent=0, distance=1, registration=1
    TSP:MSG:SEND 19-19-0-0 s=1,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=1,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=1,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=2,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=2,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=3,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=3,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=3,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=4,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=4,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=4,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=5,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=5,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=5,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=6,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=6,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=6,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=7,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=7,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=7,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=8,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=8,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=8,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    TSP:MSG:SEND 19-19-0-0 s=9,c=1,t=2,pt=1,l=1,sg=0,ft=0,st=ok:0
    Requesting initial value for each sensor
    TSP:MSG:SEND 19-19-0-0 s=9,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-19 s=9,c=1,t=2,pt=0,l=1,sg=0:0
    Receiving new value
    

  • Contest Winner

    @OliverDog Sorry my (beginners) fault the array's are counting from 0 to 8 and the sensor numbers from 1 till 9

    This should work:

    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #include <SPI.h>
    #include <MySensors.h>
    #include <livolo.h>
    
    #define CHILD_ID 1
    
    Livolo livolo(8);
    
    bool initValSent[]   = {false, false, false, false, false, false, false, false, false};
    int livoloSensCode[] = {120, 70, 1, 2, 3, 4, 5, 6, 7}; // Set correct livolo codes here
    
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup() {
      
    }
    
    void presentation()  {   
      sendSketchInfo("Livolo", "1.0");
      for (int sensor=1; sensor<=9; sensor++) { 
        // (presents each sensor, S_BINARY type)
        present(sensor, S_BINARY);
      }
    }
    
    void loop() {
      for (int sensor=1; sensor<=9; sensor++) { 
        if (!initValSent[sensor-1]) {
          msg.setSensor(sensor);
          send(msg.set(false)); 
          Serial.print("Requesting initial value for sensor: ");
          Serial.println(sensor);
          request(sensor, V_STATUS);
          wait(2000, C_SET, V_STATUS);
        }
      }
    }
    
    void receive(const MyMessage &message) {
      switch (message.type) {
        case V_LIGHT:
           if (!initValSent[message.sensor-1]) {
              Serial.print("Receiving initial value from controller for sensor: ");
              initValSent[message.sensor-1] = true;
           } else {
              Serial.print("Receiving new value for sensor: ");
              livolo.sendButton(6400, livoloSensCode[message.sensor-1]); // coded for each sensor 
           }  
           Serial.println(message.sensor);  
           break;
      }
    }
    
    


  • Perfect @BartE !!!

    Great job you did... you contributed greatly to a breakthrough in inexpensive home automation.

    Now we can buy the cheapest good finished glass RF in-wall home switches from Livolo and got total integration with All Home Automation Controllers, using one mysensors node.

    here is the final code, I added the remote code var

    // This skecth was created by @BartE from mysensors forum.
    // it was created to control 9 switches
    // livolo.h library necessary to work.
    // Just use a simple node + chinese cheap RF433 transmitter DATA plugged on Pin D8.
    
    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #include <SPI.h>
    #include <MySensors.h>
    #include <livolo.h>
    
    #define CHILD_ID 1
    
    Livolo livolo(8); //Digital pin you plugged your transmitter
    
    // now config your remote and button codes. Livolo codes are composed by "remote code, button code"
    // There are many codes already discovered, and you can test new codes or get your remote's code using the daleldalel skectch
    bool initValSent[]   = {false, false, false, false, false, false, false, false, false}; //as many as your switch number
    int livoloRemCode[]  = {5504, 5504, 5504, 7849, 7849, 7849, 17035, 17035, 17035}; //set remote livolo codes here
    int livoloSensCode[] = {16, 56, 8, 16, 8, 56, 16, 56, 8}; // Set buttons livolo codes here
    
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup() {
      
    }
    
    void presentation()  {   
      sendSketchInfo("Livolo", "1.0");
      for (int sensor=1; sensor<=9; sensor++) { // change number 9 for the total switches number you want
        // (presents each sensor, S_BINARY type)
        present(sensor, S_BINARY);
      }
    }
    
    void loop() {
      for (int sensor=1; sensor<=9; sensor++) {  // change number 9 for the total switches number you want
        if (!initValSent[sensor-1]) {
          msg.setSensor(sensor);
          send(msg.set(false)); 
          Serial.print("Requesting initial value for sensor: ");
          Serial.println(sensor);
          request(sensor, V_STATUS);
          wait(2000, C_SET, V_STATUS);
        }
      }
    }
    
    void receive(const MyMessage &message) {
      switch (message.type) {
        case V_LIGHT:
           if (!initValSent[message.sensor-1]) {
              Serial.print("Receiving initial value from controller for sensor: ");
              initValSent[message.sensor-1] = true;
           } else {
              Serial.print("Receiving new value for sensor: ");
              livolo.sendButton(livoloRemCode[message.sensor-1], livoloSensCode[message.sensor-1]); // coded for each switch 
           }  
           Serial.println(message.sensor);  
           break;
      }
    }
    
    

Log in to reply
 

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