#include #include #include #include #include const int deviceId = 0; const char *ssid = "PET Aflytningsvogn #42"; const char *password = "FuckGFwifi123"; const char *mqtt_server = "192.168.137.86"; unsigned long previousBuzzerMillis = 0; unsigned long previousEncoderButtonMillis = 0; unsigned long previousButtonMillis = 0; bool buzzerStatus = false; bool lastEncoderButtonState = false; bool lastButtonState = false; int pressAmt = 0; //a counter that controls what digit is being written to pin code int counter = 1; //controls what number is being written to the pin code int lastEncoderState; int encoderState; bool input = false; //controls whether there is being inputted a pin code or not int code[12]; unsigned long sleep = 0; //controls the amount of time (in miliseconds) an action is delayed int wakeUpAct = 0; //controls what to do after set delay int alarmStatus = 0; bool runCheck = false; //controls whether the inputted pin code in being authenticated or not bool passwordReply = false; WiFiClient espClient; PubSubClient client(espClient); int buzzerPin = D0; int encoderButtonPin = D5; int lcdColumns = 16; int lcdRows = 2; int encoderPinA = D6; int encoderPinB = D7; int buttonPin = D3; LiquidCrystal_I2C lcd(0x3f, lcdColumns, lcdRows); void setup_wifi() { lcd.clear(); lcd.setCursor(3, 0); lcd.print("Connecting"); delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); lcd.clear(); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); lcd.clear(); lcd.print("Attempting MQTT"); lcd.setCursor(0,1); lcd.print("connection..."); // Attempt to connect if (client.connect("ESP8266Client5")) { lcd.clear(); Serial.println("connected"); client.subscribe("alarm/state"); client.subscribe("display/passwordResponse"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void showStatus() { if (input == false && runCheck == false) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Status: "); lcd.setCursor(0, 1); switch (alarmStatus) { case 0: lcd.clear(); lcd.setCursor(0, 0); break; case 1: lcd.print("Arming"); break; case 2: lcd.print("Armed"); break; case 3: lcd.print("Disarmed"); break; case 4: lcd.print("Disarming"); break; case 5: lcd.print("Triggered"); break; default: break; } } } void callback(char *topic, byte *payload, unsigned int length) { StaticJsonDocument<512> doc; deserializeJson(doc, payload, length); if (strcmp(topic, "display/passwordResponse") == 0 && doc["deviceId"] == deviceId) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (unsigned int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); if (doc["correct"] == true) { passwordReply = true; lcd.clear(); lcd.setCursor(0,0); lcd.print("Correct pin"); wakeUpAct = 1; sleep = millis() + 5000; } else if (doc["correct"] == false) { passwordReply = true; lcd.clear(); lcd.setCursor(0,0); lcd.print("Incorrect pin"); wakeUpAct = 1; sleep = millis() + 5000; } } if (alarmStatus == 0 && strcmp(topic, "alarm/state") == 0) { if (strcmp(doc["status"], "Arming") == 0) { alarmStatus = 1; showStatus(); } else if (strcmp(doc["status"], "Armed") == 0) { alarmStatus = 2; showStatus(); } else if (strcmp(doc["status"], "Disarmed") == 0) { alarmStatus = 3; showStatus(); } else if (strcmp(doc["status"], "Disarming") == 0) { alarmStatus = 4; showStatus(); } else if (strcmp(doc["status"], "Triggered") == 0) { alarmStatus = 5; showStatus(); } if (strcmp(doc["status"], "Triggered") != 0) { digitalWrite(buzzerPin, LOW); } } else if (strcmp(topic, "alarm/state") == 0 && doc["changed"] == true) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (unsigned int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); if (strcmp(doc["status"], "Arming") == 0) { alarmStatus = 1; showStatus(); } else if (strcmp(doc["status"], "Armed") == 0) { alarmStatus = 2; showStatus(); } else if (strcmp(doc["status"], "Disarmed") == 0) { alarmStatus = 3; showStatus(); } else if (strcmp(doc["status"], "Disarming") == 0) { alarmStatus = 4; showStatus(); } else if (strcmp(doc["status"], "Triggered") == 0) { alarmStatus = 5; showStatus(); } if (strcmp(doc["status"], "Triggered") != 0) { digitalWrite(buzzerPin, LOW); } } } void setup() { Serial.begin(115200); lcd.init(); lcd.backlight(); pinMode(buzzerPin, OUTPUT); pinMode(buttonPin, INPUT); pinMode(encoderButtonPin, INPUT_PULLUP); pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); lastEncoderState = digitalRead(encoderPinA); setup_wifi(); client.setCallback(callback); client.setServer(mqtt_server, 1883); reconnect(); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); unsigned long currentMillis = millis(); if (currentMillis - previousBuzzerMillis >= 500 && alarmStatus == 5) { digitalWrite(buzzerPin, !buzzerStatus); buzzerStatus = !buzzerStatus; previousBuzzerMillis = currentMillis; } bool encoderButtonState = !digitalRead(encoderButtonPin); bool buttonState = !digitalRead(buttonPin); if (buttonState != lastButtonState && currentMillis - previousButtonMillis > 200 && buttonState == 1) { previousButtonMillis = currentMillis; if (input == true && runCheck == true) { if (wakeUpAct == 1) { wakeUpAct = 1; sleep = 1; } } else if (input == true) { runCheck = true; int passLength = 0; if (code[0] != 0) { for (size_t i = 0; i < 12; i++) { if (code[i] != 0) { passLength++; } } } Serial.println("Done"); if (passLength > 3) { int password[passLength]; for (int i = 0; i < passLength; i++) { password[i] = code[i]; } Serial.print("{"); for (int i = 0; i < passLength; i++) { if (i == 0) { Serial.print(password[i]); } else { Serial.print(", "); Serial.print(password[i]); } code[i] = 0; } Serial.println("}"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Authenticating"); lcd.setCursor(0,1); lcd.print("pin"); DynamicJsonDocument doc(512); doc["deviceId"] = deviceId; for (int i = 0; i < passLength; i++) { doc["password"][i] = password[i]; } char buffer[512]; size_t n = serializeJson(doc, buffer); client.publish("display/passwordEntered", buffer, n); wakeUpAct = 2; sleep = currentMillis + 3000; } else { Serial.println("Invalid password entered"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Invalid pin"); wakeUpAct = 1; sleep = currentMillis + 5000; } } } lastButtonState = buttonState; encoderState = digitalRead(encoderPinA); if (encoderState != lastEncoderState && encoderState == 1) { if (input == true && runCheck == true) { if (wakeUpAct == 1) { wakeUpAct = 1; sleep = 1; } } if (digitalRead(encoderPinB) != encoderState) { counter --; if(counter < 1) { counter = 9; } } else { counter ++; if(counter > 9) { counter = 1; } } if (input == true && runCheck == false) { lcd.setCursor(0, 1); lcd.print(counter); Serial.println(counter); } } lastEncoderState = encoderState; if (encoderButtonState != lastEncoderButtonState && currentMillis - previousEncoderButtonMillis > 200) { previousEncoderButtonMillis = currentMillis; if (encoderButtonState) { Serial.print("Button pressed "); Serial.println(pressAmt); if (input == false) { counter = 1; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Key:"); lcd.setCursor(0, 1); lcd.print(counter); input = true; } else { if (pressAmt > 11) { Serial.println("Max code length"); return; } else { lcd.setCursor(pressAmt + 4,0); lcd.print("*"); code[pressAmt] = counter; pressAmt++; if (runCheck == true) { if (wakeUpAct ==1) { wakeUpAct = 1; sleep = 1; } } } } } lastEncoderButtonState = encoderButtonState; } if (currentMillis > sleep && sleep != 0) { Serial.println("I've slept"); switch (wakeUpAct) { case 1: input = false; runCheck = false; pressAmt = 0; wakeUpAct = 0; showStatus(); for (int i = 0; i < 12; i++) { code[i] = 0; } break; case 2: if (passwordReply == false) { Serial.println("MQTT timeout on password reply"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Timeout on reply"); wakeUpAct = 1; sleep = currentMillis + 5000; return; } else { wakeUpAct = 1; sleep = 1; return; } break; default: break; } sleep = 0; } }