blob: 33301e24ecb451c0e8a7e0458d77d6d5a541a98f [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/builderconfig.hpp"
18
19#include <fstream>
20#include <iostream>
21#include <libconfig.h++>
22#include <memory>
23#include <sdbusplus/bus.hpp>
24#include <string>
25#include <unordered_map>
26
27#include "conf.hpp"
28#include "pid/builder.hpp"
29
30std::unordered_map<int64_t, std::unique_ptr<PIDZone>> BuildZonesFromConfig(
31 const std::string& path,
32 SensorManager& mgr,
33 sdbusplus::bus::bus& modeControlBus)
34{
35 using namespace libconfig;
36 // zone -> pids
37 std::map<int64_t, PIDConf> pidConfig;
38 // zone -> configs
39 std::map<int64_t, struct zone> zoneConfig;
40
41 std::cerr << "entered BuildZonesFromConfig\n";
42
43 Config cfg;
44
45 /* The load was modeled after the example source provided. */
46 try
47 {
48 cfg.readFile(path.c_str());
49 }
50 catch (const FileIOException& fioex)
51 {
52 std::cerr << "I/O error while reading file: " << fioex.what()
53 << std::endl;
54 throw;
55 }
56 catch (const ParseException& pex)
57 {
58 std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
59 << " - " << pex.getError() << std::endl;
60 throw;
61 }
62
63 try
64 {
65 const Setting& root = cfg.getRoot();
66 const Setting& zones = root["zones"];
67 int count = zones.getLength();
68
69 /* For each zone. */
70 for (int i = 0; i < count; ++i)
71 {
72 const Setting& zoneSettings = zones[i];
73
74 int id;
75 PIDConf thisZone;
76 struct zone thisZoneConfig;
77
78 zoneSettings.lookupValue("id", id);
79
80 thisZoneConfig.minthermalrpm =
81 zoneSettings.lookup("minthermalrpm");
82 thisZoneConfig.failsafepercent =
83 zoneSettings.lookup("failsafepercent");
84
85 const Setting& pids = zoneSettings["pids"];
86 int pidCount = pids.getLength();
87
88 for (int j = 0; j < pidCount; ++j)
89 {
90 const Setting& pid = pids[j];
91
92 std::string name;
93 controller_info info;
94
95 /*
96 * Mysteriously if you use lookupValue on these, and the type
97 * is float. It won't work right.
98 *
99 * If the configuration file value doesn't look explicitly like
100 * a float it won't let you assign it to one.
101 */
102 name = pid.lookup("name").c_str();
103 info.type = pid.lookup("type").c_str();
104 /* set-point is only required to be set for thermal. */
105 /* TODO(venture): Verify this works optionally here. */
106 info.setpoint = pid.lookup("set-point");
107 info.info.ts = pid.lookup("pid.sampleperiod");
108 info.info.p_c = pid.lookup("pid.p_coefficient");
109 info.info.i_c = pid.lookup("pid.i_coefficient");
110 info.info.ff_off = pid.lookup("pid.ff_off_coefficient");
111 info.info.ff_gain = pid.lookup("pid.ff_gain_coefficient");
112 info.info.i_lim.min = pid.lookup("pid.i_limit.min");
113 info.info.i_lim.max = pid.lookup("pid.i_limit.max");
114 info.info.out_lim.min = pid.lookup("pid.out_limit.min");
115 info.info.out_lim.max = pid.lookup("pid.out_limit.max");
116 info.info.slew_neg = pid.lookup("pid.slew_neg");
117 info.info.slew_pos = pid.lookup("pid.slew_pos");
118
119 std::cerr << "out_lim.min: " << info.info.out_lim.min << "\n";
120 std::cerr << "out_lim.max: " << info.info.out_lim.max << "\n";
121
122 const Setting& inputs = pid["inputs"];
123 int icount = inputs.getLength();
124
125 for (int z = 0; z < icount; ++z)
126 {
127 std::string v;
128 v = pid["inputs"][z].c_str();
129 info.inputs.push_back(v);
130 }
131
132 thisZone[name] = info;
133 }
134
135 pidConfig[static_cast<int64_t>(id)] = thisZone;
136 zoneConfig[static_cast<int64_t>(id)] = thisZoneConfig;
137 }
138 }
139 catch (const SettingTypeException &setex)
140 {
141 std::cerr << "Setting '" << setex.getPath() << "' type exception!"
142 << std::endl;
143 throw;
144 }
145 catch (const SettingNotFoundException& snex)
146 {
147 std::cerr << "Setting '" << snex.getPath() << "' not found!"
148 << std::endl;
149 throw;
150 }
151
152 return BuildZones(pidConfig, zoneConfig, mgr, modeControlBus);
153}