Sort of working version
No integration with Wallas Heater itself, but boots and connects to preconfigured Wifi - fetches time and can display HTML pages.
This commit is contained in:
BIN
resources/7193_wallas-uus-logo-1.png
Normal file
BIN
resources/7193_wallas-uus-logo-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
resources/espressif-systems-logo-png_seeklogo-407805.png
Normal file
BIN
resources/espressif-systems-logo-png_seeklogo-407805.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
resources/risc-v-core.png
Normal file
BIN
resources/risc-v-core.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
99
src/sntp_client.rs
Normal file
99
src/sntp_client.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
use core::net::{IpAddr, SocketAddr};
|
||||
use embassy_net::Stack;
|
||||
use embassy_net::dns::DnsQueryType;
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use embassy_net::udp::{PacketMetadata, UdpSocket};
|
||||
use embassy_sync::watch::Watch;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use alloc::string::String;
|
||||
|
||||
use log::error;
|
||||
use sntpc::{get_time, NtpContext, NtpTimestampGenerator};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Timestamp {
|
||||
tstamp: Instant,
|
||||
}
|
||||
|
||||
static UTC_DATETIME: Watch<CriticalSectionRawMutex, Duration, 2> = Watch::new();
|
||||
|
||||
pub fn get_now() -> String {
|
||||
let offset = UTC_DATETIME.try_get();
|
||||
match offset {
|
||||
None => {
|
||||
alloc::format!("LAUNCH+{}s", Instant::now().as_secs())
|
||||
},
|
||||
Some(duration) => {
|
||||
let now = Instant::now() + duration;
|
||||
let micros: i64 = now.as_micros() as i64;
|
||||
let dt = DateTime::<Utc>::from_timestamp_micros(micros);
|
||||
match dt {
|
||||
Some(val) => alloc::format!("{}", val.format("%Y-%m-%d %H:%M:%S")),
|
||||
None => alloc::format!("LAUNCH+{}s", Instant::now().as_secs())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl NtpTimestampGenerator for Timestamp {
|
||||
fn init(&mut self) {
|
||||
self.tstamp = Instant::now();
|
||||
}
|
||||
|
||||
fn timestamp_sec(&self) -> u64 {
|
||||
self.tstamp.as_secs()
|
||||
}
|
||||
|
||||
fn timestamp_subsec_micros(&self) -> u32 {
|
||||
(self.tstamp.as_micros() % 1_000_000) as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sntp_client_spawn(spawner: embassy_executor::Spawner, stack: Stack<'static>) {
|
||||
|
||||
spawner.must_spawn(sntp_client(stack));
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn sntp_client(stack: Stack<'static>) {
|
||||
|
||||
// Create UDP socket
|
||||
let mut rx_meta = [PacketMetadata::EMPTY; 16];
|
||||
let mut rx_buffer = [0; 4096];
|
||||
let mut tx_meta = [PacketMetadata::EMPTY; 16];
|
||||
let mut tx_buffer = [0; 4096];
|
||||
|
||||
let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer);
|
||||
socket.bind(123).unwrap();
|
||||
|
||||
let context = NtpContext::new(Timestamp{tstamp: Instant::now()});
|
||||
let server_list : alloc::vec::Vec<&str> = alloc::vec!["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org"];
|
||||
let mut current_server = 2;
|
||||
|
||||
let sender = UTC_DATETIME.sender();
|
||||
|
||||
loop {
|
||||
let dns_res = stack.dns_query (server_list[current_server], DnsQueryType::A).await.expect("Failed to resolve NTP server");
|
||||
let addr: IpAddr = dns_res[0].into();
|
||||
let result =
|
||||
get_time(SocketAddr::from((addr, 123)), &socket, context).await;
|
||||
|
||||
match result {
|
||||
Ok(time) => {
|
||||
let offset = Duration::from_micros(time.offset as u64);
|
||||
sender.send(offset);
|
||||
Timer::after(Duration::from_secs(7*24*3600)).await; // redo SNTP check in a week
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error getting time: {:?}", e);
|
||||
current_server = (current_server + 1) % 4;
|
||||
Timer::after(Duration::from_secs(30)).await;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/static/espressif-logo.png
Normal file
BIN
src/static/espressif-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
src/static/risc-v-logo.png
Normal file
BIN
src/static/risc-v-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
22
src/static/styles.css
Normal file
22
src/static/styles.css
Normal file
@@ -0,0 +1,22 @@
|
||||
body {
|
||||
font-family: serif;
|
||||
text-align: center;
|
||||
color: #321C0B;
|
||||
background-color: #D5E4F6;
|
||||
height: 100%;
|
||||
}
|
||||
h1 {
|
||||
color: #B15C1B;
|
||||
}
|
||||
h4 {
|
||||
color: #2969B2;
|
||||
}
|
||||
p.intro {
|
||||
border: 1px solid #B15C1B;
|
||||
padding: 0.2em;
|
||||
margin: 0.3em 10vw 0.3em 10vw;
|
||||
}
|
||||
div#footer {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
}
|
||||
BIN
src/static/wallas-logo.png
Normal file
BIN
src/static/wallas-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user