2019-09-21 11:33:38 -07:00
|
|
|
/**
|
|
|
|
* @file stored_value_sensor.h
|
|
|
|
* @brief Base class for a sensor that has its value asynchronously
|
|
|
|
* set, then later retrieved by a consumer.
|
|
|
|
*
|
|
|
|
* @date September 12, 2019
|
2020-01-12 00:25:23 -08:00
|
|
|
* @author Matthew Kennedy, (c) 2019-2020
|
2019-09-21 11:33:38 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "sensor.h"
|
|
|
|
|
2020-01-12 00:25:23 -08:00
|
|
|
#include "efitime.h"
|
|
|
|
|
2019-09-21 11:33:38 -07:00
|
|
|
/**
|
|
|
|
* @brief Base class for sensors that compute a value on one thread, and want
|
|
|
|
* to make it available to consumers asynchronously.
|
|
|
|
*
|
|
|
|
* Common examples include sensors that have to do heavy lifting to produce
|
|
|
|
* a reading, and don't want to perform that conversion at the time of
|
|
|
|
* consumption.
|
|
|
|
*
|
|
|
|
* To use this class, create a class for your sensor that inherits StoredValueSensor,
|
|
|
|
* and call Invalidate() and SetValidValue(float) as appropriate when readings are available
|
|
|
|
* (or known to be invalid) for your sensor.
|
|
|
|
*
|
|
|
|
* Consumers will retrieve the last set (or invalidated) value.
|
|
|
|
*/
|
|
|
|
class StoredValueSensor : public Sensor {
|
|
|
|
public:
|
2020-03-29 16:06:03 -07:00
|
|
|
SensorResult get() const final override {
|
2019-09-21 11:33:38 -07:00
|
|
|
bool valid = m_isValid;
|
|
|
|
float value = m_value;
|
|
|
|
|
2020-01-12 00:25:23 -08:00
|
|
|
if (!valid) {
|
2020-04-19 05:37:43 -07:00
|
|
|
return unexpected;
|
2020-01-12 00:25:23 -08:00
|
|
|
}
|
|
|
|
|
2021-08-15 13:04:58 -07:00
|
|
|
// Timeouts are disabled, return last value
|
|
|
|
if (Sensor::s_inhibitSensorTimeouts) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-09-03 13:58:10 -07:00
|
|
|
if (m_timeoutPeriod != 0) { // zero m_timeoutPeriod means value lasts forever
|
|
|
|
if (getTimeNowNt() - m_timeoutPeriod > m_lastUpdate) {
|
|
|
|
return unexpected;
|
|
|
|
}
|
2020-01-12 00:25:23 -08:00
|
|
|
}
|
|
|
|
|
2020-04-18 22:53:04 -07:00
|
|
|
return value;
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2020-09-03 13:58:10 -07:00
|
|
|
StoredValueSensor(SensorType type, efitick_t timeoutNt)
|
2019-09-21 11:33:38 -07:00
|
|
|
: Sensor(type)
|
2020-01-12 00:25:23 -08:00
|
|
|
, m_timeoutPeriod(timeoutNt)
|
2019-12-16 19:45:46 -08:00
|
|
|
{
|
|
|
|
}
|
2019-09-21 11:33:38 -07:00
|
|
|
|
|
|
|
// Invalidate the stored value.
|
|
|
|
void invalidate() {
|
|
|
|
m_isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A new reading is available: set and validate a new value for the sensor.
|
2020-01-12 00:25:23 -08:00
|
|
|
void setValidValue(float value, efitick_t timestamp) {
|
2019-09-21 11:33:38 -07:00
|
|
|
// Set value before valid - so we don't briefly have the valid bit set on an invalid value
|
|
|
|
m_value = value;
|
|
|
|
m_isValid = true;
|
2020-01-12 00:25:23 -08:00
|
|
|
m_lastUpdate = timestamp;
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2021-10-24 16:04:47 -07:00
|
|
|
void showInfo(const char*) const override { }
|
|
|
|
|
2019-09-21 11:33:38 -07:00
|
|
|
private:
|
|
|
|
bool m_isValid = false;
|
|
|
|
float m_value = 0.0f;
|
2020-01-12 00:25:23 -08:00
|
|
|
|
|
|
|
const efitick_t m_timeoutPeriod;
|
|
|
|
efitick_t m_lastUpdate = 0;
|
2019-09-21 11:33:38 -07:00
|
|
|
};
|