diff --git a/Cargo.lock b/Cargo.lock index e2c4b83..77f3e51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arrayvec" @@ -173,7 +173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" dependencies = [ "concurrent-queue", - "event-listener 4.0.1", + "event-listener 4.0.2", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -289,7 +289,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" dependencies = [ - "event-listener 4.0.1", + "event-listener 4.0.2", "event-listener-strategy", "pin-project-lite", ] @@ -340,13 +340,13 @@ checksum = "e1d90cd0b264dfdd8eb5bad0a2c217c1f88fa96a8573f40e7b12de23fb468f46" [[package]] name = "async-trait" -version = "0.1.76" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -483,7 +483,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits 0.2.17", - "serde 1.0.193", + "serde 1.0.194", "wasm-bindgen", "windows-targets 0.48.5", ] @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" dependencies = [ "clap_builder", "clap_derive", @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" dependencies = [ "anstream", "anstyle", @@ -528,7 +528,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -570,7 +570,7 @@ dependencies = [ "lazy_static", "nom", "rust-ini", - "serde 1.0.193", + "serde 1.0.194", "serde-hjson", "serde_json", "toml", @@ -712,7 +712,7 @@ dependencies = [ "config", "crossbeam-queue", "num_cpus", - "serde 1.0.193", + "serde 1.0.194", "tokio", ] @@ -723,7 +723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", - "serde 1.0.193", + "serde 1.0.194", ] [[package]] @@ -789,9 +789,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.1" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2cdcf274580f2d63697192d744727b3198894b1bf02923643bf59e2c26712" +checksum = "218a870470cce1469024e9fb66b901aa983929d81304a1cdb299f28118e550d5" dependencies = [ "concurrent-queue", "parking", @@ -804,7 +804,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 4.0.1", + "event-listener 4.0.2", "pin-project-lite", ] @@ -949,7 +949,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -1139,7 +1139,7 @@ dependencies = [ "infer", "pin-project-lite", "rand 0.7.3", - "serde 1.0.193", + "serde 1.0.194", "serde_json", "serde_qs", "serde_urlencoded", @@ -1281,7 +1281,7 @@ dependencies = [ "influxdb", "paho-mqtt", "postgres", - "serde 1.0.193", + "serde 1.0.194", "serde_json", "serde_yaml", "time 0.3.31", @@ -1521,7 +1521,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -1638,7 +1638,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -1775,18 +1775,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.72" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a293318316cf6478ec1ad2a21c49390a8d5b5eae9fab736467d93fbc0edc29c5" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2015,9 +2015,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] @@ -2037,24 +2037,24 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ "itoa", "ryu", - "serde 1.0.193", + "serde 1.0.194", ] [[package]] @@ -2064,7 +2064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" dependencies = [ "percent-encoding", - "serde 1.0.193", + "serde 1.0.194", "thiserror", ] @@ -2086,19 +2086,19 @@ dependencies = [ "form_urlencoded", "itoa", "ryu", - "serde 1.0.193", + "serde 1.0.194", ] [[package]] name = "serde_yaml" -version = "0.9.29" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129" +checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" dependencies = [ "indexmap", "itoa", "ryu", - "serde 1.0.193", + "serde 1.0.194", "unsafe-libyaml", ] @@ -2219,7 +2219,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ "proc-macro2", "quote", - "serde 1.0.193", + "serde 1.0.194", "serde_derive", "syn 1.0.109", ] @@ -2233,7 +2233,7 @@ dependencies = [ "base-x", "proc-macro2", "quote", - "serde 1.0.193", + "serde 1.0.194", "serde_derive", "serde_json", "sha1", @@ -2287,7 +2287,7 @@ dependencies = [ "mime_guess", "once_cell", "pin-project-lite", - "serde 1.0.193", + "serde 1.0.194", "serde_json", ] @@ -2304,9 +2304,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", @@ -2337,22 +2337,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", ] [[package]] @@ -2379,7 +2379,7 @@ dependencies = [ "deranged", "itoa", "powerfmt", - "serde 1.0.193", + "serde 1.0.194", "time-core", "time-macros 0.2.16", ] @@ -2498,7 +2498,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "serde 1.0.193", + "serde 1.0.194", ] [[package]] @@ -2581,7 +2581,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde 1.0.193", + "serde 1.0.194", ] [[package]] @@ -2647,7 +2647,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", "wasm-bindgen-shared", ] @@ -2681,7 +2681,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.46", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/src/data/shelly/mod.rs b/src/data/shelly/mod.rs index d7d0c23..dc5c87f 100644 --- a/src/data/shelly/mod.rs +++ b/src/data/shelly/mod.rs @@ -34,7 +34,7 @@ impl Timestamped for SwitchData { #[derive(Serialize, Deserialize, Clone, Debug)] pub struct CoverData { #[serde(rename = "current_pos")] - pub(crate) position: i32, + pub(crate) position: Option, #[serde(rename = "apower")] pub(crate) power: f32, pub(crate) voltage: f32, @@ -92,22 +92,22 @@ pub fn parse<'a, T: Deserialize<'a> + Clone>(msg: &'a Message) -> Result WriteType, &str)] = &[ - ("output", |data: &SwitchData| WriteType::Int(data.output as i32), "bool"), - ("power", |data: &SwitchData| WriteType::Float(data.power), "W"), - ("current", |data: &SwitchData| WriteType::Float(data.current), "A"), - ("voltage", |data: &SwitchData| WriteType::Float(data.voltage), "V"), - ("total_energy", |data: &SwitchData| WriteType::Float(data.energy.total), "Wh"), - ("temperature", |data: &SwitchData| WriteType::Float(data.temperature.t_celsius), "°C"), +const SWITCH_FIELDS: &[(&str, fn(data: &SwitchData) -> Option, &str)] = &[ + ("output", |data: &SwitchData| Some(WriteType::Int(data.output as i32)), "bool"), + ("power", |data: &SwitchData| Some(WriteType::Float(data.power)), "W"), + ("current", |data: &SwitchData| Some(WriteType::Float(data.current)), "A"), + ("voltage", |data: &SwitchData| Some(WriteType::Float(data.voltage)), "V"), + ("total_energy", |data: &SwitchData| Some(WriteType::Float(data.energy.total)), "Wh"), + ("temperature", |data: &SwitchData| Some(WriteType::Float(data.temperature.t_celsius)), "°C"), ]; -const COVER_FIELDS: &[(&str, fn(data: &CoverData) -> WriteType, &str)] = &[ - ("position", |data: &CoverData| WriteType::Int(data.position), "%"), - ("power", |data: &CoverData| WriteType::Float(data.power), "W"), - ("current", |data: &CoverData| WriteType::Float(data.current), "A"), - ("voltage", |data: &CoverData| WriteType::Float(data.voltage), "V"), - ("total_energy", |data: &CoverData| WriteType::Float(data.energy.total), "Wh"), - ("temperature", |data: &CoverData| WriteType::Float(data.temperature.t_celsius), "°C"), +const COVER_FIELDS: &[(&str, fn(data: &CoverData) -> Option, &str)] = &[ + ("position", |data: &CoverData| if let Some(position) = data.position { Some(WriteType::Int(position)) } else { None }, "%"), + ("power", |data: &CoverData| Some(WriteType::Float(data.power)), "W"), + ("current", |data: &CoverData| Some(WriteType::Float(data.current)), "A"), + ("voltage", |data: &CoverData| Some(WriteType::Float(data.voltage)), "V"), + ("total_energy", |data: &CoverData| Some(WriteType::Float(data.energy.total)), "Wh"), + ("temperature", |data: &CoverData| Some(WriteType::Float(data.temperature.t_celsius)), "°C"), ]; impl CheckMessage for ShellyLogger { @@ -121,7 +121,7 @@ impl CheckMessage for ShellyLogger { } } -fn handle_message<'a, T: Deserialize<'a> + Clone + Debug + Timestamped>(msg: &'a Message, tx: &SyncSender, fields: &[(&str, fn(&T) -> WriteType, &str)]) { +fn handle_message<'a, T: Deserialize<'a> + Clone + Debug + Timestamped>(msg: &'a Message, tx: &SyncSender, fields: &[(&str, fn(&T) -> Option, &str)]) { let location = msg.topic().split("/").nth(1).unwrap(); let result: Option = shelly::parse(&msg).unwrap(); if let Some(data) = result { @@ -133,12 +133,13 @@ fn handle_message<'a, T: Deserialize<'a> + Clone + Debug + Timestamped>(msg: &'a let query = WriteQuery::new(timestamp, *measurement); let result = value(&data); let query = match result { - WriteType::Int(i) => { + Some(WriteType::Int(i)) => { query.add_field("value", i) } - WriteType::Float(f) => { + Some(WriteType::Float(f)) => { query.add_field("value", f) } + None => {query} }; let query = query.add_tag("location", location) @@ -179,7 +180,7 @@ mod tests { let message = Message::new("shellies/bedroom-curtain/status/cover:0", "{\"id\":0, \"source\":\"limit_switch\", \"state\":\"open\",\"apower\":0.0,\"voltage\":231.7,\"current\":0.500,\"pf\":0.00,\"freq\":50.0,\"aenergy\":{\"total\":3.143,\"by_minute\":[0.000,0.000,97.712],\"minute_ts\":1703414519},\"temperature\":{\"tC\":30.7, \"tF\":87.3},\"pos_control\":true,\"last_direction\":\"open\",\"current_pos\":100}", QOS_1); let result: CoverData = parse(&message)?.unwrap(); - assert_eq!(result.position, 100); + assert_eq!(result.position, Some(100)); assert_eq!(result.power, 0.0); assert_eq!(result.voltage, 231.7); assert_eq!(result.current, 0.5); @@ -195,14 +196,18 @@ mod tests { let message = Message::new("shellies/bedroom-curtain/status/cover:0", "{\"id\":0, \"source\":\"limit_switch\", \"state\":\"open\",\"apower\":0.0,\"voltage\":231.7,\"current\":0.500,\"pf\":0.00,\"freq\":50.0,\"aenergy\":{\"total\":3.143,\"by_minute\":[0.000,0.000,97.712]},\"temperature\":{\"tC\":30.7, \"tF\":87.3},\"pos_control\":true,\"last_direction\":\"open\",\"current_pos\":100}", QOS_1); let result: CoverData = parse(&message)?.unwrap(); - assert_eq!(result.position, 100); - assert_eq!(result.power, 0.0); - assert_eq!(result.voltage, 231.7); - assert_eq!(result.current, 0.5); - assert_eq!(result.energy.total, 3.143); - assert_eq!(result.temperature.t_celsius, 30.7); assert!(result.energy.minute_ts.is_none()); Ok(()) } + + #[test] + fn test_parse_cover_status_without_position() -> Result<(), &'static str> { + let message = Message::new("shellies/bedroom-curtain/status/cover:0", "{\"id\":0, \"source\":\"limit_switch\", \"state\":\"open\",\"apower\":0.0,\"voltage\":231.7,\"current\":0.500,\"pf\":0.00,\"freq\":50.0,\"aenergy\":{\"total\":3.143,\"by_minute\":[0.000,0.000,97.712],\"minute_ts\":1703414519},\"temperature\":{\"tC\":30.7, \"tF\":87.3},\"pos_control\":true,\"last_direction\":\"open\"}", QOS_1); + let result: CoverData = parse(&message)?.unwrap(); + + assert!(result.position.is_none()); + + Ok(()) + } } \ No newline at end of file