Change integration modbus to use _attr variables (#53511)

This commit is contained in:
jan iversen 2021-07-26 21:20:34 +02:00 committed by GitHub
parent 80aaebb761
commit cfb0def718
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 110 deletions

View File

@ -60,17 +60,19 @@ class BasePlatform(Entity):
def __init__(self, hub: ModbusHub, entry: dict[str, Any]) -> None:
"""Initialize the Modbus binary sensor."""
self._hub = hub
self._name = entry[CONF_NAME]
self._slave = entry.get(CONF_SLAVE)
self._address = int(entry[CONF_ADDRESS])
self._device_class = entry.get(CONF_DEVICE_CLASS)
self._input_type = entry[CONF_INPUT_TYPE]
self._value = None
self._available = True
self._scan_interval = int(entry[CONF_SCAN_INTERVAL])
self._available = self._scan_interval == 0
self._call_active = False
self._attr_name = entry[CONF_NAME]
self._attr_should_poll = False
self._attr_device_class = entry.get(CONF_DEVICE_CLASS)
self._attr_available = True
self._attr_unit_of_measurement = None
@abstractmethod
async def async_update(self, now=None):
"""Virtual function to be overwritten."""
@ -82,26 +84,6 @@ class BasePlatform(Entity):
self.hass, self.async_update, timedelta(seconds=self._scan_interval)
)
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def should_poll(self):
"""Return True if entity has to be polled for state."""
return False
@property
def device_class(self) -> str | None:
"""Return the device class of the sensor."""
return self._device_class
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self._available
class BaseStructPlatform(BasePlatform, RestoreEntity):
"""Base class representing a sensor/climate."""
@ -229,11 +211,11 @@ class BaseSwitch(BasePlatform, RestoreEntity):
self._slave, self._address, command, self._write_type
)
if result is None:
self._available = False
self._attr_available = False
self.async_write_ha_state()
return
self._available = True
self._attr_available = True
if not self._verify_active:
self._is_on = command == self.command_on
self.async_write_ha_state()
@ -253,7 +235,7 @@ class BaseSwitch(BasePlatform, RestoreEntity):
# remark "now" is a dummy parameter to avoid problems with
# async_track_time_interval
if not self._verify_active:
self._available = True
self._attr_available = True
self.async_write_ha_state()
return
@ -266,11 +248,11 @@ class BaseSwitch(BasePlatform, RestoreEntity):
)
self._call_active = False
if result is None:
self._available = False
self._attr_available = False
self.async_write_ha_state()
return
self._available = True
self._attr_available = True
if self._verify_type == CALL_TYPE_COIL:
self._is_on = bool(result.bits[0] & 1)
else:

View File

@ -64,10 +64,10 @@ class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity):
)
self._call_active = False
if result is None:
self._available = False
self._attr_available = False
self.async_write_ha_state()
return
self._value = result.bits[0] & 1
self._available = True
self._attr_available = True
self.async_write_ha_state()

View File

