blob: 59db3437b931e9d8a214fb3bd51d2776010ac0a1 [file] [log] [blame]
Patrick Ventured1491722019-02-08 14:37:45 -08001#include "pid/buildjson.hpp"
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
Patrick Venturea0764872020-08-08 07:48:43 -07006namespace pid_control
7{
8namespace
9{
10
Patrick Ventured1491722019-02-08 14:37:45 -080011TEST(ZoneFromJson, emptyZone)
12{
13 // There is a zone key, but it's empty.
14 // This is technically invalid.
15
James Feistf81f2882019-02-26 11:26:36 -080016 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -070017 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Ventured1491722019-02-08 14:37:45 -080018
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
31TEST(ZoneFromJson, oneZoneOnePid)
32{
33 // Parse a valid configuration with one zone and one PID.
Josh Lehanc612c052022-12-12 09:56:47 -080034 // Intentionally omits "derivativeCoeff" to test that it is optional.
Patrick Ventured1491722019-02-08 14:37:45 -080035
James Feistf81f2882019-02-26 11:26:36 -080036 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -070037 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Ventured1491722019-02-08 14:37:45 -080038
39 auto j2 = R"(
40 {
41 "zones" : [{
42 "id": 1,
James Feist3484bed2019-02-25 13:28:18 -080043 "minThermalOutput": 3000.0,
Patrick Ventured1491722019-02-08 14:37:45 -080044 "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,
Patrick Venture903b0422019-02-20 07:35:48 -080054 "feedFwdOffsetCoeff": 0.0,
Patrick Ventured1491722019-02-08 14:37:45 -080055 "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);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +080069 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
70 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Patrick Ventured1491722019-02-08 14:37:45 -080071
72 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
James Feist3484bed2019-02-25 13:28:18 -080073 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
Patrick Ventured1491722019-02-08 14:37:45 -080074}
Patrick Venturee3eeef42019-03-26 07:10:59 -070075
Josh Lehan31058fd2023-01-13 11:06:16 -080076TEST(ZoneFromJson, marginZone)
77{
78 // Parse a valid configuration with one zone and one PID.
79 // This is a margin zone, and has both kinds of temperature
80 // sensors in it, absolute temperature and margin temperature.
81 // Tests that TempToMargin is parsed correctly.
82
83 std::map<int64_t, conf::PIDConf> pidConfig;
84 std::map<int64_t, conf::ZoneConfig> zoneConfig;
85
86 auto j2 = R"(
87 {
88 "zones" : [{
89 "id": 1,
90 "minThermalOutput": 3000.0,
91 "failsafePercent": 75.0,
92 "pids": [{
93 "name": "myPid",
94 "type": "margin",
95 "inputs": ["absolute0", "absolute1", "margin0", "margin1"],
96 "tempToMargin": [
97 85.0,
98 100.0
99 ],
100 "setpoint": 10.0,
101 "pid": {
102 "samplePeriod": 0.1,
103 "proportionalCoeff": 0.0,
104 "integralCoeff": 0.0,
105 "feedFwdOffsetCoeff": 0.0,
106 "feedFwdGainCoeff": 0.010,
107 "integralLimit_min": 0.0,
108 "integralLimit_max": 0.0,
109 "outLim_min": 30.0,
110 "outLim_max": 100.0,
111 "slewNeg": 0.0,
112 "slewPos": 0.0
113 }
114 }]
115 }]
116 }
117 )"_json;
118
119 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
120 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
121 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
122
123 EXPECT_EQ(pidConfig[1]["myPid"].type, "margin");
124 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
125
126 EXPECT_EQ(pidConfig[1]["myPid"].inputs[0].name, "absolute0");
127 EXPECT_DOUBLE_EQ(pidConfig[1]["myPid"].inputs[0].convertMarginZero, 85.0);
128 EXPECT_EQ(pidConfig[1]["myPid"].inputs[0].convertTempToMargin, true);
129
130 EXPECT_EQ(pidConfig[1]["myPid"].inputs[1].name, "absolute1");
131 EXPECT_DOUBLE_EQ(pidConfig[1]["myPid"].inputs[1].convertMarginZero, 100.0);
132 EXPECT_EQ(pidConfig[1]["myPid"].inputs[1].convertTempToMargin, true);
133
134 EXPECT_EQ(pidConfig[1]["myPid"].inputs[2].name, "margin0");
135 EXPECT_EQ(pidConfig[1]["myPid"].inputs[2].convertTempToMargin, false);
136
137 EXPECT_EQ(pidConfig[1]["myPid"].inputs[3].name, "margin1");
138 EXPECT_EQ(pidConfig[1]["myPid"].inputs[3].convertTempToMargin, false);
139}
140
Patrick Venturee3eeef42019-03-26 07:10:59 -0700141TEST(ZoneFromJson, oneZoneOnePidWithHysteresis)
142{
143 // Parse a valid configuration with one zone and one PID and the PID uses
144 // Hysteresis parameters.
145
146 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -0700147 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Venturee3eeef42019-03-26 07:10:59 -0700148
149 auto j2 = R"(
150 {
151 "zones" : [{
152 "id": 1,
153 "minThermalOutput": 3000.0,
154 "failsafePercent": 75.0,
155 "pids": [{
156 "name": "fan1-5",
157 "type": "fan",
158 "inputs": ["fan1", "fan5"],
159 "setpoint": 90.0,
160 "pid": {
161 "samplePeriod": 0.1,
162 "proportionalCoeff": 0.0,
163 "integralCoeff": 0.0,
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800164 "derivativeCoeff": 0.0,
Patrick Venturee3eeef42019-03-26 07:10:59 -0700165 "feedFwdOffsetCoeff": 0.0,
166 "feedFwdGainCoeff": 0.010,
167 "integralLimit_min": 0.0,
168 "integralLimit_max": 0.0,
169 "outLim_min": 30.0,
170 "outLim_max": 100.0,
171 "slewNeg": 0.0,
172 "slewPos": 0.0,
173 "positiveHysteresis": 1000.0,
174 "negativeHysteresis": 9000.0
175 }
176 }]
177 }]
178 }
179 )"_json;
180
181 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +0800182 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
183 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Patrick Venturee3eeef42019-03-26 07:10:59 -0700184
185 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
186 EXPECT_DOUBLE_EQ(pidConfig[1]["fan1-5"].pidInfo.positiveHysteresis, 1000.0);
187
188 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
189}
Hank Liou375f7092019-03-29 20:15:42 +0800190
191TEST(ZoneFromJson, oneZoneOneStepwiseWithHysteresis)
192{
193 // Parse a valid configuration with one zone and one PID and the PID uses
194 // Hysteresis parameters.
195
196 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -0700197 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Hank Liou375f7092019-03-29 20:15:42 +0800198
199 auto j2 = R"(
200 {
201 "zones" : [{
202 "id": 1,
203 "minThermalOutput": 3000.0,
204 "failsafePercent": 75.0,
205 "pids": [{
206 "name": "temp1",
207 "type": "stepwise",
208 "inputs": ["temp1"],
209 "setpoint": 30.0,
210 "pid": {
211 "samplePeriod": 0.1,
212 "positiveHysteresis": 1.0,
213 "negativeHysteresis": 1.0,
214 "isCeiling": false,
215 "reading": {
216 "0": 45,
217 "1": 46,
218 "2": 47,
219 "3": 48,
220 "4": 49,
221 "5": 50,
222 "6": 51,
223 "7": 52,
224 "8": 53,
225 "9": 54,
226 "10": 55,
227 "11": 56,
228 "12": 57,
229 "13": 58,
230 "14": 59,
231 "15": 60,
232 "16": 61,
233 "17": 62,
234 "18": 63,
235 "19": 64
236 },
237 "output": {
238 "0": 5000,
239 "1": 2400,
240 "2": 2600,
241 "3": 2800,
242 "4": 3000,
243 "5": 3200,
244 "6": 3400,
245 "7": 3600,
246 "8": 3800,
247 "9": 4000,
248 "10": 4200,
249 "11": 4400,
250 "12": 4600,
251 "13": 4800,
252 "14": 5000,
253 "15": 5200,
254 "16": 5400,
255 "17": 5600,
256 "18": 5800,
257 "19": 6000
258 }
259 }
260 }]
261 }]
262 }
263 )"_json;
264
265 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +0800266 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
267 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Hank Liou375f7092019-03-29 20:15:42 +0800268
269 EXPECT_EQ(pidConfig[1]["temp1"].type, "stepwise");
270 EXPECT_DOUBLE_EQ(pidConfig[1]["temp1"].stepwiseInfo.positiveHysteresis,
271 1.0);
272
273 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
Patrick Venturea0764872020-08-08 07:48:43 -0700274}
275
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800276TEST(ZoneFromJson, getCycleInterval)
277{
278 // Parse a valid configuration with one zone and one PID and the zone have
279 // cycleIntervalTime and updateThermalsTime parameters.
280
281 std::map<int64_t, conf::PIDConf> pidConfig;
282 std::map<int64_t, conf::ZoneConfig> zoneConfig;
283
284 auto j2 = R"(
285 {
286 "zones" : [{
287 "id": 1,
288 "minThermalOutput": 3000.0,
289 "failsafePercent": 75.0,
290 "cycleIntervalTimeMS": 1000.0,
291 "updateThermalsTimeMS": 1000.0,
292 "pids": [{
293 "name": "fan1-5",
294 "type": "fan",
295 "inputs": ["fan1", "fan5"],
296 "setpoint": 90.0,
297 "pid": {
298 "samplePeriod": 0.1,
299 "proportionalCoeff": 0.0,
300 "integralCoeff": 0.0,
301 "derivativeCoeff": 0.0,
302 "feedFwdOffsetCoeff": 0.0,
303 "feedFwdGainCoeff": 0.010,
304 "integralLimit_min": 0.0,
305 "integralLimit_max": 0.0,
306 "outLim_min": 30.0,
307 "outLim_max": 100.0,
308 "slewNeg": 0.0,
309 "slewPos": 0.0
310 }
311 }]
312 }]
313 }
314 )"_json;
315
316 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey Wu57a7af62023-06-14 16:09:46 +0800317 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
318 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800319
320 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
Harvey Wu57a7af62023-06-14 16:09:46 +0800321 EXPECT_EQ(zoneConfig[1].cycleTime.cycleIntervalTimeMS,
322 static_cast<u_int64_t>(1000));
323 EXPECT_EQ(zoneConfig[1].cycleTime.updateThermalsTimeMS,
324 static_cast<u_int64_t>(1000));
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800325 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
326}
327
Patrick Venturea0764872020-08-08 07:48:43 -0700328} // namespace
329} // namespace pid_control