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, struct 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 
35     std::map<int64_t, conf::PIDConf> pidConfig;
36     std::map<int64_t, struct conf::ZoneConfig> zoneConfig;
37 
38     auto j2 = R"(
39       {
40         "zones" : [{
41           "id": 1,
42           "minThermalOutput": 3000.0,
43           "failsafePercent": 75.0,
44           "pids": [{
45             "name": "fan1-5",
46             "type": "fan",
47             "inputs": ["fan1", "fan5"],
48             "setpoint": 90.0,
49             "pid": {
50               "samplePeriod": 0.1,
51               "proportionalCoeff": 0.0,
52               "integralCoeff": 0.0,
53               "feedFwdOffsetCoeff": 0.0,
54               "feedFwdGainCoeff": 0.010,
55               "integralLimit_min": 0.0,
56               "integralLimit_max": 0.0,
57               "outLim_min": 30.0,
58               "outLim_max": 100.0,
59               "slewNeg": 0.0,
60               "slewPos": 0.0
61             }
62           }]
63         }]
64       }
65     )"_json;
66 
67     std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
68     EXPECT_EQ(pidConfig.size(), 1);
69     EXPECT_EQ(zoneConfig.size(), 1);
70 
71     EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
72     EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
73 }
74 
75 TEST(ZoneFromJson, oneZoneOnePidWithHysteresis)
76 {
77     // Parse a valid configuration with one zone and one PID and the PID uses
78     // Hysteresis parameters.
79 
80     std::map<int64_t, conf::PIDConf> pidConfig;
81     std::map<int64_t, struct conf::ZoneConfig> zoneConfig;
82 
83     auto j2 = R"(
84       {
85         "zones" : [{
86           "id": 1,
87           "minThermalOutput": 3000.0,
88           "failsafePercent": 75.0,
89           "pids": [{
90             "name": "fan1-5",
91             "type": "fan",
92             "inputs": ["fan1", "fan5"],
93             "setpoint": 90.0,
94             "pid": {
95               "samplePeriod": 0.1,
96               "proportionalCoeff": 0.0,
97               "integralCoeff": 0.0,
98               "feedFwdOffsetCoeff": 0.0,
99               "feedFwdGainCoeff": 0.010,
100               "integralLimit_min": 0.0,
101               "integralLimit_max": 0.0,
102               "outLim_min": 30.0,
103               "outLim_max": 100.0,
104               "slewNeg": 0.0,
105               "slewPos": 0.0,
106               "positiveHysteresis": 1000.0,
107               "negativeHysteresis": 9000.0
108             }
109           }]
110         }]
111       }
112     )"_json;
113 
114     std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
115     EXPECT_EQ(pidConfig.size(), 1);
116     EXPECT_EQ(zoneConfig.size(), 1);
117 
118     EXPECT_EQ(pidConfig[1]["fan1-5"].type, "fan");
119     EXPECT_DOUBLE_EQ(pidConfig[1]["fan1-5"].pidInfo.positiveHysteresis, 1000.0);
120 
121     EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
122 }
123 
124 TEST(ZoneFromJson, oneZoneOneStepwiseWithHysteresis)
125 {
126     // Parse a valid configuration with one zone and one PID and the PID uses
127     // Hysteresis parameters.
128 
129     std::map<int64_t, conf::PIDConf> pidConfig;
130     std::map<int64_t, struct conf::ZoneConfig> zoneConfig;
131 
132     auto j2 = R"(
133       {
134         "zones" : [{
135           "id": 1,
136           "minThermalOutput": 3000.0,
137           "failsafePercent": 75.0,
138           "pids": [{
139             "name": "temp1",
140             "type": "stepwise",
141             "inputs": ["temp1"],
142             "setpoint": 30.0,
143             "pid": {
144               "samplePeriod": 0.1,
145               "positiveHysteresis": 1.0,
146               "negativeHysteresis": 1.0,
147               "isCeiling": false,
148               "reading": {
149                 "0": 45,
150                 "1": 46,
151                 "2": 47,
152                 "3": 48,
153                 "4": 49,
154                 "5": 50,
155                 "6": 51,
156                 "7": 52,
157                 "8": 53,
158                 "9": 54,
159                 "10": 55,
160                 "11": 56,
161                 "12": 57,
162                 "13": 58,
163                 "14": 59,
164                 "15": 60,
165                 "16": 61,
166                 "17": 62,
167                 "18": 63,
168                 "19": 64
169               },
170               "output": {
171                 "0": 5000,
172                 "1": 2400,
173                 "2": 2600,
174                 "3": 2800,
175                 "4": 3000,
176                 "5": 3200,
177                 "6": 3400,
178                 "7": 3600,
179                 "8": 3800,
180                 "9": 4000,
181                 "10": 4200,
182                 "11": 4400,
183                 "12": 4600,
184                 "13": 4800,
185                 "14": 5000,
186                 "15": 5200,
187                 "16": 5400,
188                 "17": 5600,
189                 "18": 5800,
190                 "19": 6000
191               }
192             }
193           }]
194         }]
195       }
196     )"_json;
197 
198     std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2);
199     EXPECT_EQ(pidConfig.size(), 1);
200     EXPECT_EQ(zoneConfig.size(), 1);
201 
202     EXPECT_EQ(pidConfig[1]["temp1"].type, "stepwise");
203     EXPECT_DOUBLE_EQ(pidConfig[1]["temp1"].stepwiseInfo.positiveHysteresis,
204                      1.0);
205 
206     EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0);
207 }
208 
209 } // namespace
210 } // namespace pid_control
211