better logging and maybe better error handling

This commit is contained in:
Alex Janka 2024-04-02 08:29:29 +11:00
parent 63afe2bb28
commit 207a5b8917
6 changed files with 64 additions and 39 deletions

4
Cargo.lock generated
View file

@ -1120,7 +1120,7 @@ dependencies = [
[[package]] [[package]]
name = "homekit-controller" name = "homekit-controller"
version = "0.4.1" version = "0.5.3"
dependencies = [ dependencies = [
"chacha20poly1305", "chacha20poly1305",
"ed25519-dalek", "ed25519-dalek",
@ -1143,7 +1143,7 @@ dependencies = [
[[package]] [[package]]
name = "homekit-exporter" name = "homekit-exporter"
version = "0.5.2" version = "0.5.3"
dependencies = [ dependencies = [
"clap", "clap",
"env_logger", "env_logger",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "homekit-controller" name = "homekit-controller"
version = "0.4.1" version = "0.5.3"
edition = "2021" edition = "2021"
# 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

View file

@ -36,16 +36,22 @@ impl PythonPairingData {
pub async fn connect( pub async fn connect(
&self, &self,
discovered: &MdnsDiscoveredList, discovered: &MdnsDiscoveredList,
name: Option<String>,
) -> Result<DeviceConnection, HomekitError> { ) -> Result<DeviceConnection, HomekitError> {
let mut connected_device: DeviceConnection = self.to_connection(discovered.clone()); let mut connected_device: DeviceConnection = self.to_connection(discovered.clone(), name);
connected_device.connect().await?; connected_device.connect().await?;
connected_device.characteristics_request(true).await?; connected_device.characteristics_request(true).await?;
Ok(connected_device) Ok(connected_device)
} }
pub fn to_connection(&self, discovered: MdnsDiscoveredList) -> DeviceConnection { pub fn to_connection(
&self,
discovered: MdnsDiscoveredList,
name: Option<String>,
) -> DeviceConnection {
DeviceConnection { DeviceConnection {
name,
accessories: Default::default(), accessories: Default::default(),
discovered, discovered,
pairing_data: DevicePairingData { pairing_data: DevicePairingData {
@ -73,6 +79,7 @@ struct DevicePairingData {
#[derive(Debug)] #[derive(Debug)]
pub struct DeviceConnection { pub struct DeviceConnection {
pub name: Option<String>,
pub accessories: HashMap<usize, Accessory>, pub accessories: HashMap<usize, Accessory>,
discovered: MdnsDiscoveredList, discovered: MdnsDiscoveredList,
pairing_data: DevicePairingData, pairing_data: DevicePairingData,
@ -245,7 +252,10 @@ impl DeviceConnection {
if let Some(e) = error.first().and_then(|v| TlvError::try_from(*v).ok()) { if let Some(e) = error.first().and_then(|v| TlvError::try_from(*v).ok()) {
return Err(e.into()); return Err(e.into());
} }
log::error!("got tlv error from device but couldn't parse it from the data!"); log::error!(
"{}got tlv error from device but couldn't parse it from the data!",
formatted_name(&self.name)
);
return Err(HomekitError::TlvNotFound); return Err(HomekitError::TlvNotFound);
} }
@ -304,7 +314,10 @@ impl DeviceConnection {
{ {
Ok(r) => r, Ok(r) => r,
Err(_) => { Err(_) => {
log::warn!("failed to update characteristics"); log::warn!(
"{}failed to update characteristics",
formatted_name(&self.name)
);
self.socket = None; self.socket = None;
Err(HomekitError::Timeout) Err(HomekitError::Timeout)
} }
@ -312,45 +325,57 @@ impl DeviceConnection {
} }
async fn characteristics_request(&mut self, additional_data: bool) -> Result<(), HomekitError> { async fn characteristics_request(&mut self, additional_data: bool) -> Result<(), HomekitError> {
'outer: loop { loop {
if self.socket.is_none() { match self.socket.as_mut() {
self.connect().await?; None => {
} log::info!("{}reconnecting...", formatted_name(&self.name));
if let Some(socket) = &mut self.socket { self.connect().await?;
for (aid, data) in &mut self.accessories { log::info!("{}reconnected", formatted_name(&self.name));
for service in data.services.values_mut() { }
let characteristic_ids = service Some(socket) => {
.characteristics for (aid, data) in &mut self.accessories {
.keys() 's: for service in data.services.values_mut() {
.map(|k| format!("{aid}.{k}")) let characteristic_ids = service
.collect::<Vec<_>>(); .characteristics
let characteristics = match socket .keys()
.get_characteristics(&characteristic_ids, additional_data) .map(|k| format!("{aid}.{k}"))
.await .collect::<Vec<_>>();
{ let characteristics = match socket
Ok(val) => val, .get_characteristics(&characteristic_ids, additional_data)
Err(_e) => { .await
continue 'outer; {
} Ok(v) => v,
}; Err(e) => {
for (cid, c) in &characteristics { log::warn!("{}error getting characteristics{} {characteristic_ids:?}:\n\t{e:?}", formatted_name(&self.name), service.name.as_ref().map(|n|format!(" for {n}")).unwrap_or_default());
if c.characteristic_type == CharacteristicType::Name {
if let Some(Data::String(name)) = &c.value { continue 's;
service.name = Some(name.clone()); }
};
for (cid, c) in &characteristics {
if c.characteristic_type == CharacteristicType::Name {
if let Some(Data::String(name)) = &c.value {
service.name = Some(name.clone());
}
}
if let Some(prev) = service.characteristics.get_mut(cid) {
prev.update_from(c);
} }
}
if let Some(prev) = service.characteristics.get_mut(cid) {
prev.update_from(c);
} }
} }
} }
return Ok(());
} }
} }
return Ok(());
} }
} }
} }
fn formatted_name(name: &Option<String>) -> String {
name.as_deref()
.map(|v| format!("{v}: "))
.unwrap_or_default()
}
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum HomekitError { pub enum HomekitError {
#[error("could not connect to any devices")] #[error("could not connect to any devices")]

View file

@ -1,6 +1,6 @@
[package] [package]
name = "homekit-exporter" name = "homekit-exporter"
version = "0.5.2" version = "0.5.3"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
description = "Prometheus exporter for HomeKit sensors" description = "Prometheus exporter for HomeKit sensors"

View file

@ -1,7 +1,7 @@
# Maintainer: Alex Janka <alex@alexjanka.com> # Maintainer: Alex Janka <alex@alexjanka.com>
pkgname=homekit-logger pkgname=homekit-logger
pkgver=0.5.2 pkgver=0.5.3
pkgrel=1 pkgrel=1
pkgdesc="Prometheus exporter for HomeKit sensors" pkgdesc="Prometheus exporter for HomeKit sensors"
arch=('x86_64' 'aarch64') arch=('x86_64' 'aarch64')

View file

@ -82,7 +82,7 @@ async fn init(pairing_data: PathBuf) -> Result<HashMap<String, DeviceConnection>
for (k, v) in devices { for (k, v) in devices {
let discovered = discovered.clone(); let discovered = discovered.clone();
set.spawn(async move { set.spawn(async move {
let mut connection = v.to_connection(discovered.clone()); let mut connection = v.to_connection(discovered.clone(), Some(k.clone()));
match tokio::time::timeout(Duration::from_secs(5), connection.connect()).await { match tokio::time::timeout(Duration::from_secs(5), connection.connect()).await {
Ok(Err(e)) => log::error!("error connecting to {k}: {e:?}"), Ok(Err(e)) => log::error!("error connecting to {k}: {e:?}"),