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