1 /**
2 * Copyright © 2021 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "dbus_sensors.hpp"
18
19 #include <utility>
20
21 namespace phosphor::power::regulators
22 {
23
enable()24 void DBusSensors::enable()
25 {
26 // Currently nothing to do here. The next monitoring cycle will set the
27 // values of all sensors, and that will set them to the enabled state.
28 }
29
endCycle()30 void DBusSensors::endCycle()
31 {
32 // Delete any sensors that were not updated during this monitoring cycle.
33 // This can happen if the hardware device producing the sensors was removed
34 // or replaced with a different version.
35 auto it = sensors.begin();
36 while (it != sensors.end())
37 {
38 // Increment iterator before potentially deleting the sensor.
39 // map::erase() invalidates iterators/references to the erased element.
40 auto& [sensorName, sensor] = *it;
41 ++it;
42
43 // Check if last update time for sensor is before cycle start time
44 if (sensor->getLastUpdateTime() < cycleStartTime)
45 {
46 sensors.erase(sensorName);
47 }
48 }
49 }
50
endRail(bool errorOccurred)51 void DBusSensors::endRail(bool errorOccurred)
52 {
53 // If an error occurred, set all sensors for current rail to the error state
54 if (errorOccurred)
55 {
56 for (auto& [sensorName, sensor] : sensors)
57 {
58 if (sensor->getRail() == rail)
59 {
60 sensor->setToErrorState();
61 }
62 }
63 }
64
65 // Clear current rail information
66 rail.clear();
67 deviceInventoryPath.clear();
68 chassisInventoryPath.clear();
69 }
70
disable()71 void DBusSensors::disable()
72 {
73 // Disable all sensors
74 for (auto& [sensorName, sensor] : sensors)
75 {
76 sensor->disable();
77 }
78 }
79
setValue(SensorType type,double value)80 void DBusSensors::setValue(SensorType type, double value)
81 {
82 // Build unique sensor name based on rail and sensor type
83 std::string sensorName{rail + '_' + sensors::toString(type)};
84
85 // Check to see if the sensor already exists
86 auto it = sensors.find(sensorName);
87 if (it != sensors.end())
88 {
89 // Sensor exists; update value
90 it->second->setValue(value);
91 }
92 else
93 {
94 // Sensor doesn't exist; create it and add it to the map
95 auto sensor = std::make_unique<DBusSensor>(
96 bus, sensorName, type, value, rail, deviceInventoryPath,
97 chassisInventoryPath);
98 sensors.emplace(sensorName, std::move(sensor));
99 }
100 }
101
startCycle()102 void DBusSensors::startCycle()
103 {
104 // Store the time when this monitoring cycle started. This is used to
105 // detect sensors that were not updated during this cycle.
106 cycleStartTime = std::chrono::system_clock::now();
107 }
108
startRail(const std::string & rail,const std::string & deviceInventoryPath,const std::string & chassisInventoryPath)109 void DBusSensors::startRail(const std::string& rail,
110 const std::string& deviceInventoryPath,
111 const std::string& chassisInventoryPath)
112 {
113 // Store current rail information; used later by setValue() and endRail()
114 this->rail = rail;
115 this->deviceInventoryPath = deviceInventoryPath;
116 this->chassisInventoryPath = chassisInventoryPath;
117 }
118
119 } // namespace phosphor::power::regulators
120