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