// NTP headers #include #include #include #include "AutoStartStop.h" #include "Logger.h" template class SessionManager { public: using MeasurementType = typename SessionT::MeasurementType; SessionManager(); void begin(int scaleDoutPin, int scaleSckPin, uint8_t tareAvgCount, int valueRightShift, MeasurementType autoStartMinTh, MeasurementType autoStartMaxTh, uint32_t autoStartMeasuresBetweenPeaks, MeasurementType autoStopTh, uint32_t autoStopNumMeasures); void tare(); long tareOffset() const { return scale_.offset(); }; int valueRightShift() const { return scale_.valueRightShift(); } void startMeasurements(); void stopMeasurements(); bool isMeasuring() const { return measuring_; } SessionT &session() { return session_; } 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(); } unsigned long getNtpTime() { return timeClient_.getEpochTime(); } private: void onMeasurementTaken(MeasurementType measurement); WiFiUDP ntpUDP_; NTPClient timeClient_; Scale scale_; //MockScale scale; SessionT session_; bool measuring_; long lastCallTime_; int scaleDoutPin_; int scaleSckPin_; uint8_t tareAvgCount_; int valueRightShift_; AutoStart autoStart_; AutoStop autoStop_; }; // ------------------------------------------------------------------------------------------------ template SessionManager::SessionManager() : timeClient_(ntpUDP_, "pool.ntp.org"), measuring_(false), lastCallTime_(0) { } template void SessionManager::tare() { if (measuring_) stopMeasurements(); LOG_INFO("Beginning tare"); scale_.begin(scaleDoutPin_, scaleSckPin_, valueRightShift_); scale_.tare(CONFIG_TARE_AVG_COUNT); LOG_INFO("Finished tare"); } template void SessionManager::begin(int scaleDoutPin, int scaleSckPin, uint8_t tareAvgCount, int valueRightShift, MeasurementType autoStartMinTh, MeasurementType autoStartMaxTh, uint32_t autoStartMeasuresBetweenPeaks, MeasurementType autoStopTh, uint32_t autoStopNumMeasures) { if(measuring_) stopMeasurements(); scaleDoutPin_ = scaleDoutPin; scaleSckPin_ = scaleSckPin; tareAvgCount_ = tareAvgCount; valueRightShift_ = valueRightShift; timeClient_.begin(); timeClient_.update(); session_.init(timeClient_.getEpochTime()); autoStart_.begin(autoStartMinTh, autoStartMaxTh, autoStartMeasuresBetweenPeaks); autoStop_.begin(autoStopTh, autoStopNumMeasures); } template void SessionManager::startMeasurements() { if (measuring_ == true) return; measuring_ = true; lastCallTime_ = 0; session_.init(timeClient_.getEpochTime()); } template void SessionManager::stopMeasurements() { if (measuring_ == false) return; session_.finalize(); measuring_ = false; } template void SessionManager::iteration() { MeasurementType measurement = -1; bool measurementDone = false; while (!measurementDone) measurementDone = scale_.measure(measurement); onMeasurementTaken(measurement); 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); LOG_WARNING("Measurements skipped: %ld, cycleDuration %ld", skipped, cycleDuration); for (int i = 0; i < skipped; ++i) onMeasurementTaken(measurement); delay(CONFIG_MEASURE_DELAY * (skipped + 1) - cycleDuration); } } lastCallTime_ = millis(); } template void SessionManager::onMeasurementTaken(MeasurementType measurement) { if (measuring_) { bool autoStop = autoStop_.autoStop(measurement); if (autoStop) { LOG_INFO("Auto stop"); stopMeasurements(); return; } bool addPointSuccessful = session_.addPoint(measurement); if (!addPointSuccessful) { LOG_INFO("Maximum time of session reached - stopping"); stopMeasurements(); return; } } else { if (autoStart_.autoStart(measurement)) { LOG_INFO("Auto start"); startMeasurements(); return; } } }