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…
- device: '127.0.0.1’
-
Please edit your post and put the sketch within code blocks so it's readable.
-
ok corrected
-
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.
-
Can you explaine me more. Sorry i am begginer user and i dont know how ? Please
Or please correct it in my sketch...please
-
Add the following line in the
receive
function eg after the call todigitalWrite
.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.
-
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?
-
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.