diff --git a/code/espurna/sensor.cpp b/code/espurna/sensor.cpp index 3af5fdce..2a5ca470 100644 --- a/code/espurna/sensor.cpp +++ b/code/espurna/sensor.cpp @@ -1746,6 +1746,7 @@ namespace internal { namespace { std::vector magnitudes; +bool real_time { sensor::build::realTimeValues() }; using ReadHandlers = std::forward_list; ReadHandlers read_handlers; @@ -1870,6 +1871,14 @@ Value safe_value(size_t index, T&& retrieve) { return out; } +void prefer_real_time_values(bool real_time) { + internal::real_time = real_time; +} + +bool prefer_real_time_values() { + return internal::real_time; +} + Value safe_value_last(size_t index) { return safe_value( index, @@ -1902,9 +1911,8 @@ enum class State { namespace internal { std::vector sensors; -size_t read_count; -bool real_time { build::realTimeValues() }; +size_t read_count; size_t report_every { build::reportEvery() }; duration::Seconds read_interval { build::readInterval() }; @@ -1912,38 +1920,18 @@ duration::Seconds init_interval { build::initInterval() }; } // namespace internal -bool realTimeValues() { - return internal::real_time; -} - -void realTimeValues(bool value) { - internal::real_time = value; -} - size_t reportEvery() { return internal::report_every; } -void reportEvery(size_t value) { - internal::report_every = value; -} - duration::Seconds readInterval() { return internal::read_interval; } -void readInterval(duration::Seconds value) { - internal::read_interval = value; -} - duration::Seconds initInterval() { return internal::init_interval; } -void initInterval(duration::Seconds value) { - internal::init_interval = value; -} - template void forEachInstance(T&& callback) { for (auto sensor : internal::sensors) { @@ -1959,28 +1947,6 @@ size_t count() { return internal::sensors.size(); } -void tick() { - for (auto sensor : internal::sensors) { - sensor->tick(); - } -} - -void pre() { - for (auto sensor : internal::sensors) { - sensor->pre(); - if (!sensor->status()) { - DEBUG_MSG_P(PSTR("[SENSOR] Could not read from %s (%s)\n"), - sensor->description().c_str(), error(sensor->error()).c_str()); - } - } -} - -void post() { - for (auto sensor : internal::sensors) { - sensor->post(); - } -} - // Registers available sensor classes. // // Notice that *every* available sensor (*_SUPPORT set to 1) is queued for initialization. @@ -3405,7 +3371,7 @@ void settings(JsonObject& root) { }} }); - root[FPSTR(settings::keys::RealTimeValues)] = realTimeValues(); + root[FPSTR(settings::keys::RealTimeValues)] = magnitude::prefer_real_time_values(); root[FPSTR(settings::keys::ReadInterval)] = readInterval().count(); root[FPSTR(settings::keys::InitInterval)] = initInterval().count(); @@ -3604,7 +3570,7 @@ void setup() { return tryHandle(request, type, [&](const Magnitude& magnitude) { request.send(magnitude::format(magnitude, - realTimeValues() ? magnitude.last : magnitude.reported)); + magnitude::prefer_real_time_values() ? magnitude.last : magnitude.reported)); return true; }); }; @@ -3825,7 +3791,7 @@ void suspend() { void resume() { internal::last_init = TimeSource::now(); internal::last_reading = TimeSource::now(); - internal::read_count = 1; + internal::read_count = 0; magnitude::forEachInstance( [](sensor::Magnitude& instance) { @@ -3894,6 +3860,43 @@ bool try_init() { return false; } +// ----------------------------------------------------------------------------- +// Magnitude processing +// ----------------------------------------------------------------------------- + +void tick() { + for (auto sensor : internal::sensors) { + sensor->tick(); + } +} + +void pre() { + for (auto sensor : internal::sensors) { + sensor->pre(); + if (!sensor->status()) { + DEBUG_MSG_P(PSTR("[SENSOR] Could not read from %s (%s)\n"), + sensor->description().c_str(), error(sensor->error()).c_str()); + } + } +} + +void post() { + for (auto sensor : internal::sensors) { + sensor->post(); + } +} + +void reset_init(duration::Seconds init_interval) { + internal::init_interval = init_interval; +} + +void reset_report(duration::Seconds read_interval, size_t report_every) { + internal::read_interval = read_interval; + internal::report_every = report_every; + internal::last_reading = TimeSource::now(); + internal::read_count = 0; +} + bool ready_to_read() { const auto timestamp = TimeSource::now(); if (timestamp - internal::last_reading > readInterval()) { @@ -4074,10 +4077,15 @@ void configure() { // TODO: implement scheduling in the sensor itself. // allow reads faster than 1sec, not just internal ones via tick() // allow 'manual' sensors that may be triggered programatically - readInterval(sensor::settings::readInterval()); - initInterval(sensor::settings::initInterval()); - reportEvery(sensor::settings::reportEvery()); - realTimeValues(sensor::settings::realTimeValues()); + reset_report( + sensor::settings::readInterval(), + sensor::settings::reportEvery()); + + // Initialization interval is also shared + reset_init(sensor::settings::initInterval()); + + // Generic 'get magnitude value' API calls prefer latest values over the reported ones + magnitude::prefer_real_time_values(sensor::settings::realTimeValues()); // TODO: something more generic? energy is an accumulating value, only allow for similar ones? // TODO: move to an external module? @@ -4095,9 +4103,7 @@ void configure() { } // Some filters must be able store up to a certain amount of readings. - if (magnitude.filter->capacity() != reportEvery()) { - magnitude.filter->resize(reportEvery()); - } + magnitude.filter->resize(reportEvery()); // process emon-specific settings first. ensure that settings use global index and we access sensor with the local one if (isEmon(magnitude.sensor) && magnitude::traits::ratio_supported(magnitude.type)) { @@ -4260,9 +4266,10 @@ espurna::sensor::Value magnitudeReportValue(unsigned char index) { } espurna::sensor::Value magnitudeValue(unsigned char index) { - return espurna::sensor::realTimeValues() - ? espurna::sensor::magnitude::safe_value_last(index) - : espurna::sensor::magnitude::safe_value_reported(index); + using namespace espurna::sensor::magnitude; + return prefer_real_time_values() + ? safe_value_last(index) + : safe_value_reported(index); } String magnitudeDescription(unsigned char index) {