| /** |
| * Copyright 2017 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "pid/builderconfig.hpp" |
| |
| #include "conf.hpp" |
| #include "pid/builder.hpp" |
| |
| #include <fstream> |
| #include <iostream> |
| #include <libconfig.h++> |
| #include <memory> |
| #include <sdbusplus/bus.hpp> |
| #include <string> |
| #include <unordered_map> |
| |
| std::unordered_map<int64_t, std::unique_ptr<PIDZone>> |
| buildZonesFromConfig(const std::string& path, SensorManager& mgr, |
| sdbusplus::bus::bus& modeControlBus) |
| { |
| using namespace libconfig; |
| // zone -> pids |
| std::map<int64_t, PIDConf> pidConfig; |
| // zone -> configs |
| std::map<int64_t, struct ZoneConfig> zoneConfig; |
| |
| std::cerr << "entered BuildZonesFromConfig\n"; |
| |
| Config cfg; |
| |
| /* The load was modeled after the example source provided. */ |
| try |
| { |
| cfg.readFile(path.c_str()); |
| } |
| catch (const FileIOException& fioex) |
| { |
| std::cerr << "I/O error while reading file: " << fioex.what() |
| << std::endl; |
| throw; |
| } |
| catch (const ParseException& pex) |
| { |
| std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() |
| << " - " << pex.getError() << std::endl; |
| throw; |
| } |
| |
| try |
| { |
| const Setting& root = cfg.getRoot(); |
| const Setting& zones = root["zones"]; |
| int count = zones.getLength(); |
| |
| /* For each zone. */ |
| for (int i = 0; i < count; ++i) |
| { |
| const Setting& zoneSettings = zones[i]; |
| |
| int id; |
| PIDConf thisZone; |
| struct ZoneConfig thisZoneConfig; |
| |
| zoneSettings.lookupValue("id", id); |
| |
| thisZoneConfig.minThermalRpm = zoneSettings.lookup("minThermalRpm"); |
| thisZoneConfig.failsafePercent = |
| zoneSettings.lookup("failsafePercent"); |
| |
| const Setting& pids = zoneSettings["pids"]; |
| int pidCount = pids.getLength(); |
| |
| for (int j = 0; j < pidCount; ++j) |
| { |
| const Setting& pid = pids[j]; |
| |
| std::string name; |
| struct ControllerInfo info; |
| |
| /* |
| * Mysteriously if you use lookupValue on these, and the type |
| * is double. It won't work right. |
| * |
| * If the configuration file value doesn't look explicitly like |
| * a double it won't let you assign it to one. |
| */ |
| name = pid.lookup("name").c_str(); |
| info.type = pid.lookup("type").c_str(); |
| /* set-point is only required to be set for thermal. */ |
| /* TODO(venture): Verify this works optionally here. */ |
| info.setpoint = pid.lookup("set-point"); |
| info.pidInfo.ts = pid.lookup("pid.sampleperiod"); |
| info.pidInfo.p_c = pid.lookup("pid.p_coefficient"); |
| info.pidInfo.i_c = pid.lookup("pid.i_coefficient"); |
| info.pidInfo.ff_off = pid.lookup("pid.ff_off_coefficient"); |
| info.pidInfo.ff_gain = pid.lookup("pid.ff_gain_coefficient"); |
| info.pidInfo.i_lim.min = pid.lookup("pid.i_limit.min"); |
| info.pidInfo.i_lim.max = pid.lookup("pid.i_limit.max"); |
| info.pidInfo.out_lim.min = pid.lookup("pid.out_limit.min"); |
| info.pidInfo.out_lim.max = pid.lookup("pid.out_limit.max"); |
| info.pidInfo.slew_neg = pid.lookup("pid.slew_neg"); |
| info.pidInfo.slew_pos = pid.lookup("pid.slew_pos"); |
| |
| std::cerr << "out_lim.min: " << info.pidInfo.out_lim.min |
| << "\n"; |
| std::cerr << "out_lim.max: " << info.pidInfo.out_lim.max |
| << "\n"; |
| |
| const Setting& inputs = pid["inputs"]; |
| int icount = inputs.getLength(); |
| |
| for (int z = 0; z < icount; ++z) |
| { |
| std::string v; |
| v = pid["inputs"][z].c_str(); |
| info.inputs.push_back(v); |
| } |
| |
| thisZone[name] = info; |
| } |
| |
| pidConfig[static_cast<int64_t>(id)] = thisZone; |
| zoneConfig[static_cast<int64_t>(id)] = thisZoneConfig; |
| } |
| } |
| catch (const SettingTypeException& setex) |
| { |
| std::cerr << "Setting '" << setex.getPath() << "' type exception!" |
| << std::endl; |
| throw; |
| } |
| catch (const SettingNotFoundException& snex) |
| { |
| std::cerr << "Setting '" << snex.getPath() << "' not found!" |
| << std::endl; |
| throw; |
| } |
| |
| return buildZones(pidConfig, zoneConfig, mgr, modeControlBus); |
| } |