Coverage for src / bluetooth_sig / gatt / characteristics / apparent_energy_32.py: 100%
12 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
1"""Apparent Energy 32 characteristic implementation."""
3from __future__ import annotations
5from ..context import CharacteristicContext
6from .base import BaseCharacteristic
7from .utils.data_parser import DataParser
10class ApparentEnergy32Characteristic(BaseCharacteristic[float]):
11 """Apparent Energy 32 characteristic (0x2B89).
13 org.bluetooth.characteristic.apparent_energy_32
15 The Apparent Energy 32 characteristic is used to represent the integral of Apparent Power over a time interval.
16 """
18 _manual_unit: str | None = (
19 "kVAh" # YAML: electrical_apparent_energy.kilovolt_ampere_hour, units.yaml: energy.kilovolt_ampere_hour
20 )
22 def _decode_value(
23 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
24 ) -> float:
25 """Decode apparent energy 32 characteristic.
27 Decodes a 32-bit unsigned integer representing apparent energy in 0.001 kVAh increments
28 per Bluetooth SIG Apparent Energy 32 characteristic specification.
30 Args:
31 data: Raw bytes from BLE characteristic (exactly 4 bytes, little-endian)
32 ctx: Optional context for parsing (device info, flags, etc.)
33 validate: Whether to validate ranges (default True)
35 Returns:
36 Apparent energy in kilovolt ampere hours, or None if value is not valid or unknown
38 Raises:
39 InsufficientDataError: If data is not exactly 4 bytes
40 """
41 raw_value = DataParser.parse_int32(data, 0, signed=False)
42 return raw_value * 0.001
44 def _encode_value(self, data: float) -> bytearray:
45 """Encode apparent energy value."""
46 raw_value = int(data / 0.001)
47 return DataParser.encode_int32(raw_value, signed=False)