prometheus (style) metrics

This commit is contained in:
Alex Janka 2024-02-23 17:52:47 +11:00
parent 7ffea13691
commit 1711b3d6ea
4 changed files with 63 additions and 349 deletions

21
Cargo.lock generated
View file

@ -898,6 +898,8 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
"strum",
"strum_macros",
"thiserror", "thiserror",
"tokio", "tokio",
"x25519-dalek", "x25519-dalek",
@ -1798,6 +1800,25 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "strum"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f"
[[package]]
name = "strum_macros"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.48",
]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.4.1"

View file

@ -20,3 +20,5 @@ http = "1.0"
httparse = "1.8" httparse = "1.8"
tokio = { version = "1.36", features = ["net"] } tokio = { version = "1.36", features = ["net"] }
zeroconf = "0.14" zeroconf = "0.14"
strum = "0.26"
strum_macros = "0.26"

View file

@ -1,4 +1,5 @@
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use strum_macros::Display;
// data from https://github.com/oznu/homebridge-gsh/blob/master/src/hap-types.ts // data from https://github.com/oznu/homebridge-gsh/blob/master/src/hap-types.ts
@ -11,7 +12,8 @@ where
CharacteristicTypeInner::deserialize(deserializer).map(|v| v.into()) CharacteristicTypeInner::deserialize(deserializer).map(|v| v.into())
} }
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Display)]
#[strum(serialize_all = "snake_case")]
pub enum CharacteristicType { pub enum CharacteristicType {
AccessControlLevel, AccessControlLevel,
@ -239,241 +241,6 @@ pub enum CharacteristicType {
Unknown, Unknown,
} }
impl std::fmt::Display for CharacteristicType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::AccessControlLevel => "000000E5-0000-1000-8000-0026BB765291",
Self::AccessoryFlags => "000000A6-0000-1000-8000-0026BB765291",
Self::ProductData => "00000220-0000-1000-8000-0026BB765291",
Self::Active => "000000B0-0000-1000-8000-0026BB765291",
Self::AdministratorOnlyAccess => "00000001-0000-1000-8000-0026BB765291",
Self::AirParticulateDensity => "00000064-0000-1000-8000-0026BB765291",
Self::AirParticulateSize => "00000065-0000-1000-8000-0026BB765291",
Self::AirQuality => "00000095-0000-1000-8000-0026BB765291",
Self::AudioFeedback => "00000005-0000-1000-8000-0026BB765291",
Self::BatteryLevel => "00000068-0000-1000-8000-0026BB765291",
Self::Brightness => "00000008-0000-1000-8000-0026BB765291",
Self::CarbonDioxideDetected => "00000092-0000-1000-8000-0026BB765291",
Self::CarbonDioxideLevel => "00000093-0000-1000-8000-0026BB765291",
Self::CarbonDioxidePeakLevel => "00000094-0000-1000-8000-0026BB765291",
Self::CarbonMonoxideDetected => "00000069-0000-1000-8000-0026BB765291",
Self::CarbonMonoxideLevel => "00000090-0000-1000-8000-0026BB765291",
Self::CarbonMonoxidePeakLevel => "00000091-0000-1000-8000-0026BB765291",
Self::ChargingState => "0000008F-0000-1000-8000-0026BB765291",
Self::ColorTemperature => "000000CE-0000-1000-8000-0026BB765291",
Self::ContactSensorState => "0000006A-0000-1000-8000-0026BB765291",
Self::CoolingThresholdTemperature => "0000000D-0000-1000-8000-0026BB765291",
Self::CurrentAirPurifierState => "000000A9-0000-1000-8000-0026BB765291",
Self::CurrentAmbientLightLevel => "0000006B-0000-1000-8000-0026BB765291",
Self::CurrentDoorState => "0000000E-0000-1000-8000-0026BB765291",
Self::CurrentFanState => "000000AF-0000-1000-8000-0026BB765291",
Self::CurrentHeaterCoolerState => "000000B1-0000-1000-8000-0026BB765291",
Self::CurrentHeatingCoolingState => "0000000F-0000-1000-8000-0026BB765291",
Self::CurrentHorizontalTiltAngle => "0000006C-0000-1000-8000-0026BB765291",
Self::CurrentHumidifierDehumidifierState => "000000B3-0000-1000-8000-0026BB765291",
Self::CurrentPosition => "0000006D-0000-1000-8000-0026BB765291",
Self::CurrentRelativeHumidity => "00000010-0000-1000-8000-0026BB765291",
Self::CurrentSlatState => "000000AA-0000-1000-8000-0026BB765291",
Self::CurrentTemperature => "00000011-0000-1000-8000-0026BB765291",
Self::CurrentTiltAngle => "000000C1-0000-1000-8000-0026BB765291",
Self::CurrentVerticalTiltAngle => "0000006E-0000-1000-8000-0026BB765291",
Self::DigitalZoom => "0000011D-0000-1000-8000-0026BB765291",
Self::FilterChangeIndication => "000000AC-0000-1000-8000-0026BB765291",
Self::FilterLifeLevel => "000000AB-0000-1000-8000-0026BB765291",
Self::FirmwareRevision => "00000052-0000-1000-8000-0026BB765291",
Self::HardwareRevision => "00000053-0000-1000-8000-0026BB765291",
Self::HeatingThresholdTemperature => "00000012-0000-1000-8000-0026BB765291",
Self::HoldPosition => "0000006F-0000-1000-8000-0026BB765291",
Self::Hue => "00000013-0000-1000-8000-0026BB765291",
Self::Identify => "00000014-0000-1000-8000-0026BB765291",
Self::ImageMirroring => "0000011F-0000-1000-8000-0026BB765291",
Self::ImageRotation => "0000011E-0000-1000-8000-0026BB765291",
Self::InUse => "000000D2-0000-1000-8000-0026BB765291",
Self::IsConfigured => "000000D6-0000-1000-8000-0026BB765291",
Self::LeakDetected => "00000070-0000-1000-8000-0026BB765291",
Self::LockControlPoint => "00000019-0000-1000-8000-0026BB765291",
Self::LockCurrentState => "0000001D-0000-1000-8000-0026BB765291",
Self::LockLastKnownAction => "0000001C-0000-1000-8000-0026BB765291",
Self::LockManagementAutoSecurityTimeout => "0000001A-0000-1000-8000-0026BB765291",
Self::LockPhysicalControls => "000000A7-0000-1000-8000-0026BB765291",
Self::LockTargetState => "0000001E-0000-1000-8000-0026BB765291",
Self::Logs => "0000001F-0000-1000-8000-0026BB765291",
Self::Manufacturer => "00000020-0000-1000-8000-0026BB765291",
Self::Model => "00000021-0000-1000-8000-0026BB765291",
Self::MotionDetected => "00000022-0000-1000-8000-0026BB765291",
Self::Mute => "0000011A-0000-1000-8000-0026BB765291",
Self::Name => "00000023-0000-1000-8000-0026BB765291",
Self::NightVision => "0000011B-0000-1000-8000-0026BB765291",
Self::NitrogenDioxideDensity => "000000C4-0000-1000-8000-0026BB765291",
Self::ObstructionDetected => "00000024-0000-1000-8000-0026BB765291",
Self::OccupancyDetected => "00000071-0000-1000-8000-0026BB765291",
Self::On => "00000025-0000-1000-8000-0026BB765291",
Self::OpticalZoom => "0000011C-0000-1000-8000-0026BB765291",
Self::OutletInUse => "00000026-0000-1000-8000-0026BB765291",
Self::OzoneDensity => "000000C3-0000-1000-8000-0026BB765291",
Self::PairSetup => "0000004C-0000-1000-8000-0026BB765291",
Self::PairVerify => "0000004E-0000-1000-8000-0026BB765291",
Self::PairingFeatures => "0000004F-0000-1000-8000-0026BB765291",
Self::PairingPairings => "00000050-0000-1000-8000-0026BB765291",
Self::PasswordSetting => "000000E4-0000-1000-8000-0026BB765291",
Self::PM10Density => "000000C7-0000-1000-8000-0026BB765291",
Self::PM2_5Density => "000000C6-0000-1000-8000-0026BB765291",
Self::PositionState => "00000072-0000-1000-8000-0026BB765291",
Self::ProgramMode => "000000D1-0000-1000-8000-0026BB765291",
Self::ProgrammableSwitchEvent => "00000073-0000-1000-8000-0026BB765291",
Self::RelativeHumidityDehumidifierThreshold => "000000C9-0000-1000-8000-0026BB765291",
Self::RelativeHumidityHumidifierThreshold => "000000CA-0000-1000-8000-0026BB765291",
Self::RemainingDuration => "000000D4-0000-1000-8000-0026BB765291",
Self::ResetFilterIndication => "000000AD-0000-1000-8000-0026BB765291",
Self::RotationDirection => "00000028-0000-1000-8000-0026BB765291",
Self::RotationSpeed => "00000029-0000-1000-8000-0026BB765291",
Self::Saturation => "0000002F-0000-1000-8000-0026BB765291",
Self::SecuritySystemAlarmType => "0000008E-0000-1000-8000-0026BB765291",
Self::SecuritySystemCurrentState => "00000066-0000-1000-8000-0026BB765291",
Self::SecuritySystemTargetState => "00000067-0000-1000-8000-0026BB765291",
Self::SelectedRTPStreamConfiguration => "00000117-0000-1000-8000-0026BB765291",
Self::SerialNumber => "00000030-0000-1000-8000-0026BB765291",
Self::ServiceLabelIndex => "000000CB-0000-1000-8000-0026BB765291",
Self::ServiceLabelNamespace => "000000CD-0000-1000-8000-0026BB765291",
Self::SetDuration => "000000D3-0000-1000-8000-0026BB765291",
Self::SetupEndpoints => "00000118-0000-1000-8000-0026BB765291",
Self::SlatType => "000000C0-0000-1000-8000-0026BB765291",
Self::SmokeDetected => "00000076-0000-1000-8000-0026BB765291",
Self::StatusActive => "00000075-0000-1000-8000-0026BB765291",
Self::StatusFault => "00000077-0000-1000-8000-0026BB765291",
Self::StatusJammed => "00000078-0000-1000-8000-0026BB765291",
Self::StatusLowBattery => "00000079-0000-1000-8000-0026BB765291",
Self::StatusTampered => "0000007A-0000-1000-8000-0026BB765291",
Self::StreamingStatus => "00000120-0000-1000-8000-0026BB765291",
Self::SulphurDioxideDensity => "000000C5-0000-1000-8000-0026BB765291",
Self::SupportedAudioStreamConfiguration => "00000115-0000-1000-8000-0026BB765291",
Self::SupportedRTPConfiguration => "00000116-0000-1000-8000-0026BB765291",
Self::SupportedVideoStreamConfiguration => "00000114-0000-1000-8000-0026BB765291",
Self::SwingMode => "000000B6-0000-1000-8000-0026BB765291",
Self::TargetAirPurifierState => "000000A8-0000-1000-8000-0026BB765291",
Self::TargetAirQuality => "000000AE-0000-1000-8000-0026BB765291",
Self::TargetDoorState => "00000032-0000-1000-8000-0026BB765291",
Self::TargetFanState => "000000BF-0000-1000-8000-0026BB765291",
Self::TargetHeaterCoolerState => "000000B2-0000-1000-8000-0026BB765291",
Self::TargetHeatingCoolingState => "00000033-0000-1000-8000-0026BB765291",
Self::TargetHorizontalTiltAngle => "0000007B-0000-1000-8000-0026BB765291",
Self::TargetHumidifierDehumidifierState => "000000B4-0000-1000-8000-0026BB765291",
Self::TargetPosition => "0000007C-0000-1000-8000-0026BB765291",
Self::TargetRelativeHumidity => "00000034-0000-1000-8000-0026BB765291",
Self::TargetSlatState => "000000BE-0000-1000-8000-0026BB765291",
Self::TargetTemperature => "00000035-0000-1000-8000-0026BB765291",
Self::TargetTiltAngle => "000000C2-0000-1000-8000-0026BB765291",
Self::TargetVerticalTiltAngle => "0000007D-0000-1000-8000-0026BB765291",
Self::TemperatureDisplayUnits => "00000036-0000-1000-8000-0026BB765291",
Self::ValveType => "000000D5-0000-1000-8000-0026BB765291",
Self::Version => "00000037-0000-1000-8000-0026BB765291",
Self::VOCDensity => "000000C8-0000-1000-8000-0026BB765291",
Self::Volume => "00000119-0000-1000-8000-0026BB765291",
Self::WaterLevel => "000000B5-0000-1000-8000-0026BB765291",
Self::RecordingAudioActive => "00000226-0000-1000-8000-0026BB765291",
Self::SupportedCameraRecordingConfiguration => "00000205-0000-1000-8000-0026BB765291",
Self::SupportedVideoRecordingConfiguration => "00000206-0000-1000-8000-0026BB765291",
Self::SupportedAudioRecordingConfiguration => "00000207-0000-1000-8000-0026BB765291",
Self::SelectedCameraRecordingConfiguration => "00000209-0000-1000-8000-0026BB765291",
Self::CameraOperatingModeIndicator => "0000021D-0000-1000-8000-0026BB765291",
Self::EventSnapshotsActive => "00000223-0000-1000-8000-0026BB765291",
Self::DiagonalFieldOfView => "00000224-0000-1000-8000-0026BB765291",
Self::HomeKitCameraActive => "0000021B-0000-1000-8000-0026BB765291",
Self::ManuallyDisabled => "00000227-0000-1000-8000-0026BB765291",
Self::ThirdPartyCameraActive => "0000021C-0000-1000-8000-0026BB765291",
Self::PeriodicSnapshotsActive => "00000225-0000-1000-8000-0026BB765291",
Self::NetworkClientProfileControl => "0000020C-0000-1000-8000-0026BB765291",
Self::NetworkClientStatusControl => "0000020D-0000-1000-8000-0026BB765291",
Self::RouterStatus => "0000020E-0000-1000-8000-0026BB765291",
Self::SupportedRouterConfiguration => "00000210-0000-1000-8000-0026BB765291",
Self::WANConfigurationList => "00000211-0000-1000-8000-0026BB765291",
Self::WANStatusList => "00000212-0000-1000-8000-0026BB765291",
Self::ManagedNetworkEnable => "00000215-0000-1000-8000-0026BB765291",
Self::NetworkAccessViolationControl => "0000021F-0000-1000-8000-0026BB765291",
Self::WiFiSatelliteStatus => "0000021E-0000-1000-8000-0026BB765291",
Self::WakeConfiguration => "00000222-0000-1000-8000-0026BB765291",
Self::SupportedTransferTransportConfiguration => "00000202-0000-1000-8000-0026BB765291",
Self::SetupTransferTransport => "00000201-0000-1000-8000-0026BB765291",
Self::ActivityInterval => "0000021E-0000-1000-8000-0000023B",
Self::CCAEnergyDetectThreshold => "0000021E-0000-1000-8000-00000246",
Self::CCASignalDetectThreshold => "0000021E-0000-1000-8000-00000245",
Self::CharacteristicValueTransitionControl => "0000021E-0000-1000-8000-00000143",
Self::SupportedCharacteristicValueTransitionConfiguration => {
"0000021E-0000-1000-8000-00000144"
}
Self::CurrentTransport => "0000021E-0000-1000-8000-0000022B",
Self::DataStreamHAPTransport => "0000021E-0000-1000-8000-00000138",
Self::DataStreamHAPTransportInterrupt => "0000021E-0000-1000-8000-00000139",
Self::EventRetransmissionMaximum => "0000021E-0000-1000-8000-0000023D",
Self::EventTransmissionCounters => "0000021E-0000-1000-8000-0000023E",
Self::HeartBeat => "0000021E-0000-1000-8000-0000024A",
Self::MACRetransmissionMaximum => "0000021E-0000-1000-8000-00000247",
Self::MACTransmissionCounters => "0000021E-0000-1000-8000-00000248",
Self::OperatingStateResponse => "0000021E-0000-1000-8000-00000232",
Self::Ping => "0000021E-0000-1000-8000-0000023C",
Self::ReceiverSensitivity => "0000021E-0000-1000-8000-00000244",
Self::ReceivedSignalStrengthIndication => "0000021E-0000-1000-8000-0000023F",
Self::SleepInterval => "0000021E-0000-1000-8000-0000023A",
Self::SignalToNoiseRatio => "0000021E-0000-1000-8000-00000241",
Self::SupportedDiagnosticsSnapshot => "0000021E-0000-1000-8000-00000238",
Self::TransmitPower => "0000021E-0000-1000-8000-00000242",
Self::TransmitPowerMaximum => "0000021E-0000-1000-8000-00000243",
Self::VideoAnalysisActive => "0000021E-0000-1000-8000-00000229",
Self::WiFiCapabilities => "0000021E-0000-1000-8000-0000022C",
Self::WiFiConfigurationControl => "0000021E-0000-1000-8000-0000022D",
Self::AppMatchingIdentifier => "000000A4-0000-1000-8000-0026BB765291",
Self::ProgrammableSwitchOutputState => "00000074-0000-1000-8000-0026BB765291",
Self::SoftwareRevision => "00000054-0000-1000-8000-0026BB765291",
Self::AccessoryIdentifier => "00000057-0000-1000-8000-0026BB765291",
Self::Category => "000000A3-0000-1000-8000-0026BB765291",
Self::ConfigureBridgedAccessory => "000000A0-0000-1000-8000-0026BB765291",
Self::ConfigureBridgedAccessoryStatus => "0000009D-0000-1000-8000-0026BB765291",
Self::CurrentTime => "0000009B-0000-1000-8000-0026BB765291",
Self::DayoftheWeek => "00000098-0000-1000-8000-0026BB765291",
Self::DiscoverBridgedAccessories => "0000009E-0000-1000-8000-0026BB765291",
Self::DiscoveredBridgedAccessories => "0000009F-0000-1000-8000-0026BB765291",
Self::LinkQuality => "0000009C-0000-1000-8000-0026BB765291",
Self::Reachable => "00000063-0000-1000-8000-0026BB765291",
Self::RelayControlPoint => "0000005E-0000-1000-8000-0026BB765291",
Self::RelayEnabled => "0000005B-0000-1000-8000-0026BB765291",
Self::RelayState => "0000005C-0000-1000-8000-0026BB765291",
Self::TimeUpdate => "0000009A-0000-1000-8000-0026BB765291",
Self::TunnelConnectionTimeout => "00000061-0000-1000-8000-0026BB765291",
Self::TunneledAccessoryAdvertising => "00000060-0000-1000-8000-0026BB765291",
Self::TunneledAccessoryConnected => "00000059-0000-1000-8000-0026BB765291",
Self::TunneledAccessoryStateNumber => "00000058-0000-1000-8000-0026BB765291",
Self::ActiveIdentifier => "000000E7-0000-1000-8000-0026BB765291",
Self::ConfiguredName => "000000E3-0000-1000-8000-0026BB765291",
Self::SleepDiscoveryMode => "000000E8-0000-1000-8000-0026BB765291",
Self::ClosedCaptions => "000000DD-0000-1000-8000-0026BB765291",
Self::DisplayOrder => "00000136-0000-1000-8000-0026BB765291",
Self::CurrentMediaState => "000000E0-0000-1000-8000-0026BB765291",
Self::TargetMediaState => "00000137-0000-1000-8000-0026BB765291",
Self::PictureMode => "000000E2-0000-1000-8000-0026BB765291",
Self::PowerModeSelection => "000000DF-0000-1000-8000-0026BB765291",
Self::RemoteKey => "000000E1-0000-1000-8000-0026BB765291",
Self::InputSourceType => "000000DB-0000-1000-8000-0026BB765291",
Self::InputDeviceType => "000000DC-0000-1000-8000-0026BB765291",
Self::Identifier => "000000E6-0000-1000-8000-0026BB765291",
Self::CurrentVisibilityState => "00000135-0000-1000-8000-0026BB765291",
Self::TargetVisibilityState => "00000134-0000-1000-8000-0026BB765291",
Self::VolumeControlType => "000000E9-0000-1000-8000-0026BB765291",
Self::VolumeSelector => "000000EA-0000-1000-8000-0026BB765291",
Self::TargetControlSupportedConfiguration => "00000123-0000-1000-8000-0026BB765291",
Self::TargetControlList => "00000124-0000-1000-8000-0026BB765291",
Self::ButtonEvent => "00000126-0000-1000-8000-0026BB765291",
Self::SelectedAudioStreamConfiguration => "00000128-0000-1000-8000-0026BB765291",
Self::SiriInputType => "00000132-0000-1000-8000-0026BB765291",
Self::SupportedDataStreamTransportConfiguration => {
"00000130-0000-1000-8000-0026BB765291"
}
Self::SetupDataStreamTransport => "00000131-0000-1000-8000-0026BB765291",
Self::Unknown => "",
}
.fmt(f)
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(field_identifier)] #[serde(field_identifier)]
enum CharacteristicTypeInner { enum CharacteristicTypeInner {
@ -1228,7 +995,8 @@ where
ServiceTypeInner::deserialize(deserializer).map(|v| v.into()) ServiceTypeInner::deserialize(deserializer).map(|v| v.into())
} }
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, Display)]
#[strum(serialize_all = "snake_case")]
pub enum ServiceType { pub enum ServiceType {
AccessControl, AccessControl,
AccessoryInformation, AccessoryInformation,
@ -1301,83 +1069,6 @@ pub enum ServiceType {
Unknown, Unknown,
} }
impl std::fmt::Display for ServiceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::AccessControl => "000000DA-0000-1000-8000-0026BB765291",
Self::AccessoryInformation => "0000003E-0000-1000-8000-0026BB765291",
Self::AirPurifier => "000000BB-0000-1000-8000-0026BB765291",
Self::AirQualitySensor => "0000008D-0000-1000-8000-0026BB765291",
Self::BatteryService => "00000096-0000-1000-8000-0026BB765291",
Self::CameraRTPStreamManagement => "00000110-0000-1000-8000-0026BB765291",
Self::CarbonDioxideSensor => "00000097-0000-1000-8000-0026BB765291",
Self::CarbonMonoxideSensor => "0000007F-0000-1000-8000-0026BB765291",
Self::ContactSensor => "00000080-0000-1000-8000-0026BB765291",
Self::Door => "00000081-0000-1000-8000-0026BB765291",
Self::Doorbell => "00000121-0000-1000-8000-0026BB765291",
Self::Fan => "00000040-0000-1000-8000-0026BB765291",
Self::Fanv2 => "000000B7-0000-1000-8000-0026BB765291",
Self::FilterMaintenance => "000000BA-0000-1000-8000-0026BB765291",
Self::Faucet => "000000D7-0000-1000-8000-0026BB765291",
Self::GarageDoorOpener => "00000041-0000-1000-8000-0026BB765291",
Self::HeaterCooler => "000000BC-0000-1000-8000-0026BB765291",
Self::HumidifierDehumidifier => "000000BD-0000-1000-8000-0026BB765291",
Self::HumiditySensor => "00000082-0000-1000-8000-0026BB765291",
Self::IrrigationSystem => "000000CF-0000-1000-8000-0026BB765291",
Self::LeakSensor => "00000083-0000-1000-8000-0026BB765291",
Self::LightSensor => "00000084-0000-1000-8000-0026BB765291",
Self::Lightbulb => "00000043-0000-1000-8000-0026BB765291",
Self::LockManagement => "00000044-0000-1000-8000-0026BB765291",
Self::LockMechanism => "00000045-0000-1000-8000-0026BB765291",
Self::Microphone => "00000112-0000-1000-8000-0026BB765291",
Self::MotionSensor => "00000085-0000-1000-8000-0026BB765291",
Self::OccupancySensor => "00000086-0000-1000-8000-0026BB765291",
Self::Outlet => "00000047-0000-1000-8000-0026BB765291",
Self::SecuritySystem => "0000007E-0000-1000-8000-0026BB765291",
Self::ServiceLabel => "000000CC-0000-1000-8000-0026BB765291",
Self::Slat => "000000B9-0000-1000-8000-0026BB765291",
Self::SmokeSensor => "00000087-0000-1000-8000-0026BB765291",
Self::SmartSpeaker => "00000228-0000-1000-8000-0026BB765291",
Self::Speaker => "00000113-0000-1000-8000-0026BB765291",
Self::StatelessProgrammableSwitch => "00000089-0000-1000-8000-0026BB765291",
Self::Switch => "00000049-0000-1000-8000-0026BB765291",
Self::TemperatureSensor => "0000008A-0000-1000-8000-0026BB765291",
Self::Thermostat => "0000004A-0000-1000-8000-0026BB765291",
Self::Valve => "000000D0-0000-1000-8000-0026BB765291",
Self::Window => "0000008B-0000-1000-8000-0026BB765291",
Self::WindowCovering => "0000008C-0000-1000-8000-0026BB765291",
Self::CameraOperatingMode => "0000021A-0000-1000-8000-0026BB765291",
Self::CameraEventRecordingManagement => "00000204-0000-1000-8000-0026BB765291",
Self::WiFiRouter => "0000020A-0000-1000-8000-0026BB765291",
Self::WiFiSatellite => "0000020F-0000-1000-8000-0026BB765291",
Self::PowerManagement => "00000221-0000-1000-8000-0026BB765291",
Self::TransferTransportManagement => "00000203-0000-1000-8000-0026BB765291",
Self::AccessoryRuntimeInformation => "00000203-0000-1000-8000-00000239",
Self::Diagnostics => "00000203-0000-1000-8000-00000237",
Self::WiFiTransport => "00000203-0000-1000-8000-0000022A",
Self::CameraControl => "00000111-0000-1000-8000-0026BB765291",
Self::StatefulProgrammableSwitch => "00000088-0000-1000-8000-0026BB765291",
Self::BridgeConfiguration => "000000A1-0000-1000-8000-0026BB765291",
Self::BridgingState => "00000062-0000-1000-8000-0026BB765291",
Self::Pairing => "00000055-0000-1000-8000-0026BB765291",
Self::ProtocolInformation => "000000A2-0000-1000-8000-0026BB765291",
Self::Relay => "0000005A-0000-1000-8000-0026BB765291",
Self::TimeInformation => "00000099-0000-1000-8000-0026BB765291",
Self::TunneledBTLEAccessoryService => "00000056-0000-1000-8000-0026BB765291",
Self::Television => "000000D8-0000-1000-8000-0026BB765291",
Self::InputSource => "000000D9-0000-1000-8000-0026BB765291",
Self::TelevisionSpeaker => "00000113-0000-1000-8000-0026BB765291",
Self::TargetControlManagement => "00000122-0000-1000-8000-0026BB765291",
Self::TargetControl => "00000125-0000-1000-8000-0026BB765291",
Self::AudioStreamManagement => "00000127-0000-1000-8000-0026BB765291",
Self::Siri => "00000133-0000-1000-8000-0026BB765291",
Self::DataStreamTransportManagement => "00000129-0000-1000-8000-0026BB765291",
Self::Unknown => "",
}
.fmt(f)
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(field_identifier)] #[serde(field_identifier)]
pub enum ServiceTypeInner { pub enum ServiceTypeInner {

View file

@ -8,58 +8,58 @@ use crate::SENSORS;
pub fn launch(paired: HashMap<String, ConnectedDevice>) -> rocket::Rocket<rocket::Build> { pub fn launch(paired: HashMap<String, ConnectedDevice>) -> rocket::Rocket<rocket::Build> {
rocket::build() rocket::build()
.manage(Mutex::new(paired)) .manage(Mutex::new(paired))
.mount("/", routes![index]) .mount("/", routes![metrics])
} }
#[get("/")] #[get("/metrics")]
pub async fn index(state: &State<Mutex<HashMap<String, ConnectedDevice>>>) -> Option<String> { pub async fn metrics(state: &State<Mutex<HashMap<String, ConnectedDevice>>>) -> Option<String> {
let mut s = String::new(); let mut s = String::new();
let mut state = state.lock().await; let mut state = state.lock().await;
let mut shown_types = Vec::new();
for (name, connected) in state.deref_mut() { for (name, connected) in state.deref_mut() {
connected.update_characteristics().await.ok()?; connected.update_characteristics().await.ok()?;
s.push_str(format!("{name}: [\n").as_str());
for (aid, accessory) in &connected.accessories { for (aid, accessory) in &connected.accessories {
s.push_str(format!("\t{} ({}): [\n", accessory.name, aid).as_str()); for service in accessory.services.values() {
for (sid, service) in &accessory.services {
if !SENSORS.contains(&service.service_type) { if !SENSORS.contains(&service.service_type) {
continue; continue;
} }
s.push_str(
format!(
"\t\t{} ({:?}) ({}): [\n",
service.name.as_ref().unwrap_or(&String::from("Unknown")),
service.service_type,
sid,
)
.as_str(),
);
for (cid, characteristic) in &service.characteristics { for (cid, characteristic) in &service.characteristics {
s.push_str( if let Some(value) = &characteristic.value {
format!( if !shown_types.contains(&characteristic.characteristic_type) {
"\t\t\t{:?} ({}): {}{}\n", s.push_str(
characteristic.characteristic_type, format!("# TYPE {} gauge\n", characteristic.characteristic_type)
cid, .as_str(),
match &characteristic.value { );
Some(Data::String(s)) => s.clone(), shown_types.push(characteristic.characteristic_type);
Some(other) => format!("{other:?}"), }
None => String::from("no data"), s.push_str(
}, format!(
characteristic "{}{{accessory=\"{}.{}.{}\"}} {}\n",
.unit characteristic.characteristic_type,
.map(|v| format!(" ({v:?})")) name,
.unwrap_or_default() aid,
cid,
match value {
Data::Bool(v) => format!("{}", if *v { 1 } else { 0 }),
Data::Uint8(v) => format!("{v}"),
Data::Uint16(v) => format!("{v}"),
Data::Uint32(v) => format!("{v}"),
Data::Uint64(v) => format!("{v}"),
Data::Int(v) => format!("{v}"),
Data::Float(v) => format!("{v}"),
Data::String(v) => v.to_string(),
Data::Tlv8(v) => v.to_string(),
Data::Data(v) => v.to_string(),
}
)
.as_str(),
) )
.as_str(), }
);
} }
s.push_str("\t\t]\n");
} }
s.push_str("\t]\n");
} }
s.push_str("]\n");
} }
Some(s) Some(s)
} }