diff --git a/.gitignore b/.gitignore index b5c2a14..c01530e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +.pio/ + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml @@ -106,3 +108,5 @@ cmake-build-debug # End of https://www.gitignore.io/api/clion+all,platformio,visualstudiocode # secrets.h +.vscode/launch.json +.pio/build/project.checksum diff --git a/.pio/build/project.checksum b/.pio/build/project.checksum index 33ea39c..cbb0283 100644 --- a/.pio/build/project.checksum +++ b/.pio/build/project.checksum @@ -1 +1 @@ -d03f253803ab29b9105b4976c1a1c7e882ed3b02 \ No newline at end of file +444c4573a3053783784b69c1be55a30f7b76e4dd \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..e80666b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/README.md b/README.md index 4f9099d..31e302a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ ESP32 port of the keyble library working, with some additions! + new features/changes from corgan: watchdog, status led, webserver auth + +- watchdog set WDT_TIMEOUT (sec) after this time the esp will reset if something hangs up +- status LED on GPIO32: constant light=wifi conected, slow blink: mqtt conected and waiting, fast blink=conected to keyble +- webserver auth, set WEBSERVER_USER and WEBSERVER_PW. Default admin:admin + + Thanks go to RoP09, tc-maxx, henfri, MariusSchiffer and of course oyooyo for their brillant work! diff --git a/lib/eQ3/eQ3.cpp b/lib/eQ3/eQ3.cpp index a96985e..e1dcb06 100644 --- a/lib/eQ3/eQ3.cpp +++ b/lib/eQ3/eQ3.cpp @@ -106,10 +106,14 @@ bool eQ3::onTick() { //xSemaphoreGive(mutex); // function will take the semaphore again queueFunc->second(); } - } else { + } else if (state.connectionState != DISCONNECTED) { sendNextFragment(); lastActivity = time(NULL); - } + } + // } else { + // sendNextFragment(); + // lastActivity = time(NULL); + // } // TODO disconnect if no answer for long time? /* if (state.connectionState >= CONNECTED && difftime(lastActivity, time(NULL)) > LOCK_TIMEOUT && sendQueue.empty()) { Serial.println("# Lock timeout"); diff --git a/platformio.ini b/platformio.ini index dcad391..1a193f9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,6 +14,7 @@ board = esp32dev framework = arduino monitor_speed = 115200 lib_ldf_mode = deep +upload_port = COM5 lib_deps = ESP32 BLE Arduino @ 1.0.1 PubSubClient diff --git a/src/main.cpp b/src/main.cpp index b72fc2c..d4825ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ #include #include #include "AutoConnect.h" +#include #define PARAM_FILE "/keyble.json" #define AUX_SETTING_URI "/keyble_setting" @@ -33,8 +34,13 @@ #define CARD_KEY "M001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +#define WDT_TIMEOUT 20 // WDT Timeout in +#define LED_GPIO 32 // LED GPIO + +#define WEBSERVER_USER "admin" +#define WEBSERVER_PW "admin" + // ---[Variables]--------------------------------------------------------------- -#pragma region WebServer Server; AutoConnect Portal(Server); AutoConnectConfig config; @@ -76,12 +82,11 @@ String mqtt_pub2 = ""; String mqtt_pub3 = ""; String mqtt_pub4 = ""; - WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); -#pragma endregion + // ---[Add Menue Items]--------------------------------------------------------- -#pragma region + static const char AUX_keyble_setting[] PROGMEM = R"raw( [ { @@ -180,7 +185,23 @@ static const char AUX_keyble_setting[] PROGMEM = R"raw( ] )raw"; -#pragma endregion +static const char PAGE_AUTH[] PROGMEM = R"( +{ + "uri": "/auth", + "title": "Auth", + "menu": true, + "element": [ + { + "name": "text", + "type": "ACText", + "value": "AutoConnect has authorized", + "style": "font-family:Arial;font-size:18px;font-weight:400;color:#191970" + } + ] +} +)"; + + // ---[getParams]--------------------------------------------------------------- void getParams(AutoConnectAux& aux) { @@ -201,6 +222,8 @@ void getParams(AutoConnectAux& aux) { KeyBleUserId = aux["KeyBleUserId"].value; KeyBleUserId.trim(); } + + // ---[loadParams]-------------------------------------------------------------- String loadParams(AutoConnectAux& aux, PageArgument& args) { (void)(args); @@ -222,6 +245,8 @@ String loadParams(AutoConnectAux& aux, PageArgument& args) { Serial.println("# " PARAM_FILE " open failed"); return String(""); } + + // ---[saveParams]-------------------------------------------------------------- String saveParams(AutoConnectAux& aux, PageArgument& args) { AutoConnectAux& keyble_setting = *Portal.aux(Portal.where()); @@ -245,6 +270,8 @@ String saveParams(AutoConnectAux& aux, PageArgument& args) { return String(""); } + + // ---[MqttCallback]------------------------------------------------------------ void MqttCallback(char* topic, byte* payload, unsigned int length) { Serial.print("# Message received: "); @@ -294,6 +321,8 @@ void MqttCallback(char* topic, byte* payload, unsigned int length) { Serial.println(mqtt_sub); } } + + // ---[MQTTpublish]------------------------------------------------------------- void MqttPublish() { @@ -371,6 +400,8 @@ void MqttPublish() Serial.println("# waiting for command..."); } + + // ---[MQTT-Setup]-------------------------------------------------------------- void SetupMqtt() { while (!mqttClient.connected()) { // Loop until we're reconnected to the MQTT server @@ -387,6 +418,8 @@ void SetupMqtt() { } } } + + // ---[RootPage]---------------------------------------------------------------- void rootPage() { @@ -432,7 +465,7 @@ void rootPage() "

MQTT User Name: " + MqttUserName + "

" "

MQTT Topic: " + MqttTopic + "

" "

KeyBLE MAC Address: " + KeyBleMac + "

" - "

KeyBLE User Key: " + KeyBleUserKey + "

" + "

KeyBLE User ID: " + KeyBleUserId + "

" "

KeyBLE last battery state: " + mqtt_pub3 + "

" "

KeyBLE last command received: " + mqtt_sub + "

" @@ -441,6 +474,8 @@ void rootPage() "

KeyBLE last task: " + mqtt_pub2 + "

" "
" "

page refresh every 30 seconds

"; + + //"

KeyBLE User Key: " + KeyBleUserKey + "

" } content += @@ -448,6 +483,8 @@ void rootPage() ""; Server.send(200, "text/html", content); } + + // ---[Wifi Signalquality]----------------------------------------------------- int GetWifiSignalQuality() { float signal = 2 * (WiFi.RSSI() + 100); @@ -456,6 +493,8 @@ if (signal > 100) else return signal; } + + // ---[SetWifi]----------------------------------------------------------------- void SetWifi(bool active) { wifiActive = active; @@ -466,16 +505,22 @@ void SetWifi(bool active) { else { WiFi.mode(WIFI_OFF); Serial.println("# WiFi disabled"); + digitalWrite(LED_GPIO,LOW); } } + + // ---[SetupWiFi]--------------------------------------------------------------- void SetupWifi() { + digitalWrite(LED_GPIO,LOW); + if (Portal.begin()) { if (WiFi.status() == WL_CONNECTED) { Serial.println("# WIFI: connected to SSiD: " + WiFi.SSID()); + digitalWrite(LED_GPIO,HIGH); } int maxWait=100; while (WiFi.status() != WL_CONNECTED) { @@ -489,8 +534,11 @@ void SetupWifi() Serial.println("# WIFI: connected!"); Serial.println("# WIFI: signalquality: " + String(GetWifiSignalQuality()) + "%"); Serial.println("# WiFi connected to IP: " + WiFi.localIP().toString()); + digitalWrite(LED_GPIO,HIGH); } } + + // ---[Setup]------------------------------------------------------------------- void setup() { delay(1000); @@ -511,8 +559,19 @@ void setup() { config.title = AP_TITLE; config.gateway = IPAddress(AP_IP); config.ota = AC_OTA_BUILTIN; + + //basic auth + config.auth = AC_AUTH_DIGEST; + config.authScope = AC_AUTHSCOPE_AUX; + config.username = WEBSERVER_USER; + config.password = WEBSERVER_PW; + Server.on("/", rootPage); Portal.config(config); + Portal.load(FPSTR(PAGE_AUTH)); + + //status led + pinMode(LED_GPIO,OUTPUT); if (Portal.load(FPSTR(AUX_keyble_setting))) { AutoConnectAux& keyble_setting = *Portal.aux(AUX_SETTING_URI); @@ -546,10 +605,17 @@ void setup() { Serial.println("# Please fill in MQTT and KeyBLE credentials first!"); } + + //watchdog + esp_task_wdt_init(WDT_TIMEOUT, true); // Initialize ESP32 Task WDT + esp_task_wdt_add(NULL); // Subscribe to the Task WDT + } + + // ---[loop]-------------------------------------------------------------------- void loop() { - + Portal.handleClient(); // This statement will declare pin 0 as digital input @@ -568,6 +634,7 @@ if (Push_button_state == LOW && WiFi.status() == WL_CONNECTED) // Wifi reconnect if (wifiActive) { + digitalWrite(LED_GPIO,HIGH); if (WiFi.status() != WL_CONNECTED) { Serial.println("# WiFi disconnected, reconnect..."); @@ -598,6 +665,9 @@ if (wifiActive) else if(mqttClient.connected()) { mqttClient.loop(); + digitalWrite(LED_GPIO,LOW); + delay(250); + digitalWrite(LED_GPIO,HIGH); } } } @@ -702,6 +772,10 @@ if (do_open || do_lock || do_unlock || do_status || do_toggle || do_pair) bool timeout=(millis() - starttime > LOCK_TIMEOUT *2000 +1000); bool finished=false; + digitalWrite(LED_GPIO,LOW); + delay(50); + digitalWrite(LED_GPIO,HIGH); + if ((keyble->_LockStatus != -1) || timeout) { if(keyble->_LockStatus == 1) @@ -710,7 +784,7 @@ if (do_open || do_lock || do_unlock || do_status || do_toggle || do_pair) if(timeout) { finished=true; - Serial.println("!!! Lockstatus 1 - timeout !!!"); + Serial.println("!!! Lockstatus 1 - timeout1 !!!"); } } else if(keyble->_LockStatus == -1) @@ -720,7 +794,7 @@ if (do_open || do_lock || do_unlock || do_status || do_toggle || do_pair) { keyble->_LockStatus = 9; //timeout finished=true; - Serial.println("!!! Lockstatus -1 - timeout !!!"); + Serial.println("!!! Lockstatus -1 - timeout2 !!!"); } } else if(keyble->_LockStatus != 1) @@ -749,4 +823,7 @@ if (do_open || do_lock || do_unlock || do_status || do_toggle || do_pair) } } } + + esp_task_wdt_reset(); + }