Skip to content

Instantly share code, notes, and snippets.

@kakopappa
Last active October 22, 2023 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kakopappa/6657119c2750c4cc662b674dba04a651 to your computer and use it in GitHub Desktop.
Save kakopappa/6657119c2750c4cc662b674dba04a651 to your computer and use it in GitHub Desktop.
#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
// 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