diff --git a/firmware/lib/session/AutoStartStop.h b/firmware/lib/session/AutoStartStop.h index a5a696c..da63543 100644 --- a/firmware/lib/session/AutoStartStop.h +++ b/firmware/lib/session/AutoStartStop.h @@ -4,6 +4,8 @@ template class AutoStart { public: + AutoStart() : enabled_(false) {} + void begin(MeasurementT minThreshold, MeasurementT maxThreshold, uint32_t maxNumMeasurementsBetweenPeeks) { minThreshold_ = minThreshold; @@ -11,10 +13,18 @@ public: maxNumMeasurementsBetweenPeeks_ = maxNumMeasurementsBetweenPeeks; measurementsSinceLastPeek_ = maxNumMeasurementsBetweenPeeks + 1; up_ = false; + enabled_ = true; } + void enable(bool enable=true) { + enabled_ = enable; + } + bool enabled() const { return enabled_; }; + bool autoStart(MeasurementT measurement) { + if(!enabled_) + return false; measurementsSinceLastPeek_ += 1; if (!up_ && measurement > maxThreshold_) { @@ -38,6 +48,8 @@ private: uint32_t measurementsSinceLastPeek_; // if measurements have been below min threshold (false) or above max threshold (true) bool up_; + + bool enabled_; }; // ------------------------------------------------------------------------------------------ @@ -46,13 +58,22 @@ template class AutoStop { public: + AutoStop() : enabled_(false) {} + void begin(MeasurementT threshold, uint32_t numMeasurementsBelowThreshold) { threshold_ = threshold; numMeasurementsBelowThreshold_ = numMeasurementsBelowThreshold; counter_ = 0; + enabled_ = true; } + void enable(bool enable=true) { + enabled_ = enable; + } + bool enabled() const { return enabled_; }; + + bool autoStop(MeasurementT measurement) { if (measurement > threshold_) @@ -76,4 +97,5 @@ private: MeasurementT threshold_; uint32_t numMeasurementsBelowThreshold_; uint32_t counter_; + bool enabled_; }; diff --git a/firmware/lib/session/SessionManager.h b/firmware/lib/session/SessionManager.h index 84498d3..822be4c 100644 --- a/firmware/lib/session/SessionManager.h +++ b/firmware/lib/session/SessionManager.h @@ -28,6 +28,11 @@ public: void iteration(); + void enableAutoStart(bool enable) { autoStart_.enable(enable); } + void enableAutoStop(bool enable) { autoStop_.enable(enable); } + bool autoStartEnabled() const { return autoStart_.enabled(); }; + bool autoStopEnabled() const { return autoStop_.enabled(); } + private: void onMeasurementTaken(MeasurementType measurement); @@ -75,13 +80,15 @@ void SessionManager::begin(int scaleDoutPin, int scaleSckPin, uint8_t MeasurementType autoStartMinTh, MeasurementType autoStartMaxTh, uint32_t autoStartMeasuresBetweenPeaks, MeasurementType autoStopTh, uint32_t autoStopNumMeasures) { + if(measuring_) + stopMeasurements(); + scaleDoutPin_ = scaleDoutPin; scaleSckPin_ = scaleSckPin; tareAvgCount_ = tareAvgCount; timeClient_.begin(); timeClient_.update(); - tare(); session_.init(timeClient_.getEpochTime()); autoStart_.begin(autoStartMinTh, autoStartMaxTh, autoStartMeasuresBetweenPeaks); @@ -107,51 +114,6 @@ void SessionManager::stopMeasurements() measuring_ = false; } -/* -template -void SessionManager::iteration() -{ - if (!measuring_) - { - delay(1); - return; // give control to HTTP server thread - } - - MeasurementType measurement = -1; - bool measurementDone = false; - while (!measurementDone) - measurementDone = scale_.measure(measurement); - bool addPointSuccessful = session_.addPoint(measurement); - //Serial.printf("Measured: %d\n", measurement); - if (!addPointSuccessful) - { - Serial.println("Maximum time of session reached - stopping"); - stopMeasurements(); - delay(1); // give control to HTTP server thread - return; - } - if (lastCallTime_ != 0) - { - const long cycleDuration = millis() - lastCallTime_; - if (cycleDuration <= CONFIG_MEASURE_DELAY) - { - delay(CONFIG_MEASURE_DELAY - cycleDuration); - } - else - { - const long skipped = (cycleDuration / CONFIG_MEASURE_DELAY); - Serial.printf("Measurements skipped: %ld, cycleDuration %ld\n", skipped, cycleDuration); - - for (int i = 0; i < skipped; ++i) - session_.addPoint(measurement); - - delay(CONFIG_MEASURE_DELAY * (skipped + 1) - cycleDuration); - } - } - lastCallTime_ = millis(); -} -*/ - template void SessionManager::iteration() { diff --git a/firmware/lib/session/SimpleMeasurementSession.h b/firmware/lib/session/SimpleMeasurementSession.h index 7bcb204..1c9d479 100644 --- a/firmware/lib/session/SimpleMeasurementSession.h +++ b/firmware/lib/session/SimpleMeasurementSession.h @@ -93,16 +93,13 @@ private: Measurement_T *startPtr = chunk->getDataPointer() + existingMeasurements; file.write((uint8_t *)(startPtr), measurementsToWrite * sizeof(Measurement_T)); - Serial.printf(" %ld Incr Save: before header patch\n", millis()); file.seek(arrayHeaderOffset); StreamingMsgPackEncoder encoder(&file); encoder.template sendArrayHeader(numMeasurements); - Serial.printf(" %ld total measurements up to now %u\n", millis(), numMeasurements); } else { - Serial.println("First save"); auto file = portablefs::open(filename.c_str(), "w"); StreamingMsgPackEncoder encoder(&file); chunk->serialize(encoder); diff --git a/firmware/src/firmware_main.cpp b/firmware/src/firmware_main.cpp index a9b410c..e17f717 100644 --- a/firmware/src/firmware_main.cpp +++ b/firmware/src/firmware_main.cpp @@ -53,6 +53,32 @@ bool firmwareUpdate() return true; } +void sessionManagerSetup() +{ + Preferences scalePrefs; + scalePrefs.begin("st_prefs"); + int valueRightShift = scalePrefs.getInt("valueRightShift", CONFIG_VALUE_RIGHT_SHIFT); + uint8_t tareAvgCount = scalePrefs.getUInt("tareAvgCount", CONFIG_TARE_AVG_COUNT); + MeasurementT autoStartMinThreshold = scalePrefs.getUInt("aStartMinTh", CONFIG_AUTO_START_MIN_THRESHOLD); + MeasurementT autoStartMaxThreshold = scalePrefs.getUInt("aStartMaxTh", CONFIG_AUTO_START_MAX_THRESHOLD); + uint32_t autoStartMaxMeasurementsBetweenPeaks = scalePrefs.getUInt("aStartCount", CONFIG_AUTO_START_MAX_MEASUREMENTS_BETWEEN_PEAKS); + MeasurementT autoStopThreshold = scalePrefs.getUInt("aStopTh", CONFIG_AUTO_STOP_THRESHOLD); + uint32_t autoStopNumMeasurements = scalePrefs.getUInt("aStopCount", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); + + bool autoStartEnabled = scalePrefs.getBool("aStartEnabled", true); + bool autoStopEnabled = scalePrefs.getBool("aStopEnabled", true); + if (wifiManager.inProvisioningMode()) + autoStartEnabled = false; + + // Session + sessionManager.begin(CONFIG_SCALE_DOUT_PIN, CONFIG_SCALE_SCK_PIN, + tareAvgCount, valueRightShift, + autoStartMinThreshold, autoStartMaxThreshold, autoStartMaxMeasurementsBetweenPeaks, + autoStopThreshold, autoStopNumMeasurements); + sessionManager.enableAutoStart(autoStartEnabled); + sessionManager.enableAutoStop(autoStopEnabled); +} + template void httpSetup(SessionManager *sessionManager, WifiManager *wifiManager) { @@ -95,6 +121,8 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage sessionObj["started"] = session.getStartTime(); sessionObj["num_measurements"] = session.numMeasurements(); } + sessionObj["auto_start"] = sessionManager->autoStartEnabled(); + sessionObj["auto_stop"] = sessionManager->autoStopEnabled(); } // scale { @@ -216,6 +244,86 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage httpd_resp_set_status(req, "400 Bad Request"); httpd_resp_send(req, "Invalid keys in JSON", -1); }; + auto cbSettingsGet = [](httpd_req_t *req) { + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_set_hdr(req, "Content-Type", "application/json"); + + StaticJsonDocument<1024> json; + Preferences prefs; + prefs.begin("st_prefs"); + + json["valueRightShift"] = prefs.getInt("valueRightShift", CONFIG_VALUE_RIGHT_SHIFT); + json["tareAvgCount"] = prefs.getUInt("tareAvgCount", CONFIG_TARE_AVG_COUNT); + json["autoStartMinThreshold"] = prefs.getUInt("aStartMinTh", CONFIG_AUTO_START_MIN_THRESHOLD); + json["autoStartMaxThreshold"] = prefs.getUInt("aStartMaxTh", CONFIG_AUTO_START_MAX_THRESHOLD); + json["autoStartMaxMeasurementsBetweenPeaks"] = prefs.getUInt("aStartCount", CONFIG_AUTO_START_MAX_MEASUREMENTS_BETWEEN_PEAKS); + json["autoStopThreshold"] = prefs.getUInt("aStopTh", CONFIG_AUTO_STOP_THRESHOLD); + json["autoStopNumMeasurements"] = prefs.getUInt("aStopCount", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); + json["autoStartEnabled"] = prefs.getBool("aStartEnabled", true); + json["autoStopEnabled"] = prefs.getBool("aStopEnabled", true); + char jsonText[1024]; + auto bytesWritten = serializeJson(json, jsonText); + httpd_resp_send(req, jsonText, bytesWritten); + }; + auto cbSettingsPost = [](httpd_req_t *req) { + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + StaticJsonDocument<1024> json; + char content[512]; + size_t recvSize = min(req->content_len, sizeof(content)); //truncate if too long + int ret = httpd_req_recv(req, content, recvSize); + if (ret <= 0) + { + if (ret == HTTPD_SOCK_ERR_TIMEOUT) + httpd_resp_send_408(req); + return; + } + DeserializationError err = deserializeJson(json, content); + if (err) + { + httpd_resp_set_status(req, "400 Bad Request"); + httpd_resp_send(req, "JSON parse error", -1); + return; + } + + Preferences prefs; + prefs.begin("st_prefs"); + if(json.containsKey("valueRightShift")) + prefs.putInt("valueRightShift", json["valueRightShift"].as()); + if(json.containsKey("tareAvgCount")) + prefs.putUInt("tareAvgCount", json["tareAvgCount"].as()); + if(json.containsKey("autoStartMinThreshold")) + prefs.putUInt("aStartMinTh", json["autoStartMinThreshold"].as()); + if(json.containsKey("autoStartMaxThreshold")) + prefs.putUInt("aStartMaxTh", json["autoStartMaxThreshold"].as()); + if(json.containsKey("autoStartMaxMeasurementsBetweenPeaks")) + prefs.putUInt("aStartCount", json["autoStartMaxMeasurementsBetweenPeaks"].as()); + if(json.containsKey("autoStopThreshold")) + prefs.putUInt("aStopTh", json["autoStopThreshold"].as()); + if(json.containsKey("autoStopNumMeasurements")) + prefs.putUInt("aStopCount", json["autoStopNumMeasurements"].as()); + if(json.containsKey("autoStartEnabled")) + prefs.putBool("aStartEnabled", json["autoStartEnabled"].as()); + if(json.containsKey("autoStopEnabled")) + prefs.putBool("aStopEnabled", json["autoStopEnabled"].as()); + + sessionManagerSetup(); + httpd_resp_send(req, "OK", -1); + }; + auto cbSettingsDelete = [](httpd_req_t *req) { + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + Preferences prefs; + prefs.begin("st_prefs"); + prefs.putInt("valueRightShift", CONFIG_VALUE_RIGHT_SHIFT); + prefs.putUInt("tareAvgCount", CONFIG_TARE_AVG_COUNT); + prefs.putUInt("aStartMinTh", CONFIG_AUTO_START_MIN_THRESHOLD); + prefs.putUInt("aStartMaxTh", CONFIG_AUTO_START_MAX_THRESHOLD); + prefs.putUInt("aStartCount", CONFIG_AUTO_START_MAX_MEASUREMENTS_BETWEEN_PEAKS); + prefs.putUInt("aStopTh", CONFIG_AUTO_STOP_THRESHOLD); + prefs.putUInt("aStopCount", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); + prefs.putBool("aStartEnabled", true); + prefs.putBool("aStopEnabled", true); + httpd_resp_send(req, "OK", -1); + }; espHttpServer.start(); @@ -236,6 +344,10 @@ void httpSetup(SessionManager *sessionManager, WifiManager *wifiManage espHttpServer.on("/api/tare", HTTP_GET, cbTare); espHttpServer.on("/api/firmwareupdate", HTTP_GET, cbFirmwareUpdate); + espHttpServer.on("/api/settings", HTTP_GET, cbSettingsGet); + espHttpServer.on("/api/settings", HTTP_POST, cbSettingsPost); + espHttpServer.on("/api/settings", HTTP_DELETE, cbSettingsDelete); + auto webdav = webdavHandler("/webdav/", "/dat"); espHttpServer.on("/webdav/*?", HTTP_GET, webdav); espHttpServer.on("/webdav/*?", HTTP_PROPFIND, webdav); @@ -296,22 +408,8 @@ void setup() mdnsSetup(fullHostname); - Preferences scalePrefs; - scalePrefs.begin("st_prefs"); - int valueRightShift = scalePrefs.getInt("valueRightShift", CONFIG_VALUE_RIGHT_SHIFT); - uint8_t tareAvgCount = scalePrefs.getUInt("tareAvgCount", CONFIG_TARE_AVG_COUNT); - MeasurementT autoStartMinThreshold = scalePrefs.getUInt("autoStartMinThreshold", CONFIG_AUTO_START_MIN_THRESHOLD); - MeasurementT autoStartMaxThreshold = scalePrefs.getUInt("autoStartMinThreshold", CONFIG_AUTO_START_MAX_THRESHOLD); - uint32_t autoStartMaxMeasurementsBetweenPeaks = scalePrefs.getUInt("autoStartMaxMeasurementsBetweenPeaks", CONFIG_AUTO_START_MAX_MEASUREMENTS_BETWEEN_PEAKS); - MeasurementT autoStopThreshold = scalePrefs.getUInt("autoStopThreshold", CONFIG_AUTO_STOP_THRESHOLD); - uint32_t autoStopNumMeasurements = scalePrefs.getUInt("autoStopNumMeasurements", CONFIG_AUTO_STOP_NUM_MEASUREMENTS); - - - // Session - sessionManager.begin(CONFIG_SCALE_DOUT_PIN, CONFIG_SCALE_SCK_PIN, - tareAvgCount, valueRightShift, - autoStartMinThreshold, autoStartMaxThreshold, autoStartMaxMeasurementsBetweenPeaks, - autoStopThreshold, autoStopNumMeasurements); + sessionManagerSetup(); + sessionManager.tare(); // HTTP & Websocket server httpSetup(&sessionManager, &wifiManager);