From 2665e93c5319828166eddf6eff1424d9f762a673 Mon Sep 17 00:00:00 2001 From: petewill Date: Mon, 6 Jul 2015 07:14:37 -0600 Subject: [PATCH 1/2] Rain Gauge Uploading initial rain gauge code and Vera files --- .../examples/RainGauge/D_RainSensor1.json | 523 +++++++++++++++ .../examples/RainGauge/D_RainSensor1.xml | 24 + .../examples/RainGauge/RainGauge.ino | 594 ++++++++++++++++++ .../examples/RainGauge/S_Rainsensor1.xml | 43 ++ 4 files changed, 1184 insertions(+) create mode 100644 libraries/MySensors/examples/RainGauge/D_RainSensor1.json create mode 100644 libraries/MySensors/examples/RainGauge/D_RainSensor1.xml create mode 100644 libraries/MySensors/examples/RainGauge/RainGauge.ino create mode 100644 libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml diff --git a/libraries/MySensors/examples/RainGauge/D_RainSensor1.json b/libraries/MySensors/examples/RainGauge/D_RainSensor1.json new file mode 100644 index 0000000..325391b --- /dev/null +++ b/libraries/MySensors/examples/RainGauge/D_RainSensor1.json @@ -0,0 +1,523 @@ +{ + "flashicon": "icons/Humidity_Sensor.swf", + "imgIconBody": "", + "imgIconDimmable": "", + "imgIconTurnable": "", + "imgIconMin": "", + "imgIconMax": "", + "halloIconsDir": "pics\/hallo", + "inScene": "0", + "DisplayStatus": {}, + "doc_url": { + "doc_language": 1, + "doc_manual": 1, + "doc_version": 1, + "doc_platform": 0, + "doc_page": "sensors" + }, + + "Tabs": [ + { + "Label": { + "lang_tag": "tabname_control", + "text": "Information" + }, + "Position": "0", + "TabType": "flash", + "SceneGroup": [ + { + "id": "1", + "top": "1.5", + "left": "0", + "x": "2", + "y": "2" + } + ], + "ControlGroup": [ + { + "id": "1", + "scenegroup": "1", + "type": "info" + }, + { + "id": "2", + "scenegroup": "1", + "type": "info" + } + ], + "Control": [ + { + "ControlGroup":"1", + "ControlPair": "1", + "ControlHeader": "1", + "top": "1", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "rain_rate", + "text": "Rate of Rain" + }, + "Display": { + "Top": 20, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"1", + "ControlPair": "1", + "ControlHeader": "1", + "top": "1", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:RainSensor1", + "Variable": "CurrentRain", + "Top": 20, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "total_rain_unit", + "text": "mm/hr" + }, + "Display": { + "Top": 20, + "Left": 200, + "Width": 25, + "Height": 20 + } + }, + { + "ControlGroup":"2", + "ControlPair": "2", + "ControlHeader": "1", + "top": "0", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "total_rain", + "text": "Rain Today:", + }, + "Display": { + "Top": 55, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"2", + "ControlPair": "2", + "ControlHeader": "1", + "top": "0", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:RainSensor1", + "Variable": "CurrentTRain", + "Top": 55, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "rain_rate_unit", + "text": "mm" + }, + "Display": { + "Top": 55, + "Left": 200, + "Width": 25, + "Height": 20 + } + }, + { + "ControlGroup":"3", + "ControlPair": "3", + "ControlHeader": "1", + "top": "0", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "rain_forty", + "text": "Yesterday:" + }, + "Display": { + "Top": 80, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"3", + "ControlPair": "3", + "ControlHeader": "1", + "top": "0", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:VContainer1", + "Variable": "Variable2", + "Top": 80, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "rain_unit", + "text": "mm" + }, + "Display": { + "Top": 80, + "Left": 200, + "Width": 25, + "Height": 20 + } + }, + { + "ControlGroup":"4", + "ControlPair": "4", + "ControlHeader": "1", + "top": "0", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "rain_seventy", + "text": "3 Days Ago:" + }, + "Display": { + "Top": 105, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"4", + "ControlPair": "4", + "ControlHeader": "1", + "top": "0", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:VContainer1", + "Variable": "Variable3", + "Top": 105, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "rain_unit1", + "text": "mm" + }, + "Display": { + "Top": 105, + "Left": 200, + "Width": 25, + "Height": 20 + } + }, + { + "ControlGroup":"5", + "ControlPair": "5", + "ControlHeader": "1", + "top": "0", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "rain_forty", + "text": "4 Days Ago:" + }, + "Display": { + "Top": 130, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"5", + "ControlPair": "5", + "ControlHeader": "1", + "top": "0", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:VContainer1", + "Variable": "Variable4", + "Top": 130, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "rain_unit2", + "text": "mm" + }, + "Display": { + "Top": 130, + "Left": 200, + "Width": 25, + "Height": 20 + } + }, + { + "ControlGroup":"6", + "ControlPair": "6", + "ControlHeader": "1", + "top": "0", + "left": "0", + "x": "1.25", + "ControlType": "label", + "Label": { + "lang_tag": "rain_hundred", + "text": "5 Days Ago:" + }, + "Display": { + "Top": 155, + "Left": 50, + "Width": 75, + "Height": 20 + } + }, + { + "ControlGroup":"6", + "ControlPair": "6", + "ControlHeader": "1", + "top": "0", + "left": "1.25", + "x": "0.75", + "ControlType": "variable", + "Display": { + "Service": "urn:upnp-org:serviceId:VContainer1", + "Variable": "Variable5", + "Top": 155, + "Left": 150, + "Width": 25, + "Height": 20 + } + }, + { + "ControlType": "label", + "Label": { + "lang_tag": "rain_unit3", + "text": "mm" + }, + "Display": { + "Top": 155, + "Left": 200, + "Width": 25, + "Height": 20 + } + } + ] + }, + { + "Label": { + "lang_tag": "advanced", + "text": "Advanced" + }, + "Position": "1", + "TabType": "javascript", + "ScriptName": "shared.js", + "Function": "advanced_device" + }, + { + "Label": { + "lang_tag": "logs", + "text": "Logs" + }, + "Position": "2", + "TabType": "javascript", + "ScriptName": "shared.js", + "Function": "device_logs" + }, + { + "Label": { + "lang_tag": "notifications", + "text": "Notifications" + }, + "Position": "3", + "TabType": "javascript", + "ScriptName": "shared.js", + "Function": "device_notifications" + } + ], + "eventList2": [ + { + "id": 1, + "label": { + "lang_tag": "total_rain_goes_above", + "text": "Total rain goes above" + }, + "serviceId": "urn:upnp-org:serviceId:RainSensor1", + "norepeat": "1", + "argumentList": [ + { + "id": 1, + "dataType": "r8", + "name": "CurrentTRain", + "comparisson": ">", + "prefix": { + "lang_tag": "total_rain", + "text": "Total rain" + }, + "suffix": { + "lang_tag": "total_rain_unit", + "text": "mm" + }, + "HumanFriendlyText": { + "lang_tag": "hft_total_rain_goes_above", + "text": "Total rain for _DEVICE_NAME_ goes above _ARGUMENT_VALUE_" + } + } + ] + }, + { + "id": 2, + "label": { + "lang_tag": "total_rain_goes_below", + "text": "Total rain goes below" + }, + "serviceId": "urn:upnp-org:serviceId:RainSensor1", + "norepeat": "1", + "argumentList": [ + { + "id": 1, + "dataType": "r8", + "name": "CurrentTRain", + "comparisson": "<", + "prefix": { + "lang_tag": "total_rain", + "text": "Total rain" + }, + "suffix": { + "lang_tag": "total_rain_unit", + "text": "mm" + }, + "HumanFriendlyText": { + "lang_tag": "hft_total_rain_goes_below", + "text": "Total rain for _DEVICE_NAME_ goes below _ARGUMENT_VALUE_" + } + } + ] + }, + { + "id": 3, + "label": { + "lang_tag": "rain_rate_goes_above", + "text": "Current rain goes above" + }, + "serviceId": "urn:upnp-org:serviceId:RainSensor1", + "norepeat": "1", + "argumentList": [ + { + "id": 1, + "dataType": "r8", + "name": "CurrentRain", + "comparisson": ">", + "prefix": { + "lang_tag": "rain_rate", + "text": "Current rain" + }, + "suffix": { + "lang_tag": "rain_rate_unit", + "text": "mm/hr" + }, + "HumanFriendlyText": { + "lang_tag": "hft_rain_rate_goes_above", + "text": "Current rain for _DEVICE_NAME_ goes above _ARGUMENT_VALUE_" + } + } + ] + }, + { + "id": 4, + "label": { + "lang_tag": "rain_rate_goes_below", + "text": "Current rain goes below" + }, + "serviceId": "urn:upnp-org:serviceId:RainSensor1", + "norepeat": "1", + "argumentList": [ + { + "id": 1, + "dataType": "r8", + "name": "CurrentRain", + "comparisson": "<", + "prefix": { + "lang_tag": "rain_rate", + "text": "Current rain" + }, + "suffix": { + "lang_tag": "rain_rate_unit", + "text": "mm/hr" + }, + "HumanFriendlyText": { + "lang_tag": "hft_rain_rate_goes_below", + "text": "Current rain for _DEVICE_NAME_ goes below _ARGUMENT_VALUE_" + } + } + ] + }, + { + "id": 5, + "label": { + "lang_tag": "battery_level_goes_below", + "text": "Battery level goes below" + }, + "serviceId": "urn:micasaverde-com:serviceId:HaDevice1", + "argumentList": [ + { + "id": 1, + "prefix": { + "lang_tag": "Level", + "text": "Level" + }, + "dataType": "i4", + "name": "BatteryLevel", + "comparisson": "<", + "suffix": { + "lang_tag": "percent_sign", + "text": "%" + }, + "HumanFriendlyText": { + "lang_tag": "hft_battery_level_goes_below", + "text": "Battery level for _DEVICE_NAME_ go below _ARGUMENT_VALUE_%" + } + } + ] + } + ], + "DeviceType": "urn:schemas-micasaverde-com:device:RainSensor:1" +} \ No newline at end of file diff --git a/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml b/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml new file mode 100644 index 0000000..c0a7492 --- /dev/null +++ b/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml @@ -0,0 +1,24 @@ + + + + 1 + 0 + + + urn:schemas-micasaverde-com:device:RainSensor:1 + 12 + D_RainSensor1.json + + + urn:schemas-upnp-org:service:RainSensor:1 + urn:upnp-org:serviceId:RainSensor1 + S_RainSensor1.xml + + + urn:schemas-micasaverde-com:service:HaDevice:1 + urn:micasaverde-com:serviceId:HaDevice1 + S_HaDevice1.xml + + + + \ No newline at end of file diff --git a/libraries/MySensors/examples/RainGauge/RainGauge.ino b/libraries/MySensors/examples/RainGauge/RainGauge.ino new file mode 100644 index 0000000..475eb0c --- /dev/null +++ b/libraries/MySensors/examples/RainGauge/RainGauge.ino @@ -0,0 +1,594 @@ +/* + Arduino Tipping Bucket Rain Gauge + + April 26, 2015 + + Version 1.4.1 alpha + + Arduino Tipping Bucket Rain Gauge + + Utilizing a tipping bucket sensor, your Vera home automation controller and the MySensors.org + gateway you can measure and sense local rain. This sketch will create two devices on your + Vera controller. One will display your total precipitation for the last 5 days. The other, + a sensor that changes state if there is recent rain (up to last 120 hours) above a threshold. + Both these settings are user definable. + + There is a build overview video here: https://youtu.be/1eMfKQaLROo + + This sketch features the following: + + * Allows you to set the rain threshold in mm + * Allows you to determine the tripped indicator window up to 120 hours. + * Displays the last 5 days of rain in Variable1 through Variable5 + of the Rain Sensor device + * Configuration changes to Sensor device updated every hour + * Should run on any Arduino + * Will retain Tripped/Not Tripped status and data in a power interruption, saving small amount + of data to EEPROM (Circular Buffer to maximize life of EEPROM) + * LED status indicator + * Optional Temp/Humidity (DHT-22 or DHT-11) and Light LUX (BH1750) sensors. To use, uncomment + #define DHT_ON and/or #define LUX_ON + * Optionally send total accumulation of each day's rainfall or send only individual days rainfall totals. + Comment out #define USE_DAILY to display individual daily rainfall. + + by @BulldogLowell and @PeteWill for free public use + + */ +#include +#include +#include +#include + +#define NODE_ID 24 //or AUTO to let controller assign +#define SKETCH_NAME "Rain Gauge" +#define SKETCH_VERSION "1.4.1a" + +#define DWELL_TIME 125 // this allows for radio to come back to power after a transmission, ideally 0 + +//#define DEBUG_ON // comment out this line to disable serial debug +#define DHT_ON // uncomment out this line to enable DHT sensor +#define LUX_ON // uncomment out this line to enable BH1750 sensor +//#define USE_DAILY // displays each time segment as an accumulation of prior periods inclusive. Comment out to display individual daily rainfall totals in the variables sent to your controller. + +#define CALIBRATE_FACTOR 60 // amount of rain per rain bucket tip e.g. 5 is .05mm +#define DHT_LUX_DELAY 300000 //Delay in milliseconds that the DHT and LUX sensors will wait before sending data + +#define CHILD_ID_RAIN_LOG 3 // Keeps track of accumulated rainfall +#define CHILD_ID_TRIPPED_INDICATOR 4 // Indicates Tripped when rain detected +#define EEPROM_BUFFER_LOCATION 0 // location of the EEPROM circular buffer +#define E_BUFFER_LENGTH 240 +#define RAIN_BUCKET_SIZE 120 + +#ifdef DEBUG_ON + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) + #define SERIAL_START(x) Serial.begin(x) + #else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define SERIAL_START(x) +#endif +// +MySensor gw; +// +MyMessage msgRainRate(CHILD_ID_RAIN_LOG, V_RAINRATE); +MyMessage msgRain(CHILD_ID_RAIN_LOG, V_RAIN); +// +MyMessage msgRainVAR1(CHILD_ID_RAIN_LOG, V_VAR1); +MyMessage msgRainVAR2(CHILD_ID_RAIN_LOG, V_VAR2); +MyMessage msgRainVAR3(CHILD_ID_RAIN_LOG, V_VAR3); +MyMessage msgRainVAR4(CHILD_ID_RAIN_LOG, V_VAR4); +MyMessage msgRainVAR5(CHILD_ID_RAIN_LOG, V_VAR5); +// +MyMessage msgTripped(CHILD_ID_TRIPPED_INDICATOR, V_TRIPPED); +MyMessage msgTrippedVar1(CHILD_ID_TRIPPED_INDICATOR, V_VAR1); +MyMessage msgTrippedVar2(CHILD_ID_TRIPPED_INDICATOR, V_VAR2); +// +#ifdef DHT_ON + #include + #define CHILD_ID_HUM 0 + #define CHILD_ID_TEMP 1 + #define HUMIDITY_SENSOR_DIGITAL_PIN 8 + DHT dht; + float lastTemp; + float lastHum; + boolean metric = true; + MyMessage msgHum(CHILD_ID_HUM, V_HUM); + MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); +#endif +// +#ifdef LUX_ON + //BH1750 is connected to SCL (analog input A5) and SDA (analog input A4) + #include + #include + #define CHILD_ID_LIGHT 2 + BH1750 lightSensor; + MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); + unsigned int lastlux; + byte heartbeat = 10; //Used to send the light lux to gateway as soon as the device is restarted and after the DHT_LUX_DELAY has happened 10 times +#endif +unsigned long sensorPreviousMillis; +int eepromIndex; +int tipSensorPin = 3; // Pin the tipping bucket is connected to. Must be interrupt capable pin +int ledPin = 5; // Pin the LED is connected to. PWM capable pin required +unsigned long dataMillis; +unsigned long serialInterval = 600000UL; +const unsigned long oneHour = 3600000UL; +unsigned long lastTipTime; +unsigned long lastRainTime; //Used for rainRate calculation +unsigned int rainBucket [RAIN_BUCKET_SIZE] ; /* 24 hours x 5 Days = 120 hours */ +unsigned int rainRate = 0; +byte rainWindow = 72; //default rain window in hours. Will be overwritten with msgTrippedVar1. +volatile int wasTippedBuffer = 0; +int rainSensorThreshold = 50; //default rain sensor sensitivity in hundredths. Will be overwritten with msgTrippedVar2. +byte state = 0; +byte oldState = -1; +int lastRainRate = 0; +int lastMeasure = 0; +boolean gotTime = false; +byte lastHour; +byte currentHour; +// +void setup() +{ + SERIAL_START(115200); + // + // Set up the IO + pinMode(tipSensorPin, INPUT_PULLUP); + attachInterrupt (1, sensorTipped, FALLING); // depending on location of the hall effect sensor may need CHANGE + pinMode(ledPin, OUTPUT); + digitalWrite(ledPin, HIGH); + // + //Let's get the controller talking to the Arduino + gw.begin(getVariables, NODE_ID); + gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); + gw.wait(DWELL_TIME); + gw.present(CHILD_ID_RAIN_LOG, S_RAIN); + gw.wait(DWELL_TIME); + gw.present(CHILD_ID_TRIPPED_INDICATOR, S_MOTION); + gw.wait(DWELL_TIME); + DEBUG_PRINTLN(F("Sensor Presentation Complete")); + // + //Sync time with the server, this will be called hourly in order to keep time from creeping with the crystal + // + unsigned long functionTimeout = millis(); + while (timeStatus() == timeNotSet && millis() - functionTimeout < 30000UL) + { + gw.process(); + gw.requestTime(receiveTime); + DEBUG_PRINTLN(F("Getting Time")); + gw.wait(1000); // call once per second + DEBUG_PRINTLN(F(".")); + } + currentHour = hour(); + lastHour = hour(); + // + //retrieve from EEPROM stored values on a power cycle. + // + boolean isDataOnEeprom = false; + for (int i = 0; i < E_BUFFER_LENGTH; i++) + { + byte locator = gw.loadState(EEPROM_BUFFER_LOCATION + i); + if (locator == 0xFE) // found the EEPROM circular buffer index + { + eepromIndex = EEPROM_BUFFER_LOCATION + i; + DEBUG_PRINT(F("EEPROM Index ")); + DEBUG_PRINTLN(eepromIndex); + //Now that we have the buffer index let's populate the rainBucket[] with data from eeprom + loadRainArray(eepromIndex); + isDataOnEeprom = true; + break; + } + } + // + if (!isDataOnEeprom) // Added for the first time it is run on a new Arduino + { + DEBUG_PRINTLN(F("I didn't find valid EEPROM Index, so I'm writing one to location 0")); + eepromIndex = EEPROM_BUFFER_LOCATION; + gw.saveState(eepromIndex, 0xFE); + gw.saveState(eepromIndex + 1, 0xFE); + //then I will clear out any bad data + for (int i = 2; i <= E_BUFFER_LENGTH; i++) + { + gw.saveState(i, 0x00); + } + } + dataMillis = millis(); + lastTipTime = millis() - oneHour; //why is this -oneHour?? Doesn't millis() start at 0 when first powered on? + // + gw.request(CHILD_ID_TRIPPED_INDICATOR, V_VAR1); + gw.wait(DWELL_TIME); + gw.request(CHILD_ID_TRIPPED_INDICATOR, V_VAR2); + gw.wait(DWELL_TIME); + // +#ifdef DHT_ON + dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); + // Register all sensors to gw (they will be created as child devices) + gw.present(CHILD_ID_HUM, S_HUM); + gw.wait(DWELL_TIME); + gw.present(CHILD_ID_TEMP, S_TEMP); + gw.wait(DWELL_TIME); + metric = gw.getConfig().isMetric; + gw.wait(DWELL_TIME); +#endif + // +#ifdef LUX_ON + gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); + gw.wait(DWELL_TIME); + lightSensor.begin(); +#endif + // + DEBUG_PRINTLN(F("Radio Setup Complete!")); + transmitRainData(); +} + +void loop() +{ + gw.process(); + if (state) + { + prettyFade(); // breathe if tripped + } + else + { + slowFlash(); // blink if not tripped + } +#ifdef DEBUG_ON // Serial Debug Block + if ( (millis() - dataMillis) >= serialInterval) + { + for (int i = 24; i <= 120; i = i + 24) + { + updateSerialData(i); + } + dataMillis = millis(); + } +#endif + // + // let's constantly check to see if the rain in the past rainWindow hours is greater than rainSensorThreshold + // + int measure = 0; // Check to see if we need to show sensor tripped in this block + for (int i = 0; i < rainWindow; i++) + { + measure += rainBucket [i]; + if (measure != lastMeasure) + { + // DEBUG_PRINT(F("measure value (total rainBucket within rainWindow): ")); + // DEBUG_PRINTLN(measure); + lastMeasure = measure; + } + } + // + state = (measure >= (rainSensorThreshold * 100)); + if (state != oldState) + { + gw.send(msgTripped.set(state)); + gw.wait(DWELL_TIME); + DEBUG_PRINT(F("New Sensor State... Sensor: ")); + DEBUG_PRINTLN(state ? "Tripped" : "Not Tripped"); + oldState = state; + } + // + unsigned long tipDelay = millis() - lastRainTime; + if (wasTippedBuffer) // if was tipped, then update the 24hour total and transmit to Vera + { + DEBUG_PRINTLN(F("Sensor Tipped")); + DEBUG_PRINT(F("rainBucket [0] value: ")); + DEBUG_PRINTLN(rainBucket [0]); + gw.send(msgRain.set((float)rainTotal(currentHour) / 100, 1)); //Calculate the total rain for the day + gw.wait(DWELL_TIME); + wasTippedBuffer--; + rainRate = ((oneHour) / tipDelay); + if (rainRate != lastRainRate) + { + gw.send(msgRainRate.set(rainRate, 1)); + gw.wait(DWELL_TIME); + DEBUG_PRINT(F("RainRate= ")); + DEBUG_PRINTLN(rainRate); + lastRainRate = rainRate; + } + lastRainTime = lastTipTime; + } + // + currentHour = hour(); + if (currentHour != lastHour) + { + DEBUG_PRINTLN(F("One hour elapsed.")); + gw.send(msgRain.set((float)rainTotal(currentHour) / 100, 1)); // send today's rainfall + gw.wait(DWELL_TIME); + gw.saveState(eepromIndex, highByte(rainBucket[0])); + gw.saveState(eepromIndex + 1, lowByte(rainBucket[0])); + DEBUG_PRINT(F("Saving rainBucket[0] to eeprom. rainBucket[0] = ")); + DEBUG_PRINTLN(rainBucket[0]); + for (int i = RAIN_BUCKET_SIZE - 1; i >= 0; i--)//cascade an hour of values back into the array + { + rainBucket [i + 1] = rainBucket [i]; + } + gw.request(CHILD_ID_TRIPPED_INDICATOR, V_VAR1); + gw.wait(DWELL_TIME); + gw.request(CHILD_ID_TRIPPED_INDICATOR, V_VAR2); + gw.wait(DWELL_TIME); + rainBucket[0] = 0; + eepromIndex = eepromIndex + 2; + if (eepromIndex > EEPROM_BUFFER_LOCATION + E_BUFFER_LENGTH) + { + eepromIndex = EEPROM_BUFFER_LOCATION; + } + DEBUG_PRINT(F("Writing to EEPROM. Index: ")); + DEBUG_PRINTLN(eepromIndex); + gw.saveState(eepromIndex, 0xFE); + gw.saveState(eepromIndex + 1, 0xFE); + gw.requestTime(receiveTime); // sync the time every hour + gw.wait(DWELL_TIME); + transmitRainData(); + rainRate = 0; + gw.send(msgRainRate.set(rainRate, 1)); + gw.wait(DWELL_TIME); + DEBUG_PRINTLN(F("Sending rainRate is 0 to controller")); + lastHour = currentHour; + } + if (millis() - sensorPreviousMillis > DHT_LUX_DELAY) + { + #ifdef DHT_ON //DHT Code + doDHT(); + #endif + #ifdef LUX_ON + doLUX(); + #endif + sensorPreviousMillis = millis(); + } +} +// +#ifdef DHT_ON +void doDHT(void) +{ + float temperature = dht.getTemperature(); + if (isnan(temperature)) + { + DEBUG_PRINTLN(F("Failed reading temperature from DHT")); + } else if (temperature != lastTemp) + { + lastTemp = temperature; + if (!metric) + { + temperature = dht.toFahrenheit(temperature); + } + gw.send(msgTemp.set(temperature, 1)); + gw.wait(DWELL_TIME); + DEBUG_PRINT(F("Temperature is: ")); + DEBUG_PRINTLN(temperature); + } + float humidity = dht.getHumidity();; + if (isnan(humidity)) + { + DEBUG_PRINTLN(F("Failed reading humidity from DHT")); + } else if (humidity != lastHum) + { + lastHum = humidity; + gw.send(msgHum.set(humidity, 1)); + gw.wait(DWELL_TIME); + DEBUG_PRINT(F("Humidity is: ")); + DEBUG_PRINTLN(humidity); + } +} +#endif +// +#ifdef LUX_ON +void doLUX(void) +{ + unsigned int lux = lightSensor.readLightLevel();// Get Lux value + DEBUG_PRINT(F("Current LUX Level: ")); + DEBUG_PRINTLN(lux); + heartbeat++; + if (lux != lastlux || heartbeat > 10) + { + gw.send(msg.set(lux)); + lastlux = lux; + } + if (heartbeat > 10) + { + heartbeat = 0; + } +} +#endif +// +void sensorTipped() +{ + unsigned long thisTipTime = millis(); + if (thisTipTime - lastTipTime > 100UL) + { + rainBucket[0] += CALIBRATE_FACTOR; // adds CALIBRATE_FACTOR hundredths of unit each tip + wasTippedBuffer++; + } + lastTipTime = thisTipTime; +} +// +int rainTotal(int hours) +{ + int total = 0; + for ( int i = 0; i <= hours; i++) + { + total += rainBucket [i]; + } + return total; +} + +void updateSerialData(int x) +{ + DEBUG_PRINT(F("Rain last ")); + DEBUG_PRINT(x); + DEBUG_PRINTLN(F(" hours: ")); + float tipCount = 0; + for (int i = 0; i < x; i++) + { + tipCount = tipCount + rainBucket [i]; + } + tipCount = tipCount / 100; + DEBUG_PRINTLN(tipCount); +} + +void loadRainArray(int value) // retrieve stored rain array from EEPROM on powerup +{ + for (int i = 0; i < RAIN_BUCKET_SIZE; i++) + { + value = value - 2; + if (value < EEPROM_BUFFER_LOCATION) + { + value = EEPROM_BUFFER_LOCATION + E_BUFFER_LENGTH; + } + DEBUG_PRINT(F("EEPROM location: ")); + DEBUG_PRINTLN(value); + byte rainValueHigh = gw.loadState(value); + byte rainValueLow = gw.loadState(value + 1); + unsigned int rainValue = rainValueHigh << 8; + rainValue |= rainValueLow; + rainBucket[i + 1] = rainValue; + // + DEBUG_PRINT(F("rainBucket[ value: ")); + DEBUG_PRINT(i + 1); + DEBUG_PRINT(F("] value: ")); + DEBUG_PRINTLN(rainBucket[i + 1]); + } +} + +void transmitRainData(void) +{ + DEBUG_PRINT(F("In transmitRainData. currentHour = ")); + DEBUG_PRINTLN(currentHour); + int rainUpdateTotal = 0; + for (int i = currentHour; i >= 0; i--) + { + rainUpdateTotal += rainBucket[i]; + DEBUG_PRINT(F("Adding rainBucket[")); + DEBUG_PRINT(i); + DEBUG_PRINTLN(F("] to rainUpdateTotal.")); + } + DEBUG_PRINT(F("TX Day 1: rainUpdateTotal = ")); + DEBUG_PRINTLN((float)rainUpdateTotal / 100.0); + gw.send(msgRainVAR1.set((float)rainUpdateTotal / 100.0, 1)); //Send current day rain totals (resets at midnight) + gw.wait(DWELL_TIME); +#ifdef USE_DAILY + rainUpdateTotal = 0; +#endif + for (int i = currentHour + 24; i > currentHour; i--) + { + rainUpdateTotal += rainBucket[i]; + DEBUG_PRINT(F("Adding rainBucket[")); + DEBUG_PRINT(i); + DEBUG_PRINTLN(F("] to rainUpdateTotal.")); + } + DEBUG_PRINT(F("TX Day 2: rainUpdateTotal = ")); + DEBUG_PRINTLN((float)rainUpdateTotal / 100.0); + gw.send(msgRainVAR2.set((float)rainUpdateTotal / 100.0, 1)); + gw.wait(DWELL_TIME); +#ifdef USE_DAILY + rainUpdateTotal = 0; +#endif + for (int i = currentHour + 48; i > currentHour + 24; i--) + { + rainUpdateTotal += rainBucket[i]; + DEBUG_PRINT(F("Adding rainBucket[")); + DEBUG_PRINT(i); + DEBUG_PRINTLN(F("] to rainUpdateTotal.")); + } + DEBUG_PRINT(F("TX Day 3: rainUpdateTotal = ")); + DEBUG_PRINTLN((float)rainUpdateTotal / 100.0); + gw.send(msgRainVAR3.set((float)rainUpdateTotal / 100.0, 1)); + gw.wait(DWELL_TIME); +#ifdef USE_DAILY + rainUpdateTotal = 0; +#endif + for (int i = currentHour + 72; i > currentHour + 48; i--) + { + rainUpdateTotal += rainBucket[i]; + DEBUG_PRINT(F("Adding rainBucket[")); + DEBUG_PRINT(i); + DEBUG_PRINTLN(F("] to rainUpdateTotal.")); + } + DEBUG_PRINT(F("TX Day 4: rainUpdateTotal = ")); + DEBUG_PRINTLN((float)rainUpdateTotal / 100.0); + gw.send(msgRainVAR4.set((float)rainUpdateTotal / 100.0, 1)); + gw.wait(DWELL_TIME); +#ifdef USE_DAILY + rainUpdateTotal = 0; +#endif + for (int i = currentHour + 96; i > currentHour + 72; i--) + { + rainUpdateTotal += rainBucket[i]; + DEBUG_PRINT(F("Adding rainBucket[")); + DEBUG_PRINT(i); + DEBUG_PRINTLN(F("] to rainUpdateTotal.")); + } + DEBUG_PRINT(F("TX Day 5: rainUpdateTotal = ")); + DEBUG_PRINTLN((float)rainUpdateTotal / 100.0); + gw.send(msgRainVAR5.set((float)rainUpdateTotal / 100.0, 1)); + gw.wait(DWELL_TIME); +} + +void getVariables(const MyMessage &message) +{ + if (message.sensor == CHILD_ID_RAIN_LOG) + { + // nothing to do here + } + else if (message.sensor == CHILD_ID_TRIPPED_INDICATOR) + { + if (message.type == V_VAR1) + { + rainWindow = atoi(message.data); + if (rainWindow > 120) + { + rainWindow = 120; + } + else if (rainWindow < 1) + { + rainWindow = 1; + } + if (rainWindow != atoi(message.data)) // if I changed the value back inside the boundries, push that number back to Vera + { + gw.send(msgTrippedVar1.set(rainWindow)); + } + } + else if (message.type == V_VAR2) + { + rainSensorThreshold = atoi(message.data); + if (rainSensorThreshold > 10000) + { + rainSensorThreshold = 10000; + } + else if (rainSensorThreshold < 1) + { + rainSensorThreshold = 1; + } + if (rainSensorThreshold != atoi(message.data)) // if I changed the value back inside the boundries, push that number back to Vera + { + gw.send(msgTrippedVar2.set(rainSensorThreshold)); + } + } + } +} + +void prettyFade(void) +{ + float val = (exp(sin(millis() / 2000.0 * PI)) - 0.36787944) * 108.0; + analogWrite(ledPin, val); +} + +void slowFlash(void) +{ + static boolean ledState = true; + static unsigned long pulseStart = millis(); + if (millis() - pulseStart < 100UL) + { + digitalWrite(ledPin, !ledState); + pulseStart = millis(); + } +} + +void receiveTime(unsigned long time) +{ + DEBUG_PRINTLN(F("Time received...")); + setTime(time); + char theTime[6]; + sprintf(theTime, "%d:%2d", hour(), minute()); + DEBUG_PRINTLN(theTime); +} diff --git a/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml b/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml new file mode 100644 index 0000000..f812265 --- /dev/null +++ b/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml @@ -0,0 +1,43 @@ + + + + 1 + 0 + + + + CurrentTRain + yes + r8 + total_rain + + + CurrentRain + yes + r8 + rain_rate + + + + + GetCurrentTRain + + + RainValue + out + CurrentTRain + + + + + GetCurrentRain + + + RainValue + out + CurrentRain + + + + + \ No newline at end of file From ac749155b52b67f883a9cfaf53db03e2b0a1467b Mon Sep 17 00:00:00 2001 From: petewill Date: Tue, 7 Jul 2015 13:20:24 -0600 Subject: [PATCH 2/2] Moved Vera Files Moved files to Vera repository --- .../examples/RainGauge/D_RainSensor1.json | 523 ------------------ .../examples/RainGauge/D_RainSensor1.xml | 24 - .../examples/RainGauge/S_Rainsensor1.xml | 43 -- 3 files changed, 590 deletions(-) delete mode 100644 libraries/MySensors/examples/RainGauge/D_RainSensor1.json delete mode 100644 libraries/MySensors/examples/RainGauge/D_RainSensor1.xml delete mode 100644 libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml diff --git a/libraries/MySensors/examples/RainGauge/D_RainSensor1.json b/libraries/MySensors/examples/RainGauge/D_RainSensor1.json deleted file mode 100644 index 325391b..0000000 --- a/libraries/MySensors/examples/RainGauge/D_RainSensor1.json +++ /dev/null @@ -1,523 +0,0 @@ -{ - "flashicon": "icons/Humidity_Sensor.swf", - "imgIconBody": "", - "imgIconDimmable": "", - "imgIconTurnable": "", - "imgIconMin": "", - "imgIconMax": "", - "halloIconsDir": "pics\/hallo", - "inScene": "0", - "DisplayStatus": {}, - "doc_url": { - "doc_language": 1, - "doc_manual": 1, - "doc_version": 1, - "doc_platform": 0, - "doc_page": "sensors" - }, - - "Tabs": [ - { - "Label": { - "lang_tag": "tabname_control", - "text": "Information" - }, - "Position": "0", - "TabType": "flash", - "SceneGroup": [ - { - "id": "1", - "top": "1.5", - "left": "0", - "x": "2", - "y": "2" - } - ], - "ControlGroup": [ - { - "id": "1", - "scenegroup": "1", - "type": "info" - }, - { - "id": "2", - "scenegroup": "1", - "type": "info" - } - ], - "Control": [ - { - "ControlGroup":"1", - "ControlPair": "1", - "ControlHeader": "1", - "top": "1", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "rain_rate", - "text": "Rate of Rain" - }, - "Display": { - "Top": 20, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"1", - "ControlPair": "1", - "ControlHeader": "1", - "top": "1", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:RainSensor1", - "Variable": "CurrentRain", - "Top": 20, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "total_rain_unit", - "text": "mm/hr" - }, - "Display": { - "Top": 20, - "Left": 200, - "Width": 25, - "Height": 20 - } - }, - { - "ControlGroup":"2", - "ControlPair": "2", - "ControlHeader": "1", - "top": "0", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "total_rain", - "text": "Rain Today:", - }, - "Display": { - "Top": 55, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"2", - "ControlPair": "2", - "ControlHeader": "1", - "top": "0", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:RainSensor1", - "Variable": "CurrentTRain", - "Top": 55, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "rain_rate_unit", - "text": "mm" - }, - "Display": { - "Top": 55, - "Left": 200, - "Width": 25, - "Height": 20 - } - }, - { - "ControlGroup":"3", - "ControlPair": "3", - "ControlHeader": "1", - "top": "0", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "rain_forty", - "text": "Yesterday:" - }, - "Display": { - "Top": 80, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"3", - "ControlPair": "3", - "ControlHeader": "1", - "top": "0", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:VContainer1", - "Variable": "Variable2", - "Top": 80, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "rain_unit", - "text": "mm" - }, - "Display": { - "Top": 80, - "Left": 200, - "Width": 25, - "Height": 20 - } - }, - { - "ControlGroup":"4", - "ControlPair": "4", - "ControlHeader": "1", - "top": "0", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "rain_seventy", - "text": "3 Days Ago:" - }, - "Display": { - "Top": 105, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"4", - "ControlPair": "4", - "ControlHeader": "1", - "top": "0", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:VContainer1", - "Variable": "Variable3", - "Top": 105, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "rain_unit1", - "text": "mm" - }, - "Display": { - "Top": 105, - "Left": 200, - "Width": 25, - "Height": 20 - } - }, - { - "ControlGroup":"5", - "ControlPair": "5", - "ControlHeader": "1", - "top": "0", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "rain_forty", - "text": "4 Days Ago:" - }, - "Display": { - "Top": 130, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"5", - "ControlPair": "5", - "ControlHeader": "1", - "top": "0", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:VContainer1", - "Variable": "Variable4", - "Top": 130, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "rain_unit2", - "text": "mm" - }, - "Display": { - "Top": 130, - "Left": 200, - "Width": 25, - "Height": 20 - } - }, - { - "ControlGroup":"6", - "ControlPair": "6", - "ControlHeader": "1", - "top": "0", - "left": "0", - "x": "1.25", - "ControlType": "label", - "Label": { - "lang_tag": "rain_hundred", - "text": "5 Days Ago:" - }, - "Display": { - "Top": 155, - "Left": 50, - "Width": 75, - "Height": 20 - } - }, - { - "ControlGroup":"6", - "ControlPair": "6", - "ControlHeader": "1", - "top": "0", - "left": "1.25", - "x": "0.75", - "ControlType": "variable", - "Display": { - "Service": "urn:upnp-org:serviceId:VContainer1", - "Variable": "Variable5", - "Top": 155, - "Left": 150, - "Width": 25, - "Height": 20 - } - }, - { - "ControlType": "label", - "Label": { - "lang_tag": "rain_unit3", - "text": "mm" - }, - "Display": { - "Top": 155, - "Left": 200, - "Width": 25, - "Height": 20 - } - } - ] - }, - { - "Label": { - "lang_tag": "advanced", - "text": "Advanced" - }, - "Position": "1", - "TabType": "javascript", - "ScriptName": "shared.js", - "Function": "advanced_device" - }, - { - "Label": { - "lang_tag": "logs", - "text": "Logs" - }, - "Position": "2", - "TabType": "javascript", - "ScriptName": "shared.js", - "Function": "device_logs" - }, - { - "Label": { - "lang_tag": "notifications", - "text": "Notifications" - }, - "Position": "3", - "TabType": "javascript", - "ScriptName": "shared.js", - "Function": "device_notifications" - } - ], - "eventList2": [ - { - "id": 1, - "label": { - "lang_tag": "total_rain_goes_above", - "text": "Total rain goes above" - }, - "serviceId": "urn:upnp-org:serviceId:RainSensor1", - "norepeat": "1", - "argumentList": [ - { - "id": 1, - "dataType": "r8", - "name": "CurrentTRain", - "comparisson": ">", - "prefix": { - "lang_tag": "total_rain", - "text": "Total rain" - }, - "suffix": { - "lang_tag": "total_rain_unit", - "text": "mm" - }, - "HumanFriendlyText": { - "lang_tag": "hft_total_rain_goes_above", - "text": "Total rain for _DEVICE_NAME_ goes above _ARGUMENT_VALUE_" - } - } - ] - }, - { - "id": 2, - "label": { - "lang_tag": "total_rain_goes_below", - "text": "Total rain goes below" - }, - "serviceId": "urn:upnp-org:serviceId:RainSensor1", - "norepeat": "1", - "argumentList": [ - { - "id": 1, - "dataType": "r8", - "name": "CurrentTRain", - "comparisson": "<", - "prefix": { - "lang_tag": "total_rain", - "text": "Total rain" - }, - "suffix": { - "lang_tag": "total_rain_unit", - "text": "mm" - }, - "HumanFriendlyText": { - "lang_tag": "hft_total_rain_goes_below", - "text": "Total rain for _DEVICE_NAME_ goes below _ARGUMENT_VALUE_" - } - } - ] - }, - { - "id": 3, - "label": { - "lang_tag": "rain_rate_goes_above", - "text": "Current rain goes above" - }, - "serviceId": "urn:upnp-org:serviceId:RainSensor1", - "norepeat": "1", - "argumentList": [ - { - "id": 1, - "dataType": "r8", - "name": "CurrentRain", - "comparisson": ">", - "prefix": { - "lang_tag": "rain_rate", - "text": "Current rain" - }, - "suffix": { - "lang_tag": "rain_rate_unit", - "text": "mm/hr" - }, - "HumanFriendlyText": { - "lang_tag": "hft_rain_rate_goes_above", - "text": "Current rain for _DEVICE_NAME_ goes above _ARGUMENT_VALUE_" - } - } - ] - }, - { - "id": 4, - "label": { - "lang_tag": "rain_rate_goes_below", - "text": "Current rain goes below" - }, - "serviceId": "urn:upnp-org:serviceId:RainSensor1", - "norepeat": "1", - "argumentList": [ - { - "id": 1, - "dataType": "r8", - "name": "CurrentRain", - "comparisson": "<", - "prefix": { - "lang_tag": "rain_rate", - "text": "Current rain" - }, - "suffix": { - "lang_tag": "rain_rate_unit", - "text": "mm/hr" - }, - "HumanFriendlyText": { - "lang_tag": "hft_rain_rate_goes_below", - "text": "Current rain for _DEVICE_NAME_ goes below _ARGUMENT_VALUE_" - } - } - ] - }, - { - "id": 5, - "label": { - "lang_tag": "battery_level_goes_below", - "text": "Battery level goes below" - }, - "serviceId": "urn:micasaverde-com:serviceId:HaDevice1", - "argumentList": [ - { - "id": 1, - "prefix": { - "lang_tag": "Level", - "text": "Level" - }, - "dataType": "i4", - "name": "BatteryLevel", - "comparisson": "<", - "suffix": { - "lang_tag": "percent_sign", - "text": "%" - }, - "HumanFriendlyText": { - "lang_tag": "hft_battery_level_goes_below", - "text": "Battery level for _DEVICE_NAME_ go below _ARGUMENT_VALUE_%" - } - } - ] - } - ], - "DeviceType": "urn:schemas-micasaverde-com:device:RainSensor:1" -} \ No newline at end of file diff --git a/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml b/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml deleted file mode 100644 index c0a7492..0000000 --- a/libraries/MySensors/examples/RainGauge/D_RainSensor1.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - 1 - 0 - - - urn:schemas-micasaverde-com:device:RainSensor:1 - 12 - D_RainSensor1.json - - - urn:schemas-upnp-org:service:RainSensor:1 - urn:upnp-org:serviceId:RainSensor1 - S_RainSensor1.xml - - - urn:schemas-micasaverde-com:service:HaDevice:1 - urn:micasaverde-com:serviceId:HaDevice1 - S_HaDevice1.xml - - - - \ No newline at end of file diff --git a/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml b/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml deleted file mode 100644 index f812265..0000000 --- a/libraries/MySensors/examples/RainGauge/S_Rainsensor1.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - 1 - 0 - - - - CurrentTRain - yes - r8 - total_rain - - - CurrentRain - yes - r8 - rain_rate - - - - - GetCurrentTRain - - - RainValue - out - CurrentTRain - - - - - GetCurrentRain - - - RainValue - out - CurrentRain - - - - - \ No newline at end of file