#zigbee2mqtt #zigbee2mqtt-json #type #lib #convert #definition #messages

yanked zigbee2mqtt-types-generator

Struct definitions for zigbee2mqtt json messages

0.2.2 May 4, 2023

#48 in #zigbee2mqtt-json

MIT license

120KB
2.5K SLoC

Zigbee2mqtt types

This is an auto generated lib containing concrete types that can easily deserialise any json MQTT payloads from zigbee2mqtt.

How to use

To speed up compile time all structs are behind feature flags, these are split into vendors e.g. if you are using a sensor by xiaomi then you will need to add the xiaomi feature to your Cargo.toml like zigbee2mqtt-types = {features = ["xiaomi"]}

Example of using a door contact sensor (note: debug is also a feature) add zigbee2mqtt-types = {features = ["debug", "xiaomi"]} to Cargo.toml dependencies

use zigbee2mqtt_types::xiaomi::ZigbeeMccgq11lm;

#[test]
fn contact_sensor_mccgq11lm() {
    //https://www.zigbee2mqtt.io/devices/MCCGQ11LM.html
    let json = serde_json::json!({
        "voltage": 2995,
        "battery": 97,
        "device_temperature": 19,
        "last_seen": "2022_10_20T11:55:07.199z", // this is a zigbee2mqtt setting, todo I need to make a nice way to handle this
        "power_outage_count": 6,
        "linkquality": 247,
        "contact": false,
        "elapsed": 2547593 // another zigbee2mqtt addon setting
    })
    .to_string();
    let parsed: zigbee2mqtt_types::xiaomi::ZigbeeMccgq11lm =
        match serde_json::from_str(&json) {
            Ok(contact) => contact,
            Err(err) => {
                println!("{:?}", err);
                assert!(false);
                unimplemented!()
            }
        };

    assert_eq!(2995, parsed.voltage);
    assert_eq!(97, parsed.battery);
    assert_eq!(19, parsed.device_temperature);
    assert_eq!(6, parsed.power_outage_count);
    assert_eq!(247, parsed.linkquality);
    assert_eq!(false, parsed.contact);
}

Last gotcha is all not all model/vendor names strings conform to Rusts struct/package naming convention, so I needed todo some transformation to them. Models roughly remove all invalid chars and have Zigbee infront of them. Vendors have an _ in place of any invalid chars example of changes to models

"ZS057-D0Z" = "ZigbeeZs057Dd0z"
"BF 265" = "ZigbeeBf265"
"5110.40" = "Zigbee5110F40"
"MEAZON_BIZY_PLUG" = "ZigbeeMeazonUbizyUplug"

example of changes to vendors

"Eaton/Halo LED" = "eaton_halo_led"
"Custom devices (DiY)" = "custom_devices__diy_"
"Villeroy & Boch" = "villeroy___boch"
"J.XUAN" = "j_xuan"
 // the bellow is just removing non ascii chars I would personally prefer to swap them for similar ascii but for now I will _
"Müller Licht" = "m_ller_licht"
"Sinopé" = "sinop_"

Model function that does conversion is here Vendor function that does conversion is here

Why

While creating a recent project I found myself being lazy with how I was defining my structs to consume MQTT payloads and given they are already defined in Zigbee2MQTT I went looking for a way to generate them programmatically.

Contributions

All development should be in the top level generator binary as zigbee-herdsman updates too frequently to maintain human updating of this lib. Atm I don't have this generating wit CI but at some point I plan to that to keep this up to date with zigbee-herdsman

Future goals

  • improve lib documentation
  • some sort of type extension to allow last seen to be correctly parsed
  • add get set methods

Up to date issues can be seen here https://gitlab.com/seam345/zigbee2mqtt-types/-/issues

Dependencies

~4–6.5MB
~120K SLoC