blob: 3508307072fb3b9efb9584a7e6a5a74707a4c4fa [file] [log] [blame]
Matthew Bartha227a162020-08-05 10:51:45 -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 */
Matthew Barthb584d812021-03-11 15:55:04 -060016#include "config.h"
17
Matthew Bartha227a162020-08-05 10:51:45 -050018#include "manager.hpp"
19
Matthew Barthde90fb42021-03-04 16:34:28 -060020#include "fan.hpp"
Matthew Bartha227a162020-08-05 10:51:45 -050021#include "json_config.hpp"
Matthew Barth06764942021-03-04 09:28:40 -060022#include "profile.hpp"
Matthew Barthacd737c2021-03-04 11:04:01 -060023#include "zone.hpp"
Matthew Bartha227a162020-08-05 10:51:45 -050024
Matthew Barthacd737c2021-03-04 11:04:01 -060025#include <nlohmann/json.hpp>
Matthew Bartha227a162020-08-05 10:51:45 -050026#include <sdbusplus/bus.hpp>
Matthew Barthacd737c2021-03-04 11:04:01 -060027#include <sdeventplus/event.hpp>
Matthew Bartha227a162020-08-05 10:51:45 -050028
Matthew Barthde90fb42021-03-04 16:34:28 -060029#include <algorithm>
Matthew Bartha227a162020-08-05 10:51:45 -050030#include <filesystem>
Matthew Barth06764942021-03-04 09:28:40 -060031#include <vector>
Matthew Bartha227a162020-08-05 10:51:45 -050032
33namespace phosphor::fan::control::json
34{
35
Matthew Barthacd737c2021-03-04 11:04:01 -060036using json = nlohmann::json;
37
38std::vector<std::string> Manager::_activeProfiles;
Matthew Barth12cb1252021-03-08 16:47:30 -060039std::map<std::string,
40 std::map<std::pair<std::string, bool>, std::vector<std::string>>>
41 Manager::_servTree;
Matthew Barth07fecfc2021-01-29 09:04:43 -060042std::map<std::string,
43 std::map<std::string, std::map<std::string, PropertyVariantType>>>
44 Manager::_objects;
Matthew Barthacd737c2021-03-04 11:04:01 -060045
Matthew Barth06764942021-03-04 09:28:40 -060046Manager::Manager(sdbusplus::bus::bus& bus, const sdeventplus::Event& event) :
Matthew Barthacd737c2021-03-04 11:04:01 -060047 _bus(bus), _event(event)
Matthew Bartha227a162020-08-05 10:51:45 -050048{
49 // Manager JSON config file is optional
50 auto confFile =
51 fan::JsonConfig::getConfFile(bus, confAppName, confFileName, true);
52 if (!confFile.empty())
53 {
54 _jsonObj = fan::JsonConfig::load(confFile);
55 }
Matthew Barth06764942021-03-04 09:28:40 -060056
Matthew Barthacd737c2021-03-04 11:04:01 -060057 // Parse and set the available profiles and which are active
58 setProfiles();
59
60 // Load the zone configurations
61 _zones = getConfig<Zone>(bus);
Matthew Barthde90fb42021-03-04 16:34:28 -060062
63 // Load the fan configurations and move each fan into its zone
64 auto fans = getConfig<Fan>(bus);
65 for (auto& fan : fans)
66 {
67 auto itZone =
68 std::find_if(_zones.begin(), _zones.end(),
69 [&fanZone = fan.second->getZone()](const auto& zone) {
70 return fanZone == zone.second->getName();
71 });
72 if (itZone != _zones.end())
73 {
74 itZone->second->addFan(std::move(fan.second));
75 }
76 }
Matthew Barthb584d812021-03-11 15:55:04 -060077
78 bus.request_name(CONTROL_BUSNAME);
Matthew Barthacd737c2021-03-04 11:04:01 -060079}
80
81const std::vector<std::string>& Manager::getActiveProfiles()
82{
83 return _activeProfiles;
Matthew Bartha227a162020-08-05 10:51:45 -050084}
85
Matthew Barth12cb1252021-03-08 16:47:30 -060086bool Manager::hasOwner(const std::string& path, const std::string& intf)
87{
88 auto itServ = _servTree.find(path);
89 if (itServ == _servTree.end())
90 {
91 // Path not found in cache, therefore owner missing
92 return false;
93 }
94 for (const auto& serv : itServ->second)
95 {
96 auto itIntf = std::find_if(
97 serv.second.begin(), serv.second.end(),
98 [&intf](const auto& interface) { return intf == interface; });
99 if (itIntf != std::end(serv.second))
100 {
101 // Service found, return owner state
102 return serv.first.second;
103 }
104 }
105 // Interface not found in cache, therefore owner missing
106 return false;
107}
108
Matthew Bartha227a162020-08-05 10:51:45 -0500109unsigned int Manager::getPowerOnDelay()
110{
111 auto powerOnDelay = 0;
112
113 // Parse optional "power_on_delay" from JSON object
114 if (!_jsonObj.empty() && _jsonObj.contains("power_on_delay"))
115 {
116 powerOnDelay = _jsonObj["power_on_delay"].get<unsigned int>();
117 }
118
119 return powerOnDelay;
120}
121
Matthew Barthacd737c2021-03-04 11:04:01 -0600122void Manager::setProfiles()
123{
124 // Profiles JSON config file is optional
125 auto confFile = fan::JsonConfig::getConfFile(_bus, confAppName,
126 Profile::confFileName, true);
127 if (!confFile.empty())
128 {
129 for (const auto& entry : fan::JsonConfig::load(confFile))
130 {
131 auto obj = std::make_unique<Profile>(entry);
132 _profiles.emplace(
133 std::make_pair(obj->getName(), obj->getProfiles()),
134 std::move(obj));
135 }
136 }
137 // Ensure all configurations use the same set of active profiles
138 // (In case a profile's active state changes during configuration)
139 for (const auto& profile : _profiles)
140 {
141 if (profile.second->isActive())
142 {
143 _activeProfiles.emplace_back(profile.first.first);
144 }
145 }
146}
147
Matthew Bartha227a162020-08-05 10:51:45 -0500148} // namespace phosphor::fan::control::json