From 58a8254b9ac44307f66057bb6b45a3f04aec9b7d Mon Sep 17 00:00:00 2001 From: nao-pon Date: Sat, 3 Feb 2024 15:13:08 +0900 Subject: [PATCH] Automatically assigning icons using device_class and optimizing import syntax And enbug fixes. --- custom_components/echonetlite/__init__.py | 64 ++++++++- custom_components/echonetlite/climate.py | 22 +-- custom_components/echonetlite/const.py | 166 ++++++++-------------- custom_components/echonetlite/number.py | 36 +++-- custom_components/echonetlite/select.py | 2 +- custom_components/echonetlite/sensor.py | 41 ++---- custom_components/echonetlite/switch.py | 8 +- custom_components/echonetlite/time.py | 5 +- 8 files changed, 163 insertions(+), 181 deletions(-) diff --git a/custom_components/echonetlite/__init__.py b/custom_components/echonetlite/__init__.py index 89898d6..4b8c33c 100644 --- a/custom_components/echonetlite/__init__.py +++ b/custom_components/echonetlite/__init__.py @@ -12,13 +12,23 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.util import Throttle -from homeassistant.const import Platform +from homeassistant.const import ( + Platform, + PERCENTAGE, + UnitOfPower, + UnitOfTemperature, + UnitOfEnergy, + UnitOfVolume, + UnitOfElectricCurrent, + UnitOfElectricPotential, +) from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.components.sensor import SensorDeviceClass +from homeassistant.components.number import NumberDeviceClass from .const import ( DOMAIN, USER_OPTIONS, TEMP_OPTIONS, - CONF_FORCE_POLLING, CONF_BATCH_SIZE_MAX, MISC_OPTIONS, ) @@ -47,8 +57,6 @@ ENL_HVAC_ROOM_TEMP, ENL_HVAC_SILENT_MODE, ENL_HVAC_OUT_TEMP, - ENL_HVAC_HUMIDIFIER_STATE, - ENL_HVAC_HUMIDIFIER_VALUE, ) from pychonet.DistributionPanelMeter import ( @@ -65,7 +73,6 @@ from pychonet.LowVoltageSmartElectricEnergyMeter import ( ENL_LVSEEM_COEF, - ENL_LVSEEM_DIGITS, ENL_LVSEEM_ENG_UNIT, ENL_LVSEEM_ENG_NOR, ENL_LVSEEM_ENG_REV, @@ -190,6 +197,52 @@ def polling_update_debug_log(values, eojgc, eojcc): return debug_log +def get_unit_by_devise_class(device_class: str) -> str | None: + if ( + device_class == SensorDeviceClass.TEMPERATURE + or device_class == NumberDeviceClass.TEMPERATURE + ): + unit = UnitOfTemperature.CELSIUS + elif ( + device_class == SensorDeviceClass.ENERGY + or device_class == NumberDeviceClass.ENERGY + ): + unit = UnitOfEnergy.WATT_HOUR + elif ( + device_class == SensorDeviceClass.POWER + or device_class == NumberDeviceClass.POWER + ): + unit = UnitOfPower.WATT + elif ( + device_class == SensorDeviceClass.CURRENT + or device_class == NumberDeviceClass.CURRENT + ): + unit = UnitOfElectricCurrent.AMPERE + elif ( + device_class == SensorDeviceClass.VOLTAGE + or device_class == NumberDeviceClass.VOLTAGE + ): + unit = UnitOfElectricPotential.VOLT + elif ( + device_class == SensorDeviceClass.HUMIDITY + or device_class == SensorDeviceClass.BATTERY + or device_class == NumberDeviceClass.HUMIDITY + or device_class == NumberDeviceClass.BATTERY + ): + unit = PERCENTAGE + elif device_class == SensorDeviceClass.GAS or device_class == NumberDeviceClass.GAS: + unit = UnitOfVolume.CUBIC_METERS + elif ( + device_class == SensorDeviceClass.WATER + or device_class == NumberDeviceClass.WATER + ): + unit = UnitOfVolume.CUBIC_METERS + else: + unit = None + + return unit + + async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry.async_on_unload(entry.add_update_listener(update_listener)) host = None @@ -409,7 +462,6 @@ class ECHONETConnector: def __init__(self, instance, hass, entry): self.hass = hass self._host = instance["host"] - self._instance = None self._eojgc = instance["eojgc"] self._eojcc = instance["eojcc"] self._eojci = instance["eojci"] diff --git a/custom_components/echonetlite/climate.py b/custom_components/echonetlite/climate.py index 2dbef3a..2b236aa 100644 --- a/custom_components/echonetlite/climate.py +++ b/custom_components/echonetlite/climate.py @@ -13,7 +13,6 @@ ENL_HVAC_ROOM_TEMP, ENL_HVAC_SILENT_MODE, FAN_SPEED, - MODES, SILENT_MODE, ) @@ -36,8 +35,9 @@ from homeassistant.const import ( ATTR_TEMPERATURE, PRECISION_WHOLE, + UnitOfTemperature, ) -from .const import DATA_STATE_ON, DOMAIN, SILENT_MODE_OPTIONS, OPTION_HA_UI_SWING +from .const import DATA_STATE_ON, DOMAIN, OPTION_HA_UI_SWING _LOGGER = logging.getLogger(__name__) @@ -64,11 +64,7 @@ async def async_setup_entry(hass, config_entry, async_add_devices): if ( entity["instance"]["eojgc"] == 0x01 and entity["instance"]["eojcc"] == 0x30 ): # Home Air Conditioner - entities.append( - EchonetClimate( - config_entry.title, entity["echonetlite"], hass.config.units - ) - ) + entities.append(EchonetClimate(config_entry.title, entity["echonetlite"])) async_add_devices(entities, True) platform = entity_platform.async_get_current_platform() @@ -89,7 +85,12 @@ class EchonetClimate(ClimateEntity): _attr_translation_key = DOMAIN def __init__( - self, name, connector, units: UnitSystem, fan_modes=None, swing_vert=None + self, + name, + connector, + units: UnitSystem | None = None, + fan_modes=None, + swing_vert=None, ): """Initialize the climate device.""" self._name = name @@ -98,7 +99,10 @@ def __init__( self._uid = ( self._connector._uidi if self._connector._uidi else self._connector._uid ) - self._unit_of_measurement = units.temperature_unit + # The temperature unit of echonet lite is defined as Celsius. + # Set temperature_unit setting to Celsius, + # HA's automatic temperature unit conversion function works correctly. + self._unit_of_measurement = UnitOfTemperature.CELSIUS self._precision = 1.0 self._target_temperature_step = 1 self._support_flags = SUPPORT_FLAGS diff --git a/custom_components/echonetlite/const.py b/custom_components/echonetlite/const.py index 494544e..99884aa 100644 --- a/custom_components/echonetlite/const.py +++ b/custom_components/echonetlite/const.py @@ -3,15 +3,12 @@ from homeassistant.const import ( CONF_ICON, CONF_TYPE, - CONF_SERVICE, CONF_SERVICE_DATA, CONF_UNIT_OF_MEASUREMENT, CONF_NAME, CONF_MINIMUM, CONF_MAXIMUM, PERCENTAGE, - UnitOfVolume, - UnitOfTemperature, ) from homeassistant.components.sensor import ( ATTR_STATE_CLASS, @@ -87,8 +84,8 @@ COVER_SELECT_OP_CODES = {0xE0: {OPEN: 0x41, CLOSE: 0x42, STOP: 0x43}} ENL_OP_CODES = { - 0x00: { - 0x11: { + 0x00: { # Sensor-related Device + 0x11: { # Temperature sensor 0xE0: { CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, @@ -96,41 +93,36 @@ }, } }, - 0x01: { - 0x30: { + 0x01: { # Air Conditioner-related Device + 0x30: { # Home air conditioner 0x84: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0x85: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, - # 0xB3: { # for develop test - # CONF_ICON: "mdi:thermometer", - # CONF_TYPE: SensorDeviceClass.TEMPERATURE, - # CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - # CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, - # TYPE_NUMBER: { # Make Number input entity if settable value - # CONF_TYPE: NumberDeviceClass.TEMPERATURE, # NumberDeviceClass.x - # CONF_AS_ZERO: 0x1, # Value as zero - # CONF_MINIMUM: 0x0, # Minimum value - # CONF_MAXIMUM: 0x32, # Maximum value - # CONF_MAX_OPC: None, # OPC of max value - # CONF_BYTE_LENGTH: 0x1, # Data byte length - # TYPE_SWITCH: { # Additional switch - # CONF_NAME: "Auto", # Additionale name - # CONF_SERVICE_DATA: {DATA_STATE_ON: 23, DATA_STATE_OFF: 22}, - # }, - # }, - # }, + 0xB3: { # for develop test + CONF_TYPE: SensorDeviceClass.TEMPERATURE, + CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, + TYPE_NUMBER: { # Make Number input entity if settable value + CONF_TYPE: NumberDeviceClass.TEMPERATURE, # NumberDeviceClass.x + CONF_AS_ZERO: 0x1, # Value as zero + CONF_MINIMUM: 0x0, # Minimum value + CONF_MAXIMUM: 0x32, # Maximum value + CONF_MAX_OPC: None, # OPC of max value + CONF_BYTE_LENGTH: 0x1, # Data byte length + TYPE_SWITCH: { # Additional switch + CONF_NAME: "Auto", # Additionale name + CONF_ICON: "mdi:thermometer", + CONF_SERVICE_DATA: {DATA_STATE_ON: 23, DATA_STATE_OFF: 22}, + }, + }, + }, 0xB4: { # Humidity setting in dry mode - CONF_ICON: "mdi:water-percent", CONF_TYPE: SensorDeviceClass.HUMIDITY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: PERCENTAGE, TYPE_NUMBER: { CONF_TYPE: NumberDeviceClass.HUMIDITY, CONF_MINIMUM: 30, @@ -138,17 +130,14 @@ }, }, 0xBA: { - CONF_ICON: "mdi:water-percent", CONF_TYPE: SensorDeviceClass.HUMIDITY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xBE: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xBB: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, @@ -168,14 +157,12 @@ CONF_ICON: "mdi:tailwind", }, }, - 0x35: { + 0x35: { # Air cleaner 0x84: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0x85: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, @@ -185,7 +172,7 @@ }, }, }, - 0x02: { + 0x02: { # Housing/Facilities-related Device 0x60: { # Electrically operated blind/shade 0xE0: { CONF_ICON: "mdi:roller-shade", @@ -278,10 +265,8 @@ CONF_ICON: "mdi:timer-outline", }, 0xD1: { # Sensor - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, TYPE_NUMBER: { CONF_TYPE: NumberDeviceClass.TEMPERATURE, CONF_MINIMUM: 30, @@ -289,10 +274,8 @@ }, }, 0xE1: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, TYPE_NUMBER: { CONF_TYPE: NumberDeviceClass.TEMPERATURE, CONF_MINIMUM: 30, @@ -308,7 +291,7 @@ 0xE7: {CONF_UNIT_OF_MEASUREMENT: "L"}, 0xEE: {CONF_UNIT_OF_MEASUREMENT: "L"}, }, - 0x79: { + 0x79: { # Home solar power generation 0xE0: { CONF_ICON: "mdi:solar-power-variant-outline", CONF_TYPE: SensorDeviceClass.POWER, @@ -318,42 +301,35 @@ CONF_ICON_ZERO: "mdi:solar-power-variant-outline", }, 0xE1: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xE3: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xE5: { CONF_ICON: "mdi:percent", - CONF_TYPE: PERCENTAGE, + CONF_UNIT_OF_MEASUREMENT: PERCENTAGE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE6: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE8: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE9: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, }, - 0x7B: { + 0x7B: { # Floor heater 0xE0: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, TYPE_NUMBER: { CONF_TYPE: NumberDeviceClass.TEMPERATURE, CONF_MINIMUM: 16, @@ -381,16 +357,12 @@ }, }, 0xE2: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, }, 0xE3: { - CONF_ICON: "mdi:thermometer", CONF_TYPE: SensorDeviceClass.TEMPERATURE, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, - CONF_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS, }, 0x90: { CONF_ICON: "mdi:timer", @@ -405,93 +377,76 @@ CONF_ICON: "mdi:timer-outline", }, }, - 0x7C: { + 0x7C: { # Fuel cell 0xC2: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xC4: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xC5: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xCC: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xCD: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xC7: { - CONF_ICON: "mdi:gas-burner", CONF_TYPE: SensorDeviceClass.GAS, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, CONF_UNIT_OF_MEASUREMENT: "L/h", }, 0xC8: { - CONF_ICON: "mdi:gas-burner", CONF_TYPE: SensorDeviceClass.GAS, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "L", }, }, - 0x7D: { + 0x7D: { # Storage battery 0xA0: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA1: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA2: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA3: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA4: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA5: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xA6: { - CONF_ICON: "mdi:percent", - CONF_TYPE: PERCENTAGE, + CONF_TYPE: SensorDeviceClass.BATTERY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xA7: { - CONF_ICON: "mdi:percent", - CONF_TYPE: PERCENTAGE, + CONF_TYPE: SensorDeviceClass.BATTERY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xA8: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xA9: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, @@ -518,42 +473,34 @@ CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xD6: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xD8: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, }, 0xE0: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xE2: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xE4: { - CONF_ICON: "mdi:battery", - CONF_TYPE: PERCENTAGE, + CONF_TYPE: SensorDeviceClass.BATTERY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE5: { - CONF_ICON: "mdi:percent", - CONF_TYPE: PERCENTAGE, + CONF_TYPE: SensorDeviceClass.BATTERY, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE7: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, 0xE8: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL, }, @@ -568,34 +515,41 @@ CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, }, - 0x80: { + 0x80: { # Electric energy meter 0xE0: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", CONF_MULTIPLIER_OPCODE: 0xE2, - } + }, + 0xE2: { + CONF_DISABLED_DEFAULT: True, + }, }, - 0x81: { + 0x81: { # Water flow meter 0xE0: { - CONF_ICON: "mdi:water", - CONF_TYPE: UnitOfVolume.CUBIC_METERS, + # CONF_ICON: "mdi:water", + CONF_TYPE: SensorDeviceClass.WATER, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_MULTIPLIER_OPCODE: 0xE1, - } + }, + 0xE1: { + CONF_DISABLED_DEFAULT: True, + }, }, - 0x82: { + 0x82: { # Gas meter 0xE0: { - CONF_ICON: "mdi:gas-burner", + # CONF_ICON: "mdi:gas-burner", CONF_TYPE: SensorDeviceClass.GAS, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_MULTIPLIER: 0.001, } }, - 0x87: { + 0x87: { # Distribution panel metering + 0xC2: { + CONF_DISABLED_DEFAULT: True, + }, 0xB3: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", @@ -603,27 +557,23 @@ CONF_MULTIPLIER_OPCODE: 0xC2, }, 0xB7: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, TYPE_DATA_ARRAY_WITH_SIZE_OPCODE: 0xB1, }, 0xC0: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", CONF_MULTIPLIER_OPCODE: 0xC2, }, 0xC1: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", CONF_MULTIPLIER_OPCODE: 0xC2, }, 0xC6: { - CONF_ICON: "mdi:flash", CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, @@ -640,17 +590,21 @@ CONF_DISABLED_DEFAULT: True, }, }, - 0x88: { + 0x88: { # Low voltage smart electric energy meter + 0xD3: { + CONF_DISABLED_DEFAULT: True, + }, 0xE0: { - CONF_ICON: None, CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", CONF_MULTIPLIER_OPCODE: 0xE1, CONF_MULTIPLIER_OPTIONAL_OPCODE: 0xD3, }, + 0xE1: { + CONF_DISABLED_DEFAULT: True, + }, 0xE3: { - CONF_ICON: None, CONF_TYPE: SensorDeviceClass.ENERGY, CONF_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, CONF_UNIT_OF_MEASUREMENT: "kWh", @@ -658,28 +612,24 @@ CONF_MULTIPLIER_OPTIONAL_OPCODE: 0xD3, }, 0xE7: { - CONF_ICON: None, CONF_TYPE: SensorDeviceClass.POWER, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, }, 0xE8: { - CONF_ICON: None, CONF_TYPE: SensorDeviceClass.CURRENT, CONF_STATE_CLASS: SensorStateClass.MEASUREMENT, TYPE_DATA_DICT: ["r_phase_amperes", "t_phase_amperes"], }, # 0xEA: { - # CONF_ICON: None, # TYPE_DATA_DICT: ["time", "culmative_value"], # }, # 0xEB: { - # CONF_ICON: None, # TYPE_DATA_DICT: ["time", "culmative_value"], # }, 0xD3: {CONF_DISABLED_DEFAULT: True}, 0xE1: {CONF_DISABLED_DEFAULT: True}, }, - 0xA3: { + 0xA3: { # Lighting system 0xC0: { # Set scene CONF_ICON: "mdi:palette", CONF_TYPE: DEVICE_CLASS_ECHONETLITE_LIGHT_SCENE, diff --git a/custom_components/echonetlite/number.py b/custom_components/echonetlite/number.py index c117c00..e7e5b6b 100644 --- a/custom_components/echonetlite/number.py +++ b/custom_components/echonetlite/number.py @@ -1,25 +1,25 @@ import logging +from homeassistant.const import ( + CONF_ICON, + CONF_TYPE, + CONF_MINIMUM, + CONF_MAXIMUM, + CONF_UNIT_OF_MEASUREMENT, +) +from homeassistant.exceptions import InvalidStateError from homeassistant.components.number import NumberEntity +from pychonet.lib.epc import EPC_CODE +from pychonet.lib.eojx import EOJX_CLASS +from . import get_unit_by_devise_class from .const import ( DOMAIN, CONF_FORCE_POLLING, ENL_OP_CODES, - CONF_ICON, - CONF_NAME, - CONF_TYPE, - CONF_MINIMUM, - CONF_MAXIMUM, CONF_AS_ZERO, CONF_MAX_OPC, CONF_BYTE_LENGTH, - CONF_UNIT_OF_MEASUREMENT, - TYPE_TIME, TYPE_NUMBER, - NumberDeviceClass, - UnitOfTemperature, ) -from pychonet.lib.epc import EPC_CODE -from pychonet.lib.eojx import EOJX_CLASS _LOGGER = logging.getLogger(__name__) @@ -39,7 +39,7 @@ async def async_setup_entry(hass, config, async_add_entities, discovery_info=Non entity["echonetlite"], config, op_code, - ENL_OP_CODES[eojgc][eojcc][op_code], + _enl_op_codes[op_code], entity["echonetlite"]._name or config.title, ) ) @@ -72,15 +72,21 @@ def __init__(self, hass, connector, config, code, options, name=None): self._byte_length = int(options[TYPE_NUMBER].get(CONF_BYTE_LENGTH, 1)) self._device_name = name - self._attr_device_class = self._options.get(CONF_TYPE, None) + self._attr_device_class = self._options.get( + CONF_TYPE, options.get(CONF_TYPE, None) + ) self._attr_should_poll = True self._attr_available = True self._attr_native_value = self.get_value() self._attr_native_max_value = self.get_max_value() self._attr_native_min_value = self._options.get(CONF_MINIMUM, 0) - self._as_zero - self._attr_native_unit_of_measurement = options.get( - CONF_UNIT_OF_MEASUREMENT, None + self._attr_native_unit_of_measurement = self._options.get( + CONF_UNIT_OF_MEASUREMENT, options.get(CONF_UNIT_OF_MEASUREMENT, None) ) + if not self._attr_native_unit_of_measurement: + self._attr_native_unit_of_measurement = get_unit_by_devise_class( + self._attr_device_class + ) self.update_option_listener() diff --git a/custom_components/echonetlite/select.py b/custom_components/echonetlite/select.py index 49130c6..8669d89 100644 --- a/custom_components/echonetlite/select.py +++ b/custom_components/echonetlite/select.py @@ -1,10 +1,10 @@ import logging +from homeassistant.const import CONF_ICON from homeassistant.components.select import SelectEntity from .const import ( DOMAIN, CONF_FORCE_POLLING, ENL_OP_CODES, - CONF_ICON, CONF_ICONS, TYPE_SELECT, ) diff --git a/custom_components/echonetlite/sensor.py b/custom_components/echonetlite/sensor.py index 12a09e3..31b582b 100644 --- a/custom_components/echonetlite/sensor.py +++ b/custom_components/echonetlite/sensor.py @@ -8,18 +8,10 @@ CONF_SERVICE, CONF_TYPE, CONF_UNIT_OF_MEASUREMENT, - PERCENTAGE, - UnitOfPower, - UnitOfTemperature, - UnitOfEnergy, - UnitOfVolume, - UnitOfElectricCurrent, - UnitOfElectricPotential, ) from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorDeviceClass -from homeassistant.helpers.typing import StateType from homeassistant.exceptions import InvalidStateError, NoEntitySpecifiedError from pychonet.GeneralLighting import ENL_BRIGHTNESS, ENL_COLOR_TEMP @@ -28,7 +20,7 @@ from pychonet.lib.eojx import EOJX_CLASS from pychonet.lib.epc_functions import _hh_mm -# from pychonet.ElectricBlind import ENL_OPENSTATE +from . import get_unit_by_devise_class from .const import ( DOMAIN, ENL_OP_CODES, @@ -307,30 +299,13 @@ def __init__(self, connector, op_code, attributes, name=None, hass=None) -> None self._uid += f'-{self._sensor_attributes["accessor_index"]}' self._name += f' {str(self._sensor_attributes["accessor_index"] + 1).zfill(len(str(self._sensor_attributes[TYPE_DATA_ARRAY_WITH_SIZE_OPCODE])))}' - if CONF_UNIT_OF_MEASUREMENT in _attr_keys: - self._unit_of_measurement = self._sensor_attributes[ - CONF_UNIT_OF_MEASUREMENT - ] - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.TEMPERATURE: - self._unit_of_measurement = UnitOfTemperature.CELSIUS - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.ENERGY: - self._unit_of_measurement = UnitOfEnergy.WATT_HOUR - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.POWER: - self._unit_of_measurement = UnitOfPower.WATT - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.CURRENT: - self._unit_of_measurement = UnitOfElectricCurrent.AMPERE - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.VOLTAGE: - self._unit_of_measurement = UnitOfElectricPotential.VOLT - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.HUMIDITY: - self._unit_of_measurement = PERCENTAGE - elif self._sensor_attributes[CONF_TYPE] == PERCENTAGE: - self._unit_of_measurement = PERCENTAGE - elif self._sensor_attributes[CONF_TYPE] == SensorDeviceClass.GAS: - self._unit_of_measurement = UnitOfVolume.CUBIC_METERS - elif self._sensor_attributes[CONF_TYPE] == UnitOfVolume.CUBIC_METERS: - self._unit_of_measurement = UnitOfVolume.CUBIC_METERS - else: - self._unit_of_measurement = None + self._unit_of_measurement = self._sensor_attributes.get( + CONF_UNIT_OF_MEASUREMENT + ) + if not self._unit_of_measurement: + self._unit_of_measurement = get_unit_by_devise_class( + self._sensor_attributes[CONF_TYPE] + ) self.update_option_listener() diff --git a/custom_components/echonetlite/switch.py b/custom_components/echonetlite/switch.py index db87815..866be5b 100644 --- a/custom_components/echonetlite/switch.py +++ b/custom_components/echonetlite/switch.py @@ -1,13 +1,12 @@ import asyncio import logging -from homeassistant.const import CONF_ICON, CONF_SERVICE_DATA +from homeassistant.const import CONF_ICON, CONF_SERVICE_DATA, CONF_NAME from homeassistant.components.switch import SwitchEntity from .const import ( DOMAIN, ENL_OP_CODES, CONF_ON_VALUE, CONF_OFF_VALUE, - CONF_NAME, DATA_STATE_ON, DATA_STATE_OFF, SWITCH_POWER, @@ -15,13 +14,10 @@ TYPE_SWITCH, TYPE_NUMBER, ENL_STATUS, - ENL_ON, - ENL_OFF, CONF_FORCE_POLLING, ) from pychonet.lib.epc import EPC_CODE from pychonet.lib.eojx import EOJX_CLASS -from pychonet.lib.const import ENL_SETMAP _LOGGER = logging.getLogger(__name__) @@ -124,7 +120,7 @@ def __init__(self, hass, connector, config, code, options, name=None): ] self._from_number = True if options.get(TYPE_NUMBER) else False self._attr_name = f"{config.title} {EPC_CODE[self._connector._eojgc][self._connector._eojcc][self._code]}" - self._attr_icon = options[CONF_ICON] + self._attr_icon = options.get(CONF_ICON) self._uid = ( f"{self._connector._uidi}-{self._code}" if self._connector._uidi diff --git a/custom_components/echonetlite/time.py b/custom_components/echonetlite/time.py index 1e2acd0..0fbf458 100644 --- a/custom_components/echonetlite/time.py +++ b/custom_components/echonetlite/time.py @@ -1,13 +1,12 @@ import logging import datetime from datetime import time -from homeassistant.components.time import TimeEntity, ENTITY_ID_FORMAT -from homeassistant.util import slugify +from homeassistant.const import CONF_ICON +from homeassistant.components.time import TimeEntity from .const import ( DOMAIN, CONF_FORCE_POLLING, ENL_OP_CODES, - CONF_ICON, TYPE_TIME, ) from pychonet.lib.epc import EPC_CODE