diff --git a/homeassistant/components/aftership/sensor.py b/homeassistant/components/aftership/sensor.py index 293fe4c647a..9b8a5637de2 100644 --- a/homeassistant/components/aftership/sensor.py +++ b/homeassistant/components/aftership/sensor.py @@ -154,7 +154,7 @@ class AfterShipSensor(Entity): async def _force_update(self): """Force update of data.""" await self.async_update(no_throttle=True) - await self.async_update_ha_state() + self.async_write_ha_state() @Throttle(MIN_TIME_BETWEEN_UPDATES) async def async_update(self, **kwargs): diff --git a/homeassistant/components/alert/__init__.py b/homeassistant/components/alert/__init__.py index 1f8176968d8..aa8d19dc40f 100644 --- a/homeassistant/components/alert/__init__.py +++ b/homeassistant/components/alert/__init__.py @@ -1,5 +1,4 @@ """Support for repeating alerts when conditions are met.""" -import asyncio from datetime import timedelta import logging @@ -144,9 +143,8 @@ async def async_setup(hass, config): DOMAIN, SERVICE_TOGGLE, async_handle_alert_service, schema=ALERT_SERVICE_SCHEMA ) - tasks = [alert.async_update_ha_state() for alert in entities] - if tasks: - await asyncio.wait(tasks) + for alert in entities: + alert.async_write_ha_state() return True @@ -318,13 +316,13 @@ class Alert(ToggleEntity): """Async Unacknowledge alert.""" _LOGGER.debug("Reset Alert: %s", self._name) self._ack = False - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Async Acknowledge alert.""" _LOGGER.debug("Acknowledged Alert: %s", self._name) self._ack = True - await self.async_update_ha_state() + self.async_write_ha_state() async def async_toggle(self, **kwargs): """Async toggle alert.""" diff --git a/homeassistant/components/anthemav/media_player.py b/homeassistant/components/anthemav/media_player.py index f4efd0de355..b7df82961c7 100644 --- a/homeassistant/components/anthemav/media_player.py +++ b/homeassistant/components/anthemav/media_player.py @@ -22,6 +22,10 @@ from homeassistant.const import ( ) from homeassistant.core import callback import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.dispatcher import ( + async_dispatcher_connect, + async_dispatcher_send, +) _LOGGER = logging.getLogger(__name__) @@ -60,7 +64,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= def async_anthemav_update_callback(message): """Receive notification from transport that new data exists.""" _LOGGER.debug("Received update callback from AVR: %s", message) - hass.async_create_task(device.async_update_ha_state()) + async_dispatcher_send(hass, DOMAIN) avr = await anthemav.Connection.create( host=host, port=port, update_callback=async_anthemav_update_callback @@ -87,6 +91,12 @@ class AnthemAVR(MediaPlayerDevice): def _lookup(self, propname, dval=None): return getattr(self.avr.protocol, propname, dval) + async def async_added_to_hass(self): + """When entity is added to hass.""" + self.async_on_remove( + async_dispatcher_connect(self.hass, DOMAIN, self.async_write_ha_state) + ) + @property def supported_features(self): """Flag media player features that are supported.""" diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index c19a0033f86..76fe619cc1c 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -389,7 +389,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity): pass self._last_triggered = utcnow() - await self.async_update_ha_state() + self.async_write_ha_state() async def async_will_remove_from_hass(self): """Remove listeners when removing automation from Home Assistant.""" diff --git a/homeassistant/components/buienradar/sensor.py b/homeassistant/components/buienradar/sensor.py index 5d709ab1e63..afa5013b339 100644 --- a/homeassistant/components/buienradar/sensor.py +++ b/homeassistant/components/buienradar/sensor.py @@ -33,6 +33,7 @@ from homeassistant.const import ( TIME_HOURS, UNIT_PERCENTAGE, ) +from homeassistant.core import callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.util import dt as dt_util @@ -260,7 +261,14 @@ class BrSensor(Entity): self.type, ) - def load_data(self, data): + @callback + def data_updated(self, data): + """Update data.""" + if self._load_data(data) and self.hass: + self.async_write_ha_state() + + @callback + def _load_data(self, data): """Load the sensor with relevant data.""" # Find sensor diff --git a/homeassistant/components/buienradar/util.py b/homeassistant/components/buienradar/util.py index 7d16f072b98..900b1caaf97 100644 --- a/homeassistant/components/buienradar/util.py +++ b/homeassistant/components/buienradar/util.py @@ -67,15 +67,12 @@ class BrData: async def update_devices(self): """Update all devices/sensors.""" - if self.devices: - tasks = [] - # Update all devices - for dev in self.devices: - if dev.load_data(self.data): - tasks.append(dev.async_update_ha_state()) + if not self.devices: + return - if tasks: - await asyncio.wait(tasks) + # Update all devices + for dev in self.devices: + dev.data_updated(self.data) async def schedule_update(self, minute=1): """Schedule an update after minute minutes.""" diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index 6bbf30b000e..0fc3e55a587 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -271,7 +271,7 @@ async def async_setup(hass, config): """Update tokens of the entities.""" for entity in component.entities: entity.async_update_token() - hass.async_create_task(entity.async_update_ha_state()) + entity.async_write_ha_state() hass.helpers.event.async_track_time_interval(update_tokens, TOKEN_CHANGE_INTERVAL) diff --git a/homeassistant/components/device_tracker/legacy.py b/homeassistant/components/device_tracker/legacy.py index 515b7cbc614..3157a00aa9f 100644 --- a/homeassistant/components/device_tracker/legacy.py +++ b/homeassistant/components/device_tracker/legacy.py @@ -175,7 +175,7 @@ class DeviceTracker: consider_home, ) if device.track: - await device.async_update_ha_state() + device.async_write_ha_state() return # Guard from calling see on entity registry entities. @@ -212,7 +212,7 @@ class DeviceTracker: ) if device.track: - await device.async_update_ha_state() + device.async_write_ha_state() self.hass.bus.async_fire( EVENT_NEW_DEVICE, @@ -259,7 +259,7 @@ class DeviceTracker: async def async_init_single_device(dev): """Init a single device_tracker entity.""" await dev.async_added_to_hass() - await dev.async_update_ha_state() + dev.async_write_ha_state() tasks = [] for device in self.devices.values(): diff --git a/homeassistant/components/dsmr/sensor.py b/homeassistant/components/dsmr/sensor.py index 257407bb763..484bd708489 100644 --- a/homeassistant/components/dsmr/sensor.py +++ b/homeassistant/components/dsmr/sensor.py @@ -15,8 +15,12 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, TIME_HOURS, ) -from homeassistant.core import CoreState -import homeassistant.helpers.config_validation as cv +from homeassistant.core import CoreState, callback +from homeassistant.helpers import config_validation as cv +from homeassistant.helpers.dispatcher import ( + async_dispatcher_connect, + async_dispatcher_send, +) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) @@ -109,12 +113,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities(devices) - def update_entities_telegram(telegram): - """Update entities with latest telegram and trigger state update.""" - # Make all device entities aware of new telegram - for device in devices: - device.telegram = telegram - hass.async_create_task(device.async_update_ha_state()) + update_entities_telegram = partial(async_dispatcher_send, hass, DOMAIN) # Creates an asyncio.Protocol factory for reading DSMR telegrams from # serial and calls update_entities_telegram to update entities on arrival @@ -188,6 +187,18 @@ class DSMREntity(Entity): self._config = config self.telegram = {} + async def async_added_to_hass(self): + """When entity is added to hass.""" + self.async_on_remove( + async_dispatcher_connect(self.hass, DOMAIN, self.update_data) + ) + + @callback + def update_data(self, telegram): + """Update data.""" + self.telegram = telegram + self.async_write_ha_state() + def get_dsmr_object_attr(self, attribute): """Read attribute from last received telegram for this DSMR object.""" # Make sure telegram contains an object for this entities obis diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index 09af5ad5c44..9a8d6177214 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -334,7 +334,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity): return self._target_temp = temperature await self._async_control_heating(force=True) - await self.async_update_ha_state() + self.async_write_ha_state() @property def min_temp(self): @@ -361,7 +361,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity): self._async_update_temp(new_state) await self._async_control_heating() - await self.async_update_ha_state() + self.async_write_ha_state() @callback def _async_switch_changed(self, entity_id, old_state, new_state): @@ -468,4 +468,4 @@ class GenericThermostat(ClimateDevice, RestoreEntity): self._target_temp = self._saved_target_temp await self._async_control_heating(force=True) - await self.async_update_ha_state() + self.async_write_ha_state() diff --git a/homeassistant/components/group/__init__.py b/homeassistant/components/group/__init__.py index f8a10017cab..53ce1c0634b 100644 --- a/homeassistant/components/group/__init__.py +++ b/homeassistant/components/group/__init__.py @@ -289,7 +289,7 @@ async def async_setup(hass, config): need_update = True if need_update: - await group.async_update_ha_state() + group.async_write_ha_state() return @@ -538,7 +538,7 @@ class Group(Entity): return self._async_update_group_state(new_state) - await self.async_update_ha_state() + self.async_write_ha_state() @property def _tracking_states(self): diff --git a/homeassistant/components/imap/sensor.py b/homeassistant/components/imap/sensor.py index ceef8acf7c3..a824d5f8ee9 100644 --- a/homeassistant/components/imap/sensor.py +++ b/homeassistant/components/imap/sensor.py @@ -130,7 +130,7 @@ class ImapSensor(Entity): try: if await self.connection(): await self.refresh_email_count() - await self.async_update_ha_state() + self.async_write_ha_state() idle = await self._connection.idle_start() await self._connection.wait_server_push() @@ -138,7 +138,7 @@ class ImapSensor(Entity): with async_timeout.timeout(10): await idle else: - await self.async_update_ha_state() + self.async_write_ha_state() except (AioImapException, asyncio.TimeoutError): self.disconnected() diff --git a/homeassistant/components/input_boolean/__init__.py b/homeassistant/components/input_boolean/__init__.py index 603aa826123..88fe94eac48 100644 --- a/homeassistant/components/input_boolean/__init__.py +++ b/homeassistant/components/input_boolean/__init__.py @@ -198,12 +198,12 @@ class InputBoolean(ToggleEntity, RestoreEntity): async def async_turn_on(self, **kwargs): """Turn the entity on.""" self._state = True - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Turn the entity off.""" self._state = False - await self.async_update_ha_state() + self.async_write_ha_state() async def async_update_config(self, config: typing.Dict) -> None: """Handle when the config is updated.""" diff --git a/homeassistant/components/knx/binary_sensor.py b/homeassistant/components/knx/binary_sensor.py index 94a171d9c2a..95e7e2cc400 100644 --- a/homeassistant/components/knx/binary_sensor.py +++ b/homeassistant/components/knx/binary_sensor.py @@ -116,7 +116,7 @@ class KNXBinarySensor(BinarySensorDevice): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/knx/climate.py b/homeassistant/components/knx/climate.py index 554ae59f397..919a20d0e4c 100644 --- a/homeassistant/components/knx/climate.py +++ b/homeassistant/components/knx/climate.py @@ -210,7 +210,7 @@ class KNXClimate(ClimateDevice): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) self.device.mode.register_device_updated_cb(after_update_callback) @@ -266,7 +266,7 @@ class KNXClimate(ClimateDevice): if temperature is None: return await self.device.set_target_temperature(temperature) - await self.async_update_ha_state() + self.async_write_ha_state() @property def hvac_mode(self) -> Optional[str]: @@ -304,7 +304,7 @@ class KNXClimate(ClimateDevice): elif self.device.mode.supports_operation_mode: knx_operation_mode = HVACOperationMode(OPERATION_MODES_INV.get(hvac_mode)) await self.device.mode.set_operation_mode(knx_operation_mode) - await self.async_update_ha_state() + self.async_write_ha_state() @property def preset_mode(self) -> Optional[str]: @@ -334,4 +334,4 @@ class KNXClimate(ClimateDevice): if self.device.mode.supports_operation_mode: knx_operation_mode = HVACOperationMode(PRESET_MODES_INV.get(preset_mode)) await self.device.mode.set_operation_mode(knx_operation_mode) - await self.async_update_ha_state() + self.async_write_ha_state() diff --git a/homeassistant/components/knx/cover.py b/homeassistant/components/knx/cover.py index 3c67e2fd558..5c4aa762b5c 100644 --- a/homeassistant/components/knx/cover.py +++ b/homeassistant/components/knx/cover.py @@ -108,7 +108,7 @@ class KNXCover(CoverDevice): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/knx/light.py b/homeassistant/components/knx/light.py index 6eb539c19ce..efd1a74f5a2 100644 --- a/homeassistant/components/knx/light.py +++ b/homeassistant/components/knx/light.py @@ -154,7 +154,7 @@ class KNXLight(Light): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/knx/sensor.py b/homeassistant/components/knx/sensor.py index a0a0f6ea18d..2679170b03d 100644 --- a/homeassistant/components/knx/sensor.py +++ b/homeassistant/components/knx/sensor.py @@ -69,7 +69,7 @@ class KNXSensor(Entity): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/knx/switch.py b/homeassistant/components/knx/switch.py index e9a0df5c983..ae798bf4c08 100644 --- a/homeassistant/components/knx/switch.py +++ b/homeassistant/components/knx/switch.py @@ -65,7 +65,7 @@ class KNXSwitch(SwitchDevice): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.device.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/lcn/cover.py b/homeassistant/components/lcn/cover.py index ba831c3a1a9..61ae05fa010 100644 --- a/homeassistant/components/lcn/cover.py +++ b/homeassistant/components/lcn/cover.py @@ -74,21 +74,21 @@ class LcnOutputsCover(LcnDevice, CoverDevice): state = pypck.lcn_defs.MotorStateModifier.DOWN self.address_connection.control_motors_outputs(state) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_open_cover(self, **kwargs): """Open the cover.""" self._closed = False state = pypck.lcn_defs.MotorStateModifier.UP self.address_connection.control_motors_outputs(state, self.reverse_time) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_stop_cover(self, **kwargs): """Stop the cover.""" self._closed = None state = pypck.lcn_defs.MotorStateModifier.STOP self.address_connection.control_motors_outputs(state, self.reverse_time) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set cover states when LCN input object (command) is received.""" @@ -140,7 +140,7 @@ class LcnRelayCover(LcnDevice, CoverDevice): states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4 states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.DOWN self.address_connection.control_motors_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_open_cover(self, **kwargs): """Open the cover.""" @@ -148,7 +148,7 @@ class LcnRelayCover(LcnDevice, CoverDevice): states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4 states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.UP self.address_connection.control_motors_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_stop_cover(self, **kwargs): """Stop the cover.""" @@ -156,7 +156,7 @@ class LcnRelayCover(LcnDevice, CoverDevice): states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4 states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.STOP self.address_connection.control_motors_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set cover states when LCN input object (command) is received.""" diff --git a/homeassistant/components/lcn/light.py b/homeassistant/components/lcn/light.py index 40a592f89c9..7f1cd547c02 100644 --- a/homeassistant/components/lcn/light.py +++ b/homeassistant/components/lcn/light.py @@ -102,7 +102,7 @@ class LcnOutputLight(LcnDevice, Light): transition = self._transition self.address_connection.dim_output(self.output.value, percent, transition) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Turn the entity off.""" @@ -117,7 +117,7 @@ class LcnOutputLight(LcnDevice, Light): self._is_dimming_to_zero = bool(transition) self.address_connection.dim_output(self.output.value, 0, transition) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set light state when LCN input object (command) is received.""" @@ -164,7 +164,7 @@ class LcnRelayLight(LcnDevice, Light): states[self.output.value] = pypck.lcn_defs.RelayStateModifier.ON self.address_connection.control_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Turn the entity off.""" @@ -174,7 +174,7 @@ class LcnRelayLight(LcnDevice, Light): states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF self.address_connection.control_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set light state when LCN input object (command) is received.""" diff --git a/homeassistant/components/lcn/switch.py b/homeassistant/components/lcn/switch.py index b0e16e412b3..a2adda95b3b 100644 --- a/homeassistant/components/lcn/switch.py +++ b/homeassistant/components/lcn/switch.py @@ -59,13 +59,13 @@ class LcnOutputSwitch(LcnDevice, SwitchDevice): """Turn the entity on.""" self._is_on = True self.address_connection.dim_output(self.output.value, 100, 0) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Turn the entity off.""" self._is_on = False self.address_connection.dim_output(self.output.value, 0, 0) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set switch state when LCN input object (command) is received.""" @@ -107,7 +107,7 @@ class LcnRelaySwitch(LcnDevice, SwitchDevice): states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8 states[self.output.value] = pypck.lcn_defs.RelayStateModifier.ON self.address_connection.control_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() async def async_turn_off(self, **kwargs): """Turn the entity off.""" @@ -116,7 +116,7 @@ class LcnRelaySwitch(LcnDevice, SwitchDevice): states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8 states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF self.address_connection.control_relays(states) - await self.async_update_ha_state() + self.async_write_ha_state() def input_received(self, input_obj): """Set switch state when LCN input object (command) is received.""" diff --git a/homeassistant/components/lifx/light.py b/homeassistant/components/lifx/light.py index 5bc0c1bc53b..e5bbe88edfb 100644 --- a/homeassistant/components/lifx/light.py +++ b/homeassistant/components/lifx/light.py @@ -435,7 +435,7 @@ class LIFXManager: entity = self.entities[bulb.mac_addr] _LOGGER.debug("%s unregister", entity.who) entity.registered = False - self.hass.async_create_task(entity.async_update_ha_state()) + entity.async_write_ha_state() class AwaitAioLIFX: @@ -573,7 +573,7 @@ class LIFXLight(Light): """Request new status and push it to hass.""" self.postponed_update = None await self.async_update() - await self.async_update_ha_state() + self.async_write_ha_state() async def update_during_transition(self, when): """Update state at the start and end of a transition.""" diff --git a/homeassistant/components/microsoft_face/__init__.py b/homeassistant/components/microsoft_face/__init__.py index 1bc9c116cda..16b25e4f85d 100644 --- a/homeassistant/components/microsoft_face/__init__.py +++ b/homeassistant/components/microsoft_face/__init__.py @@ -96,7 +96,7 @@ async def async_setup(hass, config): face.store[g_id] = {} entities[g_id] = MicrosoftFaceGroupEntity(hass, face, g_id, name) - await entities[g_id].async_update_ha_state() + entities[g_id].async_write_ha_state() except HomeAssistantError as err: _LOGGER.error("Can't create group '%s' with error: %s", g_id, err) @@ -145,7 +145,7 @@ async def async_setup(hass, config): ) face.store[g_id][name] = user_data["personId"] - await entities[g_id].async_update_ha_state() + entities[g_id].async_write_ha_state() except HomeAssistantError as err: _LOGGER.error("Can't create person '%s' with error: %s", name, err) @@ -163,7 +163,7 @@ async def async_setup(hass, config): await face.call_api("delete", f"persongroups/{g_id}/persons/{p_id}") face.store[g_id].pop(name) - await entities[g_id].async_update_ha_state() + entities[g_id].async_write_ha_state() except HomeAssistantError as err: _LOGGER.error("Can't delete person '%s' with error: %s", p_id, err) diff --git a/homeassistant/components/netio/switch.py b/homeassistant/components/netio/switch.py index 4c9b6343f2b..6baa3a63f9f 100644 --- a/homeassistant/components/netio/switch.py +++ b/homeassistant/components/netio/switch.py @@ -92,7 +92,6 @@ class NetioApiView(HomeAssistantView): @callback def get(self, request, host): """Request handler.""" - hass = request.app["hass"] data = request.query states, consumptions, cumulated_consumptions, start_dates = [], [], [], [] @@ -121,7 +120,7 @@ class NetioApiView(HomeAssistantView): ndev.start_dates = start_dates for dev in DEVICES[host].entities: - hass.async_create_task(dev.async_update_ha_state()) + dev.async_write_ha_state() return self.json(True) diff --git a/homeassistant/components/owntracks/messages.py b/homeassistant/components/owntracks/messages.py index 42f1f62d10a..8814c8968a0 100644 --- a/homeassistant/components/owntracks/messages.py +++ b/homeassistant/components/owntracks/messages.py @@ -314,7 +314,7 @@ async def async_handle_waypoint(hass, name_base, waypoint): ) zone.hass = hass zone.entity_id = entity_id - await zone.async_update_ha_state() + zone.async_write_ha_state() @HANDLERS.register("waypoint") diff --git a/homeassistant/components/rflink/__init__.py b/homeassistant/components/rflink/__init__.py index b33f2623b9d..76b225bd93a 100644 --- a/homeassistant/components/rflink/__init__.py +++ b/homeassistant/components/rflink/__init__.py @@ -498,7 +498,7 @@ class RflinkCommand(RflinkDevice): await self._async_send_command(cmd, self._signal_repetitions) # Update state of entity - await self.async_update_ha_state() + self.async_write_ha_state() def cancel_queued_send_commands(self): """Cancel queued signal repetition commands. diff --git a/homeassistant/components/saj/sensor.py b/homeassistant/components/saj/sensor.py index 55c2371aabb..fb0df36d4cb 100644 --- a/homeassistant/components/saj/sensor.py +++ b/homeassistant/components/saj/sensor.py @@ -1,5 +1,4 @@ """SAJ solar inverter interface.""" -import asyncio from datetime import date import logging @@ -100,8 +99,6 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async def async_saj(): """Update all the SAJ sensors.""" - tasks = [] - values = await saj.read(sensor_def) for sensor in hass_sensors: @@ -118,11 +115,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= not sensor.per_day_basis and not sensor.per_total_basis ): state_unknown = True - task = sensor.async_update_values(unknown_state=state_unknown) - if task: - tasks.append(task) - if tasks: - await asyncio.wait(tasks) + sensor.async_update_values(unknown_state=state_unknown) + return values def start_update_interval(event): @@ -237,7 +231,8 @@ class SAJsensor(Entity): update = True self._state = None - return self.async_update_ha_state() if update else None + if update: + self.async_write_ha_state() @property def unique_id(self): diff --git a/homeassistant/components/script/__init__.py b/homeassistant/components/script/__init__.py index 9384c58db81..6efd4c849aa 100644 --- a/homeassistant/components/script/__init__.py +++ b/homeassistant/components/script/__init__.py @@ -243,7 +243,7 @@ class ScriptEntity(ToggleEntity): self.icon = icon self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script( - hass, sequence, name, self.async_update_ha_state, logger=_LOGGER + hass, sequence, name, self.async_write_ha_state, logger=_LOGGER ) @property diff --git a/homeassistant/components/sma/sensor.py b/homeassistant/components/sma/sensor.py index 40ec4179cd1..e5afa272c40 100644 --- a/homeassistant/components/sma/sensor.py +++ b/homeassistant/components/sma/sensor.py @@ -1,5 +1,4 @@ """SMA Solar Webconnect interface.""" -import asyncio from datetime import timedelta import logging @@ -163,13 +162,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= return backoff_step = 0 - tasks = [] for sensor in hass_sensors: - task = sensor.async_update_values() - if task: - tasks.append(task) - if tasks: - await asyncio.wait(tasks) + sensor.async_update_values() interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=5) async_track_time_interval(hass, async_sma, interval) @@ -226,7 +220,8 @@ class SMAsensor(Entity): update = True self._state = self._sensor.value - return self.async_update_ha_state() if update else None + if update: + self.async_write_ha_state() @property def unique_id(self): diff --git a/homeassistant/components/songpal/media_player.py b/homeassistant/components/songpal/media_player.py index 27a81b2a667..d11ff84a73c 100644 --- a/homeassistant/components/songpal/media_player.py +++ b/homeassistant/components/songpal/media_player.py @@ -159,21 +159,21 @@ class SongpalDevice(MediaPlayerDevice): _LOGGER.debug("Volume changed: %s", volume) self._volume = volume.volume self._is_muted = volume.mute - await self.async_update_ha_state() + self.async_write_ha_state() async def _source_changed(content: ContentChange): _LOGGER.debug("Source changed: %s", content) if content.is_input: self._active_source = self._sources[content.source] _LOGGER.debug("New active source: %s", self._active_source) - await self.async_update_ha_state() + self.async_write_ha_state() else: _LOGGER.debug("Got non-handled content change: %s", content) async def _power_changed(power: PowerChange): _LOGGER.debug("Power changed: %s", power) self._state = power.status - await self.async_update_ha_state() + self.async_write_ha_state() async def _try_reconnect(connect: ConnectChange): _LOGGER.error( @@ -181,7 +181,7 @@ class SongpalDevice(MediaPlayerDevice): ) self._available = False self.dev.clear_notification_callbacks() - await self.async_update_ha_state() + self.async_write_ha_state() # Try to reconnect forever, a successful reconnect will initialize # the websocket connection again. diff --git a/homeassistant/components/utility_meter/__init__.py b/homeassistant/components/utility_meter/__init__.py index ef9d9b1ddce..24bfd77f762 100644 --- a/homeassistant/components/utility_meter/__init__.py +++ b/homeassistant/components/utility_meter/__init__.py @@ -184,11 +184,11 @@ class TariffSelect(RestoreEntity): ) return self._current_tariff = tariff - await self.async_update_ha_state() + self.async_write_ha_state() async def async_next_tariff(self): """Offset current index.""" current_index = self._tariffs.index(self._current_tariff) new_index = (current_index + 1) % len(self._tariffs) self._current_tariff = self._tariffs[new_index] - await self.async_update_ha_state() + self.async_write_ha_state() diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index ad1b27f1fe0..c891c698cf6 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -217,7 +217,7 @@ class UtilityMeterSensor(RestoreEntity): self._last_reset = dt_util.now() self._last_period = str(self._state) self._state = 0 - await self.async_update_ha_state() + self.async_write_ha_state() async def async_calibrate(self, value): """Calibrate the Utility Meter with a given value.""" @@ -253,7 +253,7 @@ class UtilityMeterSensor(RestoreEntity): self._unit_of_measurement = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) self._last_period = state.attributes.get(ATTR_LAST_PERIOD) self._last_reset = state.attributes.get(ATTR_LAST_RESET) - await self.async_update_ha_state() + self.async_write_ha_state() if state.attributes.get(ATTR_STATUS) == PAUSED: # Fake cancellation function to init the meter paused self._collecting = lambda: None diff --git a/homeassistant/components/velux/cover.py b/homeassistant/components/velux/cover.py index c9b4aa53fe5..fe5b1dcf3af 100644 --- a/homeassistant/components/velux/cover.py +++ b/homeassistant/components/velux/cover.py @@ -38,7 +38,7 @@ class VeluxCover(CoverDevice): async def after_update_callback(device): """Call after device was updated.""" - await self.async_update_ha_state() + self.async_write_ha_state() self.node.register_device_updated_cb(after_update_callback) diff --git a/homeassistant/components/yr/sensor.py b/homeassistant/components/yr/sensor.py index c6aaeea7ac9..9955a650cd3 100644 --- a/homeassistant/components/yr/sensor.py +++ b/homeassistant/components/yr/sensor.py @@ -96,11 +96,13 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= dev = [] for sensor_type in config[CONF_MONITORED_CONDITIONS]: dev.append(YrSensor(name, sensor_type)) - async_add_entities(dev) weather = YrData(hass, coordinates, forecast, dev) - async_track_utc_time_change(hass, weather.updating_devices, minute=31, second=0) + async_track_utc_time_change( + hass, weather.updating_devices, minute=randrange(60), second=0 + ) await weather.fetching_data() + async_add_entities(dev) class YrSensor(Entity): @@ -234,7 +236,6 @@ class YrData: ordered_entries.sort(key=lambda item: item[0]) # Update all devices - tasks = [] if ordered_entries: for dev in self.devices: new_state = None @@ -274,7 +275,5 @@ class YrData: # pylint: disable=protected-access if new_state != dev._state: dev._state = new_state - tasks.append(dev.async_update_ha_state()) - - if tasks: - await asyncio.wait(tasks) + if dev.hass: + dev.async_write_ha_state() diff --git a/homeassistant/components/zwave/node_entity.py b/homeassistant/components/zwave/node_entity.py index 3fb5491ea62..f1b76075ae8 100644 --- a/homeassistant/components/zwave/node_entity.py +++ b/homeassistant/components/zwave/node_entity.py @@ -87,7 +87,7 @@ class ZWaveBaseEntity(Entity): @callback def do_update(): """Really update.""" - self.hass.async_add_job(self.async_update_ha_state) + self.async_write_ha_state() self._update_scheduled = False self._update_scheduled = True diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 4cbb7a23496..bf6db55a2da 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -444,7 +444,7 @@ class EntityPlatform: await entity.async_internal_added_to_hass() await entity.async_added_to_hass() - await entity.async_update_ha_state() + entity.async_write_ha_state() async def async_reset(self) -> None: """Remove all entities and reset data. diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 145bb42af5b..c724b9e890d 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -36,7 +36,6 @@ from homeassistant.core import ( Context, HomeAssistant, callback, - is_callback, ) from homeassistant.helpers import ( condition, @@ -679,10 +678,7 @@ class Script: def _changed(self): if self.change_listener: - if is_callback(self.change_listener): - self.change_listener() - else: - self._hass.async_add_job(self.change_listener) + self._hass.async_run_job(self.change_listener) @property def is_running(self) -> bool: diff --git a/tests/components/zwave/test_node_entity.py b/tests/components/zwave/test_node_entity.py index 9136b53ff0b..28161cfa18b 100644 --- a/tests/components/zwave/test_node_entity.py +++ b/tests/components/zwave/test_node_entity.py @@ -13,6 +13,7 @@ import tests.mock.zwave as mock_zwave async def test_maybe_schedule_update(hass, mock_openzwave): """Test maybe schedule update.""" base_entity = node_entity.ZWaveBaseEntity() + base_entity.entity_id = "zwave.bla" base_entity.hass = hass with patch.object(hass.loop, "call_later") as mock_call_later: @@ -21,12 +22,12 @@ async def test_maybe_schedule_update(hass, mock_openzwave): base_entity._schedule_update() assert len(mock_call_later.mock_calls) == 1 + assert base_entity._update_scheduled is True do_update = mock_call_later.mock_calls[0][1][1] - with patch.object(hass, "async_add_job") as mock_add_job: - do_update() - assert mock_add_job.called + do_update() + assert base_entity._update_scheduled is False base_entity._schedule_update() assert len(mock_call_later.mock_calls) == 2 diff --git a/tests/helpers/test_entity_component.py b/tests/helpers/test_entity_component.py index 306402cd2b9..1c5224d89c3 100644 --- a/tests/helpers/test_entity_component.py +++ b/tests/helpers/test_entity_component.py @@ -379,15 +379,16 @@ async def test_update_entity(hass): """Test that we can update an entity with the helper.""" component = EntityComponent(_LOGGER, DOMAIN, hass) entity = MockEntity() + entity.async_write_ha_state = Mock() entity.async_update_ha_state = Mock(return_value=mock_coro()) await component.async_add_entities([entity]) # Called as part of async_add_entities - assert len(entity.async_update_ha_state.mock_calls) == 1 + assert len(entity.async_write_ha_state.mock_calls) == 1 await hass.helpers.entity_component.async_update_entity(entity.entity_id) - assert len(entity.async_update_ha_state.mock_calls) == 2 + assert len(entity.async_update_ha_state.mock_calls) == 1 assert entity.async_update_ha_state.mock_calls[-1][1][0] is True