@ -76,76 +76,37 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
"""Initialize the modbus thermostat."""
super().__init__(hub, config)
self._target_temperature_register = config[CONF_TARGET_TEMP]
self._target_temperature = None
self._current_temperature = None
self._structure = config[CONF_STRUCTURE]
self._unit = config[CONF_TEMPERATURE_UNIT]
self._max_temp = config[CONF_MAX_TEMP]
self._min_temp = config[CONF_MIN_TEMP]
self._temp_step = config[CONF_STEP]
self._structure = config[CONF_STRUCTURE]
self._attr_supported_features = SUPPORT_TARGET_TEMPERATURE
self._attr_hvac_mode = HVAC_MODE_AUTO
self._attr_hvac_modes = [HVAC_MODE_AUTO]
self._attr_current_temperature = None
self._attr_target_temperature = None
self._attr_temperature_unit = (
TEMP_FAHRENHEIT if self._unit == "F" else TEMP_CELSIUS
)
self._attr_precision = (
PRECISION_TENTHS if self._precision >= 1 else PRECISION_WHOLE
)
self._attr_min_temp = config[CONF_MIN_TEMP]
self._attr_max_temp = config[CONF_MAX_TEMP]
self._attr_target_temperature_step = config[CONF_TARGET_TEMP]
self._attr_target_temperature_step = config[CONF_STEP]
async def async_added_to_hass(self):
"""Handle entity which will be added."""
await self.async_base_added_to_hass()
state = await self.async_get_last_state()
if state and state.attributes.get(ATTR_TEMPERATURE):
self._target_temperature = float(state.attributes[ATTR_TEMPERATURE])
@property
def supported_features(self):
"""Return the list of supported features."""
return SUPPORT_TARGET_TEMPERATURE
@property
def hvac_mode(self):
"""Return the current HVAC mode."""
return HVAC_MODE_AUTO
@property
def hvac_modes(self):
"""Return the possible HVAC modes."""
return [HVAC_MODE_AUTO]
self._attr_target_temperature = float(state.attributes[ATTR_TEMPERATURE])
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode."""
# Home Assistant expects this method.
# We'll keep it here to avoid getting exceptions.
@property
def current_temperature(self):
"""Return the current temperature."""
return self._current_temperature
@property
def target_temperature(self):
"""Return the target temperature."""
return self._target_temperature
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_FAHRENHEIT if self._unit == "F" else TEMP_CELSIUS
@property
def precision(self) -> float:
"""Return the precision of the system."""
return PRECISION_TENTHS if self._precision >= 1 else PRECISION_WHOLE
@property
def min_temp(self):
"""Return the minimum temperature."""
return self._min_temp
@property
def max_temp(self):
"""Return the maximum temperature."""
return self._max_temp
@property
def target_temperature_step(self):
"""Return the supported step of target temperature."""
return self._temp_step
async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
if ATTR_TEMPERATURE not in kwargs:
@ -174,7 +135,7 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
registers,
CALL_TYPE_WRITE_REGISTERS,
)
self._available = result is not None
self._attr_available = result is not None
await self.async_update()
async def async_update(self, now=None):
@ -186,10 +147,10 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
if self._call_active:
return
self._call_active = True
self._target_temperature = await self._async_read_register(
self._attr_target_temperature = await self._async_read_register(
CALL_TYPE_REGISTER_HOLDING, self._target_temperature_register
)
self._current_temperature = await self._async_read_register(
self._attr_current_temperature = await self._async_read_register(
self._input_type, self._address
)
self._call_active = False
@ -201,12 +162,12 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
self._slave, register, self._count, register_type
)
if result is None:
self._available = False
self._attr_available = False
return -1
self.unpack_structure_result(result.registers)
self._available = True
self._attr_available = True
if self._value is None:
return None

View File

@ -73,6 +73,8 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
self._status_register = config.get(CONF_STATUS_REGISTER)
self._status_register_type = config[CONF_STATUS_REGISTER_TYPE]
self._attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
# If we read cover status from coil, and not from optional status register,
# we interpret boolean value False as closed cover, and value True as open cover.
# Intermediate states are not supported in such a setup.
@ -109,11 +111,6 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
}
self._value = convert[state.state]
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE
@property
def is_opening(self):
"""Return if the cover is opening or not."""
@ -134,7 +131,7 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
result = await self._hub.async_pymodbus_call(
self._slave, self._write_address, self._state_open, self._write_type
)
self._available = result is not None
self._attr_available = result is not None
await self.async_update()
async def async_close_cover(self, **kwargs: Any) -> None:
@ -142,7 +139,7 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
result = await self._hub.async_pymodbus_call(
self._slave, self._write_address, self._state_closed, self._write_type
)
self._available = result is not None
self._attr_available = result is not None
await self.async_update()
async def async_update(self, now=None):
@ -158,10 +155,10 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
)
self._call_active = False
if result is None:
self._available = False
self._attr_available = False
self.async_write_ha_state()
return None
self._available = True
self._attr_available = True
if self._input_type == CALL_TYPE_COIL:
self._value = bool(result.bits[0] & 1)
else:

View File

@ -47,7 +47,7 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity):
) -> None:
"""Initialize the modbus register sensor."""
super().__init__(hub, entry)
self._unit_of_measurement = entry.get(CONF_UNIT_OF_MEASUREMENT)
self._attr_unit_of_measurement = entry.get(CONF_UNIT_OF_MEASUREMENT)
async def async_added_to_hass(self):
"""Handle entity which will be added."""
@ -61,11 +61,6 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity):
"""Return the state of the sensor."""
return self._value
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit_of_measurement
async def async_update(self, now=None):
"""Update the state of the sensor."""
# remark "now" is a dummy parameter to avoid problems with
@ -74,10 +69,10 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity):
self._slave, self._address, self._count, self._input_type
)
if result is None:
self._available = False
self._attr_available = False
self.async_write_ha_state()
return
self.unpack_structure_result(result.registers)
self._available = True
self._attr_available = True
self.async_write_ha_state()