Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Node to Node communication

Node to Node communication

Scheduled Pinned Locked Moved Development
22 Posts 3 Posters 220 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • boumB boum

    Yes, you should replace the sleep with a wait. If you module is sleeping, it won't receive any message.
    While prototyping/debugging, you should put more Serial.print around your blocks, not only in the innermost block.

    I guess you are mixing different things in the message object. In the receive() function, you should test message.sensor against 10, the sensor value you put in the sent message, 15 is the node ID destination, that is the current node.

    A Offline
    A Offline
    APL2017
    wrote on last edited by APL2017
    #10

    @boum Thank you! So, in my receiving function i should have the following, where 10 is sending node?

    void receive(const MyMessage &message)
     {if (message.type==V_TRIPPED)
      {if (message.sensor==10)
        { Serial.print(message.sensor);
          Serial.print("\n");
          Serial.print(", New status: ");
          Serial.print(message.getBool());
          LEAK_RECEIVED=message.getBool();
        }
        }
     }
    
    1 Reply Last reply
    0
    • BearWithBeardB Offline
      BearWithBeardB Offline
      BearWithBeard
      wrote on last edited by BearWithBeard
      #11

      sensor or sensor ID is synonymous for child ID, one of the many sensors a single node can have. sender is the ID of the node which sent the message.

      On the sending node:

      #define MY_NODE_ID 7
      //                 ^ sender / node ID
      [...]
      MyMessage msg_LEAK_to_15( 10, V_TRIPPED );
      //                        ^^ sensor / child ID
      [...]
      msg_LEAK_to_15.setDestination(15);
      //                            ^^ ID of the destination / receiving node
      

      On the receiving node:

      // returns sender / node ID (7)
      msg.getSender();
      
      // returns sensor / child ID (10)
      msg.getSensor();
      

      So yes, with the changes in your latest code snipped, you should start seeing some serial output.

      On a different note: Not that it would change anything here, but l'd like to advise to use the availabe getter and setter functions, whenever possible.

      message.sensor==10 works perfectly fine if you want to compare the current value of the variable against 10. But if you accidently omit one of the equal signs, you assign 10 to the variable instead. Bugs like these can be hard to spot - the if-condition would always evaluate true in this case. Using message.getSensor() prevents such mistakes.

      A 1 Reply Last reply
      1
      • BearWithBeardB BearWithBeard

        sensor or sensor ID is synonymous for child ID, one of the many sensors a single node can have. sender is the ID of the node which sent the message.

        On the sending node:

        #define MY_NODE_ID 7
        //                 ^ sender / node ID
        [...]
        MyMessage msg_LEAK_to_15( 10, V_TRIPPED );
        //                        ^^ sensor / child ID
        [...]
        msg_LEAK_to_15.setDestination(15);
        //                            ^^ ID of the destination / receiving node
        

        On the receiving node:

        // returns sender / node ID (7)
        msg.getSender();
        
        // returns sensor / child ID (10)
        msg.getSensor();
        

        So yes, with the changes in your latest code snipped, you should start seeing some serial output.

        On a different note: Not that it would change anything here, but l'd like to advise to use the availabe getter and setter functions, whenever possible.

        message.sensor==10 works perfectly fine if you want to compare the current value of the variable against 10. But if you accidently omit one of the equal signs, you assign 10 to the variable instead. Bugs like these can be hard to spot - the if-condition would always evaluate true in this case. Using message.getSensor() prevents such mistakes.

        A Offline
        A Offline
        APL2017
        wrote on last edited by
        #12

        @BearWithBeard Thank you. I do not define my nodes ID, they are being assigned automatically (by controller? gateway?), but I do see nodes ID in my controller configuration. Is this a problem?

        1 Reply Last reply
        0
        • BearWithBeardB Offline
          BearWithBeardB Offline
          BearWithBeard
          wrote on last edited by
          #13

          I'm not sure if a node's automatically assigned ID can change in special circumstances (apart from clearing the EEPROM), but as long as you don't care about which specific node sent a message in a node-to-node relationship, this shouldn't be a problem. So it's best to avoid using msg.getSender() on the receiving node.

          I just added a static node ID in the example above to better illustrate what each variable means, since you seem to mix up sender and sensor.

          A 1 Reply Last reply
          1
          • BearWithBeardB BearWithBeard

            I'm not sure if a node's automatically assigned ID can change in special circumstances (apart from clearing the EEPROM), but as long as you don't care about which specific node sent a message in a node-to-node relationship, this shouldn't be a problem. So it's best to avoid using msg.getSender() on the receiving node.

            I just added a static node ID in the example above to better illustrate what each variable means, since you seem to mix up sender and sensor.

            A Offline
            A Offline
            APL2017
            wrote on last edited by
            #14

            @BearWithBeard Sorry, I am still confused. Is it possible to publish a complete example of sending Boolean from one node to another to be used in control logic? Thank you.

            1 Reply Last reply
            0
            • BearWithBeardB Offline
              BearWithBeardB Offline
              BearWithBeard
              wrote on last edited by BearWithBeard
              #15

              Unfortunately, I don't have a test setup running right now, otherwise I would quickly whip up and test two minimal example sketches.

              But here are some snippets that should include everything related to node-to-node communication you need. My best advice at this point, if it still confuses you, is to get rid of all the magic numbers in the code and define macros / constants.

              On the leak detector node, you need the following bits:

              bool leakState = false;
              bool previousLeakState = false;
              
              #define LEAK_CHILD_ID 0 // 0 to 254
              #define LEAK_CHILD_ID_TO_NODE 100 // 0 to 254
              #define LEAK_TARGET_NODE_ID 15 // The ID of the node you want to report to
              
              // Setup two separate messages. One reports to the GW, the other to the target node
              MyMessage msgToGw(LEAK_CHILD_ID, V_TRIPPED);
              MyMessage msgToNode(LEAK_CHILD_ID_TO_NODE, V_TRIPPED);
              
              void presentation() 
              {
              	// Register and present sketch and sensors
              	sendSketchInfo("Leak Detector", "1.0");
              	present(LEAK_CHILD_ID, S_WATER_LEAK);
              }
              
              void setup()  
              {
              	// Set the destination for msgToNode permanently to the target node's ID 
              	// msgToGw doesn't need that; it defaults to 0 (=GW)
              	msgToNode.setDestination(LEAK_TARGET_NODE_ID);
              }
              
              void loop() 
              {
              	// Check if things have changed
              	if (leakState != previousLeakState)
              	{
              		// Report new state to GW and target node
              		send(msgToGw.set(leakState));
              		wait(100); // Optional, but a short pause inbetween can't hurt
              		send(msgToNode.set(leakState));
              		
              		// Update state
              		previousLeakState = leakState;
              	}
              }
              

              This will inform the GW via msgToGw as well as the the node with the ID 15 (LEAK_TARGET_NODE_ID) via msgToNode about the updated leakState.

              The GW will receive this message with the child ID 0 (LEAK_CHILD_ID), node 15 will receive it with the child ID 100 (LEAK_CHILD_ID_TO_NODE). You do not need to change the child ID you send to the destination node - you can keep using the same as for the GW. Just note that you can change it.

              On the target node, you need this:

              bool leakState = false;
              bool previousLeakState = false;
              #define LEAK_CHILD_ID_INCOMING 100 
              
              void loop() 
              {
              	// Check if leakState has changed
              	if (leakState != previousLeakState)
              	{
              		// Do something
              		
              		// Update state
              		previousLeakState = leakState;
              	}
              }
              
              void receive(const MyMessage & msg) 
              {
              	Serial.print("Incoming message... ");
              
              	// Filter out our message
              	if (msg.getType() == V_TRIPPED && 
              		msg.getSensor() == LEAK_CHILD_ID_INCOMING)
              	{
              		// Update the local leakState variable
              		leakState = msg.getBool();
              
              		// Print some infos
              		Serial.println("is a new leak state!");
              		Serial.print("From (Node ID):");
              		Serial.println(msg.getSender());
              		Serial.print("Child ID: ");
              		Serial.println(msg.getSensor());
              		Serial.print("State: ");
              		Serial.println(leakState);
              	} else 
              	{
              		Serial.println("is something else. :(");
              	}
              }
              

              Hope I didn't miss anything.

              Once you got it working, it's best to remove most if not all serial prints from the receive function, as it's generally bad practice and can cause various problems.

              A 1 Reply Last reply
              1
              • BearWithBeardB BearWithBeard

                Unfortunately, I don't have a test setup running right now, otherwise I would quickly whip up and test two minimal example sketches.

                But here are some snippets that should include everything related to node-to-node communication you need. My best advice at this point, if it still confuses you, is to get rid of all the magic numbers in the code and define macros / constants.

                On the leak detector node, you need the following bits:

                bool leakState = false;
                bool previousLeakState = false;
                
                #define LEAK_CHILD_ID 0 // 0 to 254
                #define LEAK_CHILD_ID_TO_NODE 100 // 0 to 254
                #define LEAK_TARGET_NODE_ID 15 // The ID of the node you want to report to
                
                // Setup two separate messages. One reports to the GW, the other to the target node
                MyMessage msgToGw(LEAK_CHILD_ID, V_TRIPPED);
                MyMessage msgToNode(LEAK_CHILD_ID_TO_NODE, V_TRIPPED);
                
                void presentation() 
                {
                	// Register and present sketch and sensors
                	sendSketchInfo("Leak Detector", "1.0");
                	present(LEAK_CHILD_ID, S_WATER_LEAK);
                }
                
                void setup()  
                {
                	// Set the destination for msgToNode permanently to the target node's ID 
                	// msgToGw doesn't need that; it defaults to 0 (=GW)
                	msgToNode.setDestination(LEAK_TARGET_NODE_ID);
                }
                
                void loop() 
                {
                	// Check if things have changed
                	if (leakState != previousLeakState)
                	{
                		// Report new state to GW and target node
                		send(msgToGw.set(leakState));
                		wait(100); // Optional, but a short pause inbetween can't hurt
                		send(msgToNode.set(leakState));
                		
                		// Update state
                		previousLeakState = leakState;
                	}
                }
                

                This will inform the GW via msgToGw as well as the the node with the ID 15 (LEAK_TARGET_NODE_ID) via msgToNode about the updated leakState.

                The GW will receive this message with the child ID 0 (LEAK_CHILD_ID), node 15 will receive it with the child ID 100 (LEAK_CHILD_ID_TO_NODE). You do not need to change the child ID you send to the destination node - you can keep using the same as for the GW. Just note that you can change it.

                On the target node, you need this:

                bool leakState = false;
                bool previousLeakState = false;
                #define LEAK_CHILD_ID_INCOMING 100 
                
                void loop() 
                {
                	// Check if leakState has changed
                	if (leakState != previousLeakState)
                	{
                		// Do something
                		
                		// Update state
                		previousLeakState = leakState;
                	}
                }
                
                void receive(const MyMessage & msg) 
                {
                	Serial.print("Incoming message... ");
                
                	// Filter out our message
                	if (msg.getType() == V_TRIPPED && 
                		msg.getSensor() == LEAK_CHILD_ID_INCOMING)
                	{
                		// Update the local leakState variable
                		leakState = msg.getBool();
                
                		// Print some infos
                		Serial.println("is a new leak state!");
                		Serial.print("From (Node ID):");
                		Serial.println(msg.getSender());
                		Serial.print("Child ID: ");
                		Serial.println(msg.getSensor());
                		Serial.print("State: ");
                		Serial.println(leakState);
                	} else 
                	{
                		Serial.println("is something else. :(");
                	}
                }
                

                Hope I didn't miss anything.

                Once you got it working, it's best to remove most if not all serial prints from the receive function, as it's generally bad practice and can cause various problems.

                A Offline
                A Offline
                APL2017
                wrote on last edited by APL2017
                #16

                @BearWithBeard THANK YOU! It works fine. The only change I had to make is to replace msg with message in all commands. Couple of questions, if you don't mind:

                1. Is it critical to have void receive after void loop?
                2. How receiving node distinguishes between same sensor ID coming from different nodes? Or, I need to assign unique sensor ID throughout complete sensors pool?

                It will be useful to include working example into mySensors library.

                1 Reply Last reply
                0
                • BearWithBeardB Offline
                  BearWithBeardB Offline
                  BearWithBeard
                  wrote on last edited by
                  #17

                  Glad you got it working!

                  1. The order of the functions in the sketch doesn't determine their execution order, which is managed behind the scenes by the framework. You could place receive() right below the mysensors.h inclusion if you wish.

                  2. They don't. That's why I showed you how to assign a different child ID. You could assing a unique ID per node-to-node-message to make them identifiable.
                    If multiple node-to-node-message end up having the same child ID, you would have to factor in other variables, like getSender() to tell them apart. Let's say you have three nodes (IDs 1, 2, 3) sending a boolean to a fourth target node and all messages have the same child ID of 0, you could tell them apart like this:

                    #define LEAK_CHILD_ID_INCOMING 0
                    // [...]
                    void receive(const MyMessage & msg) 
                    {
                    	// Message is what we're looking for
                    	if (msg.getType() == V_TRIPPED && 
                    		msg.getSensor() == LEAK_CHILD_ID_INCOMING)
                    	{
                    		// Find out where it's from
                    		switch (msg.getSender())
                    		{
                    			case 1: // From node ID 1
                    				leakStateNode1 = msg.getBool();
                    				break;
                    			case 2: // From node ID 2
                    				leakStateNode2 = msg.getBool();
                    				break;
                    			case 3: // From node ID 3
                    				leakStateNode3 = msg.getBool();
                    				break;
                    			default: // From GW or 4 - 254
                    				break;
                    		}
                    	}
                    }
                    

                    But again, since you're using automatic ID assignment - I'm not sure if node IDs can change under specific circumstances. So If you make use of getSender() you may want to consider assigning static node IDs.

                  A 2 Replies Last reply
                  1
                  • BearWithBeardB BearWithBeard

                    Glad you got it working!

                    1. The order of the functions in the sketch doesn't determine their execution order, which is managed behind the scenes by the framework. You could place receive() right below the mysensors.h inclusion if you wish.

                    2. They don't. That's why I showed you how to assign a different child ID. You could assing a unique ID per node-to-node-message to make them identifiable.
                      If multiple node-to-node-message end up having the same child ID, you would have to factor in other variables, like getSender() to tell them apart. Let's say you have three nodes (IDs 1, 2, 3) sending a boolean to a fourth target node and all messages have the same child ID of 0, you could tell them apart like this:

                      #define LEAK_CHILD_ID_INCOMING 0
                      // [...]
                      void receive(const MyMessage & msg) 
                      {
                      	// Message is what we're looking for
                      	if (msg.getType() == V_TRIPPED && 
                      		msg.getSensor() == LEAK_CHILD_ID_INCOMING)
                      	{
                      		// Find out where it's from
                      		switch (msg.getSender())
                      		{
                      			case 1: // From node ID 1
                      				leakStateNode1 = msg.getBool();
                      				break;
                      			case 2: // From node ID 2
                      				leakStateNode2 = msg.getBool();
                      				break;
                      			case 3: // From node ID 3
                      				leakStateNode3 = msg.getBool();
                      				break;
                      			default: // From GW or 4 - 254
                      				break;
                      		}
                      	}
                      }
                      

                      But again, since you're using automatic ID assignment - I'm not sure if node IDs can change under specific circumstances. So If you make use of getSender() you may want to consider assigning static node IDs.

                    A Offline
                    A Offline
                    APL2017
                    wrote on last edited by
                    #18

                    @BearWithBeard Thank you!!!

                    1 Reply Last reply
                    0
                    • BearWithBeardB BearWithBeard

                      Glad you got it working!

                      1. The order of the functions in the sketch doesn't determine their execution order, which is managed behind the scenes by the framework. You could place receive() right below the mysensors.h inclusion if you wish.

                      2. They don't. That's why I showed you how to assign a different child ID. You could assing a unique ID per node-to-node-message to make them identifiable.
                        If multiple node-to-node-message end up having the same child ID, you would have to factor in other variables, like getSender() to tell them apart. Let's say you have three nodes (IDs 1, 2, 3) sending a boolean to a fourth target node and all messages have the same child ID of 0, you could tell them apart like this:

                        #define LEAK_CHILD_ID_INCOMING 0
                        // [...]
                        void receive(const MyMessage & msg) 
                        {
                        	// Message is what we're looking for
                        	if (msg.getType() == V_TRIPPED && 
                        		msg.getSensor() == LEAK_CHILD_ID_INCOMING)
                        	{
                        		// Find out where it's from
                        		switch (msg.getSender())
                        		{
                        			case 1: // From node ID 1
                        				leakStateNode1 = msg.getBool();
                        				break;
                        			case 2: // From node ID 2
                        				leakStateNode2 = msg.getBool();
                        				break;
                        			case 3: // From node ID 3
                        				leakStateNode3 = msg.getBool();
                        				break;
                        			default: // From GW or 4 - 254
                        				break;
                        		}
                        	}
                        }
                        

                        But again, since you're using automatic ID assignment - I'm not sure if node IDs can change under specific circumstances. So If you make use of getSender() you may want to consider assigning static node IDs.

                      A Offline
                      A Offline
                      APL2017
                      wrote on last edited by APL2017
                      #19

                      @BearWithBeard Thanks to you my water leak detection system works fine. My next challenge is to let node receive Boolean (RESET_SOFT) from GW - directly from controller logic. I am looking at example RelayActuator and trying to make sense of it, see below simplified version of it. The idea is to get message from GW (node 0) and received it as sensor ID 20 on the receiving node. Is this close to what is should be?

                      #define MY_DEBUG 
                      #define MY_RADIO_RF24
                      #include <MySensors.h>
                      
                      bool RESET_SOFT;
                      
                      void setup()  
                      {  
                       
                      }
                      void presentation() {
                        sendSketchInfo("Basement Water", "1.0");
                        present(20, S_BINARY);
                      }
                      
                      void loop() 
                      {
                        
                      }
                       void receive(const MyMessage &message)
                       {
                          if (message.getType()==S_BINARY &&
                            message.getSensor()==0)
                           {RESET_SOFT=message.getBool(); }
                           
                       } 
                      
                      1 Reply Last reply
                      0
                      • BearWithBeardB Offline
                        BearWithBeardB Offline
                        BearWithBeard
                        wrote on last edited by BearWithBeard
                        #20

                        Well, it looks like you are still mixing up the meaning of sensor and sender in the code. If the controller sends a message to the sensor you have set up in the sketch above (20), while you are comparing against 0 in receive(), you will never detect that message. Compare against 20.

                        Remember how I advised to get rid of magic numbers and use constants instead? If you would add something like #define SENSOR_ID 20 and use that variable instead of 0 and 20, you might be able to avoid such confusions, because you give those arguments a meaningful name.

                        Let's try to explain it another way, so that you can adapt it to any situation in the future.

                        Sensor: In the context of a MySensors sketch, stop thinking of a sensor being a (physical) device. It is just a unique identifier for one of many different data points a device (MySensors calls this device a node) wants to share with others. Think of a sensor (or also often called child) as one of up to 255 wires going from one node to any other, whereby each wire represents a single type of data, like a temperature, a string, voltage level, a boolean value.

                        Sender: When a node sends a message, it includes a reference to itself - the node ID - as the sender, as well as a reference to the target node as the destination. Both sender and destination enable MySensors to route messages through the network, no matter if it is a direct A-to-B connection or if the message needs to be forwarded by multiple repeaters.

                        The MyMessage class is used to manage those messages. It stores all kinds of information neccessary to share data between nodes, send and request commands independently from the selected transport method (RF24, Sub-GHz, wired) and controller connection (Serial, MQTT, WiFi, Ethernet).

                        Imagine a simplified MyMessage instance as a collection of variables and a bunch of helper functions to make your life easier. When the controller (via the GW) sends the message to the node, as you described above, the message would look like this on the receiving node:

                        MyMessage msg 
                        {
                        	sender = 0;       // Node ID of the message's origin (the GW)
                        	destination = 7;  // Node ID of this device (I assumed this number!)
                        	sensor = 20;      // Child ID / data point that this message wants to update
                        	type = 3;         // S_BINARY == 3
                        	[...]
                        	getBool();        // Returns the payload as a boolean
                        	getSensor();      // Returns the value of sensor
                        	setSensor(n);     // Changes the value of sensor
                        	getDestination(); // Returns the value of destination
                        	[...]
                        }
                        

                        So what do you have to do if you want to update the local variable RESET_SOFT on that node whenever it receives a new value? You have to test that the incoming message is of the expected type and that it concerns the right sensor. If you also want to make sure that only the controller or GW can cause an update of RESET_SOFT, you must validate that sender - in other words, the origin of this message - is valid as well.

                        I really hope this makes sense to you, as I'm running out of ideas how to explain what is going on behind the scenes.

                        Maybe a look at the Serial API introduction can also help you further.

                        A 2 Replies Last reply
                        2
                        • BearWithBeardB BearWithBeard

                          Well, it looks like you are still mixing up the meaning of sensor and sender in the code. If the controller sends a message to the sensor you have set up in the sketch above (20), while you are comparing against 0 in receive(), you will never detect that message. Compare against 20.

                          Remember how I advised to get rid of magic numbers and use constants instead? If you would add something like #define SENSOR_ID 20 and use that variable instead of 0 and 20, you might be able to avoid such confusions, because you give those arguments a meaningful name.

                          Let's try to explain it another way, so that you can adapt it to any situation in the future.

                          Sensor: In the context of a MySensors sketch, stop thinking of a sensor being a (physical) device. It is just a unique identifier for one of many different data points a device (MySensors calls this device a node) wants to share with others. Think of a sensor (or also often called child) as one of up to 255 wires going from one node to any other, whereby each wire represents a single type of data, like a temperature, a string, voltage level, a boolean value.

                          Sender: When a node sends a message, it includes a reference to itself - the node ID - as the sender, as well as a reference to the target node as the destination. Both sender and destination enable MySensors to route messages through the network, no matter if it is a direct A-to-B connection or if the message needs to be forwarded by multiple repeaters.

                          The MyMessage class is used to manage those messages. It stores all kinds of information neccessary to share data between nodes, send and request commands independently from the selected transport method (RF24, Sub-GHz, wired) and controller connection (Serial, MQTT, WiFi, Ethernet).

                          Imagine a simplified MyMessage instance as a collection of variables and a bunch of helper functions to make your life easier. When the controller (via the GW) sends the message to the node, as you described above, the message would look like this on the receiving node:

                          MyMessage msg 
                          {
                          	sender = 0;       // Node ID of the message's origin (the GW)
                          	destination = 7;  // Node ID of this device (I assumed this number!)
                          	sensor = 20;      // Child ID / data point that this message wants to update
                          	type = 3;         // S_BINARY == 3
                          	[...]
                          	getBool();        // Returns the payload as a boolean
                          	getSensor();      // Returns the value of sensor
                          	setSensor(n);     // Changes the value of sensor
                          	getDestination(); // Returns the value of destination
                          	[...]
                          }
                          

                          So what do you have to do if you want to update the local variable RESET_SOFT on that node whenever it receives a new value? You have to test that the incoming message is of the expected type and that it concerns the right sensor. If you also want to make sure that only the controller or GW can cause an update of RESET_SOFT, you must validate that sender - in other words, the origin of this message - is valid as well.

                          I really hope this makes sense to you, as I'm running out of ideas how to explain what is going on behind the scenes.

                          Maybe a look at the Serial API introduction can also help you further.

                          A Offline
                          A Offline
                          APL2017
                          wrote on last edited by APL2017
                          #21

                          @BearWithBeard Thank you! I am really embarrassed with my, let's say, luck of understanding. But you made it clear again. Everything works as required!

                          1 Reply Last reply
                          0
                          • BearWithBeardB BearWithBeard

                            Well, it looks like you are still mixing up the meaning of sensor and sender in the code. If the controller sends a message to the sensor you have set up in the sketch above (20), while you are comparing against 0 in receive(), you will never detect that message. Compare against 20.

                            Remember how I advised to get rid of magic numbers and use constants instead? If you would add something like #define SENSOR_ID 20 and use that variable instead of 0 and 20, you might be able to avoid such confusions, because you give those arguments a meaningful name.

                            Let's try to explain it another way, so that you can adapt it to any situation in the future.

                            Sensor: In the context of a MySensors sketch, stop thinking of a sensor being a (physical) device. It is just a unique identifier for one of many different data points a device (MySensors calls this device a node) wants to share with others. Think of a sensor (or also often called child) as one of up to 255 wires going from one node to any other, whereby each wire represents a single type of data, like a temperature, a string, voltage level, a boolean value.

                            Sender: When a node sends a message, it includes a reference to itself - the node ID - as the sender, as well as a reference to the target node as the destination. Both sender and destination enable MySensors to route messages through the network, no matter if it is a direct A-to-B connection or if the message needs to be forwarded by multiple repeaters.

                            The MyMessage class is used to manage those messages. It stores all kinds of information neccessary to share data between nodes, send and request commands independently from the selected transport method (RF24, Sub-GHz, wired) and controller connection (Serial, MQTT, WiFi, Ethernet).

                            Imagine a simplified MyMessage instance as a collection of variables and a bunch of helper functions to make your life easier. When the controller (via the GW) sends the message to the node, as you described above, the message would look like this on the receiving node:

                            MyMessage msg 
                            {
                            	sender = 0;       // Node ID of the message's origin (the GW)
                            	destination = 7;  // Node ID of this device (I assumed this number!)
                            	sensor = 20;      // Child ID / data point that this message wants to update
                            	type = 3;         // S_BINARY == 3
                            	[...]
                            	getBool();        // Returns the payload as a boolean
                            	getSensor();      // Returns the value of sensor
                            	setSensor(n);     // Changes the value of sensor
                            	getDestination(); // Returns the value of destination
                            	[...]
                            }
                            

                            So what do you have to do if you want to update the local variable RESET_SOFT on that node whenever it receives a new value? You have to test that the incoming message is of the expected type and that it concerns the right sensor. If you also want to make sure that only the controller or GW can cause an update of RESET_SOFT, you must validate that sender - in other words, the origin of this message - is valid as well.

                            I really hope this makes sense to you, as I'm running out of ideas how to explain what is going on behind the scenes.

                            Maybe a look at the Serial API introduction can also help you further.

                            A Offline
                            A Offline
                            APL2017
                            wrote on last edited by APL2017
                            #22
                            This post is deleted!
                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            9

                            Online

                            11.7k

                            Users

                            11.2k

                            Topics

                            113.0k

                            Posts


                            Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • MySensors
                            • OpenHardware.io
                            • Categories
                            • Recent
                            • Tags
                            • Popular