#include #include #include #include const int PIR_PIN=23; const char* ssid = "JoNelsDarlings"; const char* password = "Paris2016"; const char* mqttServerName = "mqtt.ddns.kawomi.com"; WiFiClient espClient; PubSubClient mqttClient(espClient); unsigned long lastMsg = 0; #define MSG_BUFFER_SIZE (50) char msg[MSG_BUFFER_SIZE]; void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } randomSeed(micros()); Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void send_mqtt(String status, long minutes=0) { Serial.print("MQTT Send status "); Serial.print(status); Serial.print(" mins "); Serial.println(minutes); JsonDocument doc; JsonObject object = doc.to(); object["status"] = status.c_str(); if (minutes > 0) { object["minutes"] = minutes; } static char sensorStatus[150]; serializeJson(doc, sensorStatus); Serial.println(sensorStatus); mqttClient.publish("Address/Livorno/Kitchen/PIR", sensorStatus, true); } void reconnect() { int numRetries=0; while (!mqttClient.connected()) { numRetries++; Serial.print("Attempting MQTT connection..."); // Create a random client ID String clientId = "ESP32Client-"; clientId += String(random(0xffff), HEX); if (mqttClient.connect(clientId.c_str())) { Serial.println("MQTT connected"); } else { Serial.print("MQTT failed, rc="); Serial.print(mqttClient.state()); Serial.println(" try again in 5 seconds"); if (numRetries>5){ Serial.println("Too many retries, restarting the ESP..."); ESP.restart(); } delay(5000); } } send_mqtt("ready"); } void setup() { pinMode(LED_BUILTIN,OUTPUT); pinMode(PIR_PIN,INPUT_PULLUP); Serial.begin(115200); setup_wifi(); const int mqttPort=1883; mqttClient.setServer(mqttServerName, mqttPort); } const int millisPerSecond=1000; long previousMotionMillis=millis(); short previousState=-1; long previousNoMoNotifyMinutes=0; void loop() { if (!mqttClient.connected()) { reconnect(); } mqttClient.loop(); short currentState = digitalRead(PIR_PIN); // This out pin triggering is dependent not only on movement, but also on light levels which can be configured in the app. // I set it to 255 and "below" - this triggered it for me..... //send_mqtt("occupancy_state_debug", currentState); if (currentState != previousState) { Serial.print("Status changed; currentState: "); Serial.print(currentState); Serial.print(" previousState: "); Serial.println(previousState); if (currentState == HIGH) { send_mqtt("motion"); digitalWrite(LED_BUILTIN,HIGH); previousMotionMillis=millis(); } else { send_mqtt("no_motion_ignore"); digitalWrite(LED_BUILTIN,LOW); } previousState = currentState; } const int secondsPerMinute=60; long minutesSinceLastMotion=(millis()-previousMotionMillis)/(millisPerSecond*secondsPerMinute); if ((previousNoMoNotifyMinutes != minutesSinceLastMotion) && (0 != minutesSinceLastMotion)) { send_mqtt("no_motion", minutesSinceLastMotion); previousNoMoNotifyMinutes = minutesSinceLastMotion; } delay(100); }