Fixes in new API functions

This commit is contained in:
Martin Bauer 2021-07-22 18:38:28 +02:00
parent 06c3015d22
commit fb0b455910
7 changed files with 96 additions and 42 deletions

View File

@ -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)
{

View File

@ -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_;
};

View File

@ -10,6 +10,8 @@
[platformio]
data_dir = data
default_envs = esp32
[env:esp32]
platform = espressif32

View File

@ -16,6 +16,8 @@ public:
SessionAPI(SessionManager<SessionT> &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<T>::onClientConnect(websockets::WebsocketsClient &client)
char *writeHead = msg;
*writeHead = MessageCode::INITIAL_INFO;
*writeHead = static_cast<char>(MessageCode::INITIAL_INFO);
writeHead += sizeof(uint8_t);
*writeHead = sessionManager_.isMeasuring();
@ -81,17 +83,22 @@ template <typename T>
bool SessionAPI<T>::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<T>::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<T>::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 <typename T>
@ -129,14 +138,15 @@ template <typename TServer>
void SessionAPI<T>::sendSessionStopMessages(TServer &server)
{
MessageCode code = MessageCode::SESSION_STOPPED;
server.sendToAll<32>(code);
server.template sendToAll(code);
}
template <typename T>
template <typename TServer>
void SessionAPI<T>::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<T>::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<char>(MessageCode::SESSION_NEW_DATA);
constexpr int headerSize = 1;
for (int i = 0; i < MAX_WEBSOCKET_CONNECTIONS; ++i)
@ -155,14 +165,20 @@ void SessionAPI<T>::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]);
}
}
}

View File

@ -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 <size_t managerIdx = std::tuple_size<ApiManagerTuple>::value - 1, typename std::enable_if<managerIdx != 0, bool>::type = true>
template <size_t managerIdx = 0, typename std::enable_if<(managerIdx < std::tuple_size<ApiManagerTuple>::value), bool>::type = true>
void iterationImpl()
{
std::get<managerIdx>(apiManagers_).iteration(*this);
iterationImpl<managerIdx - 1>();
iterationImpl<managerIdx + 1>();
}
template <size_t managerIdx, typename std::enable_if<managerIdx == 0, bool>::type = true>
template <size_t managerIdx, typename std::enable_if<managerIdx == std::tuple_size<ApiManagerTuple>::value, bool>::type = true>
void iterationImpl() {}
template <size_t managerIdx = std::tuple_size<ApiManagerTuple>::value - 1, typename std::enable_if<managerIdx != 0, bool>::type = true>
bool handlMessageImpl(websockets::WebsocketsClient &client, MessageCode code, const char *payload, size_t size)
template <size_t managerIdx = 0, typename std::enable_if<(managerIdx < std::tuple_size<ApiManagerTuple>::value), bool>::type = true>
bool handleMessageImpl(websockets::WebsocketsClient &client, MessageCode code, const char *payload, size_t size)
{
bool handled = std::get<managerIdx>(apiManagers_).handleMessage(client, code, payload, size);
if (handled)
return true;
else
return handlMessageImpl<managerIdx - 1>(client, code, payload, size);
return handleMessageImpl<managerIdx + 1>(client, code, payload, size);
}
template <size_t managerIdx, typename std::enable_if<managerIdx == 0, bool>::type = true>
bool handlMessageImpl(websockets::WebsocketsClient &, MessageCode, const char *, size_t) { return false; }
template <size_t managerIdx, typename std::enable_if<managerIdx == std::tuple_size<ApiManagerTuple>::value, bool>::type = true>
bool handleMessageImpl(websockets::WebsocketsClient &, MessageCode, const char *, size_t) { return false; }
template <size_t managerIdx = std::tuple_size<ApiManagerTuple>::value - 1, typename std::enable_if<managerIdx != 0, bool>::type = true>
template <size_t managerIdx = 0, typename std::enable_if<(managerIdx < std::tuple_size<ApiManagerTuple>::value), bool>::type = true>
void onClientConnectImpl(websockets::WebsocketsClient &client)
{
std::get<managerIdx>(apiManagers_).onClientConnect(client);
onClientConnectImpl<managerIdx - 1>(client);
onClientConnectImpl<managerIdx + 1>(client);
}
template <size_t managerIdx, typename std::enable_if<managerIdx == 0, bool>::type = true>
template <size_t managerIdx, typename std::enable_if<managerIdx == std::tuple_size<ApiManagerTuple>::value, bool>::type = true>
void onClientConnectImpl(websockets::WebsocketsClient &client) {}
// -- Members

View File

@ -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<bool>())
{
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<const char *>());
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<const char *>(), //
json["sta_password"].as<const char *>());
restartScheduled_ = true;

View File

@ -36,7 +36,6 @@ EspHttp espHttpServer;
WifiManager wifiManager;
auto apiTuple = std::make_tuple(SessionAPI<Session_T>(sessionManager), WifiAPI(wifiManager));
WebsocketServer<decltype(apiTuple)> websocketServer(81, apiTuple);
@ -44,6 +43,15 @@ WebsocketServer<decltype(apiTuple)> 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<SessionT> *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<SessionT> *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<SessionT> *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<SessionT> *sessionManager, WifiManager *wifiManage
prefs.putBool("aStartEnabled", json["autoStartEnabled"].as<bool>());
if (json.containsKey("autoStopEnabled"))
prefs.putBool("aStopEnabled", json["autoStopEnabled"].as<bool>());
if (json.containsKey("hostname"))
prefs.putString("hostname", json["hostname"].as<String>());
sessionManagerSetup();
httpd_resp_send(req, "OK", -1);
@ -347,6 +377,7 @@ void httpSetup(SessionManager<SessionT> *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<SessionT> *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();