blob: ef8543f01835f8a35e46981dc5e0f9d26730be41 [file] [log] [blame]
Vijay Khemkaabcc94f2020-08-11 15:27:44 -07001#include "virtualSensor.hpp"
2
3#include "config.hpp"
4
5#include <phosphor-logging/log.hpp>
6#include <sdeventplus/event.hpp>
7
8#include <fstream>
9#include <iostream>
10
11static constexpr bool DEBUG = false;
12static constexpr auto busName = "xyz.openbmc_project.VirtualSensor";
13static constexpr auto sensorDbusPath = "/xyz/openbmc_project/sensors/";
14static constexpr uint8_t defaultHighThreshold = 100;
15static constexpr uint8_t defaultLowThreshold = 0;
16
17using namespace phosphor::logging;
18
19namespace phosphor
20{
21namespace virtualSensor
22{
23
24void printParams(const VirtualSensor::ParamMap& paramMap)
25{
26 for (const auto& p : paramMap)
27 {
28 const auto& p1 = p.first;
29 const auto& p2 = p.second;
30 auto val = p2->getParamValue();
31 std::cout << p1 << " = " << val << "\n";
32 }
33}
34
35double SensorParam::getParamValue()
36{
37 switch (paramType)
38 {
39 case constParam:
40 return value;
41 break;
42 default:
43 throw std::invalid_argument("param type not supported");
44 }
45}
46
47void VirtualSensor::initVirtualSensor(const Json& sensorConfig)
48{
49
50 static const Json empty{};
51
52 /* Get threshold values if defined in config */
53 auto threshold = sensorConfig.value("Threshold", empty);
54 if (!threshold.empty())
55 {
56 sensorThreshold.criticalHigh =
57 threshold.value("CriticalHigh", defaultHighThreshold);
58 sensorThreshold.criticalLow =
59 threshold.value("CriticalLow", defaultLowThreshold);
60 sensorThreshold.warningHigh =
61 threshold.value("WarningHigh", defaultHighThreshold);
62 sensorThreshold.warningLow =
63 threshold.value("WarningLow", defaultLowThreshold);
64 }
65
66 /* Set threshold value to dbus */
67 setSensorThreshold();
68
69 /* Get expression string */
70 exprStr = sensorConfig.value("Expression", "");
71
72 /* Get all the parameter listed in configuration */
73 auto params = sensorConfig.value("Params", empty);
74
75 /* Check for constant parameter */
76 const auto& consParams = params.value("ConstParam", empty);
77 if (!consParams.empty())
78 {
79 for (auto& j : consParams)
80 {
81 if (j.find("ParamName") != j.end())
82 {
83 auto paramPtr = std::make_unique<SensorParam>(j["Value"]);
84 paramMap.emplace(j["ParamName"], std::move(paramPtr));
85 }
86 else
87 {
88 /* Invalid configuration */
89 throw std::invalid_argument(
90 "ParamName not found in configuration");
91 }
92 }
93 }
94
95 /* TODO: Check for dbus parameter */
96
97 /* Print all parameters for debug purpose only */
98 if (DEBUG)
99 printParams(paramMap);
100}
101
102void VirtualSensor::setSensorValue(double value)
103{
104 ValueIface::value(value);
105}
106
107void VirtualSensor::setSensorThreshold()
108{
109 CriticalInterface::criticalHigh(sensorThreshold.criticalHigh);
110 CriticalInterface::criticalLow(sensorThreshold.criticalLow);
111 WarningInterface::warningHigh(sensorThreshold.warningHigh);
112 WarningInterface::warningLow(sensorThreshold.warningLow);
113}
114
115/* TBD */
116void VirtualSensor::updateVirtualSensor()
117{}
118
119/** @brief Parsing Virtual Sensor config JSON file */
120Json VirtualSensors::parseConfigFile(const std::string configFile)
121{
122 std::ifstream jsonFile(configFile);
123 if (!jsonFile.is_open())
124 {
125 log<level::ERR>("config JSON file not found",
126 entry("FILENAME = %s", configFile.c_str()));
127 throw std::exception{};
128 }
129
130 auto data = Json::parse(jsonFile, nullptr, false);
131 if (data.is_discarded())
132 {
133 log<level::ERR>("config readings JSON parser failure",
134 entry("FILENAME = %s", configFile.c_str()));
135 throw std::exception{};
136 }
137
138 return data;
139}
140
141void VirtualSensors::createVirtualSensors()
142{
143 static const Json empty{};
144
145 auto data = parseConfigFile(VIRTUAL_SENSOR_CONFIG_FILE);
146 // print values
147 if (DEBUG)
148 std::cout << "Config json data:\n" << data << "\n\n";
149
150 /* Get virtual sensors config data */
151 for (const auto& j : data)
152 {
153 auto desc = j.value("Desc", empty);
154 if (!desc.empty())
155 {
156 std::string sensorType = desc.value("SensorType", "");
157 std::string name = desc.value("Name", "");
158
159 if (!name.empty() && !sensorType.empty())
160 {
161 std::string objPath(sensorDbusPath);
162 objPath += sensorType + "/" + name;
163
164 auto virtualSensorPtr =
165 std::make_unique<VirtualSensor>(bus, objPath.c_str(), j);
166 virtualSensorsMap.emplace(name, std::move(virtualSensorPtr));
167
168 log<level::INFO>("Added a new virtual sensor",
169 entry("NAME = %s", name.c_str()));
170 }
171 else
172 {
173 log<level::ERR>("Sensor type or name not found in config file");
174 }
175 }
176 else
177 {
178 log<level::ERR>(
179 "Descriptor for new virtual sensor not found in config file");
180 }
181 }
182}
183
184} // namespace virtualSensor
185} // namespace phosphor
186
187/**
188 * @brief Main
189 */
190int main()
191{
192
193 // Get a default event loop
194 auto event = sdeventplus::Event::get_default();
195
196 // Get a handle to system dbus
197 auto bus = sdbusplus::bus::new_default();
198
199 // Create an virtual sensors object
200 phosphor::virtualSensor::VirtualSensors virtualSensors(bus);
201
202 // Request service bus name
203 bus.request_name(busName);
204
205 // Attach the bus to sd_event to service user requests
206 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
207 event.loop();
208
209 return 0;
210}