blob: 7331705218b53959e2d7f706da51f4fca9f3dac2 [file] [log] [blame]
Patrick Venture5c7cc542018-06-11 14:29:38 -07001/**
2 * Copyright 2017 Google Inc.
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 "pid/builder.hpp"
18
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070019#include "conf.hpp"
Ed Tanousf8b6e552025-06-27 13:27:50 -070020#include "manager.hpp"
James Feist22c257a2018-08-31 14:07:12 -070021#include "pid/controller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070022#include "pid/fancontroller.hpp"
James Feist22c257a2018-08-31 14:07:12 -070023#include "pid/stepwisecontroller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070024#include "pid/thermalcontroller.hpp"
Patrick Venture7a98c192020-08-12 08:35:16 -070025#include "pid/zone.hpp"
26#include "pid/zone_interface.hpp"
Josh Lehan31058fd2023-01-13 11:06:16 -080027#include "util.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070028
Patrick Venturea83a3ec2020-08-04 09:52:05 -070029#include <sdbusplus/bus.hpp>
30
Patrick Ventureb748b682020-08-16 08:33:53 -070031#include <cstdint>
Patrick Venture5c7cc542018-06-11 14:29:38 -070032#include <iostream>
Ed Tanousf8b6e552025-06-27 13:27:50 -070033#include <map>
Patrick Venture5c7cc542018-06-11 14:29:38 -070034#include <memory>
Ed Tanousf8b6e552025-06-27 13:27:50 -070035#include <stdexcept>
Patrick Ventureb748b682020-08-16 08:33:53 -070036#include <string>
Patrick Venture5c7cc542018-06-11 14:29:38 -070037#include <unordered_map>
Ed Tanousf8b6e552025-06-27 13:27:50 -070038#include <utility>
Patrick Ventureb748b682020-08-16 08:33:53 -070039#include <vector>
Patrick Venture5c7cc542018-06-11 14:29:38 -070040
Patrick Venturea0764872020-08-08 07:48:43 -070041namespace pid_control
42{
43
Patrick Venture5c7cc542018-06-11 14:29:38 -070044static constexpr bool deferSignals = true;
45static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone";
46
Patrick Venture7af157b2018-10-30 11:24:40 -070047static std::string getControlPath(int64_t zone)
Patrick Venture5c7cc542018-06-11 14:29:38 -070048{
49 return std::string(objectPath) + std::to_string(zone);
50}
51
Ed Tanousd2768c52025-06-26 11:42:57 -070052static std::string getPidControlPath(int64_t zone, const std::string& pidname)
ykchiu7c6d35d2023-05-10 17:01:46 +080053{
54 return std::string(objectPath) + std::to_string(zone) + "/" + pidname;
55}
56
Patrick Williams19300272025-02-01 08:22:48 -050057std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> buildZones(
58 const std::map<int64_t, conf::PIDConf>& zonePids,
59 std::map<int64_t, conf::ZoneConfig>& zoneConfigs, SensorManager& mgr,
60 sdbusplus::bus_t& modeControlBus)
Patrick Venture5c7cc542018-06-11 14:29:38 -070061{
Johnathan Mantey5301aae2020-09-28 11:06:58 -070062 std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> zones;
Patrick Venture5c7cc542018-06-11 14:29:38 -070063
Patrick Venture2a50eda2020-08-16 08:26:35 -070064 for (const auto& [zoneId, pidConfig] : zonePids)
Patrick Venture5c7cc542018-06-11 14:29:38 -070065 {
Patrick Venture5c7cc542018-06-11 14:29:38 -070066 /* The above shouldn't be necessary but is, and I am having trouble
67 * locating my notes on why. If I recall correctly it was casting it
68 * down to a byte in at least some cases causing weird behaviors.
69 */
Patrick Venture5c7cc542018-06-11 14:29:38 -070070 auto zoneConf = zoneConfigs.find(zoneId);
71 if (zoneConf == zoneConfigs.end())
72 {
73 /* The Zone doesn't have a configuration, bail. */
74 static constexpr auto err =
75 "Bailing during load, missing Zone Configuration";
76 std::cerr << err << std::endl;
77 throw std::runtime_error(err);
78 }
79
Johnathan Mantey5301aae2020-09-28 11:06:58 -070080 auto zone = std::make_shared<DbusPidZone>(
James Feist3484bed2019-02-25 13:28:18 -080081 zoneId, zoneConf->second.minThermalOutput,
Bonnie Lo0e8fc392022-10-05 10:20:55 +080082 zoneConf->second.failsafePercent, zoneConf->second.cycleTime, mgr,
Delphine CC Chiu97889632023-11-06 11:32:46 +080083 modeControlBus, getControlPath(zoneId).c_str(), deferSignals,
84 zoneConf->second.accumulateSetPoint);
Patrick Venture5c7cc542018-06-11 14:29:38 -070085
Patrick Venture0bbeaf82018-10-30 18:50:31 -070086 std::cerr << "Zone Id: " << zone->getZoneID() << "\n";
Patrick Venture5c7cc542018-06-11 14:29:38 -070087
88 // For each PID create a Controller and a Sensor.
Patrick Venture2a50eda2020-08-16 08:26:35 -070089 for (const auto& [name, info] : pidConfig)
Patrick Venture5c7cc542018-06-11 14:29:38 -070090 {
Josh Lehan31058fd2023-01-13 11:06:16 -080091 std::vector<pid_control::conf::SensorInput> inputs;
Patrick Venture5c7cc542018-06-11 14:29:38 -070092 std::cerr << "PID name: " << name << "\n";
93
94 /*
95 * TODO(venture): Need to check if input is known to the
96 * SensorManager.
97 */
Patrick Venture2a50eda2020-08-16 08:26:35 -070098 if (info.type == "fan")
Patrick Venture5c7cc542018-06-11 14:29:38 -070099 {
Patrick Venture2a50eda2020-08-16 08:26:35 -0700100 for (const auto& i : info.inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -0700101 {
102 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800103 zone->addFanInput(i.name, i.missingIsAcceptable);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700104 }
105
Josh Lehan31058fd2023-01-13 11:06:16 -0800106 auto pid = FanController::createFanPid(
107 zone.get(), name, splitNames(inputs), info.pidInfo);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700108 zone->addFanPID(std::move(pid));
Harvey Wu92f9f3c2023-11-07 09:23:35 +0800109 zone->addPidFailSafePercent(splitNames(inputs),
110 info.failSafePercent);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700111 }
Patrick Venture2a50eda2020-08-16 08:26:35 -0700112 else if (isThermalType(info.type))
Patrick Venture5c7cc542018-06-11 14:29:38 -0700113 {
Patrick Venture2a50eda2020-08-16 08:26:35 -0700114 for (const auto& i : info.inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -0700115 {
116 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800117 zone->addThermalInput(i.name, i.missingIsAcceptable);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700118 }
119
Patrick Venture563a3562018-10-30 09:31:26 -0700120 auto pid = ThermalController::createThermalPid(
Patrick Venture2a50eda2020-08-16 08:26:35 -0700121 zone.get(), name, inputs, info.setpoint, info.pidInfo,
122 getThermalType(info.type));
James Feist22c257a2018-08-31 14:07:12 -0700123
Patrick Venture5c7cc542018-06-11 14:29:38 -0700124 zone->addThermalPID(std::move(pid));
Harvey Wu37180062023-10-02 09:42:50 +0800125 zone->addPidControlProcess(
126 name, info.type, info.setpoint, modeControlBus,
127 getPidControlPath(zoneId, name), deferSignals);
Harvey Wu92f9f3c2023-11-07 09:23:35 +0800128 zone->addPidFailSafePercent(splitNames(inputs),
129 info.failSafePercent);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700130 }
Patrick Venture2a50eda2020-08-16 08:26:35 -0700131 else if (info.type == "stepwise")
James Feist22c257a2018-08-31 14:07:12 -0700132 {
Patrick Venture2a50eda2020-08-16 08:26:35 -0700133 for (const auto& i : info.inputs)
James Feist22c257a2018-08-31 14:07:12 -0700134 {
135 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800136 zone->addThermalInput(i.name, i.missingIsAcceptable);
James Feist22c257a2018-08-31 14:07:12 -0700137 }
Patrick Venture563a3562018-10-30 09:31:26 -0700138 auto stepwise = StepwiseController::createStepwiseController(
Josh Lehan31058fd2023-01-13 11:06:16 -0800139 zone.get(), name, splitNames(inputs), info.stepwiseInfo);
James Feist22c257a2018-08-31 14:07:12 -0700140 zone->addThermalPID(std::move(stepwise));
Harvey Wu37180062023-10-02 09:42:50 +0800141 zone->addPidControlProcess(
142 name, info.type, info.setpoint, modeControlBus,
143 getPidControlPath(zoneId, name), deferSignals);
Harvey Wu92f9f3c2023-11-07 09:23:35 +0800144 zone->addPidFailSafePercent(splitNames(inputs),
145 info.failSafePercent);
James Feist22c257a2018-08-31 14:07:12 -0700146 }
Patrick Venture5c7cc542018-06-11 14:29:38 -0700147
148 std::cerr << "inputs: ";
Patrick Venture4a2dc4d2018-10-23 09:02:55 -0700149 for (const auto& i : inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -0700150 {
Josh Lehan31058fd2023-01-13 11:06:16 -0800151 std::cerr << i.name;
152 if (i.convertTempToMargin)
153 {
154 std::cerr << "[" << i.convertMarginZero << "]";
155 }
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800156 if (i.missingIsAcceptable)
157 {
158 std::cerr << "?";
159 }
Josh Lehan31058fd2023-01-13 11:06:16 -0800160 std::cerr << ", ";
Patrick Venture5c7cc542018-06-11 14:29:38 -0700161 }
162 std::cerr << "\n";
163 }
164
165 zone->emit_object_added();
166 zones[zoneId] = std::move(zone);
167 }
168
169 return zones;
170}
Patrick Venturea0764872020-08-08 07:48:43 -0700171
172} // namespace pid_control