+121
-20
src/main.rs
+121
-20
src/main.rs
···
4
4
5
5
#![no_std]
6
6
#![no_main]
7
+
use core::str::from_utf8;
8
+
use core::time;
9
+
7
10
use badge_display::display_image::DisplayImage;
8
11
use badge_display::{run_the_display, CHANGE_IMAGE, CURRENT_IMAGE, RTC_TIME_STRING};
9
-
use bt_hci::cmd::info;
10
12
use cyw43_driver::setup_cyw43;
11
13
use cyw43_pio::PioSpi;
12
14
use defmt::info;
15
+
use defmt::*;
13
16
use embassy_executor::Spawner;
17
+
use embassy_net::dns::DnsSocket;
18
+
use embassy_net::tcp::client::{TcpClient, TcpClientState};
14
19
use embassy_net::{Stack, StackResources};
15
20
use embassy_rp::clocks::RoscRng;
16
21
use embassy_rp::gpio;
···
24
29
use embassy_time::{Duration, Timer};
25
30
use env::env_value;
26
31
use gpio::{Level, Output, Pull};
32
+
use heapless::Vec;
27
33
use helpers::easy_format;
28
34
use rand::RngCore;
35
+
use reqwless::client::{HttpClient, TlsConfig, TlsVerify};
36
+
use reqwless::request::Method;
37
+
use serde::Deserialize;
29
38
use static_cell::StaticCell;
30
39
use temp_sensor::run_the_temp_sensor;
31
40
use {defmt_rtt as _, panic_probe as _};
···
100
109
RESOURCES.init(StackResources::<5>::new()),
101
110
seed,
102
111
));
112
+
//rtc setup
113
+
let mut rtc = embassy_rp::rtc::Rtc::new(p.RTC);
103
114
104
115
spawner.must_spawn(net_task(stack));
105
116
//Attempt to connect to wifi to get RTC time loop for 2 minutes
···
123
134
wifi_connection_attempts += 1;
124
135
}
125
136
137
+
let mut time_was_set = false;
126
138
if connected_to_wifi {
127
139
info!("waiting for DHCP...");
128
140
while !stack.is_config_up() {
···
139
151
info!("waiting for stack to be up...");
140
152
stack.wait_config_up().await;
141
153
info!("Stack is up!");
142
-
}
154
+
155
+
//RTC Web request
156
+
let mut rx_buffer = [0; 8192];
157
+
let mut tls_read_buffer = [0; 16640];
158
+
let mut tls_write_buffer = [0; 16640];
159
+
let client_state = TcpClientState::<1, 1024, 1024>::new();
160
+
let tcp_client = TcpClient::new(stack, &client_state);
161
+
let dns_client = DnsSocket::new(stack);
162
+
let tls_config = TlsConfig::new(
163
+
seed,
164
+
&mut tls_read_buffer,
165
+
&mut tls_write_buffer,
166
+
TlsVerify::None,
167
+
);
168
+
169
+
let mut http_client = HttpClient::new_with_tls(&tcp_client, &dns_client, tls_config);
170
+
let url = env_value("TIME_API");
171
+
info!("connecting to {}", &url);
172
+
173
+
let mut request = match http_client.request(Method::GET, &url).await {
174
+
Ok(req) => req,
175
+
Err(e) => {
176
+
error!("Failed to make HTTP request: {:?}", e);
177
+
return; // handle the error
178
+
}
179
+
};
143
180
144
-
//rtc setup
145
-
let mut rtc = embassy_rp::rtc::Rtc::new(p.RTC);
146
-
if !rtc.is_running() {
147
-
info!("Start RTC");
148
-
let now = DateTime {
149
-
year: 2000,
150
-
month: 1,
151
-
day: 1,
152
-
day_of_week: DayOfWeek::Saturday,
153
-
hour: 18,
154
-
minute: 31,
155
-
second: 0,
181
+
let response = match request.send(&mut rx_buffer).await {
182
+
Ok(resp) => resp,
183
+
Err(_e) => {
184
+
error!("Failed to send HTTP request");
185
+
return; // handle the error;
186
+
}
187
+
};
188
+
189
+
let body = match from_utf8(response.body().read_to_end().await.unwrap()) {
190
+
Ok(b) => b,
191
+
Err(_e) => {
192
+
error!("Failed to read response body");
193
+
return; // handle the error
194
+
}
156
195
};
157
-
rtc.set_datetime(now).unwrap();
196
+
info!("Response body: {:?}", &body);
197
+
198
+
let bytes = body.as_bytes();
199
+
match serde_json_core::de::from_slice::<TimeApiResponse>(bytes) {
200
+
Ok((output, _used)) => {
201
+
//Deadlines am i right?
202
+
info!("Datetime: {:?}", output.datetime);
203
+
//split at T
204
+
let datetime = output.datetime.split('T').collect::<Vec<&str, 2>>();
205
+
//split at -
206
+
let date = datetime[0].split('-').collect::<Vec<&str, 3>>();
207
+
let year = date[0].parse::<u16>().unwrap();
208
+
let month = date[1].parse::<u8>().unwrap();
209
+
let day = date[2].parse::<u8>().unwrap();
210
+
//split at :
211
+
let time = datetime[1].split(':').collect::<Vec<&str, 4>>();
212
+
let hour = time[0].parse::<u8>().unwrap();
213
+
let minute = time[1].parse::<u8>().unwrap();
214
+
//split at .
215
+
let second_split = time[2].split('.').collect::<Vec<&str, 2>>();
216
+
let second = second_split[0].parse::<f64>().unwrap();
217
+
let rtc_time = DateTime {
218
+
year: year,
219
+
month: month,
220
+
day: day,
221
+
day_of_week: match output.day_of_week {
222
+
0 => DayOfWeek::Sunday,
223
+
1 => DayOfWeek::Monday,
224
+
2 => DayOfWeek::Tuesday,
225
+
3 => DayOfWeek::Wednesday,
226
+
4 => DayOfWeek::Thursday,
227
+
5 => DayOfWeek::Friday,
228
+
6 => DayOfWeek::Saturday,
229
+
_ => DayOfWeek::Sunday,
230
+
},
231
+
hour,
232
+
minute,
233
+
second: second as u8,
234
+
};
235
+
rtc.set_datetime(rtc_time).unwrap();
236
+
time_was_set = true;
237
+
}
238
+
Err(_e) => {
239
+
error!("Failed to parse response body");
240
+
return; // handle the error
241
+
}
242
+
}
158
243
}
159
244
245
+
//
246
+
160
247
//Task spawning
161
248
spawner.must_spawn(run_the_temp_sensor(p.I2C0, p.PIN_5, p.PIN_4));
162
249
spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset));
···
174
261
continue;
175
262
}
176
263
177
-
let now = rtc.now();
178
-
match now {
179
-
Ok(time) => set_display_time(time),
180
-
Err(_) => {
181
-
info!("Error getting time");
264
+
if time_was_set {
265
+
let now = rtc.now();
266
+
match now {
267
+
Ok(time) => set_display_time(time),
268
+
Err(_) => {
269
+
info!("Error getting time");
270
+
}
182
271
}
272
+
} else {
273
+
RTC_TIME_STRING.lock(|rtc_time_string| {
274
+
rtc_time_string.borrow_mut().clear();
275
+
rtc_time_string.borrow_mut().push_str("No Wifi").unwrap();
276
+
});
183
277
}
184
278
185
279
Timer::after(Duration::from_millis(100)).await;
···
217
311
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
218
312
stack.run().await
219
313
}
314
+
315
+
#[derive(Deserialize)]
316
+
struct TimeApiResponse<'a> {
317
+
datetime: &'a str,
318
+
day_of_week: u8,
319
+
// other fields as needed
320
+
}