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 // Put the sensor in the registry
44 m_sensor = sensor;
45 return true;
46 }
47 }
48
49 void unregister() {
50 m_sensor = nullptr;
51 }
52
53 SensorResult get() const {
54 // Check if mock
55 if (m_useMock) {
56 if (!m_valid) {
57 return unexpected;
58 }
59 return m_mockValue;
60 }
61
62 // Get the sensor out of the entry
63 const Sensor *s = m_sensor;
64 if (s) {
65 // If this sensor says it doesn't exist, return unexpected
66 if (!s->hasSensor()) {
67 return UnexpectedCode::Configuration;
68 }
69
70 // If we found the sensor, ask it for a result.
71 return s->get();
72 }
73
74 // We've exhausted all valid ways to return something - sensor not found.
75 return UnexpectedCode::Configuration;
76 }
77
78 void showInfo(const char* sensorName) const {
79 if (m_useMock) {
80 efiPrintf("Sensor \"%s\" mocked with value %.2f", sensorName, m_mockValue);
81 } else {
82 const auto sensor = m_sensor;
83
84 if (sensor) {
85 sensor->showInfo(sensorName);
86 } else {
87 efiPrintf("Sensor \"%s\" is not configured.", sensorName);
88 }
89 }
90 }
91
92 bool hasSensor() const {
93 return m_useMock || (m_sensor && m_sensor->hasSensor());
94 }
95
96 float getRaw() const {
97 const auto sensor = m_sensor;
98
99 if (sensor) {
100 return sensor->getRaw();
101 }
102
103 // We've exhausted all valid ways to return something - sensor not found.
104 return 0;
105 }
106
107 bool isRedundant() const {
108 const auto sensor = m_sensor;
109
110 if (sensor) {
111 return sensor->isRedundant();
112 }
113
114 if (m_useMock) {
115 return m_mockRedundant;
116 }
117
118 return false;
119 }
120
121private:
122 bool m_useMock = false;
123 bool m_valid = false;
124 bool m_mockRedundant = false;
125 float m_mockValue;
126 Sensor* m_sensor = nullptr;
127};
128
129static SensorRegistryEntry s_sensorRegistry[static_cast<size_t>(SensorType::PlaceholderLast)] = {};
130
132 return s_sensorRegistry[getIndex()].Register(this);
133}
134
136 s_sensorRegistry[getIndex()].unregister();
137}
138
139/*static*/ void Sensor::resetRegistry() {
140 // Clear all entries
141 for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
142 auto &entry = s_sensorRegistry[i];
143
144 entry.reset();
145 }
146}
147
148/*static*/ SensorRegistryEntry *Sensor::getEntryForType(SensorType type) {
149 size_t index = getIndex(type);
150 // Check that we didn't get garbage
151 if (index >= efi::size(s_sensorRegistry)) {
152 return nullptr;
153 }
154
155 return &s_sensorRegistry[index];
156}
157
159 auto entry = getEntryForType(type);
160 return entry ? entry->getSensor() : nullptr;
161}
162
163/**
164 * @returns NotNull: sensor result or UnexpectedCode::Configuration if sensor is not registered
165 */
167 const auto entry = getEntryForType(type);
168
169 // Check if this is a valid sensor entry
170 if (!entry) {
171 return UnexpectedCode::Configuration;
172 }
173
174 return entry->get();
175}
176
177/*static*/ float Sensor::getRaw(SensorType type) {
178 const auto entry = getEntryForType(type);
179
180 return entry ? entry->getRaw() : 0;
181}
182
183/*static*/ bool Sensor::isRedundant(SensorType type) {
184 const auto entry = getEntryForType(type);
185
186 return entry ? entry->isRedundant() : false;
187}
188
189/*static*/ bool Sensor::hasSensor(SensorType type) {
190 const auto entry = getEntryForType(type);
191
192 return entry ? entry->hasSensor() : false;
193}
194
196 auto entry = getEntryForType(type);
197
198 if (entry) {
199 entry->setInvalidMockValue();
200 }
201}
202
203/*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) {
204 auto entry = getEntryForType(type);
205
206 if (entry) {
207 entry->setMockValue(value, mockRedundant);
208 }
209}
210
211/*static*/ void Sensor::resetMockValue(SensorType type) {
212 auto entry = getEntryForType(type);
213
214 if (entry) {
215 entry->resetMock();
216 }
217}
218
219/*static*/ void Sensor::resetAllMocks() {
220 // Reset all mocks
221 for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
222 s_sensorRegistry[i].resetMock();
223 }
224}
225
226/*static*/ const char* Sensor::getSensorName(SensorType type) {
227 return getSensorType(type);
228}
229
230/*static*/ bool Sensor::s_inhibitSensorTimeouts = false;
231
232/*static*/ void Sensor::inhibitTimeouts(bool inhibit) {
234}
235
236// Print information about all sensors
237/*static*/ void Sensor::showAllSensorInfo() {
238 for (size_t i = 1; i < efi::size(s_sensorRegistry); i++) {
239 auto& entry = s_sensorRegistry[i];
240 const char* name = getSensorType((SensorType)i);
241
242 entry.showInfo(name);
243 }
244}
245
246// Print information about a particular sensor
247/*static*/ void Sensor::showInfo(SensorType type) {
248 auto entry = getEntryForType(type);
249
250 if (entry) {
251 entry->showInfo(getSensorName(type));
252 }
253}
254
255/**
256 * this is definitely not the fastest implementation possible but good enough for now?
257 * todo: some sort of hashmap in the future?
258 */
260 using namespace rusefi::stringutil;
261
262 for (size_t i = 0;i < efi::size(s_sensorRegistry); i++) {
263 SensorType type = (SensorType)i;
264 const char *sensorName = getSensorType(type);
265 if (strEqualCaseInsensitive(sensorName, name)) {
266 return type;
267 }
268 }
269
270 return SensorType::Invalid;
271}
const char * getSensorType(SensorType value)
void showInfo(const char *sensorName) const override
static bool isRedundant(SensorType type)
Definition sensor.cpp:183
static void setMockValue(SensorType type, float value, bool mockRedundant=false)
Definition sensor.cpp:203
static void resetMockValue(SensorType type)
Definition sensor.cpp:211
static SensorRegistryEntry * getEntryForType(SensorType type)
Definition sensor.cpp:148
bool Register()
Definition sensor.cpp:131
static void setInvalidMockValue(SensorType type)
Definition sensor.cpp:195
virtual bool hasSensor() const
Definition sensor.h:141
static const Sensor * getSensorOfType(SensorType type)
Definition sensor.cpp:158
virtual SensorResult get() const =0
virtual bool isRedundant() const
Definition sensor.h:155
virtual float getRaw() const
Definition sensor.h:148
static float getRaw(SensorType type)
Definition sensor.cpp:177
static void showAllSensorInfo()
Definition sensor.cpp:237
virtual void showInfo(const char *sensorName) const =0
static void inhibitTimeouts(bool inhibit)
Definition sensor.cpp:232
static void resetAllMocks()
Definition sensor.cpp:219
static bool hasSensor(SensorType type)
Definition sensor.cpp:189
static void resetRegistry()
Definition sensor.cpp:139
static bool s_inhibitSensorTimeouts
Definition sensor.h:171
const char * getSensorName() const
Definition sensor.h:130
static SensorResult get(SensorType type)
Definition sensor.cpp:166
SensorType type() const
Definition sensor.h:162
void unregister()
Definition sensor.cpp:135
constexpr size_t getIndex()
Definition sensor.h:177
void firmwareError(ObdCode code, const char *fmt,...)
static Lps25Sensor sensor(device)
@ CUSTOM_OBD_26
SensorType findSensorTypeByName(const char *name)
Definition sensor.cpp:259
static SensorRegistryEntry s_sensorRegistry[static_cast< size_t >(SensorType::PlaceholderLast)]
Definition sensor.cpp:129
expected< float > SensorResult
Definition sensor.h:46
SensorType
Definition sensor_type.h:18