3-phase PV router
Loading...
Searching...
No Matches
test_main.cpp
Go to the documentation of this file.
1#include <unity.h>
2#include <cstdio>
3
4// Mock Arduino types and constants for native testing
5typedef uint8_t byte;
6#define HIGH 1
7#define LOW 0
8
9// Mock pin and config definitions
15enum outputType_t : byte
16{
19};
20
21// Simple mock relay output class for testing
23{
24public:
28
29 MockRelayOutput(int32_t import_threshold = 20, int32_t surplus_threshold = 20)
30 : m_relay_state(false), m_import_threshold(import_threshold), m_surplus_threshold(surplus_threshold) {}
31
32 // Core relay logic for negative threshold testing
33 bool proceed_relay(int32_t power_value)
34 {
35 bool new_state = m_relay_state;
36
37 if (m_import_threshold < 0)
38 {
39 // Battery scenario: negative threshold means we want surplus above abs(threshold)
40 int32_t required_surplus = -m_import_threshold;
41 if (!m_relay_state && power_value >= required_surplus)
42 {
43 new_state = true; // Turn on when surplus exceeds threshold
44 }
45 else if (m_relay_state && power_value < (required_surplus - m_surplus_threshold))
46 {
47 new_state = false; // Turn off when surplus drops below (threshold - hysteresis)
48 }
49 }
50 else
51 {
52 // Normal scenario: positive threshold means import/export boundary
53 if (!m_relay_state && power_value >= m_import_threshold)
54 {
55 new_state = true; // Turn on when import exceeds threshold
56 }
57 else if (m_relay_state && power_value < (m_import_threshold - m_surplus_threshold))
58 {
59 new_state = false; // Turn off when import drops below threshold minus hysteresis
60 }
61 }
62
63 m_relay_state = new_state;
64 return m_relay_state;
65 }
66
68 {
69 m_relay_state = false;
70 }
71};
72
73void setUp(void)
74{
75 // Set up before each test
76}
77
78void tearDown(void)
79{
80 // Clean up after each test
81}
82
84{
85 MockRelayOutput relay(20, 10); // 20W import threshold, 10W hysteresis
86
87 // Start with relay off, below threshold
88 TEST_ASSERT_FALSE(relay.proceed_relay(10)); // 10W import < 20W threshold
89 TEST_ASSERT_FALSE(relay.proceed_relay(15)); // Still below threshold
90
91 // Cross threshold - relay should turn on
92 TEST_ASSERT_TRUE(relay.proceed_relay(25)); // 25W import > 20W threshold
93 TEST_ASSERT_TRUE(relay.proceed_relay(30)); // Stay on above threshold
94
95 // Drop below threshold but above hysteresis - should stay on
96 TEST_ASSERT_TRUE(relay.proceed_relay(15)); // 15W > (20-10)W, stay on
97
98 // Drop below hysteresis - should turn off
99 TEST_ASSERT_FALSE(relay.proceed_relay(5)); // 5W < (20-10)W, turn off
100}
101
103{
104 MockRelayOutput relay(-50, 20); // -50W threshold (need 50W+ surplus), 20W hysteresis
105
106 // Start with relay off - no surplus or small surplus
107 TEST_ASSERT_FALSE(relay.proceed_relay(-10)); // 10W import, no surplus
108 TEST_ASSERT_FALSE(relay.proceed_relay(0)); // Zero import/export
109 TEST_ASSERT_FALSE(relay.proceed_relay(30)); // 30W surplus < 50W required
110
111 // Reach required surplus - relay should turn on
112 TEST_ASSERT_TRUE(relay.proceed_relay(60)); // 60W surplus > 50W required
113 TEST_ASSERT_TRUE(relay.proceed_relay(100)); // Stay on with more surplus
114
115 // Drop surplus but stay above hysteresis - should stay on
116 TEST_ASSERT_TRUE(relay.proceed_relay(40)); // 40W > (50-20)W, stay on
117
118 // Drop below hysteresis - should turn off
119 TEST_ASSERT_FALSE(relay.proceed_relay(25)); // 25W < (50-20)W, turn off
120}
121
123{
124 MockRelayOutput relay(-100, 30); // -100W threshold (need 100W+ surplus), 30W hysteresis
125
126 // Test exactly at boundaries
127 TEST_ASSERT_FALSE(relay.proceed_relay(99)); // Just below threshold
128 TEST_ASSERT_TRUE(relay.proceed_relay(100)); // Exactly at threshold
129 TEST_ASSERT_TRUE(relay.proceed_relay(101)); // Just above threshold
130
131 // Test hysteresis boundary when relay is on
132 TEST_ASSERT_TRUE(relay.proceed_relay(71)); // 71W > (100-30)W, stay on
133 TEST_ASSERT_TRUE(relay.proceed_relay(70)); // Exactly at hysteresis boundary
134 TEST_ASSERT_FALSE(relay.proceed_relay(69)); // Just below hysteresis
135}
136
138{
139 MockRelayOutput relay(-30, 15); // -30W threshold, 15W hysteresis
140
141 // Test behavior during import (negative power values)
142 TEST_ASSERT_FALSE(relay.proceed_relay(-50)); // Importing 50W, no surplus
143 TEST_ASSERT_FALSE(relay.proceed_relay(-10)); // Importing 10W, no surplus
144 TEST_ASSERT_FALSE(relay.proceed_relay(0)); // Zero point
145
146 // Move to surplus and cross threshold
147 TEST_ASSERT_FALSE(relay.proceed_relay(20)); // 20W surplus < 30W required
148 TEST_ASSERT_TRUE(relay.proceed_relay(35)); // 35W surplus > 30W required
149
150 // Drop back through zero to import - should turn off immediately
151 TEST_ASSERT_FALSE(relay.proceed_relay(-5)); // Import 5W < hysteresis boundary (15W)
152}
153
155{
156 MockRelayOutput relay(0, 10); // 0W threshold (normal scenario)
157
158 // Should behave like normal positive threshold at zero
159 TEST_ASSERT_FALSE(relay.proceed_relay(-10)); // Import, relay off
160 TEST_ASSERT_TRUE(relay.proceed_relay(5)); // Export, relay on
161 TEST_ASSERT_TRUE(relay.proceed_relay(-5)); // Back to import but above hysteresis
162 TEST_ASSERT_FALSE(relay.proceed_relay(-15)); // Below hysteresis, relay off
163}
164
166{
167 MockRelayOutput relay(-500, 100); // Very large negative threshold for high-power battery systems
168
169 // Test with realistic battery power levels
170 TEST_ASSERT_FALSE(relay.proceed_relay(-1000)); // Heavy import
171 TEST_ASSERT_FALSE(relay.proceed_relay(400)); // 400W surplus < 500W required
172 TEST_ASSERT_TRUE(relay.proceed_relay(600)); // 600W surplus > 500W required
173 TEST_ASSERT_TRUE(relay.proceed_relay(450)); // 450W > (500-100)W hysteresis
174 TEST_ASSERT_FALSE(relay.proceed_relay(350)); // 350W < 400W hysteresis boundary
175}
176
178{
179 MockRelayOutput relay(-40, 20); // -40W threshold, 20W hysteresis
180
181 printf("DEBUG: Testing negative threshold state transitions\n");
182 printf("DEBUG: Threshold=-40W (need 40W+ surplus), Hysteresis=20W\n");
183
184 // Track state changes
185 bool prev_state = false;
186 int32_t test_values[] = { -20, 0, 20, 35, 45, 30, 25, 15 };
187 const char* descriptions[] = {
188 "Import 20W", "Zero", "Surplus 20W", "Surplus 35W",
189 "Surplus 45W (ON)", "Surplus 30W", "Surplus 25W", "Surplus 15W (OFF)"
190 };
191
192 for (int i = 0; i < 8; i++)
193 {
194 bool new_state = relay.proceed_relay(test_values[i]);
195 printf("DEBUG: Power=%dW, State=%s, Description=%s\n",
196 (int)test_values[i], new_state ? "ON" : "OFF", descriptions[i]);
197
198 if (i == 4) TEST_ASSERT_TRUE(new_state); // Should be on at 45W surplus
199 if (i == 7) TEST_ASSERT_FALSE(new_state); // Should be off at 15W surplus
200
201 prev_state = new_state;
202 }
203}
204
205int main()
206{
207 UNITY_BEGIN();
208
216
217 return UNITY_END();
218}
MockRelayOutput(int32_t import_threshold=20, int32_t surplus_threshold=20)
Definition test_main.cpp:29
int32_t m_surplus_threshold
Definition test_main.cpp:27
bool proceed_relay(int32_t power_value)
Definition test_main.cpp:33
int32_t m_import_threshold
Definition test_main.cpp:26
void setUp(void)
Definition test_main.cpp:6
void tearDown(void)
Definition test_main.cpp:11
uint8_t i
unsigned char byte
Definition test_main.cpp:7
int main()
relayState_t
Definition test_main.cpp:11
@ RELAY_ON
Definition test_main.cpp:12
@ RELAY_OFF
Definition test_main.cpp:13
outputType_t
Definition test_main.cpp:16
@ DIGITAL_PIN
Definition test_main.cpp:17
@ RELAY
Definition test_main.cpp:18
void test_negative_threshold_battery_scenario()
void test_normal_positive_threshold()
Definition test_main.cpp:83
void test_zero_threshold_special_case()
void test_negative_threshold_edge_cases()
void test_large_negative_threshold()
void test_state_transitions_with_debug()
void test_negative_threshold_import_scenarios()