Molgan and Emengency Light
-
I started play with an ikea molgan to make a a motion sensor for domoticz I want also have the possibility to use the onboard led as emergency light in case of black out so i've started with the standard motion sensor sketch trying to add the funcionality but i encountred some problems.
Basically what i want is
Normal state (motion sensor)
Emergency light triggered on and off by pir (if at first motion triggering if cannot contact the gateway or if in domoticz a switch status is on )for the hardware i've connected che gate control to a digital i/o of arduino, but for the software i sill have problem.
Sometimes the status is not correctly recived from controller in an acceptable time and i didn't have at the moment an efficient method to know if the gateway is alive.
any suggest ?here the sketch used
* * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Henrik Ekblad * * DESCRIPTION * Motion Sensor example using HC-SR501 * http://www.mysensors.org/build/motion * */ // Enable debug prints #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 //#define MY_SIGNING_SOFT //Enable software Signing //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected #include <MySensors.h> #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // Sleep time between reports (in milliseconds) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define CHILD_ID 1 // Id of motion sensor child #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet #define LED_CHILD_ID 2 // Id of motion sensor child // define values for the battery measurement #define R1 1e6 #define R2 470e3 #define VMIN 3.5 #define VMAX 4.5 #define ADC_PRECISION 1024 #define VREF 3.306 int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point int oldBatteryPcnt = 0; bool ledstatus = 0; bool response =0; bool tripped =0; // Initialize motion message MyMessage msg(CHILD_ID, V_TRIPPED); MyMessage led(LED_CHILD_ID,V_TEXT); void setup() { // use the 3.3 V reference analogReference(DEFAULT); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(DIGITAL_OUTPUT_LED, OUTPUT); digitalWrite(DIGITAL_OUTPUT_LED, 0); send(led.set(0)); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Motion Sensor and EMO Light", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID, S_MOTION, "Motion Molgan ",true); wait(500); present(LED_CHILD_ID, S_INFO, "LED Molgan ",true); } void loop() { // Read digital motion value tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.print("Motion State:"); Serial.println(tripped); send(msg.set(tripped?"1":"0")); // Send tripped value to gw request(LED_CHILD_ID, V_TEXT); response=wait(5000, 2, V_TEXT); Serial.print("Controller Response:"); Serial.println(response); int batteryPcnt=getBatteryPercentage(); if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led //if (response==1) //{ Serial.print("Going to sleep"); sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS); //return; //} //else // { // if (response==0){ // digitalWrite(DIGITAL_OUTPUT_LED, 1); // } // return; // } } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_TEXT) { // Change led state ledstatus=message.getBool(); //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (ledstatus==1){ digitalWrite(DIGITAL_OUTPUT_LED, tripped); } else { if(ledstatus==0) { digitalWrite(DIGITAL_OUTPUT_LED, 0); } } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(ledstatus); } } int getBatteryPercentage() { // read analog pin value int inputValue = analogRead(BATTERY_SENSE_PIN); // calculate the max possible value and therefore the range and steps float voltageDividerFactor = 3.225622776; float maxValue = voltageDividerFactor * VREF; float voltsPerBit = maxValue / ADC_PRECISION; int batteryVoltage = (voltsPerBit * inputValue)*1000; Serial.print("Battery Voltage:"); Serial.println(batteryVoltage); //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100; int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100); Serial.print("Battery Percentage:"); Serial.println(batteryPercentage); return batteryPercentage; }
-
@markcame I'm doing a similar thing with @Yveaux 's Molgan-Hack board. Interesting to see that you are using the
wait()
function in the extended versionresponse=wait(5000, 2, V_TEXT);
I never noticed that it existed
A few remarks:- Domoticz can handle requests for (light)
V_STATUS
which fits the purpose better (and is more efficient) - Using the extend version of wait the second parameter
cmd
should be the MySensors command typeset
(value = = 1) as the node will be receiving aset
from the controller. You better use the constant nameC_SET
although not mentioned in the API (yet). InMyMessage.h
:
/// @brief The command field (message-type) defines the overall properties of a message typedef enum { C_PRESENTATION = 0, //!< Sent by a node when they present attached sensors. This is usually done in presentation() at startup. C_SET = 1, //!< This message is sent from or to a sensor when a sensor value should be updated. C_REQ = 2, //!< Requests a variable value (usually from an actuator destined for controller). C_INTERNAL = 3, //!< Internal MySensors messages (also include common messages provided/generated by the library). C_STREAM = 4 //!< For firmware and other larger chunks of data that need to be divided into pieces. } mysensor_command;
- Domoticz can handle requests for (light)
-
Ok i will try with the modification suggested.
I have at the moment some comunication problems with th radio so i've rewired my ESP8266 gateway and adding some capacitors.
what type use S-BINARY , i have had some problems retriving the status from domoticz , i don't know if it is related to the lastest beta...
-
I've tryed everything but seems that the request does not return a value, seems that domoticz does not expose the value but only send status update at the moment of the switch, request on V_VAR1... ecc. ec... instead always works but they are not exposed to the user...
-
@markcame can you please post your sketch showing the request?
-
@AWI
Sketch/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Henrik Ekblad * * DESCRIPTION * Motion Sensor example using HC-SR501 * http://www.mysensors.org/build/motion * */ // Enable debug prints #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 //#define MY_SIGNING_SOFT //Enable software Signing //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected #include <MySensors.h> #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // Sleep time between reports (in milliseconds) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define CHILD_ID 1 // Id of motion sensor child #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet #define LED_CHILD_ID 2 // Id of motion sensor child #define VOLTAGE_CHILD_ID 3 // define values for the battery measurement #define R1 1e6 #define R2 470e3 #define VMIN 3.5 #define VMAX 4.5 #define ADC_PRECISION 1024 #define VREF 3.3 int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point int oldBatteryPcnt = 200; bool ledstatus = 0; bool response =0; bool tripped =0; float batteryvoltreport=0; // Initialize motion message MyMessage msg(CHILD_ID, V_TRIPPED); MyMessage led(LED_CHILD_ID,V_STATUS); MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE); void setup() { // use the 3.3 V reference analogReference(DEFAULT); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(DIGITAL_OUTPUT_LED, OUTPUT); digitalWrite(DIGITAL_OUTPUT_LED, 0); send(led.set(0)); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Motion Sensor and EMO Light", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID, S_MOTION, "Motion Molgan ",true); wait(500); present(LED_CHILD_ID, S_BINARY, "LED Molgan ",true); wait(500); present(VOLTAGE_CHILD_ID, S_MULTIMETER, "Battery level" ); } void loop() { // Read digital motion value tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.print("Motion State:"); Serial.println(tripped); send(msg.set(tripped?"1":"0")); // Send tripped value to gw request(LED_CHILD_ID, V_STATUS); response=wait(5000, C_SET, V_STATUS); Serial.print("Controller Response:"); Serial.println(response); int batteryPcnt=getBatteryPercentage(); if (batteryPcnt < oldBatteryPcnt ) { // Power up radio after sleep sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; send(voltageMsg.set(batteryvoltreport,2)); //send battery in Volt 2 decimal places } // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led //if (response==1) //{ //Serial.print("Going to sleep"); sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS); //return; //} //else // { // if (response==0){ // digitalWrite(DIGITAL_OUTPUT_LED, 1); // } // return; // } } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_STATUS) { // Change led state ledstatus=message.getBool(); //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (ledstatus==1){ digitalWrite(DIGITAL_OUTPUT_LED, tripped); } else { if(ledstatus==0) { digitalWrite(DIGITAL_OUTPUT_LED, 0); } } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(ledstatus); } } int getBatteryPercentage() { // read analog pin value int inputValue = analogRead(BATTERY_SENSE_PIN); // calculate the max possible value and therefore the range and steps float voltageDividerFactor = 3.225622776; float maxValue = voltageDividerFactor * VREF; float voltsPerBit = maxValue / ADC_PRECISION; int batteryVoltage = (voltsPerBit * inputValue)*1000; batteryvoltreport=(voltsPerBit * inputValue); //Serial.print("Battery Voltage:"); //Serial.println(batteryVoltage); //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100; int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100); //Serial.print("Battery Percentage:"); //Serial.println(batteryPercentage); return batteryPercentage; }
Serial Debug
4242 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100 4371 TSF:MSG:READ,0-0-6,s=255,c=3,t=15,pt=6,l=2,sg=0:0100 4378 TSF:MSG:SEND,6-6-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.1.1 4386 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0 5599 TSF:MSG:READ,0-0-6,s=255,c=3,t=6,pt=0,l=1,sg=0:M 5609 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=11,pt=0,l=25,sg=0,ft=0,st=OK:Motion Sensor and EMO Lig 5619 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0 5628 TSF:MSG:SEND,6-6-0-0,s=1,c=0,t=1,pt=0,l=14,sg=0,ft=0,st=OK:Motion Molgan 5946 TSF:MSG:READ,0-0-6,s=1,c=0,t=1,pt=0,l=14,sg=0:Motion Molgan 5951 TSF:MSG:ACK 6140 TSF:MSG:SEND,6-6-0-0,s=2,c=0,t=3,pt=0,l=11,sg=0,ft=0,st=OK:LED Molgan 6246 TSF:MSG:READ,0-0-6,s=2,c=0,t=3,pt=0,l=11,sg=0:LED Molgan 6252 TSF:MSG:ACK 6652 TSF:MSG:SEND,6-6-0-0,s=3,c=0,t=30,pt=0,l=13,sg=0,ft=0,st=OK:Battery level 6660 MCO:REG:REQ 6666 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2 6804 TSF:MSG:READ,0-0-6,s=255,c=3,t=27,pt=1,l=1,sg=0:1 6808 MCO:PIM:NODE REG=1 6811 MCO:BGN:STP 6814 TSF:MSG:SEND,6-6-0-0,s=2,c=1,t=2,pt=2,l=2,sg=0,ft=0,st=OK:0 6820 MCO:BGN:INIT OK,TSP=1 Motion State:0 6824 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0 6865 !TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=NACK: Controller Response:0 11874 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=1,st=OK:100 11891 TSF:MSG:SEND,6-6-0-0,s=3,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:4.88 11897 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255 11902 MCO:SLP:TPD 11905 MCO:SLP:WUP=1 Motion State:1 11909 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:1 11916 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK: Controller Response:0 16922 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255 16928 MCO:SLP:TPD 16930 MCO:SLP:WUP=1 Motion State:0 16936 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0 16944 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK: Controller Response:0 21950 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255 21956 MCO:SLP:TPD```
Gateway
0;255;3;0;14;Gateway startup complete. 0;255;0;0;18;2.1.1 0;255;3;0;2;2.1.1 0;255;3;0;22;188673920 0;255;3;0;22;188683854 6;255;0;0;17;2.1.1 6;255;3;0;6;0 6;255;3;0;11;Motion Sensor and EMO Lig 6;255;3;0;12;1.0 6;1;0;0;1;Motion Molgan 6;2;0;0;3;LED Molgan 6;3;0;0;30;Battery level 6;2;1;0;2;0 6;1;1;0;16;0 6;2;2;0;2; 0;255;3;0;22;188693888 6;255;3;0;0;100 6;3;1;0;38;4.88 0;255;3;0;22;188703923 6;1;1;0;16;1 6;2;2;0;2; 6;1;1;0;16;0 6;2;2;0;2;
-
@markcame apart from that there is some variable type mixing (bool, int, ) the sketch looks fine. Domoticz returns values for: V_STATUS, V_PERCENTAGE, V_RGB(W), V_VARx and V_TEXT (see code snippet below (github))
You can try to have the sensor re-create in Domoticz with a fixed node Id. Experimenting could have caused Domoticz to mess up the database.if (message_type == MT_Req) { //Request a variable std::string tmpstr; switch (sub_type) { case V_STATUS: case V_PERCENTAGE: case V_RGB: case V_RGBW: if (GetSwitchValue(node_id, child_sensor_id, sub_type, tmpstr)) SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr); break; case V_VAR1: case V_VAR2: case V_VAR3: case V_VAR4: case V_VAR5: //send back a previous stored custom variable tmpstr = ""; GetVar(node_id, child_sensor_id, sub_type, tmpstr); //SendNodeSetCommand(node_id, child_sensor_id, message_type, (_eSetType)sub_type, tmpstr, true, 1000); SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr); break; case V_TEXT: { //Get Text sensor value from the database bool bExits = false; tmpstr = GetTextSensorText(node_id, child_sensor_id, bExits); SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr); } break; default: while (1==0); break; } while (1==0); }
-
Ok, how can assign a fixed id ?
-
@markcame
#define MY_NODE_ID xxx
in the start of your sketch