125 lines
4.9 KiB
Rust
125 lines
4.9 KiB
Rust
//! HAP service type and characteristic enum catalogues.
|
||
//!
|
||
//! Mirrors the HAP-1.1 service/characteristic namespace used by Apple Home
|
||
//! and the `hap` crate (https://crates.io/crates/hap). Keeping these as
|
||
//! plain Rust enums in P1 avoids the heavy `hap` dep until P2.
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
/// HAP service types exposed by the RuView bridge.
|
||
///
|
||
/// Derived from HomeKit Accessory Protocol Specification §8 (service
|
||
/// definitions) and cross-checked against HA's `homekit` integration
|
||
/// service catalog.
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||
pub enum HapAccessoryType {
|
||
/// HAP `Lightbulb` service — maps `light.*` entities.
|
||
Lightbulb,
|
||
/// HAP `Switch` service — maps generic boolean `switch.*` entities.
|
||
Switch,
|
||
/// HAP `OccupancySensor` — maps presence / occupancy binary sensors.
|
||
OccupancySensor,
|
||
/// HAP `MotionSensor` — maps motion binary sensors + RuView motion.
|
||
MotionSensor,
|
||
/// HAP `TemperatureSensor` — maps `sensor.*temperature*` entities.
|
||
TemperatureSensor,
|
||
/// HAP `HumiditySensor` — maps `sensor.*humidity*` entities.
|
||
HumiditySensor,
|
||
/// HAP `LeakSensor` — maps abnormal event sensors; used for fall detection
|
||
/// following HA's homekit_controller convention (HAP §11.42).
|
||
LeakSensor,
|
||
/// HAP `ContactSensor` — maps door / window binary sensors.
|
||
ContactSensor,
|
||
/// HAP `Door` service — maps `cover.*door*` entities.
|
||
Door,
|
||
/// HAP `LockMechanism` service — maps `lock.*` entities.
|
||
Lock,
|
||
/// HAP `SecuritySystem` service — maps alarm / security panel entities.
|
||
SecuritySystem,
|
||
}
|
||
|
||
impl HapAccessoryType {
|
||
/// All defined variants — used in tests and for UI enumeration.
|
||
pub const ALL: &'static [HapAccessoryType] = &[
|
||
HapAccessoryType::Lightbulb,
|
||
HapAccessoryType::Switch,
|
||
HapAccessoryType::OccupancySensor,
|
||
HapAccessoryType::MotionSensor,
|
||
HapAccessoryType::TemperatureSensor,
|
||
HapAccessoryType::HumiditySensor,
|
||
HapAccessoryType::LeakSensor,
|
||
HapAccessoryType::ContactSensor,
|
||
HapAccessoryType::Door,
|
||
HapAccessoryType::Lock,
|
||
HapAccessoryType::SecuritySystem,
|
||
];
|
||
}
|
||
|
||
/// HAP characteristic identifiers that the bridge reads or writes.
|
||
///
|
||
/// Each variant corresponds to one HAP characteristic UUID as specified in
|
||
/// HomeKit Accessory Protocol Specification §9.
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||
pub enum HapCharacteristic {
|
||
/// `On` (bool) — Lightbulb / Switch power state.
|
||
On,
|
||
/// `Brightness` (uint8, 0–100) — Lightbulb brightness percentage.
|
||
Brightness,
|
||
/// `CurrentTemperature` (float, °C) — TemperatureSensor reading.
|
||
CurrentTemperature,
|
||
/// `CurrentRelativeHumidity` (float, %) — HumiditySensor reading.
|
||
CurrentRelativeHumidity,
|
||
/// `OccupancyDetected` (uint8, 0=not detected, 1=detected).
|
||
OccupancyDetected,
|
||
/// `MotionDetected` (bool).
|
||
MotionDetected,
|
||
/// `LeakDetected` (uint8, 0=no leak, 1=leak detected). Re-used for falls.
|
||
LeakDetected,
|
||
/// `ContactSensorState` (uint8, 0=in contact, 1=not in contact).
|
||
ContactSensorState,
|
||
/// `CurrentDoorState` (uint8, HAP §9.30).
|
||
CurrentDoorState,
|
||
/// `LockCurrentState` (uint8, HAP §9.56).
|
||
LockCurrentState,
|
||
/// `SecuritySystemCurrentState` (uint8, HAP §9.97).
|
||
SecuritySystemCurrentState,
|
||
}
|
||
|
||
/// Typed value carried by a HAP characteristic update.
|
||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||
pub enum HapCharacteristicValue {
|
||
Bool(bool),
|
||
UInt8(u8),
|
||
Float(f64),
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn all_11_accessory_types_defined() {
|
||
assert_eq!(HapAccessoryType::ALL.len(), 11);
|
||
// Spot-check each variant is present.
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::Lightbulb));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::Switch));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::OccupancySensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::MotionSensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::TemperatureSensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::HumiditySensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::LeakSensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::ContactSensor));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::Door));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::Lock));
|
||
assert!(HapAccessoryType::ALL.contains(&HapAccessoryType::SecuritySystem));
|
||
}
|
||
|
||
#[test]
|
||
fn characteristic_value_roundtrip_serde() {
|
||
let v = HapCharacteristicValue::Float(22.5);
|
||
let json = serde_json::to_string(&v).unwrap();
|
||
let back: HapCharacteristicValue = serde_json::from_str(&json).unwrap();
|
||
assert_eq!(v, back);
|
||
}
|
||
}
|