plain mqtt works
This commit is contained in:
parent
14d8f7f683
commit
8dfbf88db8
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -185,6 +185,12 @@ dependencies = [
|
|||||||
"inout",
|
"inout",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-decoder"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5241cd7938b1b415942e943ea96f615953d500b50347b505b0b507080bad5a6f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
@ -376,7 +382,7 @@ dependencies = [
|
|||||||
"atomic-pool",
|
"atomic-pool",
|
||||||
"document-features",
|
"document-features",
|
||||||
"embassy-net-driver",
|
"embassy-net-driver",
|
||||||
"embassy-sync",
|
"embassy-sync 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
"embedded-io-async",
|
"embedded-io-async",
|
||||||
"embedded-nal-async",
|
"embedded-nal-async",
|
||||||
@ -407,6 +413,18 @@ dependencies = [
|
|||||||
"heapless 0.8.0",
|
"heapless 0.8.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embassy-sync"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "git+https://github.com/embassy-rs/embassy.git?rev=4b4777e#4b4777e6bb813dbde3f8ec05ff81cadbcb41bee0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"critical-section",
|
||||||
|
"embedded-io-async",
|
||||||
|
"futures-util",
|
||||||
|
"heapless 0.8.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embassy-time"
|
name = "embassy-time"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -632,7 +650,7 @@ dependencies = [
|
|||||||
"critical-section",
|
"critical-section",
|
||||||
"document-features",
|
"document-features",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
"embassy-sync",
|
"embassy-sync 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embassy-time-driver",
|
"embassy-time-driver",
|
||||||
"embedded-can",
|
"embedded-can",
|
||||||
"embedded-dma",
|
"embedded-dma",
|
||||||
@ -726,7 +744,7 @@ dependencies = [
|
|||||||
"critical-section",
|
"critical-section",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
"embassy-net-driver",
|
"embassy-net-driver",
|
||||||
"embassy-sync",
|
"embassy-sync 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embedded-io",
|
"embedded-io",
|
||||||
"embedded-io-async",
|
"embedded-io-async",
|
||||||
"enumset",
|
"enumset",
|
||||||
@ -780,9 +798,10 @@ dependencies = [
|
|||||||
name = "esp32c3"
|
name = "esp32c3"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"const-decoder",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-net",
|
"embassy-net",
|
||||||
"embassy-sync",
|
"embassy-sync 0.5.0 (git+https://github.com/embassy-rs/embassy.git?rev=4b4777e)",
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
"embedded-io-async",
|
"embedded-io-async",
|
||||||
"embedded-tls",
|
"embedded-tls",
|
||||||
|
@ -7,9 +7,10 @@ authors = [ "Marvin Drescher <m@sparv.in>" ]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
const-decoder = "0.3.0"
|
||||||
embassy-executor = { version = "0.5.0", features = ["nightly", "integrated-timers", "arch-riscv32", "executor-thread"] }
|
embassy-executor = { version = "0.5.0", features = ["nightly", "integrated-timers", "arch-riscv32", "executor-thread"] }
|
||||||
embassy-net = { version = "0.4.0", features = ["dhcpv4", "dhcpv4-hostname", "dns", "medium-ip", "proto-ipv4", "proto-ipv6", "tcp", "udp"] }
|
embassy-net = { version = "0.4.0", features = ["dhcpv4", "dhcpv4-hostname", "dns", "medium-ip", "proto-ipv4", "proto-ipv6", "tcp", "udp"] }
|
||||||
embassy-sync = "0.5.0"
|
embassy-sync = { git = "https://github.com/embassy-rs/embassy.git", rev = "4b4777e" }
|
||||||
embassy-time = { version = "0.3.0" }
|
embassy-time = { version = "0.3.0" }
|
||||||
embedded-io-async = "0.6.1"
|
embedded-io-async = "0.6.1"
|
||||||
embedded-tls = { version = "0.17.0", default-features = false, features = ["embedded-io-adapters"] }
|
embedded-tls = { version = "0.17.0", default-features = false, features = ["embedded-io-adapters"] }
|
||||||
@ -24,7 +25,7 @@ log = "0.4.21"
|
|||||||
mqttrust = "0.6.0"
|
mqttrust = "0.6.0"
|
||||||
rand = { version = "0.8.5", default-features = false, features = ["std_rng"] }
|
rand = { version = "0.8.5", default-features = false, features = ["std_rng"] }
|
||||||
rand_core = "0.6.4"
|
rand_core = "0.6.4"
|
||||||
rust-mqtt = { version = "0.3.0", default-features = false }
|
rust-mqtt = { version = "0.3.0", default-features = false, features = ["tls"] }
|
||||||
smart-leds = "0.4.0"
|
smart-leds = "0.4.0"
|
||||||
static_cell = { version = "2.0.0", features = ["nightly"] }
|
static_cell = { version = "2.0.0", features = ["nightly"] }
|
||||||
|
|
||||||
@ -33,6 +34,9 @@ opt-level = 3
|
|||||||
[profile.dev.package.embedded-tls]
|
[profile.dev.package.embedded-tls]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
|
[features]
|
||||||
|
tls = []
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
lto = true
|
lto = true
|
||||||
|
17
src/main.rs
17
src/main.rs
@ -19,6 +19,7 @@ use embassy_executor::Executor;
|
|||||||
use embassy_net::{Config, DhcpConfig, Stack, StackResources};
|
use embassy_net::{Config, DhcpConfig, Stack, StackResources};
|
||||||
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
|
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
|
||||||
use embassy_sync::mutex::Mutex;
|
use embassy_sync::mutex::Mutex;
|
||||||
|
use embassy_sync::once_lock::OnceLock;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_alloc::EspHeap;
|
use esp_alloc::EspHeap;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
@ -154,9 +155,12 @@ async fn moisture(
|
|||||||
supply.set_low();
|
supply.set_low();
|
||||||
// Vout = Dout * Vmax / Dmax
|
// Vout = Dout * Vmax / Dmax
|
||||||
let milli_volt = adc_voltage(pin_value, Attenuation::Attenuation11dB) as u32;
|
let milli_volt = adc_voltage(pin_value, Attenuation::Attenuation11dB) as u32;
|
||||||
let moisture = ((milli_volt.checked_sub(submerged_in_water).unwrap_or(0))
|
let moisture = {
|
||||||
<< 8 / (dry - submerged_in_water))
|
let delta = milli_volt.checked_sub(submerged_in_water).unwrap_or(0);
|
||||||
>> 8;
|
let delta_dry = dry - submerged_in_water;
|
||||||
|
let dryness = (delta << 12 / delta_dry) * 100 >> 12;
|
||||||
|
dryness
|
||||||
|
};
|
||||||
info!("moisture: {moisture}%, v_s: {milli_volt}");
|
info!("moisture: {moisture}%, v_s: {milli_volt}");
|
||||||
{
|
{
|
||||||
DATA.lock()
|
DATA.lock()
|
||||||
@ -189,7 +193,7 @@ async fn battery_monitor(
|
|||||||
.await
|
.await
|
||||||
.insert(Cow::from("vbat"), v_bat.to_string());
|
.insert(Cow::from("vbat"), v_bat.to_string());
|
||||||
}
|
}
|
||||||
Timer::after(Duration::from_secs(15)).await;
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
|
||||||
@ -258,7 +262,7 @@ fn main() -> ! {
|
|||||||
let rmt_buffer = smartLedBuffer!(1);
|
let rmt_buffer = smartLedBuffer!(1);
|
||||||
let mut led = SmartLedsAdapter::new(rmt.channel0, io.pins.gpio7, rmt_buffer, &clocks);
|
let mut led = SmartLedsAdapter::new(rmt.channel0, io.pins.gpio7, rmt_buffer, &clocks);
|
||||||
|
|
||||||
led.set_color(RGB8::new(0, 255, 255));
|
led.set_color(RGB8::new(0, 0, 0));
|
||||||
|
|
||||||
let led: Box<dyn MySmartLed> = Box::new(led);
|
let led: Box<dyn MySmartLed> = Box::new(led);
|
||||||
|
|
||||||
@ -328,6 +332,8 @@ async fn wifi_connection(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub static HAS_IP_ADDRESS: OnceLock<()> = OnceLock::new();
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn ip_task(stack: NetworkStack) {
|
async fn ip_task(stack: NetworkStack) {
|
||||||
loop {
|
loop {
|
||||||
@ -340,6 +346,7 @@ async fn ip_task(stack: NetworkStack) {
|
|||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
info!("Got IP: {}", config.address);
|
info!("Got IP: {}", config.address);
|
||||||
|
HAS_IP_ADDRESS.get_or_init(|| ());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Timer::after(Duration::from_millis(500)).await;
|
Timer::after(Duration::from_millis(500)).await;
|
||||||
|
110
src/mqtt.rs
110
src/mqtt.rs
@ -1,6 +1,8 @@
|
|||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{dns::Error as DnsError, tcp::ConnectError};
|
use embassy_net::{dns::Error as DnsError, tcp::ConnectError};
|
||||||
use embassy_time::{with_timeout, Duration, TimeoutError, Timer};
|
use embassy_time::{with_timeout, Duration, Instant, TimeoutError, Timer};
|
||||||
use embedded_tls::{Aes128GcmSha256, NoVerify, TlsConfig, TlsConnection, TlsContext, TlsError};
|
use embedded_tls::{Aes128GcmSha256, NoVerify, TlsConfig, TlsConnection, TlsContext, TlsError};
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
@ -10,9 +12,10 @@ use rand::{CryptoRng, RngCore, SeedableRng};
|
|||||||
use rust_mqtt::client::client::MqttClient;
|
use rust_mqtt::client::client::MqttClient;
|
||||||
use rust_mqtt::client::client_config::ClientConfig;
|
use rust_mqtt::client::client_config::ClientConfig;
|
||||||
use rust_mqtt::packet::v5::reason_codes::ReasonCode;
|
use rust_mqtt::packet::v5::reason_codes::ReasonCode;
|
||||||
|
use rust_mqtt::tests;
|
||||||
use rust_mqtt::utils::rng_generator::CountingRng;
|
use rust_mqtt::utils::rng_generator::CountingRng;
|
||||||
|
|
||||||
use crate::{NetworkStack, DATA};
|
use crate::{NetworkStack, DATA, HAS_IP_ADDRESS};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SendError {
|
pub enum SendError {
|
||||||
@ -24,6 +27,30 @@ pub enum SendError {
|
|||||||
Timeout(TimeoutError),
|
Timeout(TimeoutError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ErrorLocation<E: Debug> {
|
||||||
|
pub error: E,
|
||||||
|
pub location: Option<(&'static str, u32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Debug> ErrorLocation<E> {
|
||||||
|
pub fn from_result<T>(
|
||||||
|
result: Result<T, E>,
|
||||||
|
location: (&'static str, u32),
|
||||||
|
) -> Result<T, ErrorLocation<E>> {
|
||||||
|
result.map_err(|error| Self {
|
||||||
|
error,
|
||||||
|
location: Some(location),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! with_line {
|
||||||
|
($result:expr) => {
|
||||||
|
ErrorLocation::from_result($result, (file!(), line!()))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! from_impl {
|
macro_rules! from_impl {
|
||||||
($err:ty, $var:ident) => {
|
($err:ty, $var:ident) => {
|
||||||
impl From<$err> for SendError {
|
impl From<$err> for SendError {
|
||||||
@ -41,7 +68,10 @@ from_impl!(ReasonCode, MqttReason);
|
|||||||
from_impl!(TimeoutError, Timeout);
|
from_impl!(TimeoutError, Timeout);
|
||||||
|
|
||||||
const MQTT_SERVER_HOSTNAME: &str = "mqtt.shimun.net";
|
const MQTT_SERVER_HOSTNAME: &str = "mqtt.shimun.net";
|
||||||
|
#[cfg(feature = "tls")]
|
||||||
const MQTT_SERVER_PORT: u16 = 8883;
|
const MQTT_SERVER_PORT: u16 = 8883;
|
||||||
|
#[cfg(not(feature = "tls"))]
|
||||||
|
const MQTT_SERVER_PORT: u16 = 1883;
|
||||||
|
|
||||||
pub async fn send_message(
|
pub async fn send_message(
|
||||||
stack: NetworkStack,
|
stack: NetworkStack,
|
||||||
@ -53,15 +83,18 @@ pub async fn send_message(
|
|||||||
mut messages: impl Iterator<Item = (&str, &[u8])>,
|
mut messages: impl Iterator<Item = (&str, &[u8])>,
|
||||||
mut rng: impl CryptoRng + RngCore,
|
mut rng: impl CryptoRng + RngCore,
|
||||||
) -> core::result::Result<(), SendError> {
|
) -> core::result::Result<(), SendError> {
|
||||||
|
let begin = Instant::now();
|
||||||
let dns_resp = stack
|
let dns_resp = stack
|
||||||
.dns_query(MQTT_SERVER_HOSTNAME, embassy_net::dns::DnsQueryType::A)
|
.dns_query(MQTT_SERVER_HOSTNAME, embassy_net::dns::DnsQueryType::A)
|
||||||
.await
|
.await
|
||||||
.map_err(SendError::Dns)?;
|
.map_err(SendError::Dns)?;
|
||||||
|
let after_dns = Instant::now();
|
||||||
const TCP_BUFLEN: usize = 2048 << 2;
|
const TCP_BUFLEN: usize = 2048 << 2;
|
||||||
let mut rx_buffer = [0; TCP_BUFLEN];
|
let mut rx_buffer = [0; TCP_BUFLEN];
|
||||||
let mut tx_buffer = [0; TCP_BUFLEN];
|
let mut tx_buffer = [0; TCP_BUFLEN];
|
||||||
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
socket.set_timeout(Some(Duration::from_secs(30)));
|
socket.set_timeout(Some(Duration::from_secs(30)));
|
||||||
|
socket.set_keep_alive(Some(Duration::from_secs(5)));
|
||||||
let socket_addr = dns_resp
|
let socket_addr = dns_resp
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|addr| (addr, MQTT_SERVER_PORT))
|
.map(|addr| (addr, MQTT_SERVER_PORT))
|
||||||
@ -72,7 +105,8 @@ pub async fn send_message(
|
|||||||
|
|
||||||
// establish TCP connection
|
// establish TCP connection
|
||||||
socket.connect(socket_addr).await?;
|
socket.connect(socket_addr).await?;
|
||||||
trace!("connected");
|
let after_tcp = Instant::now();
|
||||||
|
info!("connected to {socket_addr:?}");
|
||||||
|
|
||||||
// seed mqtt rng from rng
|
// seed mqtt rng from rng
|
||||||
let mut mqtt_config = ClientConfig::<5, _>::new(
|
let mut mqtt_config = ClientConfig::<5, _>::new(
|
||||||
@ -82,16 +116,18 @@ pub async fn send_message(
|
|||||||
|
|
||||||
if let (Some(user), Some(pass)) = (option_env!("MQTT_USER"), option_env!("MQTT_PASSWORD")) {
|
if let (Some(user), Some(pass)) = (option_env!("MQTT_USER"), option_env!("MQTT_PASSWORD")) {
|
||||||
mqtt_config.add_username(user);
|
mqtt_config.add_username(user);
|
||||||
mqtt_config.add_username(pass);
|
mqtt_config.add_password(pass);
|
||||||
|
info!("{user}:{pass}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLS layer
|
// TLS layer
|
||||||
const TLS_BUF_LEN: usize = 4096;
|
const TLS_BUF_LEN: usize = 1 << 12;
|
||||||
let mut tls_read_record_buffer = [0; TLS_BUF_LEN];
|
let mut tls_read_record_buffer = [0; TLS_BUF_LEN];
|
||||||
let mut tls_write_record_buffer = [0; TLS_BUF_LEN];
|
let mut tls_write_record_buffer = [0; TLS_BUF_LEN];
|
||||||
|
|
||||||
|
#[cfg(feature = "tls")]
|
||||||
let mut tls = {
|
let mut tls = {
|
||||||
let config = TlsConfig::new();
|
let config = TlsConfig::new();
|
||||||
|
|
||||||
let mut tls = TlsConnection::new(
|
let mut tls = TlsConnection::new(
|
||||||
socket,
|
socket,
|
||||||
&mut tls_read_record_buffer,
|
&mut tls_read_record_buffer,
|
||||||
@ -100,19 +136,28 @@ pub async fn send_message(
|
|||||||
|
|
||||||
tls.open::<_, NoVerify>(TlsContext::<Aes128GcmSha256, _>::new(&config, &mut rng))
|
tls.open::<_, NoVerify>(TlsContext::<Aes128GcmSha256, _>::new(&config, &mut rng))
|
||||||
.await?;
|
.await?;
|
||||||
|
tls.flush().await?;
|
||||||
tls
|
tls
|
||||||
};
|
};
|
||||||
debug!("tls handshake succeeded");
|
#[cfg(feature = "tls")]
|
||||||
|
let mut mqtt_backend = tls;
|
||||||
|
#[cfg(not(feature = "tls"))]
|
||||||
|
let mut mqtt_backend = socket;
|
||||||
|
let after_tls = Instant::now();
|
||||||
|
#[cfg(feature = "tls")]
|
||||||
|
info!(
|
||||||
|
"tls handshake succeeded: +{}ms",
|
||||||
|
(after_tls - after_tcp).as_millis()
|
||||||
|
);
|
||||||
|
|
||||||
const BUF_LEN: usize = 1024;
|
mqtt_config.max_packet_size = 100;
|
||||||
|
const BUF_LEN: usize = 80;
|
||||||
let mut recv_buffer = [0; BUF_LEN];
|
let mut recv_buffer = [0; BUF_LEN];
|
||||||
let mut buffer = [0; BUF_LEN];
|
let mut buffer = [0; BUF_LEN];
|
||||||
|
|
||||||
mqtt_config.add_client_id("esp32c3");
|
|
||||||
mqtt_config.max_packet_size = (BUF_LEN - 128) as _;
|
|
||||||
// MQTT Layer
|
// MQTT Layer
|
||||||
let mut mqtt_client = MqttClient::new(
|
let mut mqtt_client = MqttClient::new(
|
||||||
tls,
|
mqtt_backend,
|
||||||
&mut buffer,
|
&mut buffer,
|
||||||
BUF_LEN,
|
BUF_LEN,
|
||||||
&mut recv_buffer,
|
&mut recv_buffer,
|
||||||
@ -120,6 +165,7 @@ pub async fn send_message(
|
|||||||
mqtt_config,
|
mqtt_config,
|
||||||
);
|
);
|
||||||
mqtt_client.connect_to_broker().await?;
|
mqtt_client.connect_to_broker().await?;
|
||||||
|
let after_mqtt = Instant::now();
|
||||||
info!("connected to broker");
|
info!("connected to broker");
|
||||||
for (topic, message) in messages {
|
for (topic, message) in messages {
|
||||||
mqtt_client
|
mqtt_client
|
||||||
@ -131,33 +177,39 @@ pub async fn send_message(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
let after_mqtt_pub = Instant::now();
|
||||||
|
info!(
|
||||||
|
"{:?} {:?} {:?} {:?} {:?}",
|
||||||
|
after_dns - begin,
|
||||||
|
after_tcp - begin,
|
||||||
|
after_tls - begin,
|
||||||
|
after_mqtt - begin,
|
||||||
|
after_mqtt_pub - begin
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
with_timeout(Duration::from_secs(60), inner(stack, messages, rng)).await?
|
with_timeout(Duration::from_secs(120), inner(stack, messages, rng)).await?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn publish_data(stack: NetworkStack, rng_seed: [u8; 32], interval: Duration) {
|
pub async fn publish_data(stack: NetworkStack, rng_seed: [u8; 32], interval: Duration) {
|
||||||
let mut rng = StdRng::from_seed(rng_seed);
|
let mut rng = StdRng::from_seed(rng_seed);
|
||||||
|
HAS_IP_ADDRESS.get().await;
|
||||||
loop {
|
loop {
|
||||||
Timer::after(interval / 10).await;
|
{
|
||||||
if stack.is_config_up() {
|
let mut data = DATA.lock().await;
|
||||||
break;
|
let res = send_message(
|
||||||
|
stack,
|
||||||
|
data.iter()
|
||||||
|
.map(|(topic, message)| (topic.as_ref(), message.as_bytes())),
|
||||||
|
&mut rng,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
if let Err(e) = res {
|
||||||
|
error!("Oh no: {e:?}");
|
||||||
|
};
|
||||||
|
data.clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
loop {
|
|
||||||
let mut data = DATA.lock().await;
|
|
||||||
let res = send_message(
|
|
||||||
stack,
|
|
||||||
data.iter()
|
|
||||||
.map(|(topic, message)| (topic.as_ref(), message.as_bytes())),
|
|
||||||
&mut rng,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
if let Err(e) = res {
|
|
||||||
error!("Oh no: {e:?}");
|
|
||||||
};
|
|
||||||
data.clear();
|
|
||||||
Timer::after(interval).await;
|
Timer::after(interval).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user