blob: 29f674abf37c874ba4528520d0a1af21d2b242f4 [file] [log] [blame]
James Feist8fd8a582018-11-16 11:10:46 -08001#pragma once
2
3#include <Thresholds.hpp>
4#include <sdbusplus/asio/object_server.hpp>
5
James Feist1169eb42018-10-31 10:08:47 -07006constexpr size_t sensorFailedPollTimeMs = 5000;
James Feista5e58722019-04-22 14:43:11 -07007
8constexpr const char* sensorValueInterface = "xyz.openbmc_project.Sensor.Value";
James Feist8fd8a582018-11-16 11:10:46 -08009struct Sensor
10{
James Feist930fcde2019-05-28 12:58:43 -070011 Sensor(const std::string& name,
James Feistd8705872019-02-08 13:26:09 -080012 std::vector<thresholds::Threshold>&& thresholdData,
13 const std::string& configurationPath, const std::string& objectType,
James Feistce3fca42018-11-21 12:58:24 -080014 const double max, const double min) :
James Feistdc6c55f2018-10-31 12:53:20 -070015 name(name),
James Feist930fcde2019-05-28 12:58:43 -070016 configurationPath(configurationPath), objectType(objectType),
17 thresholds(std::move(thresholdData)), maxValue(max), minValue(min)
James Feistdc6c55f2018-10-31 12:53:20 -070018 {
19 }
James Feist8fd8a582018-11-16 11:10:46 -080020 virtual ~Sensor() = default;
James Feistce3fca42018-11-21 12:58:24 -080021 virtual void checkThresholds(void) = 0;
James Feistdc6c55f2018-10-31 12:53:20 -070022 std::string name;
James Feistce3fca42018-11-21 12:58:24 -080023 std::string configurationPath;
24 std::string objectType;
25 double maxValue;
26 double minValue;
James Feist8fd8a582018-11-16 11:10:46 -080027 std::vector<thresholds::Threshold> thresholds;
28 std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInterface;
29 std::shared_ptr<sdbusplus::asio::dbus_interface> thresholdInterfaceWarning;
30 std::shared_ptr<sdbusplus::asio::dbus_interface> thresholdInterfaceCritical;
James Feist078f2322019-03-08 11:09:05 -080031 std::shared_ptr<sdbusplus::asio::dbus_interface> association;
James Feist8fd8a582018-11-16 11:10:46 -080032 double value = std::numeric_limits<double>::quiet_NaN();
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +053033 bool overriddenState = false;
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053034 bool internalSet = false;
James Feistce3fca42018-11-21 12:58:24 -080035
James Feistd8705872019-02-08 13:26:09 -080036 int setSensorValue(const double& newValue, double& oldValue)
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053037 {
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +053038 if (!internalSet)
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053039 {
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053040 oldValue = newValue;
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +053041 overriddenState = true;
42 // check thresholds for external set
43 value = newValue;
44 checkThresholds();
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053045 }
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +053046 else if (!overriddenState)
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +053047 {
48 oldValue = newValue;
49 }
Richard Marian Thomaiyar87219222018-11-06 20:25:38 +053050 return 1;
51 }
James Feistce3fca42018-11-21 12:58:24 -080052
53 void
James Feistd8705872019-02-08 13:26:09 -080054 setInitialProperties(std::shared_ptr<sdbusplus::asio::connection>& conn)
James Feistce3fca42018-11-21 12:58:24 -080055 {
James Feist82bac4c2019-03-11 11:16:53 -070056 createAssociation(association, configurationPath);
James Feist078f2322019-03-08 11:09:05 -080057
James Feistce3fca42018-11-21 12:58:24 -080058 sensorInterface->register_property("MaxValue", maxValue);
59 sensorInterface->register_property("MinValue", minValue);
60 sensorInterface->register_property(
James Feistd8705872019-02-08 13:26:09 -080061 "Value", value, [&](const double& newValue, double& oldValue) {
James Feistce3fca42018-11-21 12:58:24 -080062 return setSensorValue(newValue, oldValue);
63 });
64
James Feistd8705872019-02-08 13:26:09 -080065 for (auto& threshold : thresholds)
James Feistce3fca42018-11-21 12:58:24 -080066 {
67 std::shared_ptr<sdbusplus::asio::dbus_interface> iface;
68 std::string level;
69 std::string alarm;
70 if (threshold.level == thresholds::Level::CRITICAL)
71 {
72 iface = thresholdInterfaceCritical;
73 if (threshold.direction == thresholds::Direction::HIGH)
74 {
75 level = "CriticalHigh";
76 alarm = "CriticalAlarmHigh";
77 }
78 else
79 {
80 level = "CriticalLow";
81 alarm = "CriticalAlarmLow";
82 }
83 }
84 else if (threshold.level == thresholds::Level::WARNING)
85 {
86 iface = thresholdInterfaceWarning;
87 if (threshold.direction == thresholds::Direction::HIGH)
88 {
89 level = "WarningHigh";
90 alarm = "WarningAlarmHigh";
91 }
92 else
93 {
94 level = "WarningLow";
95 alarm = "WarningAlarmLow";
96 }
97 }
98 else
99 {
100 std::cerr << "Unknown threshold level" << threshold.level
101 << "\n";
102 continue;
103 }
104 if (!iface)
105 {
106 std::cout << "trying to set uninitialized interface\n";
107 continue;
108 }
109 iface->register_property(
110 level, threshold.value,
James Feistd8705872019-02-08 13:26:09 -0800111 [&](const double& request, double& oldValue) {
James Feistce3fca42018-11-21 12:58:24 -0800112 oldValue = request; // todo, just let the config do this?
113 threshold.value = request;
114 thresholds::persistThreshold(configurationPath, objectType,
James Feista222ba72019-03-01 15:57:51 -0800115 threshold, conn,
116 thresholds.size());
James Feistce3fca42018-11-21 12:58:24 -0800117 return 1;
118 });
119 iface->register_property(alarm, false);
120 }
121 if (!sensorInterface->initialize())
122 {
123 std::cerr << "error initializing value interface\n";
124 }
125 if (thresholdInterfaceWarning &&
126 !thresholdInterfaceWarning->initialize())
127 {
128 std::cerr << "error initializing warning threshold interface\n";
129 }
130
131 if (thresholdInterfaceCritical &&
132 !thresholdInterfaceCritical->initialize())
133 {
134 std::cerr << "error initializing critical threshold interface\n";
135 }
136 }
137
James Feistd8705872019-02-08 13:26:09 -0800138 void updateValue(const double& newValue)
James Feistce3fca42018-11-21 12:58:24 -0800139 {
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530140 // Ignore if overriding is enabled
141 if (!overriddenState)
142 {
143 // Indicate that it is internal set call
144 internalSet = true;
145 sensorInterface->set_property("Value", newValue);
146 internalSet = false;
147 value = newValue;
148 checkThresholds();
149 }
James Feistce3fca42018-11-21 12:58:24 -0800150 }
Richard Marian Thomaiyarc0ca7ee2019-04-24 21:22:52 +0530151};