Skip to content

Commit 04fc105

Browse files
authored
test schedule
1 parent 1686b44 commit 04fc105

File tree

4 files changed

+157
-0
lines changed

4 files changed

+157
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Copyright (c) 2023 Bert Melis. All rights reserved.
3+
4+
This work is licensed under the terms of the MIT license.
5+
For a copy, see <https://opensource.org/licenses/MIT> or
6+
the LICENSE file.
7+
*/
8+
9+
#include "ConversionHelpers.h"
10+
11+
bool isDigit(const char c) {
12+
return c >= '0' && c <= '9';
13+
}
14+
15+
namespace VitoWiFi {
16+
17+
std::size_t encodeSchedule(const char* schedule, std::size_t len, uint8_t* output) {
18+
enum ScheduleParserStep {
19+
Hours1,
20+
Hours2,
21+
Minutes1,
22+
Minutes2,
23+
Space,
24+
};
25+
26+
std::size_t i = 0 - 1; // first operation in iteration is ++i
27+
std::size_t scheduleIndex = 0;
28+
ScheduleParserStep step = ScheduleParserStep::Hours1;
29+
unsigned int hour = 0;
30+
unsigned int minutes = 0;
31+
32+
while (++i < len) {
33+
if (step == ScheduleParserStep::Hours1) {
34+
if (isDigit(schedule[i])) {
35+
hour = schedule[i] - '0';
36+
step = ScheduleParserStep::Hours2;
37+
continue;
38+
}
39+
} else if (step == ScheduleParserStep::Hours2) {
40+
if (isDigit(schedule[i])) {
41+
hour = hour * 10 + (schedule[i] - '0');
42+
continue;
43+
} else if (schedule[i] == ':') {
44+
step = ScheduleParserStep::Minutes1;
45+
continue;
46+
}
47+
} else if (step == ScheduleParserStep::Minutes1) {
48+
if (isDigit(schedule[i])) {
49+
minutes = schedule[i] - '0';
50+
step = ScheduleParserStep::Minutes2;
51+
continue;
52+
}
53+
} else if (step == ScheduleParserStep::Minutes2) {
54+
if (schedule[i] == '0') {
55+
minutes = minutes * 10 + (schedule[i] - '0');
56+
// parsing is possibly complete
57+
if (hour <= 23 || minutes <= 59) {
58+
output[scheduleIndex] = (0xF8 & hour << 3) | minutes / 10;
59+
++scheduleIndex;
60+
step = ScheduleParserStep::Space;
61+
continue;
62+
}
63+
}
64+
} else { // step == ScheduleParserStep::Space
65+
if (schedule[i] == ' ') {
66+
step = ScheduleParserStep::Hours1;
67+
continue;
68+
}
69+
}
70+
return 0;
71+
}
72+
if (scheduleIndex % 2 == 0 && step == ScheduleParserStep::Space) {
73+
// TODO(bertmelis): hours have to be ordered
74+
return (scheduleIndex + 1) / 2;
75+
}
76+
return 0;
77+
}
78+
79+
std::size_t encodeSchedule(const char* schedule, uint8_t* output) {
80+
return encodeSchedule(schedule, strlen(schedule), output);
81+
}
82+
83+
std::size_t decodeSchedule(const uint8_t* data, std::size_t len, char* output, std::size_t maxLen) {
84+
assert(len == 8);
85+
assert(maxLen >= 48); // 8 times 07:30, 7 spaces and 0-terminator --> 8 * 5 + 7 * 1 + 1
86+
87+
std::size_t pos = 0;
88+
for (std::size_t i = 0; i < 8; ++i) {
89+
unsigned int hour = std::min(23, data[i] >> 3);
90+
unsigned int minutes = std::min(59, (data[i] & 0x07) * 10);
91+
int res = snprintf("%u.02:%u.02");
92+
if (i < 7)
93+
}
94+
95+
}
96+
97+
} // end namespace VitoWiFi

src/Datapoint/ConversionHelpers.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright (c) 2025 Bert Melis. All rights reserved.
3+
4+
This work is licensed under the terms of the MIT license.
5+
For a copy, see <https://opensource.org/licenses/MIT> or
6+
the LICENSE file.
7+
*/
8+
9+
#pragma once
10+
11+
#include <cassert>
12+
#include <cstdint>
13+
#include <cstddef>
14+
#include <cstring>
15+
16+
namespace VitoWiFi {
17+
18+
/*
19+
Encodes a c-string containing a schedule to an 8-byte schedule sequence.
20+
Returns the number of pairs encoded
21+
Per byte:
22+
- b7-b3 hour
23+
- b2-b1 minute * 10
24+
25+
Output needs to be at least 8 bytes
26+
27+
A scedule consists of time pairs with minutes rounded to a multiple of 10min.
28+
Hours can be with leading zero or not.
29+
30+
Valid:
31+
- 7:30 8:30 15:00 23:50
32+
- 07:30 8:30 15:00 23:50
33+
34+
Invalid:
35+
- hours not specified in pairs
36+
- (hours not ordered earliest to latest)
37+
- no colons or spaces used
38+
- minutes not rounded to multiples of 10
39+
*/
40+
std::size_t encodeSchedule(const char* schedule, std::size_t len, uint8_t* output);
41+
std::size_t encodeSchedule(const char* schedule, uint8_t* output);
42+
43+
std::size_t decodeSchedule(const uint8_t* data, std::size_t len, char* output, std::size_t maxLen);
44+
45+
}; // end namespace VitoWiFi

src/Datapoint/Converter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ the LICENSE file.
1414
#include <cstring>
1515

1616
#include "../Logging.h"
17+
#include "ConversionHelpers.h"
1718

1819
namespace VitoWiFi {
1920

test/test_Datapoint/test_Datapoint.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,19 @@ void test_COPEncode() {
204204
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, buffer, len);
205205
}
206206

207+
void test_Schedule() {
208+
const char* schedule = "7:30 08:30 16:20 23:10";
209+
const uint8_t expected[] = {0x3B, 0x43, 0x82, 0xB9, 0x00, 0x00, 0x00, 0x00};
210+
const size_t numSchedules = 4;
211+
const std::size_t len = 8;
212+
uint8_t buffer[len];
213+
214+
std::size_t result = VitoWiFi::encodeSchedule(schedule, buffer);
215+
216+
TEST_ASSERT_EQUAL(len, result);
217+
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, buffer, len);
218+
}
219+
207220
int main() {
208221
UNITY_BEGIN();
209222
RUN_TEST(test_Converter);
@@ -222,5 +235,6 @@ int main() {
222235
RUN_TEST(test_CountShortEncode);
223236
RUN_TEST(test_COPDecode);
224237
RUN_TEST(test_COPEncode);
238+
RUN_TEST(test_Schedule);
225239
return UNITY_END();
226240
}

0 commit comments

Comments
 (0)