Unable to get relay status from Domoticz
-
Starting from relay example and @Boots33 synchronising light switch (https://forum.mysensors.org/topic/6948/synchronising-light-switch) I'm arranging a node with a DS18B20 +relay (simple thermostat).
My issue is that I cannot receive the relay status from controller (Domoticz). Looking with log parser, seems to me that PAYLOAD is empty.
This is in effect the log:
6480 TSF:MSG:SEND,10-10-0-0,s=1,c=2,t=2,pt=0,l=0,sg=1,ft=0,st=OK: 6496 TSF:MSG:SEND,10-10-0-0,s=1,c=3,t=16,pt=0,l=0,sg=1,ft=0,st=OK: 6625 TSF:MSG:READ,0-0-10,s=255,c=3,t=17,pt=6,l=25,sg=1:427C42AE0562164806668CEBC26347BE1A113516C9C14F345A 6723 TSF:MSG:SEND,10-10-0-0,s=1,c=2,t=2,pt=0,l=0,sg=1,ft=0,st=OK: 9059 TSF:MSG:READ,0-0-10,s=255,c=3,t=17,pt=6,l=25,sg=1:499D2360929A82BB0BB9B0C47873D3E460ADF357B2DECAA3F4 9153 TSF:MSG:SEND,10-10-0-0,s=0,c=1,t=0,pt=7,l=5,sg=1,ft=0,st=OK:29.5 180163 TSF:MSG:READ,0-0-10,s=1,c=3,t=16,pt=0,l=0,sg=1: 180185 TSF:MSG:SEND,10-10-0-0,s=255,c=3,t=17,pt=6,l=25,sg=1,ft=0,st=OK:F62E5E036965BB68EEE8797C8E9F12AA8C935F0C49F4359DFB 180329 TSF:MSG:READ,0-0-10,s=1,c=1,t=2,pt=0,l=1,sg=1:0 180428 TSF:MSG:SEND,10-10-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:0 241998 TSF:MSG:READ,0-0-10,s=1,c=3,t=16,pt=0,l=0,sg=1: 242184 TSF:MSG:READ,0-0-10,s=1,c=1,t=2,pt=0,l=1,sg=1:1 242284 TSF:MSG:SEND,10-10-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1
And payload seems totally empty.
Another one thing, neither I read in serial monitor the debug section println
case C_REQ: // message is a returning request from controller Serial.print("Incoming request. The request_state is now: ");
Seems never executed the case "C_REQ".
If Domoticz sends command to poweron (or poweroff) the relay, all works like a charme. I would simply get the state of relay viewed on Domoticz.
This is the script (my relay module is powered when PIN goes LOW; for this you see the "inverted" in #define section)
/** * Sketch for a relay + termostat. * * In test from 11/08/2017 * * @version 2.0 * */ /** * DEFINE MYSENSORS SECTION */ #define MY_DEBUG // Enable Basic Debug //#define MY_DEBUG_VERBOSE_SIGNING // Enable Signing Debug #define MY_RADIO_NRF24 #define MY_SIGNING_SOFT #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 #define MY_SIGNING_REQUEST_SIGNATURES #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x3B,0xF4,0x61,0xFF,0xFF,0x97,0xB1,0xFF,0xEC}}} #define MY_NODE_ID 10 // Default ID #define MY_DEFAULT_LED_BLINK_PERIOD 300 #define MY_WITH_LEDS_BLINKING_INVERSE #define MY_DEFAULT_ERR_LED_PIN 16 #define MY_DEFAULT_TX_LED_PIN 17 #define MY_DEFAULT_RX_LED_PIN 18 /** * Include libraries */ #include <SPI.h> #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> /** * Define section. * * // NAME */ #define SKETCH_NAME "Termostato+Relay" #define SKETCH_VERSION "2.0" // PIN #define PIN_DS18B20 2 #define PIN_RELAY 3 #define PIN_LED_STATUS 19 // CHILD ID #define CHILD_ID_TEMP 0 #define CHILD_ID_RELAY 1 // RELAY SECTION #define RELAY_ON 0 // if inverted, invert here #define RELAY_OFF 1 // if inverted, invert here // WAITs TIMES #define WAIT_LOOPS 5 // The status led flashes ON 10 ms and OFF 4990 ms == 5000 ms of loop. 5000 * WAIT_LOOPS = number of cycles before new read. 60 == 5 minutes #define WAIT_RETURN 1500 // Milliseconds to wait for returns from gateway /** * Various variable */ bool is_first_loop = true; bool request_state; bool state = false; // the current state of relay bool uplink_available = true; unsigned long uplink_check_time; // holder for uplink checks unsigned long uplink_check_period = 30*1000; // time between checks for uplink in milliseconds /* * One Wire Section */ OneWire oneWire(PIN_DS18B20); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. /** * Mysensors message */ // Initialize temperature message MyMessage msg_temperature(CHILD_ID_TEMP , V_TEMP); // Initialize relay message MyMessage msg_relay(CHILD_ID_RELAY , V_STATUS); /** * Before class */ void before() { // Startup up the OneWire library sensors.begin(); } /** * Presentation. * * Presents the child to the controller */ void presentation() { // send sketch name sendSketchInfo(SKETCH_NAME , SKETCH_VERSION); // Present all sensors to controller. // TEMPERATURE present(CHILD_ID_TEMP, S_TEMP); // RELAY present(CHILD_ID_RELAY , S_BINARY); } /** * Our Setup */ void setup() { // SETUP LED STATUS // Set the LED STATUS as OUTPUT and shutdown it. pinMode(PIN_LED_STATUS , OUTPUT); digitalWrite(PIN_LED_STATUS , LOW); // SETUP RELAY // Set the RELAY PIN as OUTPUT and LOW pinMode(PIN_RELAY , OUTPUT); digitalWrite(PIN_RELAY , RELAY_OFF); // initialize sensors sensors.setWaitForConversion(false); } /** * Our loop */ void loop() { Serial.println("-------------- DEBUG loop() ---------------"); Serial.print("Value of is_first_loop is "); Serial.println(is_first_loop); Serial.println("-------------------------------------------"); if ( is_first_loop == true ) { // request state of relay to the controller; getStateFromController(); // set is_first_loop = false; is_first_loop = false; } // executed the reading loopTemperature(); // light the status led... so wait lightLedStatus(); } /* * Get the state of relay from controller. * Executed once at first loop. * * @since 2.0 */ void getStateFromController() { Serial.println("-------------- DEBUG getStateFromController() ---------------"); if (request( CHILD_ID_RELAY , V_STATUS)) { // request the current state of the switch on the controller and check that an ack was received Serial.print("request( CHILD_ID_RELAY , V_STATUS) value is "); Serial.print(request( CHILD_ID_RELAY , V_STATUS)); Serial.println("Uplink available!"); wait (WAIT_RETURN); Serial.print("Relay in controller is marked as "); /* * THIS IS FOREVER FALSE == 0 :( */ Serial.println(request_state); if (request_state != state) { // check that controller is corectly showing the current relay state send(msg_relay.set(state), false); // notify controller of current state } } else { Serial.println("! ERROR uplink is not available!"); uplink_available = false; // no uplink established uplink_check_time = millis(); } Serial.println("-------------------------------------------------------------"); } /** * Loop temperature. * Executed inside loop() * * @since 2.0 */ void loopTemperature() { // Fetch temperatures from Dallas sensors // we need sensors.requestTemperatures() to NO BLOCK THE THREAD!!! sensors.requestTemperatures(); float temperature = readTemperature(); Serial.println("-------------- DEBUG loopTemperature() ---------------"); Serial.print("Temperature is now "); Serial.println(temperature); Serial.println("------------------------------------------------------"); sendTemperatureToController(temperature); } /************************************************/ /**** VARIOUS FUNCTION TO SUPPORT *****/ /************************************************/ /** * Receive function * * @since 2.0 */ void receive(const MyMessage &msg_relay) { Serial.println("-------------- DEBUG receive() ---------------"); if (msg_relay.type == V_STATUS) { // check to see if incoming message is for a switch switch (msg_relay.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 = msg_relay.getBool(); // get the new state digitalWrite(PIN_RELAY, state ? RELAY_ON : RELAY_OFF); // switch relay to new state uplink_available = true; // uplink established Serial.print("Incoming change for sensor:"); Serial.print(msg_relay.sensor); Serial.print(", New status: "); Serial.println(msg_relay.getBool()); break; case C_REQ: // message is a returning request from controller Serial.print("Incoming request. The request_state is now: "); request_state = msg_relay.getBool(); // update requestState with returning state Serial.println(request_state); break; } } Serial.println("--------------------------------------------"); } /** * Read the temperature from DS18B20 * * @since 2.0 */ float readTemperature() { // query conversion time and sleep until conversion completed int16_t conversionTime = millisToWaitForConversion(sensors.getResolution()); wait(conversionTime); // Read temperatures and send them to controller // Fetch and round temperature to one decimal float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(CHILD_ID_TEMP):sensors.getTempFByIndex(CHILD_ID_TEMP)) * 10.)) / 10.; return temperature; } /** * Get the millis to wait before reading based on resolution. * * @since 2.0 */ int16_t millisToWaitForConversion(uint8_t bitResolution) { switch (bitResolution) { case 9: return 94; case 10: return 188; case 11: return 375; default: return 750; } } /** * Send the temperature to controller * * @since 2.0 */ void sendTemperatureToController(float temperature) { if (temperature != -127.00 && temperature != 85.00) { send(msg_temperature.setSensor(CHILD_ID_TEMP).set(temperature,1)); digitalWrite(MY_DEFAULT_ERR_LED_PIN , LOW); Serial.println("-------------- DEBUG sendTemperatureToController() ---------------"); Serial.println("No error on send temperature"); Serial.println("------------------------------------------------------"); } else { // light the error led fixed! digitalWrite(MY_DEFAULT_ERR_LED_PIN , HIGH); Serial.println("-------------- DEBUG sendTemperatureToController() ---------------"); Serial.println("! ERROR sending temperature"); Serial.println("------------------------------------------------------"); } } /** * Light the LED status * * @since 2.0 */ void lightLedStatus() { int k = 0; for ( k = 0; k < WAIT_LOOPS; k++) { digitalWrite(PIN_LED_STATUS,HIGH); wait(10); // 5 * 1000 millisends = 5 seconds; digitalWrite(PIN_LED_STATUS,LOW); wait(4990); } } /**********************************************/ /**** VARIOUS FUNCTION TO DEBUG *****/ /**********************************************/ /** * Test Led status * @since 2.0 */ void testLed() { int k = 16; for (k = 16; k<20; k++) { pinMode(k,OUTPUT); digitalWrite(k,HIGH); wait(50); digitalWrite(k,LOW); wait(50); } }
Thank you for your time.
-
Do a debug print of the command you received before you enter the "case"
-
I did edit the receive function with this:
void receive(const MyMessage &msg_relay) { Serial.println("-------------- DEBUG receive() ---------------"); Serial.print("msg_relay.type value is "); Serial.println(msg_relay.type); Serial.println("------------------------------------------"); Serial.print("msg_relay.getCommand() value is "); Serial.println(msg_relay.getCommand()); Serial.println("------------------------------------------"); Serial.println("--------------------------------------------"); }
Receive is NOT called at first start ( I have no debug in monitor). Receive is called only when from DOMOTICZ I poweron or poweroff the relay.
In effect this is the debug monitor:
-------------- DEBUG getStateFromController() --------------- request( CHILD_ID_RELAY , V_STATUS) value is 1 Uplink available! Relay in controller is marked as 0 ------------------------------------------------------------- -------------- DEBUG receive() --------------- msg_relay.type value is 2 ------------------------------------------ msg_relay.getCommand() value is 1 ------------------------------------------ -------------------------------------------- -------------- DEBUG receive() --------------- msg_relay.type value is 2 ------------------------------------------ msg_relay.getCommand() value is 1 ------------------------------------------ --------------------------------------------
Last two receive() debug called only when I did poweron or poweroff the relay.
-
You could try editing out all the ifs etc in the getStateFromController and only request the state (surrounded by a few serial prints to see which bits execute). If it works in simplest form then you could build up the logic around it to see what is failing
void getStateFromController() { Serial.println(" starting GetStateFromController"); request( CHILD_ID_RELAY , V_STATUS); wait (WAIT_RETURN); serial.print("Waiting"); }
-
I still miss the point in asking the status of the relay...
-
@Ben-Andrewes request return every time "1". This is not the state of relay in Domoticz . The following state from Domoticz is "0", either if in Domoticz relay need to be on or off ....
-
@gohan to mantain them in sync after a power failure.
But you did put me on right way. I could simply put the relay off on Arduino start and send off to Domoticz.
Every 5 minutes I could send the corrent state ti Domoticz (Imagine a gateway Power failure instead).
In this mode I delegate all logic to Domoticz, when the relay need to be on or off....
-
There is the savestate and readstate functions in mysensors in case you need it
-
@gohan I know, but I would to not use the EEprom and I would also learn and understand where is my error / why cannot get the state...
-
I was just trying to point out that it is a design flaw as the nodes should be as much as indipendent as possible from controller but if you want to play around, have fun
-
Ok,
I don't know if it is necessary to open a new post.I imagine now it's a problem of Domoticz.
I did change all my logic. NOw on startup and every X minutes, the node send to the Domoticz the status of relay, to mantain it in sync.
Errrr...... the status is received but not displayed correctly
I attach an image to explain better.
Domoticz is last update version, this is the current sketch:
/** * Sketch for a relay + termostat. * * In test from 11/08/2017 * * TERMINARE SE UPLINK NON è DISPONIBILE * * @version 2.0 * */ /** * DEFINE MYSENSORS SECTION */ #define MY_DEBUG // Enable Basic Debug //#define MY_DEBUG_VERBOSE_SIGNING // Enable Signing Debug #define MY_RADIO_NRF24 #define MY_SIGNING_SOFT #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 #define MY_SIGNING_REQUEST_SIGNATURES #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x3B,0xF4,0x61,0xDF,0x1E,0xFF,0xFF,0xFF,0xEC}}} #define MY_NODE_ID 10 // Default ID #define MY_DEFAULT_LED_BLINK_PERIOD 300 #define MY_WITH_LEDS_BLINKING_INVERSE #define MY_DEFAULT_ERR_LED_PIN 16 #define MY_DEFAULT_TX_LED_PIN 17 #define MY_DEFAULT_RX_LED_PIN 18 /** * Include libraries */ #include <SPI.h> #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> /** * Define section. * * // NAME */ #define SKETCH_NAME "Termostato+Relay" #define SKETCH_VERSION "3.0" // PIN #define PIN_DS18B20 2 #define PIN_RELAY 3 #define PIN_LED_STATUS 19 // CHILD ID #define CHILD_ID_TEMP 0 #define CHILD_ID_RELAY 1 // RELAY SECTION #define RELAY_ON 0 // if inverted, invert here #define RELAY_OFF 1 // if inverted, invert here // WAITs TIMES #define WAIT_LOOPS 1 // The status led flashes ON 10 ms and OFF 4990 ms == 5000 ms of loop. 5000 * WAIT_LOOPS = number of cycles before new read. 60 == 5 minutes //#define WAIT_RETURN 1500 // Milliseconds to wait for returns from gateway /* * One Wire Section */ OneWire oneWire(PIN_DS18B20); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. /** * Mysensors message */ // Initialize temperature message MyMessage msg_temperature(CHILD_ID_TEMP , V_TEMP); // Initialize relay message MyMessage msg_relay(CHILD_ID_RELAY , V_STATUS); /** * Before class */ void before() { // Startup up the OneWire library sensors.begin(); } /** * Presentation. * * Presents the child to the controller */ void presentation() { // send sketch name sendSketchInfo(SKETCH_NAME , SKETCH_VERSION); // Present all sensors to controller. // TEMPERATURE present(CHILD_ID_TEMP, S_TEMP); // RELAY present(CHILD_ID_RELAY , S_BINARY); } /** * Our Setup */ void setup() { // SETUP LED STATUS // Set the LED STATUS as OUTPUT and shutdown it. pinMode(PIN_LED_STATUS , OUTPUT); digitalWrite(PIN_LED_STATUS , LOW); // SETUP RELAY // Set the RELAY PIN as OUTPUT and LOW pinMode(PIN_RELAY , OUTPUT); digitalWrite(PIN_RELAY , RELAY_OFF); // initialize sensors sensors.setWaitForConversion(false); } /** * Our loop */ void loop() { // send the relay state to controller sendRelayStateToController(); // executed the reading loopTemperature(); // light the status led... so wait lightLedStatus(); } /* * Send the state of relay to controller. * * @since 3.0 */ void sendRelayStateToController() { Serial.println("-------------- DEBUG sendRelayStateToController() ---------------"); bool current_state = digitalRead(PIN_RELAY); if (current_state == 1) { current_state = RELAY_ON; } else { current_state = RELAY_OFF; } Serial.print("current_state value is "); Serial.println(current_state); send(msg_relay.set(current_state) , true); Serial.println("------------------------------------------------------------"); } /** * Loop temperature. * Executed inside loop() * * @since 2.0 */ void loopTemperature() { // Fetch temperatures from Dallas sensors // we need sensors.requestTemperatures() to NO BLOCK THE THREAD!!! sensors.requestTemperatures(); float temperature = readTemperature(); sendTemperatureToController(temperature); } /************************************************/ /**** VARIOUS FUNCTION TO SUPPORT *****/ /************************************************/ /** * Receive function * * @since 2.0 */ void receive(const MyMessage &message) { if ( !message.isAck() ) { if ( message.type == V_STATUS) { if ( message.getCommand() == 1 ) { bool received_state = message.getBool(); Serial.print("received_state value is "); Serial.println(received_state); if ( received_state == 1) { digitalWrite(PIN_RELAY , RELAY_ON); } else { digitalWrite(PIN_RELAY , RELAY_OFF); } } } } Serial.println("--------------------------------------------"); } /** * Read the temperature from DS18B20 * * @since 2.0 */ float readTemperature() { // query conversion time and sleep until conversion completed int16_t conversionTime = millisToWaitForConversion(sensors.getResolution()); wait(conversionTime); // Read temperatures and send them to controller // Fetch and round temperature to one decimal float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(CHILD_ID_TEMP):sensors.getTempFByIndex(CHILD_ID_TEMP)) * 10.)) / 10.; return temperature; } /** * Get the millis to wait before reading based on resolution. * * @since 2.0 */ int16_t millisToWaitForConversion(uint8_t bitResolution) { switch (bitResolution) { case 9: return 94; case 10: return 188; case 11: return 375; default: return 750; } } /** * Send the temperature to controller * * @since 2.0 */ void sendTemperatureToController(float temperature) { if (temperature != -127.00 && temperature != 85.00) { send(msg_temperature.setSensor(CHILD_ID_TEMP).set(temperature,1)); digitalWrite(MY_DEFAULT_ERR_LED_PIN , LOW); //Serial.println("-------------- DEBUG sendTemperatureToController() ---------------"); //Serial.println("No error on send temperature"); //Serial.println("------------------------------------------------------"); } else { // light the error led fixed! digitalWrite(MY_DEFAULT_ERR_LED_PIN , HIGH); //Serial.println("-------------- DEBUG sendTemperatureToController() ---------------"); //Serial.println("! ERROR sending temperature"); //Serial.println("------------------------------------------------------"); } } /** * Light the LED status * * @since 2.0 */ void lightLedStatus() { int k = 0; for ( k = 0; k < WAIT_LOOPS; k++) { digitalWrite(PIN_LED_STATUS,HIGH); wait(10); // 5 * 1000 millisends = 5 seconds; digitalWrite(PIN_LED_STATUS,LOW); wait(4990); } }
-
Is displayed opposite or it is not updated?
-
@gohan Totally not updated. I did upload just now the @boots33 sketch in synch and it works. So it is my fault... But I cannot find!
I re-start from fresh (err.. from boots sketch).