1 #include "pid/buildjson.hpp" 2 3 #include <gmock/gmock.h> 4 #include <gtest/gtest.h> 5 6 namespace pid_control 7 { 8 namespace 9 { 10 11 TEST(ZoneFromJson, emptyZone) 12 { 13 // There is a zone key, but it's empty. 14 // This is technically invalid. 15 16 std::map<int64_t, conf::PIDConf> pidConfig; 17 std::map<int64_t, conf::ZoneConfig> zoneConfig; 18 19 auto j2 = R"( 20 { 21 "zones": [] 22 } 23 )"_json; 24 25 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); 26 27 EXPECT_TRUE(pidConfig.empty()); 28 EXPECT_TRUE(zoneConfig.empty()); 29 } 30 31 TEST(ZoneFromJson, oneZoneOnePid) 32 { 33 // Parse a valid configuration with one zone and one PID. 34 // Intentionally omits "derivativeCoeff" to test that it is optional. 35 36 std::map<int64_t, conf::PIDConf> pidConfig; 37 std::map<int64_t, conf::ZoneConfig> zoneConfig; 38 39 auto j2 = R"( 40 { 41 "zones" : [{ 42 "id": 1, 43 "minThermalOutput": 3000.0, 44 "failsafePercent": 75.0, 45 "pids": [{ 46 "name": "fan1-5", 47 "type": "fan", 48 "inputs": ["fan1", "fan5"], 49 "setpoint": 90.0, 50 "pid": { 51 "samplePeriod": 0.1, 52 "proportionalCoeff": 0.0, 53 "integralCoeff": 0.0, 54 "feedFwdOffsetCoeff": 0.0, 55 "feedFwdGainCoeff": 0.010, 56 "integralLimit_min": 0.0, 57 "integralLimit_max": 0.0, 58 "outLim_min": 30.0, 59 "outLim_max": 100.0, 60 "slewNeg": 0.0, 61 "slewPos": 0.0 62 } 63 }] 64 }] 65 } 66 )"_json; 67 68 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); 69 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1)); 70 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1)); 71 72 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan"); 73 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); 74 } 75 76 TEST(ZoneFromJson, oneZoneOnePidWithHysteresis) 77 { 78 // Parse a valid configuration with one zone and one PID and the PID uses 79 // Hysteresis parameters. 80 81 std::map<int64_t, conf::PIDConf> pidConfig; 82 std::map<int64_t, conf::ZoneConfig> zoneConfig; 83 84 auto j2 = R"( 85 { 86 "zones" : [{ 87 "id": 1, 88 "minThermalOutput": 3000.0, 89 "failsafePercent": 75.0, 90 "pids": [{ 91 "name": "fan1-5", 92 "type": "fan", 93 "inputs": ["fan1", "fan5"], 94 "setpoint": 90.0, 95 "pid": { 96 "samplePeriod": 0.1, 97 "proportionalCoeff": 0.0, 98 "integralCoeff": 0.0, 99 "derivativeCoeff": 0.0, 100 "feedFwdOffsetCoeff": 0.0, 101 "feedFwdGainCoeff": 0.010, 102 "integralLimit_min": 0.0, 103 "integralLimit_max": 0.0, 104 "outLim_min": 30.0, 105 "outLim_max": 100.0, 106 "slewNeg": 0.0, 107 "slewPos": 0.0, 108 "positiveHysteresis": 1000.0, 109 "negativeHysteresis": 9000.0 110 } 111 }] 112 }] 113 } 114 )"_json; 115 116 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); 117 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1)); 118 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1)); 119 120 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan"); 121 EXPECT_DOUBLE_EQ(pidConfig[1]["fan1-5"].pidInfo.positiveHysteresis, 1000.0); 122 123 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); 124 } 125 126 TEST(ZoneFromJson, oneZoneOneStepwiseWithHysteresis) 127 { 128 // Parse a valid configuration with one zone and one PID and the PID uses 129 // Hysteresis parameters. 130 131 std::map<int64_t, conf::PIDConf> pidConfig; 132 std::map<int64_t, conf::ZoneConfig> zoneConfig; 133 134 auto j2 = R"( 135 { 136 "zones" : [{ 137 "id": 1, 138 "minThermalOutput": 3000.0, 139 "failsafePercent": 75.0, 140 "pids": [{ 141 "name": "temp1", 142 "type": "stepwise", 143 "inputs": ["temp1"], 144 "setpoint": 30.0, 145 "pid": { 146 "samplePeriod": 0.1, 147 "positiveHysteresis": 1.0, 148 "negativeHysteresis": 1.0, 149 "isCeiling": false, 150 "reading": { 151 "0": 45, 152 "1": 46, 153 "2": 47, 154 "3": 48, 155 "4": 49, 156 "5": 50, 157 "6": 51, 158 "7": 52, 159 "8": 53, 160 "9": 54, 161 "10": 55, 162 "11": 56, 163 "12": 57, 164 "13": 58, 165 "14": 59, 166 "15": 60, 167 "16": 61, 168 "17": 62, 169 "18": 63, 170 "19": 64 171 }, 172 "output": { 173 "0": 5000, 174 "1": 2400, 175 "2": 2600, 176 "3": 2800, 177 "4": 3000, 178 "5": 3200, 179 "6": 3400, 180 "7": 3600, 181 "8": 3800, 182 "9": 4000, 183 "10": 4200, 184 "11": 4400, 185 "12": 4600, 186 "13": 4800, 187 "14": 5000, 188 "15": 5200, 189 "16": 5400, 190 "17": 5600, 191 "18": 5800, 192 "19": 6000 193 } 194 } 195 }] 196 }] 197 } 198 )"_json; 199 200 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); 201 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1)); 202 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1)); 203 204 EXPECT_EQ(pidConfig[1]["temp1"].type, "stepwise"); 205 EXPECT_DOUBLE_EQ(pidConfig[1]["temp1"].stepwiseInfo.positiveHysteresis, 206 1.0); 207 208 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); 209 } 210 211 TEST(ZoneFromJson, getCycleInterval) 212 { 213 // Parse a valid configuration with one zone and one PID and the zone have 214 // cycleIntervalTime and updateThermalsTime parameters. 215 216 std::map<int64_t, conf::PIDConf> pidConfig; 217 std::map<int64_t, conf::ZoneConfig> zoneConfig; 218 219 auto j2 = R"( 220 { 221 "zones" : [{ 222 "id": 1, 223 "minThermalOutput": 3000.0, 224 "failsafePercent": 75.0, 225 "cycleIntervalTimeMS": 1000.0, 226 "updateThermalsTimeMS": 1000.0, 227 "pids": [{ 228 "name": "fan1-5", 229 "type": "fan", 230 "inputs": ["fan1", "fan5"], 231 "setpoint": 90.0, 232 "pid": { 233 "samplePeriod": 0.1, 234 "proportionalCoeff": 0.0, 235 "integralCoeff": 0.0, 236 "derivativeCoeff": 0.0, 237 "feedFwdOffsetCoeff": 0.0, 238 "feedFwdGainCoeff": 0.010, 239 "integralLimit_min": 0.0, 240 "integralLimit_max": 0.0, 241 "outLim_min": 30.0, 242 "outLim_max": 100.0, 243 "slewNeg": 0.0, 244 "slewPos": 0.0 245 } 246 }] 247 }] 248 } 249 )"_json; 250 251 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); 252 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1)); 253 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1)); 254 255 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan"); 256 EXPECT_EQ(zoneConfig[1].cycleTime.cycleIntervalTimeMS, 257 static_cast<u_int64_t>(1000)); 258 EXPECT_EQ(zoneConfig[1].cycleTime.updateThermalsTimeMS, 259 static_cast<u_int64_t>(1000)); 260 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); 261 } 262 263 } // namespace 264 } // namespace pid_control 265