|
|
|
@ -1,13 +1,30 @@ |
|
|
|
|
#define ADC_PIN A0 |
|
|
|
|
#define RELAY_PIN 13 |
|
|
|
|
#define RELAY_OFF LOW |
|
|
|
|
#define RELAY_ON HIGH |
|
|
|
|
#include <ArduinoMqttClient.h> |
|
|
|
|
#include <ESP8266WiFi.h> |
|
|
|
|
|
|
|
|
|
#define NUM_SAMPLES 20 |
|
|
|
|
#define SAMPLE_TIME 100 |
|
|
|
|
#define WATER_THRESHOLD 750 |
|
|
|
|
#include "secrets.h" |
|
|
|
|
|
|
|
|
|
#define ADC_PIN A0 |
|
|
|
|
#define RELAY_PIN 13 |
|
|
|
|
#define RELAY_OFF LOW |
|
|
|
|
#define RELAY_ON HIGH |
|
|
|
|
|
|
|
|
|
#define NUM_SAMPLES 20 |
|
|
|
|
#define SAMPLE_TIME 100 |
|
|
|
|
#define WATER_THRESHOLD 750 |
|
|
|
|
|
|
|
|
|
#define MESSAGE_INTERVAL 1000 * 60 * 60 // one hour
|
|
|
|
|
|
|
|
|
|
WiFiClient wifiClient; |
|
|
|
|
MqttClient mqttClient(wifiClient); |
|
|
|
|
|
|
|
|
|
const char broker[] = BROKER; |
|
|
|
|
int port = 1883; |
|
|
|
|
const char topic[] = "iot/water"; |
|
|
|
|
|
|
|
|
|
String macAddress = String(ESP.getChipId(), HEX); |
|
|
|
|
String shortName = macAddress.substring(0, 4); |
|
|
|
|
String deviceName = "ws_" + shortName; |
|
|
|
|
|
|
|
|
|
bool leakDetected = false; |
|
|
|
|
|
|
|
|
|
void relayOn() { |
|
|
|
|
Serial.println("Setting relay ON"); |
|
|
|
@ -41,24 +58,99 @@ bool sampleWater() { |
|
|
|
|
return waterDetected; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sendWaterLeakTrue() { |
|
|
|
|
mqttClient.beginMessage(topic); |
|
|
|
|
mqttClient.print("{\"id\": \""); |
|
|
|
|
mqttClient.print(deviceName); |
|
|
|
|
mqttClient.print("\", \"water_leak\": true}"); |
|
|
|
|
mqttClient.endMessage(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sendWaterLeakFalse() { |
|
|
|
|
mqttClient.beginMessage(topic); |
|
|
|
|
mqttClient.print("{\"id\": \""); |
|
|
|
|
mqttClient.print(deviceName); |
|
|
|
|
mqttClient.print("\", \"water_leak\": false}"); |
|
|
|
|
mqttClient.endMessage(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void setup() { |
|
|
|
|
pinMode(RELAY_PIN, OUTPUT); |
|
|
|
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
//Serial.setDebugOutput(true);
|
|
|
|
|
delay(1000); |
|
|
|
|
|
|
|
|
|
Serial.println(); |
|
|
|
|
Serial.println(); |
|
|
|
|
Serial.println(); |
|
|
|
|
Serial.println("===== BOOT UP ====="); |
|
|
|
|
|
|
|
|
|
pinMode(RELAY_PIN, OUTPUT); |
|
|
|
|
WiFi.mode(WIFI_STA); |
|
|
|
|
WiFi.begin(SECRET_SSID, SECRET_PASS); |
|
|
|
|
Serial.print("[WIFI] Attempting to connect to wifi"); |
|
|
|
|
while (WiFi.status() != WL_CONNECTED) { |
|
|
|
|
delay(500); |
|
|
|
|
Serial.print("."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Serial.println(""); |
|
|
|
|
Serial.println("[WIFI] Connected to the network"); |
|
|
|
|
Serial.println(); |
|
|
|
|
|
|
|
|
|
mqttClient.setId(deviceName); |
|
|
|
|
|
|
|
|
|
Serial.print("[MQTT] Attempting to connect to the MQTT broker: "); |
|
|
|
|
Serial.println(broker); |
|
|
|
|
|
|
|
|
|
while (!mqttClient.connect(broker, port)) { |
|
|
|
|
Serial.print("MQTT connection failed! Error code = "); |
|
|
|
|
Serial.println(mqttClient.connectError()); |
|
|
|
|
delay(5000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Serial.println("[MQTT] Connected to the MQTT broker."); |
|
|
|
|
|
|
|
|
|
Serial.println("Turning relay on."); |
|
|
|
|
relayOn(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void loop() { |
|
|
|
|
if (sampleWater()) { |
|
|
|
|
Serial.println("Water detected"); |
|
|
|
|
static unsigned long last_pos_message = 0; |
|
|
|
|
static unsigned long last_neg_message = 0; |
|
|
|
|
|
|
|
|
|
bool leakDetected = sampleWater(); |
|
|
|
|
|
|
|
|
|
if (leakDetected) { |
|
|
|
|
relayOff(); |
|
|
|
|
Serial.println("Leak detected"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mqttClient.poll(); |
|
|
|
|
|
|
|
|
|
if (WiFi.status() != WL_CONNECTED) { |
|
|
|
|
Serial.println("[WIFI] Lost connection. Reconnecting..."); |
|
|
|
|
WiFi.begin(SECRET_SSID, SECRET_PASS); |
|
|
|
|
return; |
|
|
|
|
} else if (!mqttClient.connected()) { |
|
|
|
|
Serial.print("[MQTT] Not connected! Error code = "); |
|
|
|
|
Serial.println(mqttClient.connectError()); |
|
|
|
|
Serial.println("[MQTT] Reconnecting..."); |
|
|
|
|
mqttClient.connect(broker, port); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: replace this spaghetti with a state machine
|
|
|
|
|
if (leakDetected) { |
|
|
|
|
if (!last_pos_message || millis() - last_pos_message > MESSAGE_INTERVAL) { |
|
|
|
|
last_pos_message = millis(); |
|
|
|
|
last_neg_message = 0; |
|
|
|
|
sendWaterLeakTrue(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
Serial.println("No water"); |
|
|
|
|
if (!last_neg_message || millis() - last_neg_message > MESSAGE_INTERVAL) { |
|
|
|
|
last_pos_message = 0; |
|
|
|
|
last_neg_message = millis(); |
|
|
|
|
sendWaterLeakFalse(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|