blob: 70214303cdf1918843279ca4d1a7b5e21b3b0948 [file] [log] [blame]
James Feist8fd8a582018-11-16 11:10:46 -08001#pragma once
Bruce Lee1263c3d2021-06-04 15:16:33 +08002#include "dbus-sensor_config.h"
James Feist8fd8a582018-11-16 11:10:46 -08003
Ed Tanous6cb732a2021-02-18 15:33:51 -08004#include <SensorPaths.hpp>
Ed Tanous8a57ec02020-10-09 12:46:52 -07005#include <Thresholds.hpp>
6#include <Utils.hpp>
James Feist38fb5982020-05-28 10:09:54 -07007#include <sdbusplus/asio/object_server.hpp>
8
Patrick Venturefd6ba732019-10-31 14:27:39 -07009#include <limits>
10#include <memory>
Patrick Venturefd6ba732019-10-31 14:27:39 -070011#include <string>
12#include <vector>
James Feist8fd8a582018-11-16 11:10:46 -080013
James Feist1169eb42018-10-31 10:08:47 -070014constexpr size_t sensorFailedPollTimeMs = 5000;
James Feista5e58722019-04-22 14:43:11 -070015
Josh Lehan3bcd8232020-10-29 00:22:12 -070016// Enable useful logging with sensor instrumentation
17// This is intentionally not DEBUG, avoid clash with usage in .cpp files
18constexpr bool enableInstrumentation = false;
19
James Feista5e58722019-04-22 14:43:11 -070020constexpr const char* sensorValueInterface = "xyz.openbmc_project.Sensor.Value";
Jie Yang3291b9c2021-07-29 14:46:51 -070021constexpr const char* valueMutabilityInterfaceName =
22 "xyz.openbmc_project.Sensor.ValueMutability";
James Feist67601bd2020-06-16 17:14:44 -070023constexpr const char* availableInterfaceName =
24 "xyz.openbmc_project.State.Decorator.Availability";
James Feist961bf092020-07-01 16:38:12 -070025constexpr const char* operationalInterfaceName =
26 "xyz.openbmc_project.State.Decorator.OperationalStatus";
27constexpr const size_t errorThreshold = 5;
28
Josh Lehan3bcd8232020-10-29 00:22:12 -070029struct SensorInstrumentation
30{
31 // These are for instrumentation for debugging
32 int numCollectsGood = 0;
33 int numCollectsMiss = 0;
34 int numStreakGreats = 0;
35 int numStreakMisses = 0;
36 double minCollected = 0.0;
37 double maxCollected = 0.0;
38};
39
James Feist8fd8a582018-11-16 11:10:46 -080040struct Sensor
41{
James Feist930fcde2019-05-28 12:58:43 -070042 Sensor(const std::string& name,
James Feistd8705872019-02-08 13:26:09 -080043 std::vector<thresholds::Threshold>&& thresholdData,
44 const std::string& configurationPath, const std::string& objectType,
Jie Yang3291b9c2021-07-29 14:46:51 -070045 bool isSettable, bool isMutable, const double max, const double min,
James Feiste3338522020-09-15 15:40:30 -070046 std::shared_ptr<sdbusplus::asio::connection>& conn,
James Feist961bf092020-07-01 16:38:12 -070047 PowerState readState = PowerState::always) :
Ed Tanous6cb732a2021-02-18 15:33:51 -080048 name(sensor_paths::escapePathForDbus(name)),
James Feist930fcde2019-05-28 12:58:43 -070049 configurationPath(configurationPath), objectType(objectType),
Jie Yang3291b9c2021-07-29 14:46:51 -070050 isSensorSettable(isSettable), isValueMutable(isMutable), maxValue(max),
51 minValue(min), thresholds(std::move(thresholdData)),
Josh Lehan883fb3a2020-02-27 14:41:39 -080052 hysteresisTrigger((max - min) * 0.01),
James Feiste3338522020-09-15 15:40:30 -070053 hysteresisPublish((max - min) * 0.0001), dbusConnection(conn),
Josh Lehan3bcd8232020-10-29 00:22:12 -070054 readState(readState), errCount(0),
55 instrumentation(enableInstrumentation
56 ? std::make_unique<SensorInstrumentation>()
57 : nullptr)
James Feist38fb5982020-05-28 10:09:54 -070058 {}
James Feist8fd8a582018-11-16 11:10:46 -080059 virtual ~Sensor() = default;
James Feistce3fca42018-11-21 12:58:24 -080060 virtual void checkThresholds(void) = 0;
James Feistdc6c55f2018-10-31 12:53:20 -070061 std::string name;
James Feistce3fca42018-11-21 12:58:24 -080062 std::string configurationPath;
63 std::string objectType;
Bruce Lee1263c3d2021-06-04 15:16:33 +080064 bool isSensorSettable;
Jie Yang3291b9c2021-07-29 14:46:51 -070065
66 /* A flag indicates if properties of xyz.openbmc_project.Sensor.Value
67 * interface are mutable. If mutable, then
68 * xyz.openbmc_project.Sensor.ValueMutability interface will be
69 * instantiated.
70 */
71 bool isValueMutable;
James Feistce3fca42018-11-21 12:58:24 -080072 double maxValue;
73 double minValue;
James Feist8fd8a582018-11-16 11:10:46 -080074 std::vector<thresholds::Threshold> thresholds;
75 std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInterface;
James Feist078f2322019-03-08 11:09:05 -080076 std::shared_ptr<sdbusplus::asio::dbus_interface> association;
James Feist67601bd2020-06-16 17:14:44 -070077 std::shared_ptr<sdbusplus::asio::dbus_interface> availableInterface;
James Feist961bf092020-07-01 16:38:12 -070078 std::shared_ptr<sdbusplus::asio::dbus_interface> operationalInterface;
Jie Yang3291b9c2021-07-29 14:46:51 -070079 std::shared_ptr<sdbusplus::asio::dbus_interface> valueMutabilityInterface;
James Feist8fd8a582018-11-16 11:10:46 -080080 double value = std::numeric_limits<double>::quiet_NaN();
Zhikui Rend3da1282020-09-11 17:02:01 -070081 double rawValue = std::numeric_limits<double>::quiet_NaN();
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +053082 bool overriddenState = false;
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053083 bool internalSet = false;
Josh Lehan883fb3a2020-02-27 14:41:39 -080084 double hysteresisTrigger;
85 double hysteresisPublish;
James Feiste3338522020-09-15 15:40:30 -070086 std::shared_ptr<sdbusplus::asio::connection> dbusConnection;
James Feist961bf092020-07-01 16:38:12 -070087 PowerState readState;
88 size_t errCount;
Josh Lehan3bcd8232020-10-29 00:22:12 -070089 std::unique_ptr<SensorInstrumentation> instrumentation;
90
Josh Lehanffe18342021-03-17 13:29:51 -070091 // This member variable provides a hook that can be used to receive
92 // notification whenever this Sensor's value is externally set via D-Bus.
93 // If interested, assign your own lambda to this variable, during
94 // construction of your Sensor subclass. See ExternalSensor for example.
95 std::function<void()> externalSetHook;
96
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053097 struct ThresholdProperty
98 {
99 thresholds::Level level;
100 thresholds::Direction direction;
101 uint8_t sevOrder;
102 const char* levelProperty;
103 const char* alarmProperty;
104 const char* dirOrder;
105 };
106
Jayashree Dhanapal091c92c2022-01-11 14:55:20 +0530107 constexpr static std::array<ThresholdProperty, 8> thresProp = {
Jayashree Dhanapal45f27022021-12-07 12:56:35 +0530108 {{thresholds::Level::WARNING, thresholds::Direction::HIGH, 0,
109 "WarningHigh", "WarningAlarmHigh", "greater than"},
110 {thresholds::Level::WARNING, thresholds::Direction::LOW, 0,
111 "WarningLow", "WarningAlarmLow", "less than"},
112 {thresholds::Level::CRITICAL, thresholds::Direction::HIGH, 1,
113 "CriticalHigh", "CriticalAlarmHigh", "greater than"},
114 {thresholds::Level::CRITICAL, thresholds::Direction::LOW, 1,
Jayashree Dhanapal091c92c2022-01-11 14:55:20 +0530115 "CriticalLow", "CriticalAlarmLow", "less than"},
116 {thresholds::Level::SOFTSHUTDOWN, thresholds::Direction::HIGH, 2,
117 "SoftShutdownHigh", "SoftShutdownAlarmHigh", "greater than"},
118 {thresholds::Level::SOFTSHUTDOWN, thresholds::Direction::LOW, 2,
119 "SoftShutdownLow", "SoftShutdownAlarmLow", "less than"},
120 {thresholds::Level::HARDSHUTDOWN, thresholds::Direction::HIGH, 3,
121 "HardShutdownHigh", "HardShutdownAlarmHigh", "greater than"},
122 {thresholds::Level::HARDSHUTDOWN, thresholds::Direction::LOW, 3,
123 "HardShutdownLow", "HardShutdownAlarmLow", "less than"}}};
Jayashree Dhanapal45f27022021-12-07 12:56:35 +0530124
Jayashree Dhanapal091c92c2022-01-11 14:55:20 +0530125 std::array<std::shared_ptr<sdbusplus::asio::dbus_interface>, 4>
Jayashree Dhanapal56678082022-01-04 17:27:20 +0530126 thresholdInterfaces;
127
128 std::shared_ptr<sdbusplus::asio::dbus_interface>
129 getThresholdInterface(thresholds::Level lev)
130 {
131 size_t index = static_cast<size_t>(lev);
132 if (index >= thresholdInterfaces.size())
133 {
134 std::cout << "Unknown threshold level \n";
135 return nullptr;
136 }
137 std::shared_ptr<sdbusplus::asio::dbus_interface> interface =
138 thresholdInterfaces[index];
139 return interface;
140 }
141
Josh Lehan3bcd8232020-10-29 00:22:12 -0700142 void updateInstrumentation(double readValue)
143 {
144 // Do nothing if this feature is not enabled
145 if constexpr (!enableInstrumentation)
146 {
147 return;
148 }
149 if (!instrumentation)
150 {
151 return;
152 }
153
154 // Save some typing
155 auto& inst = *instrumentation;
156
157 // Show constants if first reading (even if unsuccessful)
158 if ((inst.numCollectsGood == 0) && (inst.numCollectsMiss == 0))
159 {
160 std::cerr << "Sensor " << name << ": Configuration min=" << minValue
161 << ", max=" << maxValue << ", type=" << objectType
162 << ", path=" << configurationPath << "\n";
163 }
164
165 // Sensors can use "nan" to indicate unavailable reading
166 if (!std::isfinite(readValue))
167 {
168 // Only show this if beginning a new streak
169 if (inst.numStreakMisses == 0)
170 {
171 std::cerr << "Sensor " << name
172 << ": Missing reading, Reading counts good="
173 << inst.numCollectsGood
174 << ", miss=" << inst.numCollectsMiss
175 << ", Prior good streak=" << inst.numStreakGreats
176 << "\n";
177 }
178
179 inst.numStreakGreats = 0;
180 ++(inst.numCollectsMiss);
181 ++(inst.numStreakMisses);
182
183 return;
184 }
185
186 // Only show this if beginning a new streak and not the first time
187 if ((inst.numStreakGreats == 0) && (inst.numCollectsGood != 0))
188 {
189 std::cerr << "Sensor " << name
190 << ": Recovered reading, Reading counts good="
191 << inst.numCollectsGood
192 << ", miss=" << inst.numCollectsMiss
193 << ", Prior miss streak=" << inst.numStreakMisses << "\n";
194 }
195
196 // Initialize min/max if the first successful reading
197 if (inst.numCollectsGood == 0)
198 {
199 std::cerr << "Sensor " << name << ": First reading=" << readValue
200 << "\n";
201
202 inst.minCollected = readValue;
203 inst.maxCollected = readValue;
204 }
205
206 inst.numStreakMisses = 0;
207 ++(inst.numCollectsGood);
208 ++(inst.numStreakGreats);
209
210 // Only provide subsequent output if new min/max established
211 if (readValue < inst.minCollected)
212 {
213 std::cerr << "Sensor " << name << ": Lowest reading=" << readValue
214 << "\n";
215
216 inst.minCollected = readValue;
217 }
218
219 if (readValue > inst.maxCollected)
220 {
221 std::cerr << "Sensor " << name << ": Highest reading=" << readValue
222 << "\n";
223
224 inst.maxCollected = readValue;
225 }
226 }
James Feistce3fca42018-11-21 12:58:24 -0800227
James Feistd8705872019-02-08 13:26:09 -0800228 int setSensorValue(const double& newValue, double& oldValue)
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +0530229 {
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +0530230 if (!internalSet)
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +0530231 {
Bruce Lee1263c3d2021-06-04 15:16:33 +0800232 if (insecureSensorOverride == false)
233 { // insecure sesnor override.
234 if (isSensorSettable == false)
235 { // sensor is not settable.
236 if (getManufacturingMode() == false)
237 { // manufacture mode is not enable.
Patrick Williams379b1132021-09-02 05:42:25 -0500238 std::cerr << "Sensor " << name
239 << ": Not allowed to set property value.\n";
240 return -EACCES;
Bruce Lee1263c3d2021-06-04 15:16:33 +0800241 }
242 }
243 }
244
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +0530245 oldValue = newValue;
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530246 overriddenState = true;
247 // check thresholds for external set
248 value = newValue;
249 checkThresholds();
Josh Lehanffe18342021-03-17 13:29:51 -0700250
251 // Trigger the hook, as an external set has just happened
252 if (externalSetHook)
253 {
254 externalSetHook();
255 }
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +0530256 }
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530257 else if (!overriddenState)
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +0530258 {
259 oldValue = newValue;
260 }
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +0530261 return 1;
262 }
James Feistce3fca42018-11-21 12:58:24 -0800263
264 void
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800265 setInitialProperties(std::shared_ptr<sdbusplus::asio::connection>& conn,
Zev Weiss6b6891c2021-04-22 02:46:21 -0500266 const std::string& unit,
Ed Tanous8a57ec02020-10-09 12:46:52 -0700267 const std::string& label = std::string(),
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800268 size_t thresholdSize = 0)
James Feistce3fca42018-11-21 12:58:24 -0800269 {
James Feist961bf092020-07-01 16:38:12 -0700270 if (readState == PowerState::on || readState == PowerState::biosPost)
271 {
272 setupPowerMatch(conn);
273 }
274
James Feist82bac4c2019-03-11 11:16:53 -0700275 createAssociation(association, configurationPath);
AppaRao Pulic82213c2020-02-27 01:24:58 +0530276
Zev Weiss6b6891c2021-04-22 02:46:21 -0500277 sensorInterface->register_property("Unit", unit);
James Feistce3fca42018-11-21 12:58:24 -0800278 sensorInterface->register_property("MaxValue", maxValue);
279 sensorInterface->register_property("MinValue", minValue);
280 sensorInterface->register_property(
James Feistd8705872019-02-08 13:26:09 -0800281 "Value", value, [&](const double& newValue, double& oldValue) {
James Feistce3fca42018-11-21 12:58:24 -0800282 return setSensorValue(newValue, oldValue);
283 });
James Feistd8705872019-02-08 13:26:09 -0800284 for (auto& threshold : thresholds)
James Feistce3fca42018-11-21 12:58:24 -0800285 {
Rashmica Gupta1e34cec2021-08-31 16:47:39 +1000286 if (std::isnan(threshold.hysteresis))
287 {
288 threshold.hysteresis = hysteresisTrigger;
289 }
Jayashree Dhanapal56678082022-01-04 17:27:20 +0530290 if (!(thresholds::findOrder(threshold.level, threshold.direction)))
James Feistce3fca42018-11-21 12:58:24 -0800291 {
James Feistce3fca42018-11-21 12:58:24 -0800292 continue;
293 }
Jayashree Dhanapal56678082022-01-04 17:27:20 +0530294 std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
295 getThresholdInterface(threshold.level);
296
James Feistce3fca42018-11-21 12:58:24 -0800297 if (!iface)
298 {
299 std::cout << "trying to set uninitialized interface\n";
300 continue;
301 }
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800302
Jayashree Dhanapal45f27022021-12-07 12:56:35 +0530303 std::string level =
304 propertyLevel(threshold.level, threshold.direction);
305 std::string alarm =
306 propertyAlarm(threshold.level, threshold.direction);
307
308 if ((level.empty()) || (alarm.empty()))
309 {
310 continue;
311 }
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800312 size_t thresSize =
313 label.empty() ? thresholds.size() : thresholdSize;
James Feistce3fca42018-11-21 12:58:24 -0800314 iface->register_property(
315 level, threshold.value,
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800316 [&, label, thresSize](const double& request, double& oldValue) {
James Feistce3fca42018-11-21 12:58:24 -0800317 oldValue = request; // todo, just let the config do this?
318 threshold.value = request;
319 thresholds::persistThreshold(configurationPath, objectType,
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800320 threshold, conn, thresSize,
321 label);
Josh Lehan883fb3a2020-02-27 14:41:39 -0800322 // Invalidate previously remembered value,
323 // so new thresholds will be checked during next update,
324 // even if sensor reading remains unchanged.
325 value = std::numeric_limits<double>::quiet_NaN();
326
327 // Although tempting, don't call checkThresholds() from here
328 // directly. Let the regular sensor monitor call the same
329 // using updateValue(), which can check conditions like
330 // poweron, etc., before raising any event.
James Feistce3fca42018-11-21 12:58:24 -0800331 return 1;
332 });
333 iface->register_property(alarm, false);
334 }
335 if (!sensorInterface->initialize())
336 {
337 std::cerr << "error initializing value interface\n";
338 }
James Feistce3fca42018-11-21 12:58:24 -0800339
Jayashree Dhanapal56678082022-01-04 17:27:20 +0530340 for (auto& thresIface : thresholdInterfaces)
James Feistce3fca42018-11-21 12:58:24 -0800341 {
Jayashree Dhanapal56678082022-01-04 17:27:20 +0530342 if (thresIface)
343 {
344 if (!thresIface->initialize(true))
345 {
346 std::cerr << "Error initializing threshold interface \n";
347 }
348 }
James Feistce3fca42018-11-21 12:58:24 -0800349 }
James Feist67601bd2020-06-16 17:14:44 -0700350
Jie Yang3291b9c2021-07-29 14:46:51 -0700351 if (isValueMutable)
352 {
353 valueMutabilityInterface =
354 std::make_shared<sdbusplus::asio::dbus_interface>(
355 conn, sensorInterface->get_object_path(),
356 valueMutabilityInterfaceName);
357 valueMutabilityInterface->register_property("Mutable", true);
358 if (!valueMutabilityInterface->initialize())
359 {
360 std::cerr
361 << "error initializing sensor value mutability interface\n";
362 valueMutabilityInterface = nullptr;
363 }
364 }
365
James Feist67601bd2020-06-16 17:14:44 -0700366 if (!availableInterface)
367 {
368 availableInterface =
369 std::make_shared<sdbusplus::asio::dbus_interface>(
370 conn, sensorInterface->get_object_path(),
371 availableInterfaceName);
372 availableInterface->register_property(
373 "Available", true, [this](const bool propIn, bool& old) {
374 if (propIn == old)
375 {
376 return 1;
377 }
James Feist961bf092020-07-01 16:38:12 -0700378 old = propIn;
James Feist67601bd2020-06-16 17:14:44 -0700379 if (!propIn)
380 {
381 updateValue(std::numeric_limits<double>::quiet_NaN());
382 }
James Feist67601bd2020-06-16 17:14:44 -0700383 return 1;
384 });
385 availableInterface->initialize();
386 }
James Feist961bf092020-07-01 16:38:12 -0700387 if (!operationalInterface)
388 {
389 operationalInterface =
390 std::make_shared<sdbusplus::asio::dbus_interface>(
391 conn, sensorInterface->get_object_path(),
392 operationalInterfaceName);
393 operationalInterface->register_property("Functional", true);
394 operationalInterface->initialize();
395 }
396 }
397
Jayashree Dhanapal45f27022021-12-07 12:56:35 +0530398 std::string propertyLevel(const thresholds::Level lev,
399 const thresholds::Direction dir)
400 {
401 for (ThresholdProperty prop : thresProp)
402 {
403 if ((prop.level == lev) && (prop.direction == dir))
404 {
405 return prop.levelProperty;
406 }
407 }
408 return "";
409 }
410
411 std::string propertyAlarm(const thresholds::Level lev,
412 const thresholds::Direction dir)
413 {
414 for (ThresholdProperty prop : thresProp)
415 {
416 if ((prop.level == lev) && (prop.direction == dir))
417 {
418 return prop.alarmProperty;
419 }
420 }
421 return "";
422 }
423
James Feist961bf092020-07-01 16:38:12 -0700424 bool readingStateGood()
425 {
426 if (readState == PowerState::on && !isPowerOn())
427 {
428 return false;
429 }
430 if (readState == PowerState::biosPost &&
431 (!hasBiosPost() || !isPowerOn()))
432 {
433 return false;
434 }
435
436 return true;
437 }
438
439 void markFunctional(bool isFunctional)
440 {
441 if (operationalInterface)
442 {
443 operationalInterface->set_property("Functional", isFunctional);
444 }
445 if (isFunctional)
446 {
447 errCount = 0;
448 }
449 else
450 {
451 updateValue(std::numeric_limits<double>::quiet_NaN());
452 }
453 }
454
455 void markAvailable(bool isAvailable)
456 {
457 if (availableInterface)
458 {
459 availableInterface->set_property("Available", isAvailable);
460 errCount = 0;
461 }
462 }
463
464 void incrementError()
465 {
466 if (!readingStateGood())
467 {
468 markAvailable(false);
469 return;
470 }
471
472 if (errCount >= errorThreshold)
473 {
474 return;
475 }
476
477 errCount++;
478 if (errCount == errorThreshold)
479 {
480 std::cerr << "Sensor " << name << " reading error!\n";
481 markFunctional(false);
482 }
James Feistce3fca42018-11-21 12:58:24 -0800483 }
484
James Feistd8705872019-02-08 13:26:09 -0800485 void updateValue(const double& newValue)
James Feistce3fca42018-11-21 12:58:24 -0800486 {
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530487 // Ignore if overriding is enabled
James Feist961bf092020-07-01 16:38:12 -0700488 if (overriddenState)
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530489 {
Josh Lehan883fb3a2020-02-27 14:41:39 -0800490 return;
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530491 }
Josh Lehan883fb3a2020-02-27 14:41:39 -0800492
James Feist961bf092020-07-01 16:38:12 -0700493 if (!readingStateGood())
494 {
495 markAvailable(false);
Adrian Ambrożewicz623723b2020-07-29 12:53:54 +0200496 updateValueProperty(std::numeric_limits<double>::quiet_NaN());
James Feist961bf092020-07-01 16:38:12 -0700497 return;
498 }
499
Adrian Ambrożewicz623723b2020-07-29 12:53:54 +0200500 updateValueProperty(newValue);
Josh Lehan3bcd8232020-10-29 00:22:12 -0700501 updateInstrumentation(newValue);
Josh Lehan883fb3a2020-02-27 14:41:39 -0800502
503 // Always check thresholds after changing the value,
504 // as the test against hysteresisTrigger now takes place in
505 // the thresholds::checkThresholds() method,
506 // which is called by checkThresholds() below,
507 // in all current implementations of sensors that have thresholds.
508 checkThresholds();
James Feist961bf092020-07-01 16:38:12 -0700509 if (!std::isnan(newValue))
510 {
511 markFunctional(true);
512 markAvailable(true);
513 }
James Feistce3fca42018-11-21 12:58:24 -0800514 }
Zbigniew Kurzynski4f45e422020-06-09 12:42:15 +0200515
516 void updateProperty(
517 std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
518 double& oldValue, const double& newValue, const char* dbusPropertyName)
519 {
520 if (requiresUpdate(oldValue, newValue))
521 {
522 oldValue = newValue;
Jae Hyun Yoo1a540b82020-07-30 23:33:18 -0700523 if (interface &&
524 !(interface->set_property(dbusPropertyName, newValue)))
Zbigniew Kurzynski4f45e422020-06-09 12:42:15 +0200525 {
526 std::cerr << "error setting property " << dbusPropertyName
527 << " to " << newValue << "\n";
528 }
529 }
530 }
531
532 bool requiresUpdate(const double& lVal, const double& rVal)
533 {
534 if (std::isnan(lVal) || std::isnan(rVal))
535 {
536 return true;
537 }
538 double diff = std::abs(lVal - rVal);
539 if (diff > hysteresisPublish)
540 {
541 return true;
542 }
543 return false;
544 }
Adrian Ambrożewicz623723b2020-07-29 12:53:54 +0200545
546 private:
547 void updateValueProperty(const double& newValue)
548 {
549 // Indicate that it is internal set call, not an external overwrite
550 internalSet = true;
551 updateProperty(sensorInterface, value, newValue, "Value");
552 internalSet = false;
553 }
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530554};