blob: de7bc26ba21606cb725211cb2b2d6b81bf418141 [file] [log] [blame]
Matthew Barthd87f89f2020-07-30 10:41:32 -05001/**
2 * Copyright © 2020 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#include "json_parser.hpp"
17
Matthew Barth3174e722020-09-15 15:13:40 -050018#include "json/event.hpp"
Matthew Barthfcfa0522020-08-24 16:40:24 -050019#include "json/fan.hpp"
Matthew Barthdfd4a052020-09-02 16:31:51 -050020#include "json/group.hpp"
Matthew Bartha227a162020-08-05 10:51:45 -050021#include "json/manager.hpp"
Matthew Barth2331d182020-08-18 15:00:27 -050022#include "json/profile.hpp"
Matthew Barth4f0d3b72020-08-27 14:32:15 -050023#include "json/zone.hpp"
Matthew Barth23ac24c2020-08-04 13:55:43 -050024#include "types.hpp"
25
26#include <sdbusplus/bus.hpp>
27
Matthew Barth413e4d02020-09-29 10:44:37 -050028#include <algorithm>
29#include <cstdlib>
Matthew Bartha3a8cc52021-01-15 12:40:25 -060030#include <string>
Matthew Barth413e4d02020-09-29 10:44:37 -050031#include <tuple>
32#include <vector>
33
Matthew Barthd87f89f2020-07-30 10:41:32 -050034namespace phosphor::fan::control
Matthew Barth23ac24c2020-08-04 13:55:43 -050035{
36
Matthew Barth413e4d02020-09-29 10:44:37 -050037bool checkEntry(const std::vector<std::string>& activeProfiles,
38 const std::vector<std::string>& entryProfiles)
39{
40 // Include entry if its list of profiles to be included in is empty
41 if (entryProfiles.empty())
42 {
43 // Entry always to be included
44 return true;
45 }
46 else
47 {
48 for (const auto& profile : activeProfiles)
49 {
50 auto iter =
51 std::find(entryProfiles.begin(), entryProfiles.end(), profile);
52 if (iter != entryProfiles.end())
53 {
54 // Entry configured to be included in active profile
55 return true;
56 }
57 }
58 }
59 return false;
60}
61
Matthew Barth23ac24c2020-08-04 13:55:43 -050062const std::vector<ZoneGroup> getZoneGroups(sdbusplus::bus::bus& bus)
63{
64 std::vector<ZoneGroup> zoneGrps;
65
Matthew Barth2331d182020-08-18 15:00:27 -050066 // Profiles are optional
67 auto profiles = getConfig<json::Profile>(bus, true);
Matthew Barthfcfa0522020-08-24 16:40:24 -050068 // Fans to be controlled
69 auto fans = getConfig<json::Fan>(bus);
Matthew Barth4f0d3b72020-08-27 14:32:15 -050070 // Zones within the system
71 auto zones = getConfig<json::Zone>(bus);
Matthew Barth3174e722020-09-15 15:13:40 -050072 // Fan control events are optional
73 auto events = getConfig<json::Event>(bus, true);
74 if (!events.empty())
75 {
76 // Groups to include in events
77 auto groups = getConfig<json::Group>(bus);
78 }
Matthew Barth2331d182020-08-18 15:00:27 -050079
Matthew Barth413e4d02020-09-29 10:44:37 -050080 // Ensure all configurations use the same set of active profiles
81 // (In case a profile's active state changes during configuration)
82 std::vector<std::string> activeProfiles;
83 for (const auto& profile : profiles)
84 {
85 if (profile.second->isActive())
86 {
87 activeProfiles.emplace_back(profile.first.first);
88 }
89 }
90
91 // Conditions list empty for JSON based configurations
92 // TODO Remove conditions after YAML based configuration removed
93 std::vector<Condition> conditions;
94 std::vector<ZoneDefinition> zoneDefs;
95 for (const auto& zone : zones)
96 {
97 // Check zone profiles against active profiles
98 if (checkEntry(activeProfiles, zone.second->getProfiles()))
99 {
100 auto zoneName = zone.second->getName();
101 // Create FanDefinition list for zone
102 std::vector<FanDefinition> fanDefs;
103 for (const auto& fan : fans)
104 {
105 // Check fan profiles against active profiles and
106 // if the fan is included in the zone
107 if (checkEntry(activeProfiles, fan.second->getProfiles()) &&
108 fan.second->getZone() == zoneName)
109 {
Matthew Bartha3a8cc52021-01-15 12:40:25 -0600110 // Adjust fan object sensor list to be included in the
111 // YAML fan definitions structure
112 std::vector<std::string> fanSensorList;
113 for (const auto& sensorMap : fan.second->getSensors())
114 {
115 auto sensor = sensorMap.first;
116 sensor.erase(0, 38);
117 fanSensorList.emplace_back(sensor);
118 }
119 fanDefs.emplace_back(
120 std::make_tuple(fan.second->getName(), fanSensorList,
121 fan.second->getInterface()));
Matthew Barth413e4d02020-09-29 10:44:37 -0500122 }
123 }
124
125 // Create SetSpeedEvents list for zone
126 std::vector<SetSpeedEvent> speedEvents;
127 // TODO Populate SetSpeedEvents list with configured events
128
129 // YAML zone name was an integer, JSON is a string
130 // Design direction is for it to be a string and this can be
131 // removed after YAML based configurations are removed.
132 char* zoneName_end;
133 auto zoneNum = std::strtol(zoneName.c_str(), &zoneName_end, 10);
134 if (*zoneName_end)
135 {
136 throw std::runtime_error(
137 "Zone names must be a string representation of a number");
138 }
139
140 zoneDefs.emplace_back(std::make_tuple(
141 zoneNum, zone.second->getFullSpeed(),
142 zone.second->getDefaultFloor(), zone.second->getIncDelay(),
143 zone.second->getDecInterval(), zone.second->getZoneHandlers(),
144 std::move(fanDefs), std::move(speedEvents)));
145 }
146 }
147 // TODO Should only result in a single entry but YAML based configurations
148 // produce a list of zone groups. Change to single zone group after YAML
149 // based configuartions are removed.
150 zoneGrps.emplace_back(std::make_tuple(conditions, zoneDefs));
Matthew Barth2331d182020-08-18 15:00:27 -0500151
Matthew Barth23ac24c2020-08-04 13:55:43 -0500152 return zoneGrps;
153}
154
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500155const unsigned int getPowerOnDelay(sdbusplus::bus::bus& bus)
156{
Matthew Bartha227a162020-08-05 10:51:45 -0500157 json::Manager mgr{bus};
158 return mgr.getPowerOnDelay();
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500159}
160
Matthew Barth23ac24c2020-08-04 13:55:43 -0500161} // namespace phosphor::fan::control