1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
"""Device status for IOmeter bridge and core"""
import json
from dataclasses import dataclass, field
@dataclass
class Bridge:
"""Represents the bridge device status"""
rssi: int
version: str
@dataclass
class Core:
"""Represents the core device status"""
connection_status: str
rssi: int | None
version: str | None
power_status: str | None
attachment_status: str | None
pin_status: str | None
battery_level: int | None
@dataclass
class Device:
"""Represents the complete device information"""
bridge: Bridge
id: str
core: Core
@dataclass
class Meter:
"""Represents the meter device."""
number: str | None
class NullMeter(Meter):
"""Null Object for Meter to avoid None-attribute errors."""
def __init__(self) -> None:
super().__init__(number=None)
def __bool__(self) -> bool:
return False
@dataclass
class Status:
"""Top level class representing the complete device status"""
device: Device
meter: Meter = field(default_factory=NullMeter)
typename: str = "iometer.status.v1"
@classmethod
def from_json(cls, json_str: str) -> "Status":
"""Create a Status instance from JSON string"""
data = json.loads(json_str)
# Create bridge
bridge = Bridge(
rssi=data["device"]["bridge"]["rssi"],
version=data["device"]["bridge"]["version"],
)
# Create Core
core_data = data["device"]["core"]
core = Core(
connection_status=core_data["connectionStatus"],
rssi=core_data.get("rssi", None),
version=core_data.get("version", None),
power_status=core_data.get("powerStatus", None),
battery_level=core_data.get("batteryLevel", None),
attachment_status=core_data.get("attachmentStatus", None),
pin_status=core_data.get("pinStatus", None),
)
# Create device
device = Device(bridge=bridge, id=data["device"]["id"], core=core)
# Create meter (use Null Object if missing)
meter = (
Meter(number=data["meter"]["number"]) if data.get("meter") else NullMeter()
)
# Create full status
return cls(meter=meter, device=device)
def to_json(self) -> str:
"""Convert the status to JSON string"""
return json.dumps(
{
"__typename": self.typename,
# If meter is a NullMeter, serialize as null
"meter": {"number": self.meter.number} if self.meter else None,
"device": {
"bridge": {
"rssi": self.device.bridge.rssi,
"version": self.device.bridge.version,
},
"id": self.device.id,
"core": {
"connectionStatus": self.device.core.connection_status,
"rssi": self.device.core.rssi,
"version": self.device.core.version,
"powerStatus": self.device.core.power_status,
"batteryLevel": self.device.core.battery_level,
"attachmentStatus": self.device.core.attachment_status,
"pinStatus": self.device.core.pin_status,
},
},
}
)
def __str__(self) -> str:
return self.to_json()
|