blob: 12c2c99620cb857642e3074144867cf18e10e9f6 [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
Matthew Barth391ade02021-01-15 14:33:21 -060067 auto profiles = getConfig<json::Profile>(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
Matthew Barthacd737c2021-03-04 11:04:01 -060071 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);
Matthew Barth2331d182020-08-18 15:00:27 -050074
Matthew Barth413e4d02020-09-29 10:44:37 -050075 // Ensure all configurations use the same set of active profiles
76 // (In case a profile's active state changes during configuration)
77 std::vector<std::string> activeProfiles;
78 for (const auto& profile : profiles)
79 {
80 if (profile.second->isActive())
81 {
82 activeProfiles.emplace_back(profile.first.first);
83 }
84 }
85
86 // Conditions list empty for JSON based configurations
87 // TODO Remove conditions after YAML based configuration removed
88 std::vector<Condition> conditions;
89 std::vector<ZoneDefinition> zoneDefs;
90 for (const auto& zone : zones)
91 {
92 // Check zone profiles against active profiles
93 if (checkEntry(activeProfiles, zone.second->getProfiles()))
94 {
95 auto zoneName = zone.second->getName();
96 // Create FanDefinition list for zone
97 std::vector<FanDefinition> fanDefs;
98 for (const auto& fan : fans)
99 {
100 // Check fan profiles against active profiles and
101 // if the fan is included in the zone
102 if (checkEntry(activeProfiles, fan.second->getProfiles()) &&
103 fan.second->getZone() == zoneName)
104 {
Matthew Bartha3a8cc52021-01-15 12:40:25 -0600105 // Adjust fan object sensor list to be included in the
106 // YAML fan definitions structure
107 std::vector<std::string> fanSensorList;
108 for (const auto& sensorMap : fan.second->getSensors())
109 {
110 auto sensor = sensorMap.first;
111 sensor.erase(0, 38);
112 fanSensorList.emplace_back(sensor);
113 }
114 fanDefs.emplace_back(
115 std::make_tuple(fan.second->getName(), fanSensorList,
116 fan.second->getInterface()));
Matthew Barth413e4d02020-09-29 10:44:37 -0500117 }
118 }
119
120 // Create SetSpeedEvents list for zone
121 std::vector<SetSpeedEvent> speedEvents;
122 // TODO Populate SetSpeedEvents list with configured events
123
124 // YAML zone name was an integer, JSON is a string
125 // Design direction is for it to be a string and this can be
126 // removed after YAML based configurations are removed.
127 char* zoneName_end;
128 auto zoneNum = std::strtol(zoneName.c_str(), &zoneName_end, 10);
129 if (*zoneName_end)
130 {
131 throw std::runtime_error(
132 "Zone names must be a string representation of a number");
133 }
134
135 zoneDefs.emplace_back(std::make_tuple(
Matthew Barthe47c9582021-03-09 14:24:02 -0600136 zoneNum, zone.second->getDefaultCeiling(),
Matthew Barth413e4d02020-09-29 10:44:37 -0500137 zone.second->getDefaultFloor(), zone.second->getIncDelay(),
Matthew Barth75627722021-03-11 09:58:39 -0600138 zone.second->getDecInterval(), std::vector<ZoneHandler>{},
Matthew Barth413e4d02020-09-29 10:44:37 -0500139 std::move(fanDefs), std::move(speedEvents)));
140 }
141 }
142 // TODO Should only result in a single entry but YAML based configurations
143 // produce a list of zone groups. Change to single zone group after YAML
144 // based configuartions are removed.
145 zoneGrps.emplace_back(std::make_tuple(conditions, zoneDefs));
Matthew Barth2331d182020-08-18 15:00:27 -0500146
Matthew Barth23ac24c2020-08-04 13:55:43 -0500147 return zoneGrps;
148}
149
Matthew Barth06764942021-03-04 09:28:40 -0600150const unsigned int getPowerOnDelay(sdbusplus::bus::bus& bus,
151 const sdeventplus::Event& event)
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500152{
Matthew Barth06764942021-03-04 09:28:40 -0600153 json::Manager mgr{bus, event};
Matthew Bartha227a162020-08-05 10:51:45 -0500154 return mgr.getPowerOnDelay();
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500155}
156
Matthew Barth23ac24c2020-08-04 13:55:43 -0500157} // namespace phosphor::fan::control