diff --git a/homeassistant/components/opentherm_gw/binary_sensor.py b/homeassistant/components/opentherm_gw/binary_sensor.py index 9e3c4d41229..a896b37a26b 100644 --- a/homeassistant/components/opentherm_gw/binary_sensor.py +++ b/homeassistant/components/opentherm_gw/binary_sensor.py @@ -1,14 +1,22 @@ """Support for OpenTherm Gateway binary sensors.""" import logging +from pprint import pformat from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT, BinarySensorEntity from homeassistant.const import CONF_ID from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import async_generate_entity_id +from homeassistant.helpers.entity_registry import async_get_registry from . import DOMAIN -from .const import BINARY_SENSOR_INFO, DATA_GATEWAYS, DATA_OPENTHERM_GW +from .const import ( + BINARY_SENSOR_INFO, + DATA_GATEWAYS, + DATA_OPENTHERM_GW, + DEPRECATED_BINARY_SENSOR_SOURCE_LOOKUP, + TRANSLATE_SOURCE, +) _LOGGER = logging.getLogger(__name__) @@ -16,16 +24,51 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the OpenTherm Gateway binary sensors.""" sensors = [] + deprecated_sensors = [] + gw_dev = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] + ent_reg = await async_get_registry(hass) for var, info in BINARY_SENSOR_INFO.items(): device_class = info[0] friendly_name_format = info[1] - sensors.append( - OpenThermBinarySensor( - hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]], - var, - device_class, - friendly_name_format, + status_sources = info[2] + + for source in status_sources: + sensors.append( + OpenThermBinarySensor( + gw_dev, + var, + source, + device_class, + friendly_name_format, + ) ) + + old_style_entity_id = async_generate_entity_id( + ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ) + old_ent = ent_reg.async_get(old_style_entity_id) + if old_ent and old_ent.config_entry_id == config_entry.entry_id: + if old_ent.disabled: + ent_reg.async_remove(old_style_entity_id) + else: + deprecated_sensors.append( + DeprecatedOpenThermBinarySensor( + gw_dev, + var, + device_class, + friendly_name_format, + ) + ) + + sensors.extend(deprecated_sensors) + + if deprecated_sensors: + _LOGGER.warning( + "The following binary_sensor entities are deprecated and may " + "no longer behave as expected. They will be removed in a " + "future version. You can force removal of these entities by " + "disabling them and restarting Home Assistant.\n%s", + pformat([s.entity_id for s in deprecated_sensors]), ) async_add_entities(sensors) @@ -34,15 +77,20 @@ async def async_setup_entry(hass, config_entry, async_add_entities): class OpenThermBinarySensor(BinarySensorEntity): """Represent an OpenTherm Gateway binary sensor.""" - def __init__(self, gw_dev, var, device_class, friendly_name_format): + def __init__(self, gw_dev, var, source, device_class, friendly_name_format): """Initialize the binary sensor.""" self.entity_id = async_generate_entity_id( - ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ENTITY_ID_FORMAT, f"{var}_{source}_{gw_dev.gw_id}", hass=gw_dev.hass ) self._gateway = gw_dev self._var = var + self._source = source self._state = None self._device_class = device_class + if TRANSLATE_SOURCE[source] is not None: + friendly_name_format = ( + f"{friendly_name_format} ({TRANSLATE_SOURCE[source]})" + ) self._friendly_name = friendly_name_format.format(gw_dev.name) self._unsub_updates = None @@ -73,7 +121,7 @@ class OpenThermBinarySensor(BinarySensorEntity): @callback def receive_report(self, status): """Handle status updates from the component.""" - state = status.get(self._var) + state = status[self._source].get(self._var) self._state = None if state is None else bool(state) self.async_write_ha_state() @@ -96,7 +144,7 @@ class OpenThermBinarySensor(BinarySensorEntity): @property def unique_id(self): """Return a unique ID.""" - return f"{self._gateway.gw_id}-{self._var}" + return f"{self._gateway.gw_id}-{self._source}-{self._var}" @property def is_on(self): @@ -112,3 +160,26 @@ class OpenThermBinarySensor(BinarySensorEntity): def should_poll(self): """Return False because entity pushes its state.""" return False + + +class DeprecatedOpenThermBinarySensor(OpenThermBinarySensor): + """Represent a deprecated OpenTherm Gateway Binary Sensor.""" + + # pylint: disable=super-init-not-called + def __init__(self, gw_dev, var, device_class, friendly_name_format): + """Initialize the binary sensor.""" + self.entity_id = async_generate_entity_id( + ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ) + self._gateway = gw_dev + self._var = var + self._source = DEPRECATED_BINARY_SENSOR_SOURCE_LOOKUP[var] + self._state = None + self._device_class = device_class + self._friendly_name = friendly_name_format.format(gw_dev.name) + self._unsub_updates = None + + @property + def unique_id(self): + """Return a unique ID.""" + return f"{self._gateway.gw_id}-{self._var}" diff --git a/homeassistant/components/opentherm_gw/climate.py b/homeassistant/components/opentherm_gw/climate.py index 237733e6870..8ec536e7331 100644 --- a/homeassistant/components/opentherm_gw/climate.py +++ b/homeassistant/components/opentherm_gw/climate.py @@ -101,10 +101,10 @@ class OpenThermClimate(ClimateEntity): @callback def receive_report(self, status): """Receive and handle a new report from the Gateway.""" - self._available = bool(status) - ch_active = status.get(gw_vars.DATA_SLAVE_CH_ACTIVE) - flame_on = status.get(gw_vars.DATA_SLAVE_FLAME_ON) - cooling_active = status.get(gw_vars.DATA_SLAVE_COOLING_ACTIVE) + self._available = status != gw_vars.DEFAULT_STATUS + ch_active = status[gw_vars.BOILER].get(gw_vars.DATA_SLAVE_CH_ACTIVE) + flame_on = status[gw_vars.BOILER].get(gw_vars.DATA_SLAVE_FLAME_ON) + cooling_active = status[gw_vars.BOILER].get(gw_vars.DATA_SLAVE_COOLING_ACTIVE) if ch_active and flame_on: self._current_operation = CURRENT_HVAC_HEAT self._hvac_mode = HVAC_MODE_HEAT @@ -114,8 +114,10 @@ class OpenThermClimate(ClimateEntity): else: self._current_operation = CURRENT_HVAC_IDLE - self._current_temperature = status.get(gw_vars.DATA_ROOM_TEMP) - temp_upd = status.get(gw_vars.DATA_ROOM_SETPOINT) + self._current_temperature = status[gw_vars.THERMOSTAT].get( + gw_vars.DATA_ROOM_TEMP + ) + temp_upd = status[gw_vars.THERMOSTAT].get(gw_vars.DATA_ROOM_SETPOINT) if self._target_temperature != temp_upd: self._new_target_temperature = None @@ -123,14 +125,14 @@ class OpenThermClimate(ClimateEntity): # GPIO mode 5: 0 == Away # GPIO mode 6: 1 == Away - gpio_a_state = status.get(gw_vars.OTGW_GPIO_A) + gpio_a_state = status[gw_vars.OTGW].get(gw_vars.OTGW_GPIO_A) if gpio_a_state == 5: self._away_mode_a = 0 elif gpio_a_state == 6: self._away_mode_a = 1 else: self._away_mode_a = None - gpio_b_state = status.get(gw_vars.OTGW_GPIO_B) + gpio_b_state = status[gw_vars.OTGW].get(gw_vars.OTGW_GPIO_B) if gpio_b_state == 5: self._away_mode_b = 0 elif gpio_b_state == 6: @@ -139,11 +141,11 @@ class OpenThermClimate(ClimateEntity): self._away_mode_b = None if self._away_mode_a is not None: self._away_state_a = ( - status.get(gw_vars.OTGW_GPIO_A_STATE) == self._away_mode_a + status[gw_vars.OTGW].get(gw_vars.OTGW_GPIO_A_STATE) == self._away_mode_a ) if self._away_mode_b is not None: self._away_state_b = ( - status.get(gw_vars.OTGW_GPIO_B_STATE) == self._away_mode_b + status[gw_vars.OTGW].get(gw_vars.OTGW_GPIO_B_STATE) == self._away_mode_b ) self.async_write_ha_state() diff --git a/homeassistant/components/opentherm_gw/config_flow.py b/homeassistant/components/opentherm_gw/config_flow.py index 59f14ab2ee5..8da530bebda 100644 --- a/homeassistant/components/opentherm_gw/config_flow.py +++ b/homeassistant/components/opentherm_gw/config_flow.py @@ -54,7 +54,7 @@ class OpenThermGwConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): otgw = pyotgw.pyotgw() status = await otgw.connect(self.hass.loop, device) await otgw.disconnect() - return status.get(gw_vars.OTGW_ABOUT) + return status[gw_vars.OTGW].get(gw_vars.OTGW_ABOUT) try: res = await asyncio.wait_for(test_connection(), timeout=10) diff --git a/homeassistant/components/opentherm_gw/const.py b/homeassistant/components/opentherm_gw/const.py index 3ff1577c436..2c3e2f7071d 100644 --- a/homeassistant/components/opentherm_gw/const.py +++ b/homeassistant/components/opentherm_gw/const.py @@ -40,244 +40,599 @@ SERVICE_SET_MAX_MOD = "set_max_modulation" SERVICE_SET_OAT = "set_outside_temperature" SERVICE_SET_SB_TEMP = "set_setback_temperature" +TRANSLATE_SOURCE = { + gw_vars.BOILER: "Boiler", + gw_vars.OTGW: None, + gw_vars.THERMOSTAT: "Thermostat", +} + UNIT_KW = "kW" UNIT_L_MIN = f"L/{TIME_MINUTES}" BINARY_SENSOR_INFO = { - # [device_class, friendly_name format] - gw_vars.DATA_MASTER_CH_ENABLED: [None, "Thermostat Central Heating Enabled {}"], - gw_vars.DATA_MASTER_DHW_ENABLED: [None, "Thermostat Hot Water Enabled {}"], - gw_vars.DATA_MASTER_COOLING_ENABLED: [None, "Thermostat Cooling Enabled {}"], + # [device_class, friendly_name format, [status source, ...]] + gw_vars.DATA_MASTER_CH_ENABLED: [ + None, + "Thermostat Central Heating {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_DHW_ENABLED: [ + None, + "Thermostat Hot Water {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_COOLING_ENABLED: [ + None, + "Thermostat Cooling {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], gw_vars.DATA_MASTER_OTC_ENABLED: [ None, - "Thermostat Outside Temperature Correction Enabled {}", + "Thermostat Outside Temperature Correction {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_CH2_ENABLED: [ + None, + "Thermostat Central Heating 2 {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_FAULT_IND: [ + DEVICE_CLASS_PROBLEM, + "Boiler Fault {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_MASTER_CH2_ENABLED: [None, "Thermostat Central Heating 2 Enabled {}"], - gw_vars.DATA_SLAVE_FAULT_IND: [DEVICE_CLASS_PROBLEM, "Boiler Fault Indication {}"], gw_vars.DATA_SLAVE_CH_ACTIVE: [ DEVICE_CLASS_HEAT, - "Boiler Central Heating Status {}", + "Boiler Central Heating {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_DHW_ACTIVE: [ + DEVICE_CLASS_HEAT, + "Boiler Hot Water {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_FLAME_ON: [ + DEVICE_CLASS_HEAT, + "Boiler Flame {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_COOLING_ACTIVE: [ + DEVICE_CLASS_COLD, + "Boiler Cooling {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_SLAVE_DHW_ACTIVE: [DEVICE_CLASS_HEAT, "Boiler Hot Water Status {}"], - gw_vars.DATA_SLAVE_FLAME_ON: [DEVICE_CLASS_HEAT, "Boiler Flame Status {}"], - gw_vars.DATA_SLAVE_COOLING_ACTIVE: [DEVICE_CLASS_COLD, "Boiler Cooling Status {}"], gw_vars.DATA_SLAVE_CH2_ACTIVE: [ DEVICE_CLASS_HEAT, - "Boiler Central Heating 2 Status {}", + "Boiler Central Heating 2 {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_DIAG_IND: [ DEVICE_CLASS_PROBLEM, - "Boiler Diagnostics Indication {}", + "Boiler Diagnostics {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_DHW_PRESENT: [ + None, + "Boiler Hot Water Present {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_CONTROL_TYPE: [ + None, + "Boiler Control Type {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_COOLING_SUPPORTED: [ + None, + "Boiler Cooling Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_DHW_CONFIG: [ + None, + "Boiler Hot Water Configuration {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_MASTER_LOW_OFF_PUMP: [ + None, + "Boiler Pump Commands Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_CH2_PRESENT: [ + None, + "Boiler Central Heating 2 Present {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_SLAVE_DHW_PRESENT: [None, "Boiler Hot Water Present {}"], - gw_vars.DATA_SLAVE_CONTROL_TYPE: [None, "Boiler Control Type {}"], - gw_vars.DATA_SLAVE_COOLING_SUPPORTED: [None, "Boiler Cooling Support {}"], - gw_vars.DATA_SLAVE_DHW_CONFIG: [None, "Boiler Hot Water Configuration {}"], - gw_vars.DATA_SLAVE_MASTER_LOW_OFF_PUMP: [None, "Boiler Pump Commands Support {}"], - gw_vars.DATA_SLAVE_CH2_PRESENT: [None, "Boiler Central Heating 2 Present {}"], gw_vars.DATA_SLAVE_SERVICE_REQ: [ DEVICE_CLASS_PROBLEM, "Boiler Service Required {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_REMOTE_RESET: [ + None, + "Boiler Remote Reset Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_SLAVE_REMOTE_RESET: [None, "Boiler Remote Reset Support {}"], gw_vars.DATA_SLAVE_LOW_WATER_PRESS: [ DEVICE_CLASS_PROBLEM, "Boiler Low Water Pressure {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_GAS_FAULT: [ + DEVICE_CLASS_PROBLEM, + "Boiler Gas Fault {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_SLAVE_GAS_FAULT: [DEVICE_CLASS_PROBLEM, "Boiler Gas Fault {}"], gw_vars.DATA_SLAVE_AIR_PRESS_FAULT: [ DEVICE_CLASS_PROBLEM, "Boiler Air Pressure Fault {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_WATER_OVERTEMP: [ DEVICE_CLASS_PROBLEM, "Boiler Water Overtemperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_REMOTE_TRANSFER_DHW: [ None, "Remote Hot Water Setpoint Transfer Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_REMOTE_TRANSFER_MAX_CH: [ None, "Remote Maximum Central Heating Setpoint Write Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_REMOTE_RW_DHW: [ + None, + "Remote Hot Water Setpoint Write Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_REMOTE_RW_DHW: [None, "Remote Hot Water Setpoint Write Support {}"], gw_vars.DATA_REMOTE_RW_MAX_CH: [ None, "Remote Central Heating Setpoint Write Support {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_ROVRD_MAN_PRIO: [None, "Remote Override Manual Change Priority {}"], - gw_vars.DATA_ROVRD_AUTO_PRIO: [None, "Remote Override Program Change Priority {}"], - gw_vars.OTGW_GPIO_A_STATE: [None, "Gateway GPIO A State {}"], - gw_vars.OTGW_GPIO_B_STATE: [None, "Gateway GPIO B State {}"], - gw_vars.OTGW_IGNORE_TRANSITIONS: [None, "Gateway Ignore Transitions {}"], - gw_vars.OTGW_OVRD_HB: [None, "Gateway Override High Byte {}"], + gw_vars.DATA_ROVRD_MAN_PRIO: [ + None, + "Remote Override Manual Change Priority {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_ROVRD_AUTO_PRIO: [ + None, + "Remote Override Program Change Priority {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.OTGW_GPIO_A_STATE: [None, "Gateway GPIO A {}", [gw_vars.OTGW]], + gw_vars.OTGW_GPIO_B_STATE: [None, "Gateway GPIO B {}", [gw_vars.OTGW]], + gw_vars.OTGW_IGNORE_TRANSITIONS: [ + None, + "Gateway Ignore Transitions {}", + [gw_vars.OTGW], + ], + gw_vars.OTGW_OVRD_HB: [None, "Gateway Override High Byte {}", [gw_vars.OTGW]], } SENSOR_INFO = { - # [device_class, unit, friendly_name] + # [device_class, unit, friendly_name, [status source, ...]] gw_vars.DATA_CONTROL_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Control Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_MEMBERID: [ + None, + None, + "Thermostat Member ID {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_MEMBERID: [ + None, + None, + "Boiler Member ID {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_OEM_FAULT: [ + None, + None, + "Boiler OEM Fault Code {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_COOLING_CONTROL: [ + None, + PERCENTAGE, + "Cooling Control Signal {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_MASTER_MEMBERID: [None, None, "Thermostat Member ID {}"], - gw_vars.DATA_SLAVE_MEMBERID: [None, None, "Boiler Member ID {}"], - gw_vars.DATA_SLAVE_OEM_FAULT: [None, None, "Boiler OEM Fault Code {}"], - gw_vars.DATA_COOLING_CONTROL: [None, PERCENTAGE, "Cooling Control Signal {}"], gw_vars.DATA_CONTROL_SETPOINT_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Control Setpoint 2 {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_ROOM_SETPOINT_OVRD: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint Override {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_MAX_RELATIVE_MOD: [ None, PERCENTAGE, "Boiler Maximum Relative Modulation {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_MAX_CAPACITY: [ + None, + UNIT_KW, + "Boiler Maximum Capacity {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_SLAVE_MAX_CAPACITY: [None, UNIT_KW, "Boiler Maximum Capacity {}"], gw_vars.DATA_SLAVE_MIN_MOD_LEVEL: [ None, PERCENTAGE, "Boiler Minimum Modulation Level {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_ROOM_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_REL_MOD_LEVEL: [ + None, + PERCENTAGE, + "Relative Modulation Level {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_REL_MOD_LEVEL: [None, PERCENTAGE, "Relative Modulation Level {}"], gw_vars.DATA_CH_WATER_PRESS: [ None, PRESSURE_BAR, "Central Heating Water Pressure {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_DHW_FLOW_RATE: [ + None, + UNIT_L_MIN, + "Hot Water Flow Rate {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_DHW_FLOW_RATE: [None, UNIT_L_MIN, "Hot Water Flow Rate {}"], gw_vars.DATA_ROOM_SETPOINT_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint 2 {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_ROOM_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_CH_WATER_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Central Heating Water Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_DHW_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_OUTSIDE_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Outside Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_RETURN_WATER_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Return Water Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SOLAR_STORAGE_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Solar Storage Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SOLAR_COLL_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Solar Collector Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_CH_WATER_TEMP_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Central Heating 2 Water Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_DHW_TEMP_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water 2 Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_EXHAUST_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Exhaust Temperature {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_DHW_MAX_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Maximum Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_DHW_MIN_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Minimum Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_CH_MAX_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Boiler Maximum Central Heating Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_SLAVE_CH_MIN_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Boiler Minimum Central Heating Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_DHW_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], gw_vars.DATA_MAX_CH_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Maximum Central Heating Setpoint {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], ], - gw_vars.DATA_OEM_DIAG: [None, None, "OEM Diagnostic Code {}"], - gw_vars.DATA_TOTAL_BURNER_STARTS: [None, None, "Total Burner Starts {}"], - gw_vars.DATA_CH_PUMP_STARTS: [None, None, "Central Heating Pump Starts {}"], - gw_vars.DATA_DHW_PUMP_STARTS: [None, None, "Hot Water Pump Starts {}"], - gw_vars.DATA_DHW_BURNER_STARTS: [None, None, "Hot Water Burner Starts {}"], - gw_vars.DATA_TOTAL_BURNER_HOURS: [None, TIME_HOURS, "Total Burner Hours {}"], - gw_vars.DATA_CH_PUMP_HOURS: [None, TIME_HOURS, "Central Heating Pump Hours {}"], - gw_vars.DATA_DHW_PUMP_HOURS: [None, TIME_HOURS, "Hot Water Pump Hours {}"], - gw_vars.DATA_DHW_BURNER_HOURS: [None, TIME_HOURS, "Hot Water Burner Hours {}"], - gw_vars.DATA_MASTER_OT_VERSION: [None, None, "Thermostat OpenTherm Version {}"], - gw_vars.DATA_SLAVE_OT_VERSION: [None, None, "Boiler OpenTherm Version {}"], - gw_vars.DATA_MASTER_PRODUCT_TYPE: [None, None, "Thermostat Product Type {}"], - gw_vars.DATA_MASTER_PRODUCT_VERSION: [None, None, "Thermostat Product Version {}"], - gw_vars.DATA_SLAVE_PRODUCT_TYPE: [None, None, "Boiler Product Type {}"], - gw_vars.DATA_SLAVE_PRODUCT_VERSION: [None, None, "Boiler Product Version {}"], - gw_vars.OTGW_MODE: [None, None, "Gateway/Monitor Mode {}"], - gw_vars.OTGW_DHW_OVRD: [None, None, "Gateway Hot Water Override Mode {}"], - gw_vars.OTGW_ABOUT: [None, None, "Gateway Firmware Version {}"], - gw_vars.OTGW_BUILD: [None, None, "Gateway Firmware Build {}"], - gw_vars.OTGW_CLOCKMHZ: [None, None, "Gateway Clock Speed {}"], - gw_vars.OTGW_LED_A: [None, None, "Gateway LED A Mode {}"], - gw_vars.OTGW_LED_B: [None, None, "Gateway LED B Mode {}"], - gw_vars.OTGW_LED_C: [None, None, "Gateway LED C Mode {}"], - gw_vars.OTGW_LED_D: [None, None, "Gateway LED D Mode {}"], - gw_vars.OTGW_LED_E: [None, None, "Gateway LED E Mode {}"], - gw_vars.OTGW_LED_F: [None, None, "Gateway LED F Mode {}"], - gw_vars.OTGW_GPIO_A: [None, None, "Gateway GPIO A Mode {}"], - gw_vars.OTGW_GPIO_B: [None, None, "Gateway GPIO B Mode {}"], + gw_vars.DATA_OEM_DIAG: [ + None, + None, + "OEM Diagnostic Code {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_TOTAL_BURNER_STARTS: [ + None, + None, + "Total Burner Starts {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_CH_PUMP_STARTS: [ + None, + None, + "Central Heating Pump Starts {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_DHW_PUMP_STARTS: [ + None, + None, + "Hot Water Pump Starts {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_DHW_BURNER_STARTS: [ + None, + None, + "Hot Water Burner Starts {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_TOTAL_BURNER_HOURS: [ + None, + TIME_HOURS, + "Total Burner Hours {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_CH_PUMP_HOURS: [ + None, + TIME_HOURS, + "Central Heating Pump Hours {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_DHW_PUMP_HOURS: [ + None, + TIME_HOURS, + "Hot Water Pump Hours {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_DHW_BURNER_HOURS: [ + None, + TIME_HOURS, + "Hot Water Burner Hours {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_OT_VERSION: [ + None, + None, + "Thermostat OpenTherm Version {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_OT_VERSION: [ + None, + None, + "Boiler OpenTherm Version {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_PRODUCT_TYPE: [ + None, + None, + "Thermostat Product Type {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_MASTER_PRODUCT_VERSION: [ + None, + None, + "Thermostat Product Version {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_PRODUCT_TYPE: [ + None, + None, + "Boiler Product Type {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.DATA_SLAVE_PRODUCT_VERSION: [ + None, + None, + "Boiler Product Version {}", + [gw_vars.BOILER, gw_vars.THERMOSTAT], + ], + gw_vars.OTGW_MODE: [None, None, "Gateway/Monitor Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_DHW_OVRD: [ + None, + None, + "Gateway Hot Water Override Mode {}", + [gw_vars.OTGW], + ], + gw_vars.OTGW_ABOUT: [None, None, "Gateway Firmware Version {}", [gw_vars.OTGW]], + gw_vars.OTGW_BUILD: [None, None, "Gateway Firmware Build {}", [gw_vars.OTGW]], + gw_vars.OTGW_CLOCKMHZ: [None, None, "Gateway Clock Speed {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_A: [None, None, "Gateway LED A Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_B: [None, None, "Gateway LED B Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_C: [None, None, "Gateway LED C Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_D: [None, None, "Gateway LED D Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_E: [None, None, "Gateway LED E Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_LED_F: [None, None, "Gateway LED F Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_GPIO_A: [None, None, "Gateway GPIO A Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_GPIO_B: [None, None, "Gateway GPIO B Mode {}", [gw_vars.OTGW]], gw_vars.OTGW_SB_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Gateway Setback Temperature {}", + [gw_vars.OTGW], + ], + gw_vars.OTGW_SETP_OVRD_MODE: [ + None, + None, + "Gateway Room Setpoint Override Mode {}", + [gw_vars.OTGW], + ], + gw_vars.OTGW_SMART_PWR: [None, None, "Gateway Smart Power Mode {}", [gw_vars.OTGW]], + gw_vars.OTGW_THRM_DETECT: [ + None, + None, + "Gateway Thermostat Detection {}", + [gw_vars.OTGW], + ], + gw_vars.OTGW_VREF: [ + None, + None, + "Gateway Reference Voltage Setting {}", + [gw_vars.OTGW], ], - gw_vars.OTGW_SETP_OVRD_MODE: [None, None, "Gateway Room Setpoint Override Mode {}"], - gw_vars.OTGW_SMART_PWR: [None, None, "Gateway Smart Power Mode {}"], - gw_vars.OTGW_THRM_DETECT: [None, None, "Gateway Thermostat Detection {}"], - gw_vars.OTGW_VREF: [None, None, "Gateway Reference Voltage Setting {}"], +} + +DEPRECATED_BINARY_SENSOR_SOURCE_LOOKUP = { + gw_vars.DATA_MASTER_CH_ENABLED: gw_vars.THERMOSTAT, + gw_vars.DATA_MASTER_DHW_ENABLED: gw_vars.THERMOSTAT, + gw_vars.DATA_MASTER_OTC_ENABLED: gw_vars.THERMOSTAT, + gw_vars.DATA_MASTER_CH2_ENABLED: gw_vars.THERMOSTAT, + gw_vars.DATA_SLAVE_FAULT_IND: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CH_ACTIVE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DHW_ACTIVE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_FLAME_ON: gw_vars.BOILER, + gw_vars.DATA_SLAVE_COOLING_ACTIVE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CH2_ACTIVE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DIAG_IND: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DHW_PRESENT: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CONTROL_TYPE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_COOLING_SUPPORTED: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DHW_CONFIG: gw_vars.BOILER, + gw_vars.DATA_SLAVE_MASTER_LOW_OFF_PUMP: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CH2_PRESENT: gw_vars.BOILER, + gw_vars.DATA_SLAVE_SERVICE_REQ: gw_vars.BOILER, + gw_vars.DATA_SLAVE_REMOTE_RESET: gw_vars.BOILER, + gw_vars.DATA_SLAVE_LOW_WATER_PRESS: gw_vars.BOILER, + gw_vars.DATA_SLAVE_GAS_FAULT: gw_vars.BOILER, + gw_vars.DATA_SLAVE_AIR_PRESS_FAULT: gw_vars.BOILER, + gw_vars.DATA_SLAVE_WATER_OVERTEMP: gw_vars.BOILER, + gw_vars.DATA_REMOTE_TRANSFER_DHW: gw_vars.BOILER, + gw_vars.DATA_REMOTE_TRANSFER_MAX_CH: gw_vars.BOILER, + gw_vars.DATA_REMOTE_RW_DHW: gw_vars.BOILER, + gw_vars.DATA_REMOTE_RW_MAX_CH: gw_vars.BOILER, + gw_vars.DATA_ROVRD_MAN_PRIO: gw_vars.THERMOSTAT, + gw_vars.DATA_ROVRD_AUTO_PRIO: gw_vars.THERMOSTAT, + gw_vars.OTGW_GPIO_A_STATE: gw_vars.OTGW, + gw_vars.OTGW_GPIO_B_STATE: gw_vars.OTGW, + gw_vars.OTGW_IGNORE_TRANSITIONS: gw_vars.OTGW, + gw_vars.OTGW_OVRD_HB: gw_vars.OTGW, +} + +DEPRECATED_SENSOR_SOURCE_LOOKUP = { + gw_vars.DATA_CONTROL_SETPOINT: gw_vars.BOILER, + gw_vars.DATA_MASTER_MEMBERID: gw_vars.THERMOSTAT, + gw_vars.DATA_SLAVE_MEMBERID: gw_vars.BOILER, + gw_vars.DATA_SLAVE_OEM_FAULT: gw_vars.BOILER, + gw_vars.DATA_COOLING_CONTROL: gw_vars.BOILER, + gw_vars.DATA_CONTROL_SETPOINT_2: gw_vars.BOILER, + gw_vars.DATA_ROOM_SETPOINT_OVRD: gw_vars.THERMOSTAT, + gw_vars.DATA_SLAVE_MAX_RELATIVE_MOD: gw_vars.BOILER, + gw_vars.DATA_SLAVE_MAX_CAPACITY: gw_vars.BOILER, + gw_vars.DATA_SLAVE_MIN_MOD_LEVEL: gw_vars.BOILER, + gw_vars.DATA_ROOM_SETPOINT: gw_vars.THERMOSTAT, + gw_vars.DATA_REL_MOD_LEVEL: gw_vars.BOILER, + gw_vars.DATA_CH_WATER_PRESS: gw_vars.BOILER, + gw_vars.DATA_DHW_FLOW_RATE: gw_vars.BOILER, + gw_vars.DATA_ROOM_SETPOINT_2: gw_vars.THERMOSTAT, + gw_vars.DATA_ROOM_TEMP: gw_vars.THERMOSTAT, + gw_vars.DATA_CH_WATER_TEMP: gw_vars.BOILER, + gw_vars.DATA_DHW_TEMP: gw_vars.BOILER, + gw_vars.DATA_OUTSIDE_TEMP: gw_vars.THERMOSTAT, + gw_vars.DATA_RETURN_WATER_TEMP: gw_vars.BOILER, + gw_vars.DATA_SOLAR_STORAGE_TEMP: gw_vars.BOILER, + gw_vars.DATA_SOLAR_COLL_TEMP: gw_vars.BOILER, + gw_vars.DATA_CH_WATER_TEMP_2: gw_vars.BOILER, + gw_vars.DATA_DHW_TEMP_2: gw_vars.BOILER, + gw_vars.DATA_EXHAUST_TEMP: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DHW_MAX_SETP: gw_vars.BOILER, + gw_vars.DATA_SLAVE_DHW_MIN_SETP: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CH_MAX_SETP: gw_vars.BOILER, + gw_vars.DATA_SLAVE_CH_MIN_SETP: gw_vars.BOILER, + gw_vars.DATA_DHW_SETPOINT: gw_vars.BOILER, + gw_vars.DATA_MAX_CH_SETPOINT: gw_vars.BOILER, + gw_vars.DATA_OEM_DIAG: gw_vars.BOILER, + gw_vars.DATA_TOTAL_BURNER_STARTS: gw_vars.BOILER, + gw_vars.DATA_CH_PUMP_STARTS: gw_vars.BOILER, + gw_vars.DATA_DHW_PUMP_STARTS: gw_vars.BOILER, + gw_vars.DATA_DHW_BURNER_STARTS: gw_vars.BOILER, + gw_vars.DATA_TOTAL_BURNER_HOURS: gw_vars.BOILER, + gw_vars.DATA_CH_PUMP_HOURS: gw_vars.BOILER, + gw_vars.DATA_DHW_PUMP_HOURS: gw_vars.BOILER, + gw_vars.DATA_DHW_BURNER_HOURS: gw_vars.BOILER, + gw_vars.DATA_MASTER_OT_VERSION: gw_vars.THERMOSTAT, + gw_vars.DATA_SLAVE_OT_VERSION: gw_vars.BOILER, + gw_vars.DATA_MASTER_PRODUCT_TYPE: gw_vars.THERMOSTAT, + gw_vars.DATA_MASTER_PRODUCT_VERSION: gw_vars.THERMOSTAT, + gw_vars.DATA_SLAVE_PRODUCT_TYPE: gw_vars.BOILER, + gw_vars.DATA_SLAVE_PRODUCT_VERSION: gw_vars.BOILER, + gw_vars.OTGW_MODE: gw_vars.OTGW, + gw_vars.OTGW_DHW_OVRD: gw_vars.OTGW, + gw_vars.OTGW_ABOUT: gw_vars.OTGW, + gw_vars.OTGW_BUILD: gw_vars.OTGW, + gw_vars.OTGW_CLOCKMHZ: gw_vars.OTGW, + gw_vars.OTGW_LED_A: gw_vars.OTGW, + gw_vars.OTGW_LED_B: gw_vars.OTGW, + gw_vars.OTGW_LED_C: gw_vars.OTGW, + gw_vars.OTGW_LED_D: gw_vars.OTGW, + gw_vars.OTGW_LED_E: gw_vars.OTGW, + gw_vars.OTGW_LED_F: gw_vars.OTGW, + gw_vars.OTGW_GPIO_A: gw_vars.OTGW, + gw_vars.OTGW_GPIO_B: gw_vars.OTGW, + gw_vars.OTGW_SB_TEMP: gw_vars.OTGW, + gw_vars.OTGW_SETP_OVRD_MODE: gw_vars.OTGW, + gw_vars.OTGW_SMART_PWR: gw_vars.OTGW, + gw_vars.OTGW_THRM_DETECT: gw_vars.OTGW, + gw_vars.OTGW_VREF: gw_vars.OTGW, } diff --git a/homeassistant/components/opentherm_gw/manifest.json b/homeassistant/components/opentherm_gw/manifest.json index 558f4adced8..066cee61c05 100644 --- a/homeassistant/components/opentherm_gw/manifest.json +++ b/homeassistant/components/opentherm_gw/manifest.json @@ -2,7 +2,7 @@ "domain": "opentherm_gw", "name": "OpenTherm Gateway", "documentation": "https://www.home-assistant.io/integrations/opentherm_gw", - "requirements": ["pyotgw==0.6b1"], + "requirements": ["pyotgw==1.0b1"], "codeowners": ["@mvn23"], "config_flow": true } diff --git a/homeassistant/components/opentherm_gw/sensor.py b/homeassistant/components/opentherm_gw/sensor.py index b2f8e272983..4a20aa651cd 100644 --- a/homeassistant/components/opentherm_gw/sensor.py +++ b/homeassistant/components/opentherm_gw/sensor.py @@ -1,14 +1,22 @@ """Support for OpenTherm Gateway sensors.""" import logging +from pprint import pformat from homeassistant.components.sensor import ENTITY_ID_FORMAT from homeassistant.const import CONF_ID from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity, async_generate_entity_id +from homeassistant.helpers.entity_registry import async_get_registry from . import DOMAIN -from .const import DATA_GATEWAYS, DATA_OPENTHERM_GW, SENSOR_INFO +from .const import ( + DATA_GATEWAYS, + DATA_OPENTHERM_GW, + DEPRECATED_SENSOR_SOURCE_LOOKUP, + SENSOR_INFO, + TRANSLATE_SOURCE, +) _LOGGER = logging.getLogger(__name__) @@ -16,18 +24,54 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the OpenTherm Gateway sensors.""" sensors = [] + deprecated_sensors = [] + gw_dev = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] + ent_reg = await async_get_registry(hass) for var, info in SENSOR_INFO.items(): device_class = info[0] unit = info[1] friendly_name_format = info[2] - sensors.append( - OpenThermSensor( - hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]], - var, - device_class, - unit, - friendly_name_format, + status_sources = info[3] + + for source in status_sources: + sensors.append( + OpenThermSensor( + gw_dev, + var, + source, + device_class, + unit, + friendly_name_format, + ) ) + + old_style_entity_id = async_generate_entity_id( + ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ) + old_ent = ent_reg.async_get(old_style_entity_id) + if old_ent and old_ent.config_entry_id == config_entry.entry_id: + if old_ent.disabled: + ent_reg.async_remove(old_style_entity_id) + else: + deprecated_sensors.append( + DeprecatedOpenThermSensor( + gw_dev, + var, + device_class, + unit, + friendly_name_format, + ) + ) + + sensors.extend(deprecated_sensors) + + if deprecated_sensors: + _LOGGER.warning( + "The following sensor entities are deprecated and may no " + "longer behave as expected. They will be removed in a future " + "version. You can force removal of these entities by disabling " + "them and restarting Home Assistant.\n%s", + pformat([s.entity_id for s in deprecated_sensors]), ) async_add_entities(sensors) @@ -36,16 +80,21 @@ async def async_setup_entry(hass, config_entry, async_add_entities): class OpenThermSensor(Entity): """Representation of an OpenTherm Gateway sensor.""" - def __init__(self, gw_dev, var, device_class, unit, friendly_name_format): + def __init__(self, gw_dev, var, source, device_class, unit, friendly_name_format): """Initialize the OpenTherm Gateway sensor.""" self.entity_id = async_generate_entity_id( - ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ENTITY_ID_FORMAT, f"{var}_{source}_{gw_dev.gw_id}", hass=gw_dev.hass ) self._gateway = gw_dev self._var = var + self._source = source self._value = None self._device_class = device_class self._unit = unit + if TRANSLATE_SOURCE[source] is not None: + friendly_name_format = ( + f"{friendly_name_format} ({TRANSLATE_SOURCE[source]})" + ) self._friendly_name = friendly_name_format.format(gw_dev.name) self._unsub_updates = None @@ -74,7 +123,7 @@ class OpenThermSensor(Entity): @callback def receive_report(self, status): """Handle status updates from the component.""" - value = status.get(self._var) + value = status[self._source].get(self._var) if isinstance(value, float): value = f"{value:2.1f}" self._value = value @@ -99,7 +148,7 @@ class OpenThermSensor(Entity): @property def unique_id(self): """Return a unique ID.""" - return f"{self._gateway.gw_id}-{self._var}" + return f"{self._gateway.gw_id}-{self._source}-{self._var}" @property def device_class(self): @@ -120,3 +169,27 @@ class OpenThermSensor(Entity): def should_poll(self): """Return False because entity pushes its state.""" return False + + +class DeprecatedOpenThermSensor(OpenThermSensor): + """Represent a deprecated OpenTherm Gateway Sensor.""" + + # pylint: disable=super-init-not-called + def __init__(self, gw_dev, var, device_class, unit, friendly_name_format): + """Initialize the OpenTherm Gateway sensor.""" + self.entity_id = async_generate_entity_id( + ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass + ) + self._gateway = gw_dev + self._var = var + self._source = DEPRECATED_SENSOR_SOURCE_LOOKUP[var] + self._value = None + self._device_class = device_class + self._unit = unit + self._friendly_name = friendly_name_format.format(gw_dev.name) + self._unsub_updates = None + + @property + def unique_id(self): + """Return a unique ID.""" + return f"{self._gateway.gw_id}-{self._var}" diff --git a/requirements_all.txt b/requirements_all.txt index 917006cea97..5bb2f37d9a0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1587,7 +1587,7 @@ pyoppleio==1.0.5 pyota==2.0.5 # homeassistant.components.opentherm_gw -pyotgw==0.6b1 +pyotgw==1.0b1 # homeassistant.auth.mfa_modules.notify # homeassistant.auth.mfa_modules.totp diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 485caf8bfce..7ff9bd8c974 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -797,7 +797,7 @@ pyopenuv==1.0.9 pyopnsense==0.2.0 # homeassistant.components.opentherm_gw -pyotgw==0.6b1 +pyotgw==1.0b1 # homeassistant.auth.mfa_modules.notify # homeassistant.auth.mfa_modules.totp diff --git a/tests/components/opentherm_gw/test_config_flow.py b/tests/components/opentherm_gw/test_config_flow.py index a7be6ddcf6b..e0f4c6eda99 100644 --- a/tests/components/opentherm_gw/test_config_flow.py +++ b/tests/components/opentherm_gw/test_config_flow.py @@ -1,7 +1,7 @@ """Test the Opentherm Gateway config flow.""" import asyncio -from pyotgw.vars import OTGW_ABOUT +from pyotgw.vars import OTGW, OTGW_ABOUT from serial import SerialException from homeassistant import config_entries, data_entry_flow, setup @@ -15,6 +15,8 @@ from homeassistant.const import CONF_DEVICE, CONF_ID, CONF_NAME, PRECISION_HALVE from tests.async_mock import patch from tests.common import MockConfigEntry +MINIMAL_STATUS = {OTGW: {OTGW_ABOUT: "OpenTherm Gateway 4.2.5"}} + async def test_form_user(hass): """Test we get the form.""" @@ -32,8 +34,7 @@ async def test_form_user(hass): "homeassistant.components.opentherm_gw.async_setup_entry", return_value=True, ) as mock_setup_entry, patch( - "pyotgw.pyotgw.connect", - return_value={OTGW_ABOUT: "OpenTherm Gateway 4.2.5"}, + "pyotgw.pyotgw.connect", return_value=MINIMAL_STATUS ) as mock_pyotgw_connect, patch( "pyotgw.pyotgw.disconnect", return_value=None ) as mock_pyotgw_disconnect: @@ -65,8 +66,7 @@ async def test_form_import(hass): "homeassistant.components.opentherm_gw.async_setup_entry", return_value=True, ) as mock_setup_entry, patch( - "pyotgw.pyotgw.connect", - return_value={OTGW_ABOUT: "OpenTherm Gateway 4.2.5"}, + "pyotgw.pyotgw.connect", return_value=MINIMAL_STATUS ) as mock_pyotgw_connect, patch( "pyotgw.pyotgw.disconnect", return_value=None ) as mock_pyotgw_disconnect: @@ -108,8 +108,7 @@ async def test_form_duplicate_entries(hass): "homeassistant.components.opentherm_gw.async_setup_entry", return_value=True, ) as mock_setup_entry, patch( - "pyotgw.pyotgw.connect", - return_value={OTGW_ABOUT: "OpenTherm Gateway 4.2.5"}, + "pyotgw.pyotgw.connect", return_value=MINIMAL_STATUS ) as mock_pyotgw_connect, patch( "pyotgw.pyotgw.disconnect", return_value=None ) as mock_pyotgw_disconnect: