205 lines
4.9 KiB
C++
205 lines
4.9 KiB
C++
#ifdef CORE_DEBUG_LEVEL
|
|
#undef CORE_DEBUG_LEVEL
|
|
#endif
|
|
|
|
#define CORE_DEBUG_LEVEL 3
|
|
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
|
#define DOOR_SENSOR_PIN 19
|
|
#define PIR_SENSOR_PIN 13
|
|
|
|
#include <WiFi.h>
|
|
#include <ArduinoJson.h>
|
|
#include <HTTPClient.h>
|
|
#include <base64.h>
|
|
#include <ESPmDNS.h>
|
|
#include <PubSubClient.h>
|
|
|
|
IPAddress serverIp;
|
|
const char* ssid = "Unknown Network";
|
|
const char* password = "HDUUpdcbEc3w";
|
|
const char* hostname = "Front-Door";
|
|
|
|
// MQTT Broker
|
|
const char *mqtt_broker = "192.168.0.42";
|
|
const char *doorTopic = "esp32/door";
|
|
const char *movementTopic = "esp32/movement";
|
|
const int mqtt_port = 1883;
|
|
|
|
WiFiClient espClient;
|
|
PubSubClient mqttClient(espClient);
|
|
long lastMsg = 0;
|
|
char msg[50];
|
|
int doorState = LOW;
|
|
int pirState = LOW;
|
|
int doorPrevState = LOW;
|
|
int pirPrevState = LOW;
|
|
|
|
bool pubDoorState = false;
|
|
bool pubPirState = false;
|
|
|
|
//variables to keep track of the timing of recent interrupts
|
|
unsigned long button_time = 0;
|
|
unsigned long last_button_time = 0;
|
|
unsigned long motion_time = 0;
|
|
unsigned long last_motion_time = 0;
|
|
|
|
void IRAM_ATTR pir_ISR() {
|
|
motion_time = millis();
|
|
if (motion_time - last_motion_time > 750)
|
|
{
|
|
pirState = digitalRead(PIR_SENSOR_PIN);
|
|
if (pirState != pirPrevState) {
|
|
pubPirState = true;
|
|
pirPrevState = pirState;
|
|
}
|
|
delay(250);
|
|
}
|
|
|
|
last_motion_time = motion_time;
|
|
}
|
|
|
|
void IRAM_ATTR door_ISR() {
|
|
button_time = millis();
|
|
if (button_time - last_button_time > 500)
|
|
{
|
|
doorState = digitalRead(DOOR_SENSOR_PIN);
|
|
if (doorState != doorPrevState) {
|
|
Serial.print("Door state: ");
|
|
Serial.println(doorState);
|
|
pubDoorState = true;
|
|
doorPrevState = doorState;
|
|
}
|
|
delay(250);
|
|
}
|
|
|
|
last_button_time = button_time;
|
|
}
|
|
|
|
void IRAM_ATTR window_ISR() {
|
|
mqttClient.publish("esp32/temperature", "The window is closed.");
|
|
}
|
|
|
|
/* Returns a semi-unique id for the device. The id is based
|
|
on part of a MAC address or chip ID so it won't be
|
|
globally unique. */
|
|
uint16_t GetDeviceId()
|
|
{
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
return ESP.getEfuseMac();
|
|
#else
|
|
return ESP.getChipId();
|
|
#endif
|
|
}
|
|
|
|
/* Append a semi-unique id to the name template */
|
|
String MakeMine(const char *NameTemplate)
|
|
{
|
|
uint16_t uChipId = GetDeviceId();
|
|
String Result = String(NameTemplate) + String(uChipId, HEX);
|
|
return Result;
|
|
}
|
|
|
|
void AdvertiseServices(const char *MyName)
|
|
{
|
|
if (MDNS.begin(MyName))
|
|
{
|
|
Serial.println(F("mDNS responder started"));
|
|
Serial.print(F("I am: "));
|
|
Serial.println(MyName);
|
|
|
|
// Add service to MDNS-SD
|
|
//MDNS.addService("sensor", "tcp", 8080);
|
|
}
|
|
else
|
|
{
|
|
while (1)
|
|
{
|
|
Serial.println(F("Error setting up MDNS responder"));
|
|
delay(1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FindServer()
|
|
{
|
|
while (serverIp.toString() == "0.0.0.0") {
|
|
Serial.println("Resolving host...");
|
|
delay(250);
|
|
serverIp = MDNS.queryHost("Home-Server");
|
|
}
|
|
|
|
Serial.println("Server IP: " + serverIp.toString());
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
pinMode(PIR_SENSOR_PIN, INPUT_PULLUP); // declare sensor as input
|
|
attachInterrupt(digitalPinToInterrupt(PIR_SENSOR_PIN), pir_ISR, HIGH);
|
|
|
|
pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); // declare sensor as input
|
|
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR_PIN), door_ISR, CHANGE);
|
|
|
|
|
|
WiFi.setHostname(hostname);
|
|
WiFi.begin(ssid, password);
|
|
Serial.println("Connecting");
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
}
|
|
Serial.println("");
|
|
Serial.print("Connected to WiFi network with IP Address: ");
|
|
Serial.println(WiFi.localIP());
|
|
|
|
mqttClient.setServer(mqtt_broker, 1883);
|
|
|
|
String MyName = MakeMine("Door monitor");
|
|
AdvertiseServices(MyName.c_str());
|
|
|
|
//FindServer();
|
|
}
|
|
|
|
void reconnect() {
|
|
// Loop until we're reconnected
|
|
while (!mqttClient.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
// Attempt to connect
|
|
String MyName = MakeMine("Door monitor");
|
|
if (mqttClient.connect(MyName.c_str())) {
|
|
Serial.println("connected");
|
|
mqttClient.publish("esp32/movement", "Door sensor online.");
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(mqttClient.state());
|
|
Serial.println(" try again in 5 seconds");
|
|
// Wait 5 seconds before retrying
|
|
delay(5000);
|
|
}
|
|
}
|
|
}
|
|
void loop() {
|
|
if (!mqttClient.connected()) {
|
|
reconnect();
|
|
}
|
|
|
|
mqttClient.loop();
|
|
if (pubDoorState) {
|
|
if (doorState == LOW) {
|
|
mqttClient.publish("esp32/door", "The door is open.");
|
|
} else {
|
|
mqttClient.publish("esp32/door", "The door is closed.");
|
|
}
|
|
|
|
pubDoorState = false;
|
|
delay(100);
|
|
}
|
|
|
|
if (pubPirState) {
|
|
mqttClient.publish("esp32/motion", "Motion detected at door.");
|
|
pubDoorState = false;
|
|
delay(100);
|
|
}
|
|
// put your main code here, to run repeatedly:
|
|
|
|
} |