An LCD node is polling the controller (Home Assistant) to get statuses of other nodes, a HOWTO.
-
To get the status of different door nodes on my LCD node there are two methods:
- direct node to node communication: The sending node is not only sending his status to the controller, but also directly to the LCD node
In short the code in the door node for sending his status to the LCD node:
#define LCD_NODE_ID 100 #define LCD_CHILD_ID 4 //destination virtual child sensor of the LCD node #define CHILD_ID 1 // Each radio node can report data for up to 254 different child sensors. You are free to choose the child id yourself. You should avoid using child-id 255 because it is used for things like sending in battery level and other (protocol internal) node specific information. ... MyMessage msg(CHILD_ID,V_TRIPPED); MyMessage msgLCD(LCD_CHILD_ID, V_STATUS);
Then in the loop method
send(msg.set(value==HIGH ? 0 : 1)); // to the gateway ==> controller send(msgLCD.setDestination(LCD_NODE_ID).set(value==HIGH ? 0 : 1)); // send also to LCD node
- by polling the controller to get the status of other sensors:
You could do it only with node to node communication, but what if the distance it too long between the nodes to have a reliable connection? Some battery nodes are close to the gateway, but (too) far from the LCD node.
Also the battery nodes are sleeping most of the time, so directly requesting them will not work!
A node can request data from the controller or from a node.
From the docs:bool request (const uint8_t childSensorId, const uint8_t variableType, const uint8_t destination = GATEWAY_ADDRESS) Requests a value from gateway or some other sensor in the radio network. Make sure to add callback-method in begin-method to handle request responses. Parameters childSensorId The unique child id for the different sensors connected to this Arduino. 0-254. variableType The variableType to fetch destination The nodeId of other node in radio network. Default is gateway Returns true Returns true if message reached the first stop on its way to destination.
When requesting from the controller, there is no way to requesting data from another node. A node can only request data from itself.
Workaround:- create child sensors (S_CUSTOM & V_CUSTOM) in the LCD node, one child sensor for each external node you want the status from and send these values to the controller.
- get the controller so far that he is copying the statuses of the wanted nodes to these fields
- request this data again from the controller (polling)
How?
See the sketch for detailed information (https://github.com/ericvb/MySensorsArduinoSketches/blob/master/sketches/ArduinoLCDDisplaySensorWithEncryptionGithub/ArduinoLCDDisplaySensorWithEncryptionGithub.ino), but in short- Present the child sensors in the LCD node
// Register all sensors to gw (they will be created as child devices) by their ID and S_TYPE // for Home Assistant : S_CUSTOM together with V_CUSTOM present(LCD_CHILD_ID_pGarBike, S_CUSTOM);
- Create only the first time the child devices in the loop (not sure anymore if this is really needed, was done during my tests). Put in comments after the first run!
send(MyMessage(LCD_CHILD_ID_pGarBike,V_CUSTOM).set(1));
- Let the controller copy the statuses from the other nodes in these child devices
- Request the data from the controller
request(LCD_CHILD_ID_pGarBike, V_CUSTOM);
- Treat the requested message in the receive method of the LCD node
How to let the controller Home Assistant copy statuses from one node to the child devices of the LCD node?
Maybe first a little word how MySensors is integrated in HA.
When nodes are presenting them selves to HA, the Mysensors integration will create a mysensors.json (by default a mysensors.pickle file, but I reconfigured this to create a human readable json file) with your gateway(s) and nodes.{ "0": { "sensor_id": 0, "children": {}, "type": 18, "sketch_name": null, "sketch_version": null, "battery_level": 0, "protocol_version": "2.3.2", "heartbeat": 0 }, "1": { "sensor_id": 1, "children": { "1": { "id": 1, "type": 15, "description": "", "values": { "13": "11" } } }, "type": 17, "sketch_name": "Distance Sensor", "sketch_version": "1.2", "battery_level": 0, "protocol_version": "2.3.2", "heartbeat": 0 }, "100": { "sensor_id": 100, "children": { "1": { "id": 1, "type": 23, "description": "", "values": { "48": "0" } } }, "type": 18, "sketch_name": "LCD Display Panel Sensor", "sketch_version": "1.1", "battery_level": 0, "protocol_version": "2.3.2", "heartbeat": 7207526 } }
The values of the child sensors are putted in this file and read by the normal workflow of HA, see the "100" entry above.
Home Assistant itself has nothing, I'm aware of, to copy or notify another sensor that a value/status of a device, did change.
So in a first attempt I did use a custom python script from the HA community who could, with the help of an automatization, change a status and/or attributes for a given entity_id when the status of another entity did change (= trigger).
This worked in the screens of HA, but the values in the json file didn't change and when requesting data from the controller by the LCD node or when HA did resync itself, the values of the json file were again taken, throwing away the modified values of the custom python script.A second attempt was to try to read the python code of the MySensors integration, but I must admin, my python skills are not so great
After many thoughts and tests, my eyes just opened up, if I used an automatization with the mqtt push service, simulating a fake mqtt message apparently coming from the gateway saying that the child sensor had a new payload?
Bingo, that workedSo two HA automatizations for each child devices, are triggered each minute to verify what the status is of the other device/sensor. Depending on the status, one of the automatizations will put a mqtt message on the mqtt bus.
For example:topic: mysensorsgateway-out/100/3/1/0/48 payload: 1
- mysensorsgateway-out: simulates that it comes from the gateway
- 100 : the LCD node id
- 3 : the LCD child sensor id
- 1 : the message type: defines what the message contains and what the sub-type means: here the 'set' message type
- Presentation (0): Contains the S_xxx sensor type
- set/req (1/2): Contains the V_xxx data type
- Internal (3): Contains an I_xxx constant that describes what the payload is - ex. I_CONFIG (6) or I_SKETCH_VERSION (12) from my example above
- stream (4): for fw update. - 0 : ack field : The **ack **field is used to know if a message is an ack to a previous message or a real message. I assume here a normal real message, so it will be always 0.
- 48 : the sub-type = the V_CUSTOM field
HA is also subscribed to this topic, so it will consume directly this message, setting the correct fields in the mysensors.json file!
Probably these two automations can be refactored to one automation with conditions in the action, but that must be still found out.
Example of one automatization that triggers each minute:
- direct node to node communication: The sending node is not only sending his status to the controller, but also directly to the LCD node