from __future__ import annotations
import time
from typing import Any, Dict, List
from state import DeviceState, save
class BaseDevice:
def __init__(self, state: DeviceState):
self.state = state
# ── helpers ──────────────────────────────────────────────
def _uptime(self) -> int:
return int(time.time() - self.state.uptime_start)
def _is_setup(self) -> bool:
return self.state.status == "setup"
def _check_auth(self, headers: Dict[str, str]) -> bool:
if self._is_setup():
return True
auth = headers.get("Authorization", "")
if not auth.startswith("Bearer "):
return False
token = auth[7:]
return token == (self.state.token or "")
def _ensure_channels_schema(self, channels_count: int = 8) -> None:
if not self.state.channels_schema:
schema: List[int] = []
for ch in range(channels_count):
base = ch * 4
schema.extend([base, ch, 255, 0])
self.state.channels_schema = schema
def _ensure_channels(self, count: int) -> None:
while len(self.state.channels) < count:
self.state.channels.append({"state": "off"})
for ch in self.state.channels:
ch.setdefault("state", "off")
# ── common endpoints ─────────────────────────────────────
def about(self, ip_address: str) -> Dict[str, Any]:
return {
"device_name": self.state.device_name,
"device_type": self.state.device_type,
"platform": self.state.platform,
"firmware_version": self.state.firmware_version,
"core_version": self.state.core_version,
"device_id": self.state.device_id,
"server": self.state.server_url,
"status": self.state.status,
"ip_address": ip_address,
"mac_address": self.state.mac_address,
"uptime": self._uptime(),
"channels": self.state.channel_count,
}
def set_token(self, token: str) -> Dict[str, Any]:
self.state.token = token
self.state.status = "normal"
save(self.state)
return {
"status": "ok",
"message": "Token set. Device mode: normal",
}
def reset(self) -> Dict[str, Any]:
self.state.token = None
self.state.status = "setup"
self.state.uptime_start = time.time()
for ch in self.state.channels:
ch["state"] = "off"
save(self.state)
return {
"status": "ok",
"message": "Device reset to factory settings. Entering setup mode.",
}
def get_channels_schema(self) -> Dict[str, Any]:
self._ensure_channels_schema()
return {
"status": "ok",
"schema": self.state.channels_schema,
}
def set_channels_schema(self, schema: List[int]) -> Dict[str, Any]:
self.state.channels_schema = schema
save(self.state)
return {
"status": "ok",
"message": "Channels schema updated",
}
# ── to be overridden ─────────────────────────────────────
def status(self) -> Dict[str, Any]:
raise NotImplementedError
def action(self, action_name: str, params: Dict[str, Any]) -> Dict[str, Any]:
raise NotImplementedError