Last active
October 22, 2023 04:21
-
-
Save kakopappa/6657119c2750c4cc662b674dba04a651 to your computer and use it in GitHub Desktop.
Detecting floods using water sensor : https://help.sinric.pro/pages/tutorials/custom-device-types/water-sensor/flood-leak-rain-sensor.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _FLOODSENSOR_H_ | |
#define _FLOODSENSOR_H_ | |
#include <SinricProDevice.h> | |
#include <Capabilities/ModeController.h> | |
#include <Capabilities/RangeController.h> | |
#include <Capabilities/PushNotification.h> | |
class FloodSensor | |
: public SinricProDevice | |
, public ModeController<FloodSensor> | |
, public RangeController<FloodSensor> | |
, public PushNotification<FloodSensor> { | |
friend class ModeController<FloodSensor>; | |
friend class RangeController<FloodSensor>; | |
friend class PushNotification<FloodSensor>; | |
public: | |
FloodSensor(const String &deviceId) : SinricProDevice(deviceId, "FloodSensor") {}; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Uncomment the following line to enable serial debug output | |
//#define ENABLE_DEBUG | |
#ifdef ENABLE_DEBUG | |
#define DEBUG_ESP_PORT Serial | |
#define NODEBUG_WEBSOCKETS | |
#define NDEBUG | |
#endif | |
#include <Arduino.h> | |
#ifdef ESP8266 | |
#include <ESP8266WiFi.h> | |
#endif | |
#ifdef ESP32 | |
#include <WiFi.h> | |
#endif | |
#include <SinricPro.h> | |
#include "FloodSensor.h" | |
#include <math.h> | |
// Grab it from https://portal.sinric.pro. | |
#define APP_KEY "" //Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx" | |
#define APP_SECRET "" //Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx" | |
#define DEVICE_ID "" //Should look like "6534xxxxxxxc08c6ea1b" | |
#define SSID "" // Your WiFi SSID | |
#define PASS "" // Your WiFi Password | |
#define BAUD_RATE 115200 | |
#define EVENT_WAIT_TIME 60000 // send event every 60 seconds | |
#if defined(ESP8266) | |
const int sPin = A0; | |
const int vccPin = D2; | |
#elif defined(ESP32) | |
const int sPin = 34; | |
const int vccPin = 17; | |
#elif defined(ARDUINO_ARCH_RP2040) | |
const int sPin = 26; | |
const int vccPin = 6; | |
#endif | |
FloodSensor &floodSensor = SinricPro[DEVICE_ID]; | |
const int FLOOD_THRESHOLD = 100; | |
const int SENSOR_MAX = 560; | |
const int SENSOR_MIN = 1; | |
int waterSensorValue = 0; | |
int lastWaterSensorValue = 0; | |
String lastIsFloodingStr = ""; | |
// ModeController | |
void updateMode(String mode) { | |
floodSensor.sendModeEvent("modeInstance1", mode, "PHYSICAL_INTERACTION"); | |
} | |
// RangeController | |
void updateRangeValue(float value) { | |
floodSensor.sendRangeValueEvent("rangeInstance1", value); | |
} | |
// PushNotificationController | |
void sendPushNotification(String notification) { | |
floodSensor.sendPushNotification(notification); | |
} | |
float floatMap(float x, float a, float b, float c, float d) { | |
float f=x/(b-a)*(d-c)+c; | |
return f; | |
} | |
float floatRound(float in_value, int decimal_place) { | |
float multiplier = powf( 10.0f, decimal_place ); | |
in_value = roundf( in_value * multiplier ) / multiplier; | |
return in_value; | |
} | |
void handleWaterSensor() { | |
if (SinricPro.isConnected() == false) { | |
return; | |
} | |
static unsigned long last_millis; | |
unsigned long current_millis = millis(); | |
if (last_millis && current_millis - last_millis < EVENT_WAIT_TIME) return; | |
last_millis = current_millis; | |
digitalWrite(vccPin, HIGH); // turn on the power for sensor. | |
delay(100); // wait 100ms | |
waterSensorValue = analogRead(sPin); // make a reading from sensor | |
digitalWrite(vccPin, LOW); // turn off the sensor | |
Serial.printf("Water sensor value: %d\r\n", waterSensorValue); | |
if (waterSensorValue == lastWaterSensorValue) { | |
Serial.printf("Water sensor did not changed. do nothing...!\r\n"); | |
return; | |
} | |
/* determine whether flooding */ | |
String isFloodingStr = ""; | |
if(waterSensorValue > FLOOD_THRESHOLD) { | |
isFloodingStr = "Yes"; // NOTE: must be Yes, No. This is from modes list in template. | |
} else { | |
isFloodingStr = "No"; | |
} | |
/* Update Flooding label if changed */ | |
if(lastIsFloodingStr != isFloodingStr) { | |
lastIsFloodingStr = isFloodingStr; | |
updateMode(isFloodingStr); | |
} | |
delay(500); | |
/* update Water Level label */ | |
float sensorValueToInches = floatMap(waterSensorValue, SENSOR_MIN, SENSOR_MAX, 0, 1.9); /* map the sensor value to inches */ | |
float roundedSensorValueToInches = floatRound(sensorValueToInches, 2); /* round the sensor value to 1 decimal point */ | |
Serial.printf("Water level height in inches: %f\r\n", roundedSensorValueToInches); | |
updateRangeValue(roundedSensorValueToInches); | |
/* send a push notification when flooding is detected! */ | |
if(waterSensorValue > FLOOD_THRESHOLD) { | |
sendPushNotification("Flooding detected in the basement!"); | |
} | |
lastWaterSensorValue = waterSensorValue; // save to compare next time. | |
} | |
/********* | |
* Setup * | |
*********/ | |
void setupWaterSensor() { | |
pinMode(sPin, INPUT); | |
pinMode(vccPin, OUTPUT); | |
digitalWrite(vccPin, LOW); // turn off the sensor at the begining. | |
} | |
void setupSinricPro() { | |
SinricPro.onConnected([]{ Serial.printf("[SinricPro]: Connected\r\n"); }); | |
SinricPro.onDisconnected([]{ Serial.printf("[SinricPro]: Disconnected\r\n"); }); | |
SinricPro.begin(APP_KEY, APP_SECRET); | |
}; | |
void setupWiFi() { | |
#if defined(ESP8266) | |
WiFi.setSleepMode(WIFI_NONE_SLEEP); | |
WiFi.setAutoReconnect(true); | |
#elif defined(ESP32) | |
WiFi.setSleep(false); | |
WiFi.setAutoReconnect(true); | |
#endif | |
WiFi.begin(SSID, PASS); | |
Serial.printf("[WiFi]: Connecting to %s", SSID); | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.printf("."); | |
delay(250); | |
} | |
Serial.printf("connected\r\n"); | |
} | |
void setup() { | |
Serial.begin(BAUD_RATE); | |
setupWaterSensor(); | |
setupWiFi(); | |
setupSinricPro(); | |
} | |
/******** | |
* Loop * | |
********/ | |
void loop() { | |
handleWaterSensor(); | |
SinricPro.handle(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment