From fb0b4559108f418887b2be3e55be1a95509e8e73 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Thu, 22 Jul 2021 18:38:28 +0200 Subject: [PATCH] Fixes in new API functions --- firmware/lib/wifimanager/WifiManager.cpp | 24 +++++++---- firmware/lib/wifimanager/WifiManager.h | 3 +- firmware/platformio.ini | 2 + firmware/src/SessionAPI.h | 28 ++++++++++--- firmware/src/WebsocketServer.h | 24 +++++------ firmware/src/WifiAPI.cpp | 5 ++- firmware/src/firmware_main.cpp | 52 +++++++++++++++++------- 7 files changed, 96 insertions(+), 42 deletions(-) diff --git a/firmware/lib/wifimanager/WifiManager.cpp b/firmware/lib/wifimanager/WifiManager.cpp index 7b4d7bf..4def673 100644 --- a/firmware/lib/wifimanager/WifiManager.cpp +++ b/firmware/lib/wifimanager/WifiManager.cpp @@ -1,8 +1,9 @@ #include "WifiManager.h" -void WifiManager::begin(const String &hostname) +void WifiManager::begin(const String &hostname, const String & wifiStaModeName) { hostname_ = hostname; + wifiStaModeName_ = wifiStaModeName; prefs_.begin("st_wifi_manager"); startWifi(); } @@ -20,19 +21,24 @@ void WifiManager::startWifi() // station mode WiFi.mode(WIFI_STA); WiFi.begin(staSSID.c_str(), staPassword.c_str()); + Serial.printf("Starting WiFi station mode to ssid %s, hostname %s\n", staSSID.c_str(), hostname_.c_str()); WiFi.setHostname(hostname_.c_str()); int connectCounter = 0; bool successful = true; + delay(5000); + while (WiFi.status() != WL_CONNECTED) { - delay(2000); + Serial.printf("WiFI connection problem %d\n", WiFi.status()); WiFi.begin(staSSID.c_str(), staPassword.c_str()); + connectCounter += 1; if (connectCounter >= 60) // for two minutes no connection { successful = false; break; // fallback to AP mode } + delay(5000); } state_ = STA; if (successful) @@ -42,14 +48,17 @@ void WifiManager::startWifi() WiFi.mode(WIFI_AP); WiFi.softAPConfig(IPAddress(192, 168, 42, 1), IPAddress(192, 168, 42, 1), IPAddress(255, 255, 255, 0)); WiFi.softAPsetHostname(hostname_.c_str()); + if (apPassword.length() > 0) { - WiFi.softAP(hostname_.c_str(), apPassword.c_str()); + Serial.printf("Secured AP mode, name %s\n", wifiStaModeName_.c_str()); + WiFi.softAP(wifiStaModeName_.c_str(), apPassword.c_str()); state_ = AP_SECURE; } else { - WiFi.softAP(hostname_.c_str()); + Serial.printf("Provisioning AP mode, name %s\n", wifiStaModeName_.c_str()); + WiFi.softAP(wifiStaModeName_.c_str()); state_ = AP_PROVISIONING; } } @@ -80,15 +89,14 @@ void WifiManager::resetToApProvisioning() void WifiManager::iteration() { - if (state_ == STA && WiFi.status() != WL_CONNECTED) { + if (state_ == STA && WiFi.status() != WL_CONNECTED) + { startWifi(); Serial.println("Connection lost - Restarting WIFI"); } - } - -const char * WifiManager::stateToString(WifiManager::State state) +const char *WifiManager::stateToString(WifiManager::State state) { switch (state) { diff --git a/firmware/lib/wifimanager/WifiManager.h b/firmware/lib/wifimanager/WifiManager.h index 09f28d4..7403643 100644 --- a/firmware/lib/wifimanager/WifiManager.h +++ b/firmware/lib/wifimanager/WifiManager.h @@ -28,7 +28,7 @@ public: }; WifiManager() : state_(INVALID) {} - void begin(const String &hostname); + void begin(const String &hostname, const String & wifiStaModeName); void setStaCredentials(const char *wifiName, const char *password); void setApCredentials(const char *password); @@ -48,4 +48,5 @@ private: Preferences prefs_; State state_; String hostname_; + String wifiStaModeName_; }; diff --git a/firmware/platformio.ini b/firmware/platformio.ini index 3d3df69..c70ee4c 100644 --- a/firmware/platformio.ini +++ b/firmware/platformio.ini @@ -10,6 +10,8 @@ [platformio] data_dir = data +default_envs = esp32 + [env:esp32] platform = espressif32 diff --git a/firmware/src/SessionAPI.h b/firmware/src/SessionAPI.h index 332e239..611211a 100644 --- a/firmware/src/SessionAPI.h +++ b/firmware/src/SessionAPI.h @@ -16,6 +16,8 @@ public: SessionAPI(SessionManager &sessionManager) : sessionManager_(sessionManager) { + for (int i = 0; i < MAX_WEBSOCKET_CONNECTIONS; ++i) + numSentMeasurements_[i] = 0; } void onClientConnect(websockets::WebsocketsClient &client); @@ -60,7 +62,7 @@ void SessionAPI::onClientConnect(websockets::WebsocketsClient &client) char *writeHead = msg; - *writeHead = MessageCode::INITIAL_INFO; + *writeHead = static_cast(MessageCode::INITIAL_INFO); writeHead += sizeof(uint8_t); *writeHead = sessionManager_.isMeasuring(); @@ -81,17 +83,22 @@ template bool SessionAPI::handleMessage(websockets::WebsocketsClient &client, MessageCode code, const char *payload, size_t size) { + Serial.println("Handling message in SessionAPI"); switch (code) { case MessageCode::START_SESSION: + Serial.println("SessionAPI: starting measurement session"); this->sessionManager_.startMeasurements(); return true; case MessageCode::STOP_SESSION: + Serial.println("SessionAPI: stopping measurement session"); this->sessionManager_.stopMeasurements(); return true; case MessageCode::TARE: this->sessionManager_.tare(); return true; + default: + return false; } return false; } @@ -105,12 +112,14 @@ void SessionAPI::iteration(TServer &server) sendSessionStartMessages(server); for (int i = 0; i < MAX_WEBSOCKET_CONNECTIONS; ++i) numSentMeasurements_[i] = 0; + running_ = true; } else if (running_ && !sessionManager_.isMeasuring()) { sendSessionStopMessages(server); for (int i = 0; i < MAX_WEBSOCKET_CONNECTIONS; ++i) numSentMeasurements_[i] = 0; + running_ = false; } sendNewDataMessages(server); } @@ -121,7 +130,7 @@ void SessionAPI::sendSessionStartMessages(TServer &server) { StaticJsonDocument<128> data; data["sessionId"] = sessionManager_.session().getStartTime(); - server.sendToAll<32>(MessageCode::SESSION_STARTED, data); + server.template sendToAll<32>(MessageCode::SESSION_STARTED, data); } template @@ -129,14 +138,15 @@ template void SessionAPI::sendSessionStopMessages(TServer &server) { MessageCode code = MessageCode::SESSION_STOPPED; - server.sendToAll<32>(code); + server.template sendToAll(code); } template template void SessionAPI::sendNewDataMessages(TServer &server) { - constexpr size_t MAX_MEASUREMENTS_PER_MSG = 16; + + constexpr size_t MAX_MEASUREMENTS_PER_MSG = 15; constexpr size_t WAIT_UNTIL_AT_LEAST_NUM_MEASUREMENTS = 1; // new data messages are the only messages not sent in msgpack format @@ -144,8 +154,8 @@ void SessionAPI::sendNewDataMessages(TServer &server) using MeasurementT = typename T::MeasurementType; auto &session = sessionManager_.session(); - char buffer[1 + MAX_MEASUREMENTS_PER_MSG]; - buffer[0] = MessageCode::SESSION_NEW_DATA; + char buffer[1 + MAX_MEASUREMENTS_PER_MSG * sizeof(MeasurementT)]; + buffer[0] = static_cast(MessageCode::SESSION_NEW_DATA); constexpr int headerSize = 1; for (int i = 0; i < MAX_WEBSOCKET_CONNECTIONS; ++i) @@ -155,14 +165,20 @@ void SessionAPI::sendNewDataMessages(TServer &server) { MeasurementT *dataToSend = session.getDataPointer() + numSentMeasurements_[i]; int32_t numMeasurementsToSend = int32_t(session.numMeasurements()) - int32_t(numSentMeasurements_[i]); + if (numMeasurementsToSend >= WAIT_UNTIL_AT_LEAST_NUM_MEASUREMENTS) { + //Serial.printf("-> i=%d, numSentMeasurements_[i]=%d, to send %d\n", i, numSentMeasurements_[i], numMeasurementsToSend); + if (numMeasurementsToSend > MAX_MEASUREMENTS_PER_MSG) numMeasurementsToSend = MAX_MEASUREMENTS_PER_MSG; + //Serial.printf(" Sending %d measurements\n", numMeasurementsToSend); + memcpy(buffer + headerSize, dataToSend, sizeof(MeasurementT) * numMeasurementsToSend); c.sendBinary(buffer, headerSize + sizeof(MeasurementT) * numMeasurementsToSend); numSentMeasurements_[i] += numMeasurementsToSend; + //Serial.printf(" Sent measurements %d\n", numSentMeasurements_[i]); } } } diff --git a/firmware/src/WebsocketServer.h b/firmware/src/WebsocketServer.h index d1ba245..dbacabe 100644 --- a/firmware/src/WebsocketServer.h +++ b/firmware/src/WebsocketServer.h @@ -40,7 +40,7 @@ public: const size_t length = message.length(); MessageCode msgCode = MessageCode((uint8_t)(data[0])); - this->handlMessageImpl(client, msgCode, data + 1, length - 1); + this->handleMessageImpl(client, msgCode, data + 1, length - 1); } else client.close(CloseReason_UnsupportedData); @@ -96,34 +96,34 @@ public: private: // -- Tuple calls - template ::value - 1, typename std::enable_if::type = true> + template ::value), bool>::type = true> void iterationImpl() { std::get(apiManagers_).iteration(*this); - iterationImpl(); + iterationImpl(); } - template ::type = true> + template ::value, bool>::type = true> void iterationImpl() {} - template ::value - 1, typename std::enable_if::type = true> - bool handlMessageImpl(websockets::WebsocketsClient &client, MessageCode code, const char *payload, size_t size) + template ::value), bool>::type = true> + bool handleMessageImpl(websockets::WebsocketsClient &client, MessageCode code, const char *payload, size_t size) { bool handled = std::get(apiManagers_).handleMessage(client, code, payload, size); if (handled) return true; else - return handlMessageImpl(client, code, payload, size); + return handleMessageImpl(client, code, payload, size); } - template ::type = true> - bool handlMessageImpl(websockets::WebsocketsClient &, MessageCode, const char *, size_t) { return false; } + template ::value, bool>::type = true> + bool handleMessageImpl(websockets::WebsocketsClient &, MessageCode, const char *, size_t) { return false; } - template ::value - 1, typename std::enable_if::type = true> + template ::value), bool>::type = true> void onClientConnectImpl(websockets::WebsocketsClient &client) { std::get(apiManagers_).onClientConnect(client); - onClientConnectImpl(client); + onClientConnectImpl(client); } - template ::type = true> + template ::value, bool>::type = true> void onClientConnectImpl(websockets::WebsocketsClient &client) {} // -- Members diff --git a/firmware/src/WifiAPI.cpp b/firmware/src/WifiAPI.cpp index 7a5e20e..268ab77 100644 --- a/firmware/src/WifiAPI.cpp +++ b/firmware/src/WifiAPI.cpp @@ -26,7 +26,7 @@ bool WifiAPI::handleMessage(websockets::WebsocketsClient &client, MessageCode co { StaticJsonDocument<1024> json; - DeserializationError err = deserializeJson(json, payload, size); + DeserializationError err = deserializeMsgPack(json, payload, size); if (err) { sendErrorToClient(client, "Deserialization Error"); @@ -34,18 +34,21 @@ bool WifiAPI::handleMessage(websockets::WebsocketsClient &client, MessageCode co } if (json.containsKey("reset_to_provisioning") && json["reset_to_provisioning"].as()) { + Serial.println("wifi: reset_to_provisioning"); wifiManager_.resetToApProvisioning(); restartScheduled_ = true; return true; } else if (json.containsKey("ap_password")) { + Serial.println("wifi: ap_password"); wifiManager_.setApCredentials(json["ap_password"].as()); restartScheduled_ = true; return true; } else if (json.containsKey("sta_ssid") && json.containsKey("sta_password")) { + Serial.println("wifi: sta_ssid"); wifiManager_.setStaCredentials(json["sta_ssid"].as(), // json["sta_password"].as()); restartScheduled_ = true; diff --git a/firmware/src/firmware_main.cpp b/firmware/src/firmware_main.cpp index 5ae5c0a..ac74506 100644 --- a/firmware/src/firmware_main.cpp +++ b/firmware/src/firmware_main.cpp @@ -36,7 +36,6 @@ EspHttp espHttpServer; WifiManager wifiManager; - auto apiTuple = std::make_tuple(SessionAPI(sessionManager), WifiAPI(wifiManager)); WebsocketServer websocketServer(81, apiTuple); @@ -44,6 +43,15 @@ WebsocketServer websocketServer(81, apiTuple); extern const uint8_t certificate_pem[] asm("_binary_certificate_pem_start"); +String getIdSuffix() +{ + uint8_t baseMac[6]; + esp_read_mac(baseMac, ESP_MAC_WIFI_STA); + char baseMacChr[18] = {0}; + sprintf(baseMacChr, "-%02X%02X%02X", baseMac[3], baseMac[4], baseMac[5]); + return String(baseMacChr); +} + bool firmwareUpdate() { esp_http_client_config_t config; @@ -178,6 +186,24 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage firmware["compile_date"] = descr->date; firmware["compile_time"] = descr->time; } + // device ids + { + uint8_t baseMac[6]; + esp_read_mac(baseMac, ESP_MAC_WIFI_STA); + char baseMacChr[18] = {0}; + sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", + baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]); + + esp_chip_info_t chipInfo; + esp_chip_info(&chipInfo); + char modelString[16]; + sprintf(modelString, "%d.%d", chipInfo.model, chipInfo.revision); + + JsonObject device = json.createNestedObject("device"); + device["mac"] = baseMacChr; + device["chip"] = modelString; + device["unique_name"] = "swimtracker" + getIdSuffix(); + } char jsonText[512]; auto bytesWritten = serializeJson(json, jsonText); httpd_resp_send(req, jsonText, bytesWritten); @@ -186,7 +212,7 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage { auto sessionId = sessionManager->session().getStartTime(); uint32_t startIdx = getUrlQueryParameter(req, "startIdx", 0); - //Serial.printf("Data request, start index: %d\n", startIdx); + if (startIdx >= sessionManager->session().numMeasurements()) { httpd_resp_send_404(req); @@ -284,6 +310,8 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage json["autoStopNumMeasurements"] = prefs.getUInt("aStopCount", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); json["autoStartEnabled"] = prefs.getBool("aStartEnabled", true); json["autoStopEnabled"] = prefs.getBool("aStopEnabled", true); + json["hostname"] = prefs.getString("hostname", CONFIG_HOSTNAME + getIdSuffix()); + char jsonText[1024]; auto bytesWritten = serializeJson(json, jsonText); httpd_resp_send(req, jsonText, bytesWritten); @@ -329,6 +357,8 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage prefs.putBool("aStartEnabled", json["autoStartEnabled"].as()); if (json.containsKey("autoStopEnabled")) prefs.putBool("aStopEnabled", json["autoStopEnabled"].as()); + if (json.containsKey("hostname")) + prefs.putString("hostname", json["hostname"].as()); sessionManagerSetup(); httpd_resp_send(req, "OK", -1); @@ -347,6 +377,7 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage prefs.putUInt("aStopCount", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); prefs.putBool("aStartEnabled", true); prefs.putBool("aStopEnabled", true); + prefs.putBool("hostname", CONFIG_HOSTNAME + getIdSuffix()); httpd_resp_send(req, "OK", -1); }; @@ -386,15 +417,6 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage } } -String getIdSuffix() -{ - uint8_t baseMac[6]; - esp_read_mac(baseMac, ESP_MAC_WIFI_STA); - char baseMacChr[18] = {0}; - sprintf(baseMacChr, "-%02X%02X%02X", baseMac[3], baseMac[4], baseMac[5]); - return String(baseMacChr); -} - void mdnsSetup(const String &fullHostname) { if (!MDNS.begin(fullHostname.c_str())) @@ -427,13 +449,15 @@ void setup() userStorage.init(); // WiFi - String fullHostname = String(CONFIG_HOSTNAME) + getIdSuffix(); - wifiManager.begin(fullHostname); + Preferences prefs; + String uniqueName = "swimtracker" + getIdSuffix(); + String configuredHostname = prefs.getString("hostname", CONFIG_HOSTNAME + getIdSuffix()); + wifiManager.begin(configuredHostname, uniqueName); Serial.print("Connected to WiFi. IP:"); Serial.println(WiFi.localIP()); Serial.printf("WIFI state: %s\n", wifiManager.stateStr()); - mdnsSetup(fullHostname); + mdnsSetup(configuredHostname); sessionManagerSetup(); sessionManager.tare();