1 #include "util.hpp" 2 3 #include <cmath> 4 #include <cstdint> 5 #include <iostream> 6 #include <map> 7 #include <regex> 8 #include <set> 9 #include <string> 10 #include <unordered_map> 11 #include <utility> 12 #include <variant> 13 #include <vector> 14 15 using Property = std::string; 16 using Value = std::variant<int64_t, double, std::string, bool>; 17 using PropertyMap = std::map<Property, Value>; 18 19 namespace pid_control 20 { 21 22 int64_t setZoneIndex(const std::string& name, 23 std::map<std::string, int64_t>& zones, int64_t index) 24 { 25 auto it = zones.find(name); 26 if (it != zones.end()) 27 { 28 // Name already allocated, make no change, return existing 29 return it->second; 30 } 31 32 // The zone name is known not to exist yet 33 for (;;) 34 { 35 bool usedIndex = false; 36 37 // See if desired index number is free 38 for (const auto& zi : zones) 39 { 40 if (index == zi.second) 41 { 42 usedIndex = true; 43 break; 44 } 45 } 46 47 // Increment until a free index number is found 48 if (usedIndex) 49 { 50 ++index; 51 continue; 52 } 53 54 break; 55 } 56 57 // Allocate and return new zone index number for this name 58 zones[name] = index; 59 return index; 60 } 61 62 int64_t getZoneIndex(const std::string& name, 63 std::map<std::string, int64_t>& zones) 64 { 65 auto it = zones.find(name); 66 if (it != zones.end()) 67 { 68 return it->second; 69 } 70 71 // Auto-assign next unused zone number, using 0-based numbering 72 return setZoneIndex(name, zones, 0); 73 } 74 75 bool findSensors(const std::unordered_map<std::string, std::string>& sensors, 76 const std::string& search, 77 std::vector<std::pair<std::string, std::string>>& matches) 78 { 79 std::smatch match; 80 std::regex reg('/' + search + '$'); 81 for (const auto& sensor : sensors) 82 { 83 if (std::regex_search(sensor.first, match, reg)) 84 { 85 matches.push_back(sensor); 86 } 87 } 88 return matches.size() > 0; 89 } 90 91 std::string getSensorPath(const std::string& type, const std::string& id) 92 { 93 std::string layer; 94 if (type == "fan") 95 { 96 layer = "fan_tach"; 97 } 98 else if (type == "temp") 99 { 100 layer = "temperature"; 101 } 102 else if (type == "margin") 103 { 104 layer = "temperature"; 105 } 106 else if (type == "power") 107 { 108 layer = "power"; 109 } 110 else if (type == "powersum") 111 { 112 layer = "power"; 113 } 114 else 115 { 116 layer = "unknown"; // TODO(venture): Need to handle. 117 } 118 119 return std::string("/xyz/openbmc_project/sensors/" + layer + "/" + id); 120 } 121 122 std::string getMatch(const std::string& path) 123 { 124 return std::string("type='signal'," 125 "interface='org.freedesktop.DBus.Properties'," 126 "member='PropertiesChanged'," 127 "path='" + 128 path + "'"); 129 } 130 131 bool validType(const std::string& type) 132 { 133 static std::set<std::string> valid = {"fan", "temp", "margin", "power", 134 "powersum"}; 135 return (valid.find(type) != valid.end()); 136 } 137 138 void scaleSensorReading(const double min, const double max, double& value) 139 { 140 if (max <= 0 || max <= min) 141 { 142 return; 143 } 144 value -= min; 145 value /= (max - min); 146 } 147 148 } // namespace pid_control 149