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]]
name = "homekit-controller"
version = "0.4.1"
version = "0.5.3"
dependencies = [
"chacha20poly1305",
"ed25519-dalek",
@ -1143,7 +1143,7 @@ dependencies = [
[[package]]
name = "homekit-exporter"
version = "0.5.2"
version = "0.5.3"
dependencies = [
"clap",
"env_logger",

View file

@ -1,6 +1,6 @@
[package]
name = "homekit-controller"
version = "0.4.1"
version = "0.5.3"
edition = "2021"
# 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(
&self,
discovered: &MdnsDiscoveredList,
name: Option<String>,
) -> 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.characteristics_request(true).await?;
Ok(connected_device)
}
pub fn to_connection(&self, discovered: MdnsDiscoveredList) -> DeviceConnection {
pub fn to_connection(
&self,
discovered: MdnsDiscoveredList,
name: Option<String>,
) -> DeviceConnection {
DeviceConnection {
name,
accessories: Default::default(),
discovered,
pairing_data: DevicePairingData {
@ -73,6 +79,7 @@ struct DevicePairingData {
#[derive(Debug)]
pub struct DeviceConnection {
pub name: Option<String>,
pub accessories: HashMap<usize, Accessory>,
discovered: MdnsDiscoveredList,
pairing_data: DevicePairingData,
@ -245,7 +252,10 @@ impl DeviceConnection {
if let Some(e) = error.first().and_then(|v| TlvError::try_from(*v).ok()) {
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);
}
@ -304,7 +314,10 @@ impl DeviceConnection {
{
Ok(r) => r,
Err(_) => {
log::warn!("failed to update characteristics");
log::warn!(
"{}failed to update characteristics",
formatted_name(&self.name)
);
self.socket = None;
Err(HomekitError::Timeout)
}
@ -312,45 +325,57 @@ impl DeviceConnection {
}
async fn characteristics_request(&mut self, additional_data: bool) -> Result<(), HomekitError> {
'outer: loop {
if self.socket.is_none() {
self.connect().await?;
}
if let Some(socket) = &mut self.socket {
for (aid, data) in &mut self.accessories {
for service in data.services.values_mut() {
let characteristic_ids = service
.characteristics
.keys()
.map(|k| format!("{aid}.{k}"))
.collect::<Vec<_>>();
let characteristics = match socket
.get_characteristics(&characteristic_ids, additional_data)
.await
{
Ok(val) => val,
Err(_e) => {
continue 'outer;
}
};
for (cid, c) in &characteristics {
if c.characteristic_type == CharacteristicType::Name {
if let Some(Data::String(name)) = &c.value {
service.name = Some(name.clone());
loop {
match self.socket.as_mut() {
None => {
log::info!("{}reconnecting...", formatted_name(&self.name));
self.connect().await?;
log::info!("{}reconnected", formatted_name(&self.name));
}
Some(socket) => {
for (aid, data) in &mut self.accessories {
's: for service in data.services.values_mut() {
let characteristic_ids = service
.characteristics
.keys()
.map(|k| format!("{aid}.{k}"))
.collect::<Vec<_>>();
let characteristics = match socket
.get_characteristics(&characteristic_ids, additional_data)
.await
{
Ok(v) => v,
Err(e) => {
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());
continue 's;
}
};
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)]
pub enum HomekitError {
#[error("could not connect to any devices")]

View file

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

View file

@ -1,7 +1,7 @@
# Maintainer: Alex Janka <alex@alexjanka.com>
pkgname=homekit-logger
pkgver=0.5.2
pkgver=0.5.3
pkgrel=1
pkgdesc="Prometheus exporter for HomeKit sensors"
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 {
let discovered = discovered.clone();
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 {
Ok(Err(e)) => log::error!("error connecting to {k}: {e:?}"),