File: status.py

package info (click to toggle)
python-iometer 0.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 152 kB
  • sloc: python: 591; makefile: 3
file content (124 lines) | stat: -rw-r--r-- 3,481 bytes parent folder | download
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()