""" domain/value_objects/device_info.py ──────────────────────────────────── DeviceInfo — immutable value object describing an IoT sensor device. Value objects have no identity — two DeviceInfo objects with the same field values are considered equal (enforced by ``frozen=True``). """ from __future__ import annotations from dataclasses import dataclass from typing import Optional @dataclass(frozen=True) class DeviceInfo: """ Describes the IoT sensor/device that produced a PPG signal. Attributes: device_id: Unique hardware identifier (MAC, serial, etc.). device_type: Human-readable device category (e.g. ``"PPG Wristband"``). firmware_version: Firmware version string at time of recording. manufacturer: Optional manufacturer name. """ device_id: str device_type: str firmware_version: str manufacturer: Optional[str] = None def __post_init__(self) -> None: if not self.device_id or not self.device_id.strip(): raise ValueError("DeviceInfo.device_id must be a non-empty string") if not self.device_type or not self.device_type.strip(): raise ValueError("DeviceInfo.device_type must be a non-empty string") if not self.firmware_version or not self.firmware_version.strip(): raise ValueError("DeviceInfo.firmware_version must be a non-empty string") def __str__(self) -> str: return ( f"{self.device_type} [{self.device_id}] " f"fw={self.firmware_version}" + (f" by {self.manufacturer}" if self.manufacturer else "") )