decode_datetime_pretend_live/
decode_datetime_pretend_live.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright 2024-2025 René Ladan <rene0+codeberg@freedom.nl>
3
4use radio_datetime_utils::{DST_ANNOUNCED, DST_PROCESSED, DST_SUMMER};
5
6use msf60_utils::MSFUtils;
7
8// quick and dirty parsing function
9fn parse_dst(dst: Option<u8>) -> String {
10    if dst.is_none() {
11        return String::from("*");
12    }
13    let mut res = String::from("");
14    let s_dst = dst.unwrap();
15    if s_dst & DST_ANNOUNCED != 0 {
16        res += "announced ";
17    }
18    if s_dst & DST_PROCESSED != 0 {
19        res += "processed ";
20    }
21    if s_dst & DST_SUMMER != 0 {
22        res += "summer";
23    }
24    res
25}
26
27fn str_weekday(day: Option<u8>) -> String {
28    String::from(match day {
29        Some(0) => "Sunday",
30        Some(1) => "Monday",
31        Some(2) => "Tuesday",
32        Some(3) => "Wednesday",
33        Some(4) => "Thursday",
34        Some(5) => "Friday",
35        Some(6) => "Saturday",
36        Some(7) => "?",
37        None => "None",
38        _ => "<panic>",
39    })
40}
41
42fn main() {
43    // Pretend to do live decoding, e.g. by detecting the time differences in microseconds from
44    // edges read from a GPIO pin. Samples need to be in absolute time since some point, not in
45    // relative time to each other. Format is (time-in-us-since-some-point, edge-becomes-high).
46    // The boolean value is the inverse of the radio signal.
47    const SAMPLES: [(u32, bool); 135] = [
48        (480097898, false),
49        (480909129, true),
50        (480998372, false),
51        (481905456, true),
52        (482396098, false),
53        (482906504, true),
54        (482993883, false),
55        (483908888, true),
56        (483993519, false),
57        (483993578, false),
58        (483993623, false),
59        (484905643, true),
60        (484999472, false),
61        (485909536, true),
62        (485997179, false),
63        (486908192, true),
64        (486998019, false),
65        (487906286, true),
66        (487997465, false),
67        (488900307, true),
68        (488999571, false),
69        (489904756, true),
70        (489996274, false),
71        (490905915, true),
72        (490993902, false),
73        (491904343, true),
74        (491998425, false),
75        (492905411, true),
76        (492994929, false),
77        (493907275, true),
78        (494000510, false),
79        (494909312, true),
80        (494997767, false),
81        (495907859, true),
82        (495999521, false),
83        (496903804, true),
84        (496996022, false),
85        (497904393, true),
86        (497998389, false),
87        (498902023, true),
88        (498995599, false),
89        (499906248, true),
90        (499994605, false),
91        (500911975, true),
92        (501097918, false),
93        (501906651, true),
94        (502000289, false),
95        (502907018, true),
96        (502999103, false),
97        (503905111, true),
98        (503998501, false),
99        (504903060, true),
100        (505093147, false),
101        (505905830, true),
102        (505997306, false),
103        (506908387, true),
104        (507092576, false),
105        (507909534, true),
106        (507993459, false),
107        (508903628, true),
108        (509001819, false),
109        (509902333, true),
110        (509998524, false),
111        (510906592, true),
112        (511093691, false),
113        (511903057, true),
114        (511999019, false),
115        (512905544, true),
116        (512998127, false),
117        (513904291, true),
118        (513996323, false),
119        (514909090, true),
120        (515094873, false),
121        (515906002, true),
122        (515999869, false),
123        (516905713, true),
124        (517094858, false),
125        (517905143, true),
126        (518096078, false),
127        (518902241, true),
128        (519094998, false),
129        (519903930, true),
130        (519998402, false),
131        (520905710, true),
132        (520995714, false),
133        (521907100, true),
134        (522094065, false),
135        (522905204, true),
136        (523000056, false),
137        (523000091, false),
138        (523000103, true),
139        (523000116, false),
140        (523000129, false),
141        (523904895, true),
142        (523995464, false),
143        (524906217, true),
144        (525000486, false),
145        (525904862, true),
146        (526094321, false),
147        (526905690, true),
148        (527090263, false),
149        (527911351, true),
150        (527994518, false),
151        (528903925, true),
152        (529093867, false),
153        (529903335, true),
154        (530092889, false),
155        (530902052, true),
156        (530994385, false),
157        (531904428, true),
158        (531995603, false),
159        (532904460, true),
160        (532997952, false),
161        (533908377, true),
162        (533994459, false),
163        (534908716, true),
164        (535095720, false),
165        (535906164, true),
166        (536192900, false),
167        (536903709, true),
168        (537192272, false),
169        (537907007, true),
170        (538192799, false),
171        (538910068, true),
172        (539095963, false),
173        (539906169, true),
174        (540094776, false),
175        (540905086, true),
176        (540996129, false),
177        (541903768, true),
178        (542391315, false),
179        (542903986, true),
180        (542993789, false),
181        (543902386, true),
182        (543996392, false),
183    ];
184
185    let mut msf = MSFUtils::default();
186    let mut old_time = SAMPLES[0].0;
187    let mut old_second = 0xff;
188    for s in SAMPLES {
189        msf.handle_new_edge(s.1, s.0);
190        if s.1 {
191            println!(
192                "{}{} {:?} {:?} {} {}",
193                if msf.get_second() == old_second {
194                    "* "
195                } else {
196                    ""
197                },
198                msf.get_second(),
199                msf.get_current_bit_a(),
200                msf.get_current_bit_b(),
201                msf.is_new_minute(),
202                msf.is_past_new_minute(),
203            );
204            old_second = msf.get_second();
205            if (s.0 - old_time > msf.get_spike_limit()) && !msf.increase_second() {
206                println!(
207                    "Bad increase_second at second {}->{}",
208                    old_second,
209                    msf.get_second()
210                );
211            }
212        } else if msf.is_new_minute() {
213            // This happens _before_ the above two println!() in time, because
214            // handle_new_edge() just found the 0111_1110 bit train at the high-to-low edge.
215            println!("New minute! Time to decode!");
216            msf.decode_time(true, true);
217            let rdt = msf.get_radio_datetime();
218            println!("DUT1={:?}", rdt.get_dut1());
219            println!(
220                "Parities={:?} {:?} {:?} {:?}",
221                msf.get_parity_1(),
222                msf.get_parity_2(),
223                msf.get_parity_3(),
224                msf.get_parity_4()
225            );
226            println!(
227                "Date/time={:?}-{:?}-{:?} {:?}:{:?} {} {}",
228                rdt.get_year(),
229                rdt.get_month(),
230                rdt.get_day(),
231                rdt.get_hour(),
232                rdt.get_minute(),
233                str_weekday(rdt.get_weekday()),
234                parse_dst(rdt.get_dst())
235            );
236        }
237        old_time = s.0;
238    }
239}