diff --git a/haco/client.py b/haco/client.py index fa553e6..ce7abcb 100644 --- a/haco/client.py +++ b/haco/client.py @@ -34,7 +34,7 @@ class ClientHaco(mqtt.Client): payload = message.payload.decode() logger.info(f"{message.topic.value}{Constants.ARROW}{payload}") topic_command = self.device.subscriptions[message.topic.value] - echo_val = await topic_command.wrap_back(message) + echo_val = await topic_command.handle(message) diff --git a/haco/number.py b/haco/number.py index 53524d5..e60574a 100644 --- a/haco/number.py +++ b/haco/number.py @@ -1,38 +1,32 @@ +from dataclasses import dataclass +from enum import StrEnum +from typing import ClassVar, Type + from haco.control import Control -from haco.tools import get_range_pair - -from haco.data.uom import Uom +from haco.uom import Uom +from haco.utils import Converters, ConvertersNumeric +class Mode(StrEnum): + BOX = "box" + SLIDER = "slider" + + +@dataclass(kw_only=True) class Number(Control): - NAME = 'number' - UOM = Uom + DATA = dict( + platform='number' + ) + converters: ClassVar[Type[Converters]] = ConvertersNumeric - # def init(name, number_range, mode, step, uom, entity_id, icon, callbacks) - def __init__(self, name, number_range: range, icon=None, mode=None, step=None, uom=None): + min: float = 0. + max: float = 100. + mode: Mode = Mode.SLIDER + step: float = 1. + uom: Uom | None = None - self.min, self.max = get_range_pair(number_range) - self.mode = mode - self.step = step - self.uom = uom + def command(self, value): + raise NotImplementedError() - super().__init__(name, icon=icon) - - @property - def control_type(self): - - if self.step is None or self.step == 1: - return int - else: - return float - - def get_config_ha_ex(self): - data = { - 'min': self.min, - 'max': self.max, - 'mode': self.mode, - 'unit_of_measurement': self.uom, - 'step': self.step - } - - return data + def state(self, value): + raise NotImplementedError() diff --git a/haco/topics.py b/haco/topics.py index 4dee0d2..8923120 100644 --- a/haco/topics.py +++ b/haco/topics.py @@ -34,7 +34,7 @@ class AnnounceTopic: method_name = self.callback_name method = getattr(self.capability.control, method_name, None) self.control_method = method - setattr(self.capability.control, method_name, self.wrap_back) + setattr(self.capability.control, method_name, self.handle) def fill(self, mask): return mask.format(**self.fills) @@ -76,7 +76,7 @@ class AnnounceTopic: def capability(self): return self.parent - def wrap_back(self, value): + async def handle(self, value): raise NotImplementedError() @@ -87,7 +87,7 @@ class AnnounceTopicState(AnnounceTopic): def get_subscriptions(self): return {} - async def wrap_back(self, value): + async def handle(self, value=None): if not self.control_method: logger.error(f'Incomplete base class: {self.callback_class_method_name}') @@ -117,7 +117,7 @@ class AnnounceTopicCommand(AnnounceTopic): def state(self): return self.capability.state - async def wrap_back(self, message): + async def handle(self, message): if not self.control_method: logger.error(f'Incomplete base class: {self.callback_class_method_name}') @@ -141,7 +141,7 @@ class AnnounceTopicCommand(AnnounceTopic): # Echo back as new state topic_state = self.state if topic_state: - await topic_state.wrap_back(value_raw) + await topic_state.handle(value_raw) def get_subscriptions(self): diff --git a/haco/uom.py b/haco/uom.py index 2d2c0dc..3986da8 100644 --- a/haco/uom.py +++ b/haco/uom.py @@ -1,138 +1,142 @@ -class Uom: +from enum import StrEnum + + +class Uom(StrEnum): """ - Sourced from: https://github.com/home-assistant/core/blob/03b1c7ad1deb4b9494df01b27ef8e1d7dfe179ba/homeassistant/const.py#L489C1-L489C1 + Sourced from: https://github.com/home-assistant/core/blob/03b1c7ad1deb4b9494df01b27ef8e1d7dfe179ba/homeassistant/const.py#L489 """ - POWER_WATT: str = "W" - POWER_KILO_WATT: str = "kW" + POWER_WATT = "W" + POWER_KILO_WATT = "kW" - VOLT: str = "V" + VOLT = "V" - ENERGY_WATT_HOUR: str = "Wh" - ENERGY_KILO_WATT_HOUR: str = "kWh" + ENERGY_WATT_HOUR = "Wh" + ENERGY_KILO_WATT_HOUR = "kWh" - ELECTRICAL_CURRENT_AMPERE: str = "A" - ELECTRICAL_VOLT_AMPERE: str = "VA" + ELECTRICAL_CURRENT_AMPERE = "A" + ELECTRICAL_VOLT_AMPERE = "VA" - DEGREE: str = "°" + DEGREE = "°" - CURRENCY_EURO: str = "€" - CURRENCY_DOLLAR: str = "$" - CURRENCY_CENT: str = "¢" + CURRENCY_EURO = "€" + CURRENCY_DOLLAR = "$" + CURRENCY_CENT = "¢" - TEMP_CELSIUS: str = "°C" - TEMP_FAHRENHEIT: str = "°F" - TEMP_KELVIN: str = "K" + TEMP_CELSIUS = "°C" + TEMP_FAHRENHEIT = "°F" + TEMP_KELVIN = "K" - TIME_MICROSECONDS: str = "μs" - TIME_MILLISECONDS: str = "ms" - TIME_SECONDS: str = "s" - TIME_MINUTES: str = "min" - TIME_HOURS: str = "h" - TIME_DAYS: str = "d" - TIME_WEEKS: str = "w" - TIME_MONTHS: str = "m" - TIME_YEARS: str = "y" + TIME_MICROSECONDS = "μs" + TIME_MILLISECONDS = "ms" + TIME_SECONDS = "s" + TIME_MINUTES = "min" + TIME_HOURS = "h" + TIME_DAYS = "d" + TIME_WEEKS = "w" + TIME_MONTHS = "m" + TIME_YEARS = "y" - LENGTH_MILLIMETERS: str = "mm" - LENGTH_CENTIMETERS: str = "cm" - LENGTH_METERS: str = "m" - LENGTH_KILOMETERS: str = "km" + LENGTH_MILLIMETERS = "mm" + LENGTH_CENTIMETERS = "cm" + LENGTH_METERS = "m" + LENGTH_KILOMETERS = "km" - LENGTH_INCHES: str = "in" - LENGTH_FEET: str = "ft" - LENGTH_YARD: str = "yd" - LENGTH_MILES: str = "mi" + LENGTH_INCHES = "in" + LENGTH_FEET = "ft" + LENGTH_YARD = "yd" + LENGTH_MILES = "mi" - FREQUENCY_HERTZ: str = "Hz" - FREQUENCY_GIGAHERTZ: str = "GHz" + FREQUENCY_HERTZ = "Hz" + FREQUENCY_GIGAHERTZ = "GHz" - PRESSURE_PA: str = "Pa" - PRESSURE_HPA: str = "hPa" - PRESSURE_BAR: str = "bar" - PRESSURE_MBAR: str = "mbar" - PRESSURE_INHG: str = "inHg" - PRESSURE_PSI: str = "psi" + PRESSURE_PA = "Pa" + PRESSURE_HPA = "hPa" + PRESSURE_BAR = "bar" + PRESSURE_MBAR = "mbar" + PRESSURE_INHG = "inHg" + PRESSURE_PSI = "psi" - VOLUME_LITERS: str = "L" - VOLUME_MILLILITERS: str = "mL" - VOLUME_CUBIC_METERS: str = "m³" - VOLUME_CUBIC_FEET: str = "ft³" + VOLUME_LITERS = "L" + VOLUME_MILLILITERS = "mL" + VOLUME_CUBIC_METERS = "m³" + VOLUME_CUBIC_FEET = "ft³" - VOLUME_GALLONS: str = "gal" - VOLUME_FLUID_OUNCE: str = "fl. oz." + VOLUME_GALLONS = "gal" + VOLUME_FLUID_OUNCE = "fl. oz." - VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: str = "m³/h" - VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: str = "ft³/m" + VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR = "m³/h" + VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE = "ft³/m" - AREA_SQUARE_METERS: str = "m²" + AREA_SQUARE_METERS = "m²" - MASS_GRAMS: str = "g" - MASS_KILOGRAMS: str = "kg" - MASS_MILLIGRAMS: str = "mg" - MASS_MICROGRAMS: str = "µg" + MASS_GRAMS = "g" + MASS_KILOGRAMS = "kg" + MASS_MILLIGRAMS = "mg" + MASS_MICROGRAMS = "µg" - MASS_OUNCES: str = "oz" - MASS_POUNDS: str = "lb" + MASS_OUNCES = "oz" + MASS_POUNDS = "lb" - CONDUCTIVITY: str = "µS/cm" + CONDUCTIVITY = "µS/cm" - LIGHT_LUX: str = "lx" + LIGHT_LUX = "lx" - UV_INDEX: str = "UV index" + UV_INDEX = "UV index" - PERCENTAGE: str = "%" + PERCENTAGE = "%" - IRRADIATION_WATTS_PER_SQUARE_METER: str = "W/m²" + IRRADIATION_WATTS_PER_SQUARE_METER = "W/m²" - PRECIPITATION_MILLIMETERS_PER_HOUR: str = "mm/h" + PRECIPITATION_MILLIMETERS_PER_HOUR = "mm/h" - CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: str = "µg/m³" - CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: str = "mg/m³" - CONCENTRATION_PARTS_PER_CUBIC_METER: str = "p/m³" - CONCENTRATION_PARTS_PER_MILLION: str = "ppm" - CONCENTRATION_PARTS_PER_BILLION: str = "ppb" + CONCENTRATION_MICROGRAMS_PER_CUBIC_METER = "µg/m³" + CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER = "mg/m³" + CONCENTRATION_PARTS_PER_CUBIC_METER = "p/m³" + CONCENTRATION_PARTS_PER_MILLION = "ppm" + CONCENTRATION_PARTS_PER_BILLION = "ppb" - SPEED_MILLIMETERS_PER_DAY: str = "mm/d" - SPEED_INCHES_PER_DAY: str = "in/d" - SPEED_METERS_PER_SECOND: str = "m/s" - SPEED_INCHES_PER_HOUR: str = "in/h" - SPEED_KILOMETERS_PER_HOUR: str = "km/h" - SPEED_MILES_PER_HOUR: str = "mph" + SPEED_MILLIMETERS_PER_DAY = "mm/d" + SPEED_INCHES_PER_DAY = "in/d" + SPEED_METERS_PER_SECOND = "m/s" + SPEED_INCHES_PER_HOUR = "in/h" + SPEED_KILOMETERS_PER_HOUR = "km/h" + SPEED_MILES_PER_HOUR = "mph" - SIGNAL_STRENGTH_DECIBELS: str = "dB" - SIGNAL_STRENGTH_DECIBELS_MILLIWATT: str = "dBm" + SIGNAL_STRENGTH_DECIBELS = "dB" + SIGNAL_STRENGTH_DECIBELS_MILLIWATT = "dBm" - DATA_BITS: str = "bit" - DATA_KILOBITS: str = "kbit" - DATA_MEGABITS: str = "Mbit" - DATA_GIGABITS: str = "Gbit" - DATA_BYTES: str = "B" - DATA_KILOBYTES: str = "kB" - DATA_MEGABYTES: str = "MB" - DATA_GIGABYTES: str = "GB" - DATA_TERABYTES: str = "TB" - DATA_PETABYTES: str = "PB" - DATA_EXABYTES: str = "EB" - DATA_ZETTABYTES: str = "ZB" - DATA_YOTTABYTES: str = "YB" - DATA_KIBIBYTES: str = "KiB" - DATA_MEBIBYTES: str = "MiB" - DATA_GIBIBYTES: str = "GiB" - DATA_TEBIBYTES: str = "TiB" - DATA_PEBIBYTES: str = "PiB" - DATA_EXBIBYTES: str = "EiB" - DATA_ZEBIBYTES: str = "ZiB" - DATA_YOBIBYTES: str = "YiB" - DATA_RATE_BITS_PER_SECOND: str = "bit/s" - DATA_RATE_KILOBITS_PER_SECOND: str = "kbit/s" - DATA_RATE_MEGABITS_PER_SECOND: str = "Mbit/s" - DATA_RATE_GIGABITS_PER_SECOND: str = "Gbit/s" - DATA_RATE_BYTES_PER_SECOND: str = "B/s" - DATA_RATE_KILOBYTES_PER_SECOND: str = "kB/s" - DATA_RATE_MEGABYTES_PER_SECOND: str = "MB/s" - DATA_RATE_GIGABYTES_PER_SECOND: str = "GB/s" - DATA_RATE_KIBIBYTES_PER_SECOND: str = "KiB/s" - DATA_RATE_MEBIBYTES_PER_SECOND: str = "MiB/s" - DATA_RATE_GIBIBYTES_PER_SECOND: str = "GiB/s" + DATA_BITS = "bit" + DATA_KILOBITS = "kbit" + DATA_MEGABITS = "Mbit" + DATA_GIGABITS = "Gbit" + DATA_BYTES = "B" + DATA_KILOBYTES = "kB" + DATA_MEGABYTES = "MB" + DATA_GIGABYTES = "GB" + DATA_TERABYTES = "TB" + DATA_PETABYTES = "PB" + DATA_EXABYTES = "EB" + DATA_ZETTABYTES = "ZB" + DATA_YOTTABYTES = "YB" + DATA_KIBIBYTES = "KiB" + DATA_MEBIBYTES = "MiB" + DATA_GIBIBYTES = "GiB" + DATA_TEBIBYTES = "TiB" + DATA_PEBIBYTES = "PiB" + DATA_EXBIBYTES = "EiB" + DATA_ZEBIBYTES = "ZiB" + DATA_YOBIBYTES = "YiB" + + DATA_RATE_BITS_PER_SECOND = "bit/s" + DATA_RATE_KILOBITS_PER_SECOND = "kbit/s" + DATA_RATE_MEGABITS_PER_SECOND = "Mbit/s" + DATA_RATE_GIGABITS_PER_SECOND = "Gbit/s" + DATA_RATE_BYTES_PER_SECOND = "B/s" + DATA_RATE_KILOBYTES_PER_SECOND = "kB/s" + DATA_RATE_MEGABYTES_PER_SECOND = "MB/s" + DATA_RATE_GIGABYTES_PER_SECOND = "GB/s" + DATA_RATE_KIBIBYTES_PER_SECOND = "KiB/s" + DATA_RATE_MEBIBYTES_PER_SECOND = "MiB/s" + DATA_RATE_GIBIBYTES_PER_SECOND = "GiB/s" diff --git a/haco/utils.py b/haco/utils.py index 8aac036..c223482 100644 --- a/haco/utils.py +++ b/haco/utils.py @@ -2,6 +2,7 @@ import string from dataclasses import dataclass from typing import Callable +from fmtr.tools import json from fmtr.tools.datatype_tools import to_bool CHARS_ALLOWED = string.ascii_lowercase + string.digits @@ -48,6 +49,11 @@ class ConvertersString(Converters): command: Callable = str state: Callable = str + +class ConvertersNumeric(Converters): + command: Callable = json.from_json + state: Callable = json.to_json + @dataclass class Metadata: exclude: bool = False