rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
sensor.cpp
Go to the documentation of this file.
1#include "pch.h"
3
4// This struct represents one sensor in the registry.
5// It stores whether the sensor should use a mock value,
6// the value to use, and if not a pointer to the sensor that
7// can provide a real value.
8class SensorRegistryEntry {
9public:
10 const Sensor* getSensor() {
11 return m_sensor;
12 }
13
14 void setInvalidMockValue() {
15 m_useMock = true;
16 m_valid = false;
17 }
18
19 void setMockValue(float value, bool mockRedundant) {
20 m_mockValue = value;
21 m_useMock = true;
22 m_valid = true;
23 m_mockRedundant = mockRedundant;
24 }
25
26 void resetMock() {
27 m_useMock = false;
28 m_mockValue = 0.0f;
29 }
30
31 void reset() {
32 m_sensor = nullptr;
33 resetMock();
34 }
35
36 bool Register(Sensor* sensor) {
37 // If there's somebody already here - a consumer tried to double-register a sensor
38 if (m_sensor && m_sensor != sensor) {
39 // This sensor has already been registered. Don't re-register it.
40 firmwareError(ObdCode::CUSTOM_OBD_26, "Duplicate registration for sensor \"%s\"", sensor->getSensorName());
41 return false;
42 } else {
43
44#if VERBOSE_SENSOR_DEBUG
45 efiPrintf("Register sensor %s", sensor->getSensorName());
46#endif
47
48 // Put the sensor in the registry
49 m_sensor = sensor;
50 return true;
51 }
52 }
53
54 void unregister() {
55#if VERBOSE_SENSOR_DEBUG
56 if (m_sensor) {
57 efiPrintf("Unregistering sensor %s", m_sensor->getSensorName());
58 } else {
59 efiPrintf("Unregistering null sensor");
60 }
61#endif
62 m_sensor = nullptr;
63 }
64
65 SensorResult get() const {
66 // Check if mock
67 if (m_useMock) {
68 if (!m_valid) {
69 return unexpected;
70 }
71 return m_mockValue;
72 }
73
74 // Get the sensor out of the entry
75 const Sensor *s = m_sensor;
76 if (s) {
77 // If this sensor says it doesn't exist, return unexpected
78 if (!s->hasSensor()) {
79 return UnexpectedCode::Configuration;
80 }
81
82 // If we found the sensor, ask it for a result.
83 return s->get();
84 }
85
86 // We've exhausted all valid ways to return something - sensor not found.
87 return UnexpectedCode::Configuration;
88 }
89
90 void showInfo(const char* sensorName) const {
91 if (m_useMock) {
92 efiPrintf("Sensor \"%s\" mocked with value %.2f", sensorName, m_mockValue);
93 } else {
94 const auto sensor = m_sensor;
95
96 if (sensor) {
97 sensor->showInfo(sensorName);
98 } else {
99 efiPrintf("Sensor \"%s\" is not configured.", sensorName);
100 }
101 }
102 }
103
104 bool hasSensor() const {
105 return m_useMock || (m_sensor && m_sensor->hasSensor());
106 }
107
108 float getRaw() const {
109 const auto sensor = m_sensor;
110
111 if (sensor) {
112 return sensor->getRaw();
113 }
114
115 // We've exhausted all valid ways to return something - sensor not found.
116 return 0;
117 }
118
119 bool isRedundant() const {
120 const auto sensor = m_sensor;
121
122 if (sensor) {
123 return sensor->isRedundant();
124 }
125
126 if (m_useMock) {
127 return m_mockRedundant;
128 }
129
130 return false;
131 }
132
133private:
134 bool m_useMock = false;
135 bool m_valid = false;
136 bool m_mockRedundant = false;
137 float m_mockValue;
138 Sensor* m_sensor = nullptr;
139};
140
141static SensorRegistryEntry s_sensorRegistry[static_cast<size_t>(SensorType::PlaceholderLast)] = {};
142
144 return s_sensorRegistry[getIndex()].Register(this);
145}
146
148 s_sensorRegistry[getIndex()].unregister();
149}
150
151/*static*/ void Sensor::resetRegistry() {
152 // Clear all entries
153 for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
154 auto &entry = s_sensorRegistry[i];
155
156 entry.reset();
157 }
158}
159
160/*static*/ SensorRegistryEntry *Sensor::getEntryForType(SensorType type) {
161 size_t index = getIndex(type);
162 // Check that we didn't get garbage
163 if (index >= efi::size(s_sensorRegistry)) {
164 return nullptr;
165 }
166
167 return &s_sensorRegistry[index];
168}
169
171 auto entry = getEntryForType(type);
172 return entry ? entry->getSensor() : nullptr;
173}
174
175/**
176 * @returns NotNull: sensor result or UnexpectedCode::Configuration if sensor is not registered
177 */
179 const auto entry = getEntryForType(type);
180
181 // Check if this is a valid sensor entry
182 if (!entry) {
183 return UnexpectedCode::Configuration;
184 }
185
186 return entry->get();
187}
188
189/*static*/ float Sensor::getRaw(SensorType type) {
190 const auto entry = getEntryForType(type);
191
192 return entry ? entry->getRaw() : 0;
193}
194
195/*static*/ bool Sensor::isRedundant(SensorType type) {
196 const auto entry = getEntryForType(type);
197
198 return entry ? entry->isRedundant() : false;
199}
200
201/*static*/ bool Sensor::hasSensor(SensorType type) {
202 const auto entry = getEntryForType(type);
203
204 return entry ? entry->hasSensor() : false;
205}
206
208 auto entry = getEntryForType(type);
209
210 if (entry) {
211 entry->setInvalidMockValue();
212 }
213}
214
215/*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) {
216 auto entry = getEntryForType(type);
217
218 if (entry) {
219 entry->setMockValue(value, mockRedundant);
220 }
221}
222
223/*static*/ void Sensor::resetMockValue(SensorType type) {
224 auto entry = getEntryForType(type);
225
226 if (entry) {
227 entry->resetMock();
228 }
229}
230
231/*static*/ void Sensor::resetAllMocks() {
232 // Reset all mocks
233 for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
234 s_sensorRegistry[i].resetMock();
235 }
236}
237
238/*static*/ const char* Sensor::getSensorName(SensorType type) {
239 return getSensorType(type);
240}
241
242/*static*/ bool Sensor::s_inhibitSensorTimeouts = false;
243
244/*static*/ void Sensor::inhibitTimeouts(bool inhibit) {
246}
247
248// Print information about all sensors
249/*static*/ void Sensor::showAllSensorInfo() {
250 for (size_t i = 1; i < efi::size(s_sensorRegistry); i++) {
251 auto& entry = s_sensorRegistry[i];
252 const char* name = getSensorType((SensorType)i);
253
254 entry.showInfo(name);
255 }
256}
257
258// Print information about a particular sensor
259/*static*/ void Sensor::showInfo(SensorType type) {
260 auto entry = getEntryForType(type);
261
262 if (entry) {
263 entry->showInfo(getSensorName(type));
264 }
265}
266
267/**
268 * this is definitely not the fastest implementation possible but good enough for now?
269 * todo: some sort of hashmap in the future?
270 */
272 using namespace rusefi::stringutil;
273
274 for (size_t i = 0;i < efi::size(s_sensorRegistry); i++) {
275 SensorType type = (SensorType)i;
276 const char *sensorName = getSensorType(type);
277 if (strEqualCaseInsensitive(sensorName, name)) {
278 return type;
279 }
280 }
281
282 return SensorType::Invalid;
283}
const char * getSensorType(SensorType value)
void showInfo(const char *sensorName) const override
static bool isRedundant(SensorType type)
Definition sensor.cpp:195
static void setMockValue(SensorType type, float value, bool mockRedundant=false)
Definition sensor.cpp:215
static void resetMockValue(SensorType type)
Definition sensor.cpp:223
static SensorRegistryEntry * getEntryForType(SensorType type)
Definition sensor.cpp:160
bool Register()
Definition sensor.cpp:143
static void setInvalidMockValue(SensorType type)
Definition sensor.cpp:207
virtual bool hasSensor() const
Definition sensor.h:145
static const Sensor * getSensorOfType(SensorType type)
Definition sensor.cpp:170
virtual SensorResult get() const =0
virtual bool isRedundant() const
Definition sensor.h:159
virtual float getRaw() const
Definition sensor.h:152
static float getRaw(SensorType type)
Definition sensor.cpp:189
static void showAllSensorInfo()
Definition sensor.cpp:249
virtual void showInfo(const char *sensorName) const =0
static void inhibitTimeouts(bool inhibit)
Definition sensor.cpp:244
static void resetAllMocks()
Definition sensor.cpp:231
static bool hasSensor(SensorType type)
Definition sensor.cpp:201
static void resetRegistry()
Definition sensor.cpp:151
static bool s_inhibitSensorTimeouts
Definition sensor.h:175
const char * getSensorName() const
Definition sensor.h:134
static SensorResult get(SensorType type)
Definition sensor.cpp:178
SensorType type() const
Definition sensor.h:166
void unregister()
Definition sensor.cpp:147
constexpr size_t getIndex()
Definition sensor.h:181
void firmwareError(ObdCode code, const char *fmt,...)
static Lps25Sensor sensor(device)
@ CUSTOM_OBD_26
SensorType findSensorTypeByName(const char *name)
Definition sensor.cpp:271
static SensorRegistryEntry s_sensorRegistry[static_cast< size_t >(SensorType::PlaceholderLast)]
Definition sensor.cpp:141
expected< float > SensorResult
Definition sensor.h:50
SensorType
Definition sensor_type.h:18