/* * file: statusclient.ino * desc: This file is part of the Krautspace Doorstatus project. It's the * main file for a client, who deals with the input from a reed sensor and * push these values to a server. The code is make to run on a NodeMCU with * ESP8266 chip. */ #include #include #include #include "config.h" #include "certs.h" #include "credentials.h" const int LED_PIN = 16; // D0 const int REED_PIN = 5; // D1 typedef enum { DOOR_CLOSED = 0, DOOR_OPEN = 1 } door_state; door_state current_door_state = DOOR_CLOSED; door_state new_door_state = DOOR_CLOSED; void init_serial() { /* * set baudrate and debug modus */ Serial.begin(BAUD_RATE); Serial.setDebugOutput(DEBUG); Serial.println(); Serial.println("[Srl] Serial interface initialized"); } void init_pins() { /* * set gpio for reed sensor and led */ pinMode(REED_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); Serial.println("[Pin] LED and REED initialized"); } void init_wifi() { /* * first turn wifi off and than in access point mode * maybe turn of is not needed! */ ESP8266WiFiMulti wifi; WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_STA); wifi.addAP(SSID_1, PSK_1); wifi.addAP(SSID_2, PSK_2); Serial.println("[Wifi] Wifi initialized"); wifi.run(); if (WiFi.status() == WL_CONNECTED) { Serial.print("[Wif] Connected to "); Serial.println(WiFi.SSID()); Serial.print("[Wifi] IP: "); Serial.println(WiFi.localIP()); } else { Serial.println("[Wifi] Error: Failed to connect"); } } door_state read_door_state() { /* * die initialisierung des reed-pin mit pullup bewirkt, daß am pin * 3,3 volt anliegen. die verbindung des pins mit GND sorgt dafür, * daß die spannung "abfließen" kann. dadurch hat der pin dann den * status 'low'. * geschlossene tür -> reed geschlossen -> low * geöffnete tür -> reed offen -> high */ if (digitalRead(REED_PIN) == HIGH) { return DOOR_OPEN; } return DOOR_CLOSED; } void toggle_led(door_state state) { /* * turns onboard led on or depends on the door state */ if (state == DOOR_OPEN) { digitalWrite(LED_PIN, LOW); } else { digitalWrite(LED_PIN, HIGH); } delay(500); } void set_clock() { configTime(TZ_STRING, NTP_URL); Serial.print("Waiting for NTP time sync: "); time_t now = time(nullptr); while (now < 8 * 3600 * 2) { delay(500); Serial.print("."); now = time(nullptr); } Serial.println(""); struct tm timeinfo; gmtime_r(&now, &timeinfo); Serial.print("Current time: "); Serial.print(asctime(&timeinfo)); } int send_status(door_state state) { /* * geht die initialisierung mit einem byte länge? * terminiert strcpy den status mit \0? */ char status[2] = ""; if (state == DOOR_CLOSED) { strncpy(status, "0", 1); } else if (state == DOOR_OPEN) { strncpy(status, "1", 1); } else { return 1; } BearSSL::WiFiClientSecure client; BearSSL::X509List server_cert(SERVER_CERT); BearSSL::X509List client_cert(CLIENT_CERT); BearSSL::PrivateKey client_key(CLIENT_KEY); client.setTrustAnchors(&server_cert); client.setClientRSACert(&client_cert, &client_key); delay(500); Serial.println("[Ctx] SSL Context initialized"); Serial.print("[Ctx] Free Heap: "); Serial.println(ESP.getFreeHeap()); delay(500); Serial.printf("[Send] Connect to %s:%i\n", SERVER_URL, SERVER_PORT); client.connect(SERVER_URL, SERVER_PORT); if (!client.connected()) { Serial.println("[Send] Can't connect to server"); Serial.print("[Send] SSL Error: "); Serial.println(client.getLastSSLError()); client.stop(); return 1; } else { ESP.resetFreeContStack(); uint32_t freeStackStart = ESP.getFreeContStack(); Serial.println("[Send] Connection successful established"); Serial.printf("[Send] Send status: %s\n", status); client.write(status); } return 0; } void setup() { /* * things to do once at boot time */ init_serial(); Serial.print("[Init] Free Heap ( after serial init): "); Serial.println(ESP.getFreeHeap()); init_pins(); Serial.print("[Init] Free Heap (after pins init): "); Serial.println(ESP.getFreeHeap()); init_wifi(); Serial.print("[Init] Free Heap (after wifi init): "); Serial.println(ESP.getFreeHeap()); delay(500); set_clock(); Serial.print("[Init] Free Heap (after setting clock): "); Serial.println(ESP.getFreeHeap()); delay(500); } void loop() { /* * things are running in a endless loop */ new_door_state = read_door_state(); if (new_door_state != current_door_state) { Serial.printf("[Loop] Status has changed to %i\n", new_door_state); toggle_led(new_door_state); send_status(new_door_state); current_door_state = new_door_state; } Serial.print("[Loop] Free Heap: "); Serial.println(ESP.getFreeHeap()); delay(FREQUENCY); }