blob: c0747367eb01e79f5185a8eec430d56af16d5003 [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>
30#include <tuple>
31#include <vector>
32
Matthew Barthd87f89f2020-07-30 10:41:32 -050033namespace phosphor::fan::control
Matthew Barth23ac24c2020-08-04 13:55:43 -050034{
35
Matthew Barth413e4d02020-09-29 10:44:37 -050036bool checkEntry(const std::vector<std::string>& activeProfiles,
37 const std::vector<std::string>& entryProfiles)
38{
39 // Include entry if its list of profiles to be included in is empty
40 if (entryProfiles.empty())
41 {
42 // Entry always to be included
43 return true;
44 }
45 else
46 {
47 for (const auto& profile : activeProfiles)
48 {
49 auto iter =
50 std::find(entryProfiles.begin(), entryProfiles.end(), profile);
51 if (iter != entryProfiles.end())
52 {
53 // Entry configured to be included in active profile
54 return true;
55 }
56 }
57 }
58 return false;
59}
60
Matthew Barth23ac24c2020-08-04 13:55:43 -050061const std::vector<ZoneGroup> getZoneGroups(sdbusplus::bus::bus& bus)
62{
63 std::vector<ZoneGroup> zoneGrps;
64
Matthew Barth2331d182020-08-18 15:00:27 -050065 // Profiles are optional
66 auto profiles = getConfig<json::Profile>(bus, true);
Matthew Barthfcfa0522020-08-24 16:40:24 -050067 // Fans to be controlled
68 auto fans = getConfig<json::Fan>(bus);
Matthew Barth4f0d3b72020-08-27 14:32:15 -050069 // Zones within the system
70 auto zones = getConfig<json::Zone>(bus);
Matthew Barth3174e722020-09-15 15:13:40 -050071 // Fan control events are optional
72 auto events = getConfig<json::Event>(bus, true);
73 if (!events.empty())
74 {
75 // Groups to include in events
76 auto groups = getConfig<json::Group>(bus);
77 }
Matthew Barth2331d182020-08-18 15:00:27 -050078
Matthew Barth413e4d02020-09-29 10:44:37 -050079 // Ensure all configurations use the same set of active profiles
80 // (In case a profile's active state changes during configuration)
81 std::vector<std::string> activeProfiles;
82 for (const auto& profile : profiles)
83 {
84 if (profile.second->isActive())
85 {
86 activeProfiles.emplace_back(profile.first.first);
87 }
88 }
89
90 // Conditions list empty for JSON based configurations
91 // TODO Remove conditions after YAML based configuration removed
92 std::vector<Condition> conditions;
93 std::vector<ZoneDefinition> zoneDefs;
94 for (const auto& zone : zones)
95 {
96 // Check zone profiles against active profiles
97 if (checkEntry(activeProfiles, zone.second->getProfiles()))
98 {
99 auto zoneName = zone.second->getName();
100 // Create FanDefinition list for zone
101 std::vector<FanDefinition> fanDefs;
102 for (const auto& fan : fans)
103 {
104 // Check fan profiles against active profiles and
105 // if the fan is included in the zone
106 if (checkEntry(activeProfiles, fan.second->getProfiles()) &&
107 fan.second->getZone() == zoneName)
108 {
109 fanDefs.emplace_back(std::make_tuple(
110 fan.second->getName(), fan.second->getSensors(),
111 fan.second->getInterface()));
112 }
113 }
114
115 // Create SetSpeedEvents list for zone
116 std::vector<SetSpeedEvent> speedEvents;
117 // TODO Populate SetSpeedEvents list with configured events
118
119 // YAML zone name was an integer, JSON is a string
120 // Design direction is for it to be a string and this can be
121 // removed after YAML based configurations are removed.
122 char* zoneName_end;
123 auto zoneNum = std::strtol(zoneName.c_str(), &zoneName_end, 10);
124 if (*zoneName_end)
125 {
126 throw std::runtime_error(
127 "Zone names must be a string representation of a number");
128 }
129
130 zoneDefs.emplace_back(std::make_tuple(
131 zoneNum, zone.second->getFullSpeed(),
132 zone.second->getDefaultFloor(), zone.second->getIncDelay(),
133 zone.second->getDecInterval(), zone.second->getZoneHandlers(),
134 std::move(fanDefs), std::move(speedEvents)));
135 }
136 }
137 // TODO Should only result in a single entry but YAML based configurations
138 // produce a list of zone groups. Change to single zone group after YAML
139 // based configuartions are removed.
140 zoneGrps.emplace_back(std::make_tuple(conditions, zoneDefs));
Matthew Barth2331d182020-08-18 15:00:27 -0500141
Matthew Barth23ac24c2020-08-04 13:55:43 -0500142 return zoneGrps;
143}
144
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500145const unsigned int getPowerOnDelay(sdbusplus::bus::bus& bus)
146{
Matthew Bartha227a162020-08-05 10:51:45 -0500147 json::Manager mgr{bus};
148 return mgr.getPowerOnDelay();
Matthew Barth2dc5aba2020-08-04 14:23:34 -0500149}
150
Matthew Barth23ac24c2020-08-04 13:55:43 -0500151} // namespace phosphor::fan::control