Browse Source

draw the rest of the owl

master
eta 3 months ago
parent
commit
57f9d1076f
  1. 353
      Cargo.lock
  2. 3
      Cargo.toml
  3. 15
      src/config.rs
  4. 29
      src/main.rs
  5. 146
      src/probe.rs

353
Cargo.lock generated

@ -84,6 +84,7 @@ dependencies = [ @@ -84,6 +84,7 @@ dependencies = [
"log",
"openh264",
"pretty_env_logger",
"reqwest",
"retina",
"serde",
"tokio",
@ -246,6 +247,15 @@ version = "1.8.0" @@ -246,6 +247,15 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "encoding_rs"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
dependencies = [
"cfg-if",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@ -300,9 +310,15 @@ dependencies = [ @@ -300,9 +310,15 @@ dependencies = [
"futures-sink",
"nanorand",
"pin-project",
"spin",
"spin 0.9.4",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.1.0"
@ -440,6 +456,25 @@ dependencies = [ @@ -440,6 +456,25 @@ dependencies = [
"weezl",
]
[[package]]
name = "h2"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "h264-reader"
version = "0.6.0"
@ -462,6 +497,12 @@ dependencies = [ @@ -462,6 +497,12 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -483,6 +524,17 @@ version = "0.1.4" @@ -483,6 +524,17 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5491a308e0214554f07a81d8944abe45f552871c12e3c3c6e7e5d354039a6c4c"
[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-auth"
version = "0.1.6"
@ -498,6 +550,29 @@ dependencies = [ @@ -498,6 +550,29 @@ dependencies = [
"sha2",
]
[[package]]
name = "http-body"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
[[package]]
name = "httpdate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "humantime"
version = "1.3.0"
@ -507,6 +582,43 @@ dependencies = [ @@ -507,6 +582,43 @@ dependencies = [
"quick-error",
]
[[package]]
name = "hyper"
version = "0.14.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
dependencies = [
"http",
"hyper",
"rustls",
"tokio",
"tokio-rustls",
]
[[package]]
name = "idna"
version = "0.3.0"
@ -536,6 +648,28 @@ dependencies = [ @@ -536,6 +648,28 @@ dependencies = [
"tiff",
]
[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "ipnet"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
[[package]]
name = "itoa"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]]
name = "jobserver"
version = "0.1.25"
@ -619,6 +753,12 @@ dependencies = [ @@ -619,6 +753,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -744,8 +884,6 @@ dependencies = [ @@ -744,8 +884,6 @@ dependencies = [
[[package]]
name = "openh264-sys2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b4dbf4c810df4cab1b8dcf249f24bf6aa0f150768ceae9b4bb87bb346ffd99"
dependencies = [
"cc",
"nasm-rs",
@ -955,6 +1093,45 @@ version = "0.6.28" @@ -955,6 +1093,45 @@ version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "reqwest"
version = "0.11.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"hyper-rustls",
"ipnet",
"js-sys",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-rustls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots",
"winreg",
]
[[package]]
name = "retina"
version = "0.4.3"
@ -994,6 +1171,21 @@ dependencies = [ @@ -994,6 +1171,21 @@ dependencies = [
"mpeg4-audio-const",
]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin 0.5.2",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "rtsp-types"
version = "0.0.3"
@ -1006,6 +1198,33 @@ dependencies = [ @@ -1006,6 +1198,33 @@ dependencies = [
"url",
]
[[package]]
name = "rustls"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
dependencies = [
"base64",
]
[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "same-file"
version = "1.0.6"
@ -1027,6 +1246,16 @@ version = "1.1.0" @@ -1027,6 +1246,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "sdp-types"
version = "0.1.5"
@ -1057,6 +1286,29 @@ dependencies = [ @@ -1057,6 +1286,29 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.6"
@ -1102,6 +1354,12 @@ dependencies = [ @@ -1102,6 +1354,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.4"
@ -1228,6 +1486,17 @@ dependencies = [ @@ -1228,6 +1486,17 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"tokio",
"webpki",
]
[[package]]
name = "tokio-util"
version = "0.7.4"
@ -1251,6 +1520,12 @@ dependencies = [ @@ -1251,6 +1520,12 @@ dependencies = [
"serde",
]
[[package]]
name = "tower-service"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.37"
@ -1271,6 +1546,12 @@ dependencies = [ @@ -1271,6 +1546,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "typenum"
version = "1.16.0"
@ -1298,6 +1579,12 @@ dependencies = [ @@ -1298,6 +1579,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.3.1"
@ -1326,6 +1613,16 @@ dependencies = [ @@ -1326,6 +1613,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
@ -1363,6 +1660,18 @@ dependencies = [ @@ -1363,6 +1660,18 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
@ -1392,6 +1701,35 @@ version = "0.2.83" @@ -1392,6 +1701,35 @@ version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[package]]
name = "web-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.22.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
dependencies = [
"webpki",
]
[[package]]
name = "weezl"
version = "0.1.7"
@ -1485,3 +1823,12 @@ name = "windows_x86_64_msvc" @@ -1485,3 +1823,12 @@ name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]

3
Cargo.toml

@ -15,4 +15,5 @@ serde = { version = "1.0", features = ["derive"] } @@ -15,4 +15,5 @@ serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
log = { version = "0.4", features = ["serde"] }
pretty_env_logger = "0.4"
# Use Rustls in order to be cross-compilable.
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features = false }

15
src/config.rs

@ -4,12 +4,12 @@ use serde::Deserialize; @@ -4,12 +4,12 @@ use serde::Deserialize;
/// A probe: a request to export the brightness of a given pixel as an entity
/// in Home Assistant.
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, Clone)]
pub struct Probe {
/// The X coordinate of the pixel to sample.
pub(crate) x: usize,
pub(crate) x: u32,
/// The Y coordinate of the pixel to sample.
pub(crate) y: usize,
pub(crate) y: u32,
/// A unique ID for this probe.
pub(crate) unique_id: String,
/// A Home Assistant icon for this probe.
@ -20,12 +20,16 @@ pub struct Probe { @@ -20,12 +20,16 @@ pub struct Probe {
pub(crate) friendly_name: String,
}
fn default_retrans_interval() -> u64 {
60
}
fn default_log_level() -> log::LevelFilter {
log::LevelFilter::Info
}
/// Configuration for the program.
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, Clone)]
pub struct Configuration {
/// RTSP URI to subscribe to.
pub(crate) rtsp_uri: String,
@ -43,4 +47,7 @@ pub struct Configuration { @@ -43,4 +47,7 @@ pub struct Configuration {
/// Path to save the first decoded image to.
#[serde(default)]
pub(crate) image_path: Option<String>,
/// Time between retransmits of all state.
#[serde(default = "default_retrans_interval")]
pub(crate) state_retrans_interval_sec: u64,
}

29
src/main.rs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
use anyhow::{anyhow, Context};
use byteorder::{BigEndian, ReadBytesExt};
use futures_util::StreamExt;
use futures_util::{StreamExt, TryFutureExt};
use image::{ImageBuffer, Rgb};
use log::{debug, error, info, trace, warn};
use openh264::decoder::{Decoder, DecoderConfig};
@ -9,10 +9,15 @@ use retina::codec::{CodecItem, ParametersRef}; @@ -9,10 +9,15 @@ use retina::codec::{CodecItem, ParametersRef};
use std::fs::File;
use std::io::{Cursor, Read, Seek, SeekFrom};
use std::time::{Duration, Instant};
use tokio::sync::mpsc;
use tokio::sync::mpsc::error::TrySendError;
mod config;
mod probe;
use crate::config::{Configuration, Probe};
use crate::config::Configuration;
pub(crate) type DecodedImage = ImageBuffer<Rgb<u8>, Vec<u8>>;
fn print_usage() {
let our_name = std::env::args()
@ -56,6 +61,19 @@ async fn main() -> anyhow::Result<()> { @@ -56,6 +61,19 @@ async fn main() -> anyhow::Result<()> {
.init();
info!("boiler-stats v{}", env!("CARGO_PKG_VERSION"));
let (tx, rx) = mpsc::channel(10);
let client = reqwest::Client::new();
let prober = probe::Prober {
config: config.clone(),
rx,
reqwest: client,
};
tokio::spawn(prober.run().map_err(|e| {
error!("Probe loop failed: {}", e);
e
}));
info!("connecting to RTSP stream at {}", config.rtsp_uri);
let uri = config.rtsp_uri.parse().context("parsing RTSP URI")?;
@ -196,6 +214,13 @@ async fn main() -> anyhow::Result<()> { @@ -196,6 +214,13 @@ async fn main() -> anyhow::Result<()> {
}
imaged = true;
}
match tx.try_send(ibuf) {
Err(TrySendError::Closed(_)) => {
return Err(anyhow!("probe loop failed"));
}
Err(TrySendError::Full(_)) => trace!("probe loop behind!"),
_ => {}
}
}
Ok(None) => {
last_success = Instant::now();

146
src/probe.rs

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
//! Identifying probed pixels and submitting them to Home Assistant.
use crate::config::Probe;
use crate::{Configuration, DecodedImage};
use anyhow::anyhow;
use image::Pixel;
use log::{debug, info, warn};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, Instant};
use tokio::sync::mpsc::Receiver;
pub(crate) struct Prober {
pub(crate) rx: Receiver<DecodedImage>,
pub(crate) config: Configuration,
pub(crate) reqwest: Client,
}
#[derive(Serialize)]
struct HassAttributes {
icon: String,
friendly_name: String,
device_class: String,
unique_id: String,
}
#[derive(Serialize)]
struct HassPayload {
state: &'static str,
attributes: HassAttributes,
}
#[derive(Deserialize)]
struct HassStateReply {
state: String,
}
impl Prober {
async fn state_get(&self, probe: &Probe) -> anyhow::Result<String> {
let resp = self
.reqwest
.get(format!(
"{}/api/states/binary_sensor.{}",
self.config.home_assistant_uri, probe.unique_id
))
.header(
"Authorization",
format!("Bearer {}", self.config.home_assistant_token),
)
.send()
.await?;
let ret: HassStateReply = resp.json().await?;
Ok(ret.state)
}
async fn state_set(&self, probe: &Probe, state: bool) -> anyhow::Result<()> {
self.reqwest
.post(format!(
"{}/api/states/binary_sensor.{}",
self.config.home_assistant_uri, probe.unique_id
))
.header(
"Authorization",
format!("Bearer {}", self.config.home_assistant_token),
)
.header("Content-Type", "application/json")
.json(&HassPayload {
state: if state { "on" } else { "off" },
attributes: HassAttributes {
icon: probe.icon.clone(),
friendly_name: probe.friendly_name.clone(),
device_class: probe.device_class.clone(),
unique_id: format!("binary_sensor.{}", probe.unique_id),
},
})
.send()
.await?;
Ok(())
}
pub(crate) async fn run(mut self) -> anyhow::Result<()> {
// we use an Option to discern "not observed yet" from "off"
let mut states: HashMap<String, (Option<bool>, Probe)> = HashMap::new();
for probe in self.config.probes.iter() {
if states.contains_key(&probe.unique_id) {
return Err(anyhow!(
"Multiple probes have the unique ID {}",
probe.unique_id
));
}
states.insert(probe.unique_id.clone(), (None, probe.clone()));
}
let retrans_dur = Duration::from_secs(self.config.state_retrans_interval_sec);
let mut next_retrans = Instant::now() + retrans_dur;
while let Some(i) = self.rx.recv().await {
for (id, (state, probe)) in states.iter_mut() {
let pixel_luma = i.get_pixel(probe.x, probe.y).to_luma()[0];
let new_state = pixel_luma >= self.config.on_luma;
debug!(
"{}: ({}, {}) = {} ({})",
id, probe.x, probe.y, pixel_luma, new_state
);
if *state != Some(new_state) {
*state = Some(new_state);
info!(
"Probe {} ({}) detected as {}",
id,
probe.friendly_name,
if new_state { "ON" } else { "OFF" }
);
if let Err(e) = self.state_set(probe, new_state).await {
warn!("Failed to update Home Assistant: {}", e);
}
}
}
if next_retrans < Instant::now() {
debug!("Doing periodic state check");
for (id, (state, probe)) in states.iter() {
if let Some(state) = state {
match self.state_get(probe).await {
Ok(hass) => {
let expected = if *state { "on" } else { "off" };
debug!("{}: hass {} expected {}", id, hass, expected);
if hass == expected {
continue;
}
warn!(
"Probe {} ({}) is {}, but Home Assistant thinks it's {}!",
id, probe.friendly_name, expected, hass
);
if let Err(e) = self.state_set(probe, *state).await {
warn!("Failed to retransmit to Home Assistant: {}", e);
}
}
Err(e) => {
warn!("Failed to get state for {} from Home Assistant: {}", id, e);
}
}
}
}
next_retrans = Instant::now() + retrans_dur;
}
}
debug!("probe loop stopped");
Ok(())
}
}
Loading…
Cancel
Save