Some questions about the code (version 1.4)
@hek and other knowledgeable users,
It would help me to understand the codebase if I can ask a few questions. I'm hoping these are the type where you can easily answer in a couple of minutes, things which I might have to puzzle over for a longtime. Some are about how, some about why some just confirming. I figure that documenting the tricky parts here will ultimately benefit more than just me.
- First, I'd like to check my understanding. It looks like the nodes send numeric values to the gateway in binary (the gateway formats them into strings for the SSV (semicolon separated values) text format interface. However the gateway sends numeric values to the nodes as strings (except STREAM type);
Q1) Is that right? What's the reasoning?
I would think that consistently sending numeric values to nodes in binary would allow smaller code (no need to accept both string-encoded and binary-encoded values, no need to link atoi and atol and atof etc, perhaps for some nodes no need for the floating point library, etc). In my mind, the biggest "win" of the 1.4 protocol would have been avoiding the code to convert numbers to/from string format, but if that number-as-string code has to be there in addition to the binary-format code, what is the payoff of adding the binary format too?
Another thing which puzzles me is this line in MySensors.cpp, currently line 270 within process():
RF24::writeAckPayload(pipe,&pipe, 1 );
This appears to load up a one byte packet Ack payload (containing the pipe number) to be transmitted the next time an ESB packet is received on the same page. So if a node sends a packet to the gateway (using ESB with ack) then instead of an empty ACK it will get an ack with the pipe number as the payload. Starting with the second time.
Q2) Where is that used and what's the purpose?
I would have expected that this would put a one byte packet into the receive FIFO of the node whenever it sends a report to the gateway. I don't see where this packet is used, nor where it's cleared out, nor where the received packet is checked for an appropriate length. (There is a test for Protocol Version, but that value would probably be unchanged from the last command packet received as receiving a one byte packet would overwrite only the first two bytes of the msg buffer).
More to come. Thanks.
Allowing binary transfers is the first step. Now you can easily create a BinaryGateway or Plug a nrf-chip to some other hardware and send binary data all the way to sensor.
I had some ideas of using the ack package content but they were never realized.
However the gateway sends numeric values to the nodes as strings (except STREAM type);
That's true and I already had this discussion some time ago with Henrik.
The nodes just send data in binary format, depending on the type of the variable storing the value to send to the gateway. The set method is overloaded for each data type that can be sent by the library and the compiler automatically calls the correct one for your variable.
The gateway on the other hand receives all values to be sent to a node as text. It does not know if an textual value of "1" should be sent as e.g boolean, unsigned int, float or just text. Therefore it just sends everything as text. Not very efficient, but probably the clearest it can do in the current state of the library.
@hek suggested to pass the data type as a separate value in the serial command, which is one possible way to implement it.
When using the gateway to send messages from c++ code to nodes the whole thing changes of course and the same types as a sensor node can be used.
So there is currently no way for the HA controller to pass the payload type to the gateway (even if the controller knew that), so gateway doesn't know how to encode the value in binary? Thus it has to send the value OTA as text and hope the node understands it.
That does make sense, but it raises questions for me.
This seems like one of the cases where my suggestion of gateway retained metadata received from the node would pay off. Suppose we DID want to enable the gateway to send values [only] in binary to a given node.
- The node receiving the binary data inherently HAS to know what format it's going to ask for, and in fact has to be the ultimate authority on what format it will accept.
- How would the controller know what format each node accpets, except to have some configuration that has to be (manually?) kept in sync? The HA controller would at best be a secondary source of that knowledge.
- The controller to gateway serial format could be enhanced to add a "payload type" code, but that would break the symmetry of controller->gateway and gateway->controller (or add a null field to the latter).
- Is it inherently any business of the controller to know what binary or text format the gateway uses OTA to communicate with the node? Any more than it has to know about ESB acks or 5 byte addresses or frequency (channel) used to communicate between gateway and node?
I would say that good information partitioning would keep the OTA payload format information private to the OTA nodes (gateway node and sensactuator node). So having the node inform the gateway as to the format it expects to receive makes a lot of sense; the controller shouldn't need to care about that kind of internal detail.
I think we can reduce the code size a bit if nodes use only binary formats (and in some cases need no floating point or atoX or sprintf libraries).
But that's covered in another thread about an alternative vision of conveying variables between the central hub and the nodes. Maybe by version 1.5 or 2.0 that idea will have some traction, maybe not.
Meanwhile I really appreciate the working system that exists now! So thanks for responding.
This post is deleted!
Is there a way to know gateway protocol version sending command from controller ?
Send a VERSION command to gateway (node id 0) from controller.
@hek great thx.
According to the explanation "Sensors report their library version at startup using this message type" i though the message was automatically sent once just after sensor startup.
Gateway is not a sensor