blob: 690e6dd225383cc46d37eaad9005b708a831721f [file] [log] [blame]
Ed Tanousf8b6e552025-06-27 13:27:50 -07001#include "conf.hpp"
Patrick Ventured1491722019-02-08 14:37:45 -08002#include "pid/buildjson.hpp"
3
Ed Tanousf8b6e552025-06-27 13:27:50 -07004#include <sys/types.h>
5
6#include <cstdint>
7#include <map>
8#include <tuple>
9
Patrick Ventured1491722019-02-08 14:37:45 -080010#include <gtest/gtest.h>
11
Patrick Venturea0764872020-08-08 07:48:43 -070012namespace pid_control
13{
14namespace
15{
16
Patrick Ventured1491722019-02-08 14:37:45 -080017TEST(ZoneFromJson, emptyZone)
18{
19 // There is a zone key, but it's empty.
20 // This is technically invalid.
21
James Feistf81f2882019-02-26 11:26:36 -080022 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -070023 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Ventured1491722019-02-08 14:37:45 -080024
25 auto j2 = R"(
26 {
27 "zones": []
28 }
29 )"_json;
30
31 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
32
33 EXPECT_TRUE(pidConfig.empty());
34 EXPECT_TRUE(zoneConfig.empty());
35}
36
37TEST(ZoneFromJson, oneZoneOnePid)
38{
39 // Parse a valid configuration with one zone and one PID.
Josh Lehanc612c052022-12-12 09:56:47 -080040 // Intentionally omits "derivativeCoeff" to test that it is optional.
Patrick Ventured1491722019-02-08 14:37:45 -080041
James Feistf81f2882019-02-26 11:26:36 -080042 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -070043 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Ventured1491722019-02-08 14:37:45 -080044
45 auto j2 = R"(
46 {
47 "zones" : [{
48 "id": 1,
James Feist3484bed2019-02-25 13:28:18 -080049 "minThermalOutput": 3000.0,
Patrick Ventured1491722019-02-08 14:37:45 -080050 "failsafePercent": 75.0,
51 "pids": [{
52 "name": "fan1-5",
53 "type": "fan",
54 "inputs": ["fan1", "fan5"],
55 "setpoint": 90.0,
56 "pid": {
57 "samplePeriod": 0.1,
58 "proportionalCoeff": 0.0,
59 "integralCoeff": 0.0,
Patrick Venture903b0422019-02-20 07:35:48 -080060 "feedFwdOffsetCoeff": 0.0,
Patrick Ventured1491722019-02-08 14:37:45 -080061 "feedFwdGainCoeff": 0.010,
62 "integralLimit_min": 0.0,
63 "integralLimit_max": 0.0,
64 "outLim_min": 30.0,
65 "outLim_max": 100.0,
66 "slewNeg": 0.0,
67 "slewPos": 0.0
68 }
69 }]
70 }]
71 }
72 )"_json;
73
74 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +080075 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
76 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Patrick Ventured1491722019-02-08 14:37:45 -080077
78 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
James Feist3484bed2019-02-25 13:28:18 -080079 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
Patrick Ventured1491722019-02-08 14:37:45 -080080}
Patrick Venturee3eeef42019-03-26 07:10:59 -070081
Josh Lehan31058fd2023-01-13 11:06:16 -080082TEST(ZoneFromJson, marginZone)
83{
84 // Parse a valid configuration with one zone and one PID.
85 // This is a margin zone, and has both kinds of temperature
86 // sensors in it, absolute temperature and margin temperature.
87 // Tests that TempToMargin is parsed correctly.
88
89 std::map<int64_t, conf::PIDConf> pidConfig;
90 std::map<int64_t, conf::ZoneConfig> zoneConfig;
91
92 auto j2 = R"(
93 {
94 "zones" : [{
95 "id": 1,
96 "minThermalOutput": 3000.0,
97 "failsafePercent": 75.0,
98 "pids": [{
99 "name": "myPid",
100 "type": "margin",
101 "inputs": ["absolute0", "absolute1", "margin0", "margin1"],
102 "tempToMargin": [
103 85.0,
104 100.0
105 ],
106 "setpoint": 10.0,
107 "pid": {
108 "samplePeriod": 0.1,
109 "proportionalCoeff": 0.0,
110 "integralCoeff": 0.0,
111 "feedFwdOffsetCoeff": 0.0,
112 "feedFwdGainCoeff": 0.010,
113 "integralLimit_min": 0.0,
114 "integralLimit_max": 0.0,
115 "outLim_min": 30.0,
116 "outLim_max": 100.0,
117 "slewNeg": 0.0,
118 "slewPos": 0.0
119 }
120 }]
121 }]
122 }
123 )"_json;
124
125 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
126 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
127 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
128
129 EXPECT_EQ(pidConfig[1]["myPid"].type, "margin");
130 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
131
132 EXPECT_EQ(pidConfig[1]["myPid"].inputs[0].name, "absolute0");
133 EXPECT_DOUBLE_EQ(pidConfig[1]["myPid"].inputs[0].convertMarginZero, 85.0);
134 EXPECT_EQ(pidConfig[1]["myPid"].inputs[0].convertTempToMargin, true);
135
136 EXPECT_EQ(pidConfig[1]["myPid"].inputs[1].name, "absolute1");
137 EXPECT_DOUBLE_EQ(pidConfig[1]["myPid"].inputs[1].convertMarginZero, 100.0);
138 EXPECT_EQ(pidConfig[1]["myPid"].inputs[1].convertTempToMargin, true);
139
140 EXPECT_EQ(pidConfig[1]["myPid"].inputs[2].name, "margin0");
141 EXPECT_EQ(pidConfig[1]["myPid"].inputs[2].convertTempToMargin, false);
142
143 EXPECT_EQ(pidConfig[1]["myPid"].inputs[3].name, "margin1");
144 EXPECT_EQ(pidConfig[1]["myPid"].inputs[3].convertTempToMargin, false);
145}
146
Patrick Venturee3eeef42019-03-26 07:10:59 -0700147TEST(ZoneFromJson, oneZoneOnePidWithHysteresis)
148{
149 // Parse a valid configuration with one zone and one PID and the PID uses
150 // Hysteresis parameters.
151
152 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -0700153 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Patrick Venturee3eeef42019-03-26 07:10:59 -0700154
155 auto j2 = R"(
156 {
157 "zones" : [{
158 "id": 1,
159 "minThermalOutput": 3000.0,
160 "failsafePercent": 75.0,
161 "pids": [{
162 "name": "fan1-5",
163 "type": "fan",
164 "inputs": ["fan1", "fan5"],
165 "setpoint": 90.0,
166 "pid": {
167 "samplePeriod": 0.1,
168 "proportionalCoeff": 0.0,
169 "integralCoeff": 0.0,
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800170 "derivativeCoeff": 0.0,
Patrick Venturee3eeef42019-03-26 07:10:59 -0700171 "feedFwdOffsetCoeff": 0.0,
172 "feedFwdGainCoeff": 0.010,
173 "integralLimit_min": 0.0,
174 "integralLimit_max": 0.0,
175 "outLim_min": 30.0,
176 "outLim_max": 100.0,
177 "slewNeg": 0.0,
178 "slewPos": 0.0,
179 "positiveHysteresis": 1000.0,
180 "negativeHysteresis": 9000.0
181 }
182 }]
183 }]
184 }
185 )"_json;
186
187 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +0800188 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
189 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Patrick Venturee3eeef42019-03-26 07:10:59 -0700190
191 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
192 EXPECT_DOUBLE_EQ(pidConfig[1]["fan1-5"].pidInfo.positiveHysteresis, 1000.0);
193
194 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
195}
Hank Liou375f7092019-03-29 20:15:42 +0800196
197TEST(ZoneFromJson, oneZoneOneStepwiseWithHysteresis)
198{
199 // Parse a valid configuration with one zone and one PID and the PID uses
200 // Hysteresis parameters.
201
202 std::map<int64_t, conf::PIDConf> pidConfig;
Patrick Venture1df9e872020-10-08 15:35:01 -0700203 std::map<int64_t, conf::ZoneConfig> zoneConfig;
Hank Liou375f7092019-03-29 20:15:42 +0800204
205 auto j2 = R"(
206 {
207 "zones" : [{
208 "id": 1,
209 "minThermalOutput": 3000.0,
210 "failsafePercent": 75.0,
211 "pids": [{
212 "name": "temp1",
213 "type": "stepwise",
214 "inputs": ["temp1"],
215 "setpoint": 30.0,
216 "pid": {
217 "samplePeriod": 0.1,
218 "positiveHysteresis": 1.0,
219 "negativeHysteresis": 1.0,
220 "isCeiling": false,
221 "reading": {
222 "0": 45,
223 "1": 46,
224 "2": 47,
225 "3": 48,
226 "4": 49,
227 "5": 50,
228 "6": 51,
229 "7": 52,
230 "8": 53,
231 "9": 54,
232 "10": 55,
233 "11": 56,
234 "12": 57,
235 "13": 58,
236 "14": 59,
237 "15": 60,
238 "16": 61,
239 "17": 62,
240 "18": 63,
241 "19": 64
242 },
243 "output": {
244 "0": 5000,
245 "1": 2400,
246 "2": 2600,
247 "3": 2800,
248 "4": 3000,
249 "5": 3200,
250 "6": 3400,
251 "7": 3600,
252 "8": 3800,
253 "9": 4000,
254 "10": 4200,
255 "11": 4400,
256 "12": 4600,
257 "13": 4800,
258 "14": 5000,
259 "15": 5200,
260 "16": 5400,
261 "17": 5600,
262 "18": 5800,
263 "19": 6000
264 }
265 }
266 }]
267 }]
268 }
269 )"_json;
270
271 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey.Wua1ae4fa2022-10-28 17:38:35 +0800272 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
273 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Hank Liou375f7092019-03-29 20:15:42 +0800274
275 EXPECT_EQ(pidConfig[1]["temp1"].type, "stepwise");
276 EXPECT_DOUBLE_EQ(pidConfig[1]["temp1"].stepwiseInfo.positiveHysteresis,
277 1.0);
278
279 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
Patrick Venturea0764872020-08-08 07:48:43 -0700280}
281
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800282TEST(ZoneFromJson, getCycleInterval)
283{
284 // Parse a valid configuration with one zone and one PID and the zone have
285 // cycleIntervalTime and updateThermalsTime parameters.
286
287 std::map<int64_t, conf::PIDConf> pidConfig;
288 std::map<int64_t, conf::ZoneConfig> zoneConfig;
289
290 auto j2 = R"(
291 {
292 "zones" : [{
293 "id": 1,
294 "minThermalOutput": 3000.0,
295 "failsafePercent": 75.0,
296 "cycleIntervalTimeMS": 1000.0,
297 "updateThermalsTimeMS": 1000.0,
298 "pids": [{
299 "name": "fan1-5",
300 "type": "fan",
301 "inputs": ["fan1", "fan5"],
302 "setpoint": 90.0,
303 "pid": {
304 "samplePeriod": 0.1,
305 "proportionalCoeff": 0.0,
306 "integralCoeff": 0.0,
307 "derivativeCoeff": 0.0,
308 "feedFwdOffsetCoeff": 0.0,
309 "feedFwdGainCoeff": 0.010,
310 "integralLimit_min": 0.0,
311 "integralLimit_max": 0.0,
312 "outLim_min": 30.0,
313 "outLim_max": 100.0,
314 "slewNeg": 0.0,
315 "slewPos": 0.0
316 }
317 }]
318 }]
319 }
320 )"_json;
321
322 std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
Harvey Wu57a7af62023-06-14 16:09:46 +0800323 EXPECT_EQ(pidConfig.size(), static_cast<u_int64_t>(1));
324 EXPECT_EQ(zoneConfig.size(), static_cast<u_int64_t>(1));
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800325
326 EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
Harvey Wu57a7af62023-06-14 16:09:46 +0800327 EXPECT_EQ(zoneConfig[1].cycleTime.cycleIntervalTimeMS,
328 static_cast<u_int64_t>(1000));
329 EXPECT_EQ(zoneConfig[1].cycleTime.updateThermalsTimeMS,
330 static_cast<u_int64_t>(1000));
Bonnie Lo0e8fc392022-10-05 10:20:55 +0800331 EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
332}
333
Patrick Venturea0764872020-08-08 07:48:43 -0700334} // namespace
335} // namespace pid_control