Directly call write state 2 (#33513)

* Directly call async_write_ha_state pt2

* Directly call async_write_ha_state pt2

* Fix mock

* Address comments
This commit is contained in:
Paulus Schoutsen 2020-04-03 00:34:50 -07:00 committed by GitHub
parent 83cc871edf
commit aef06a3544
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 127 additions and 117 deletions

View file

@ -154,7 +154,7 @@ class AfterShipSensor(Entity):
async def _force_update(self): async def _force_update(self):
"""Force update of data.""" """Force update of data."""
await self.async_update(no_throttle=True) await self.async_update(no_throttle=True)
await self.async_update_ha_state() self.async_write_ha_state()
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self, **kwargs): async def async_update(self, **kwargs):

View file

@ -1,5 +1,4 @@
"""Support for repeating alerts when conditions are met.""" """Support for repeating alerts when conditions are met."""
import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
@ -144,9 +143,8 @@ async def async_setup(hass, config):
DOMAIN, SERVICE_TOGGLE, async_handle_alert_service, schema=ALERT_SERVICE_SCHEMA DOMAIN, SERVICE_TOGGLE, async_handle_alert_service, schema=ALERT_SERVICE_SCHEMA
) )
tasks = [alert.async_update_ha_state() for alert in entities] for alert in entities:
if tasks: alert.async_write_ha_state()
await asyncio.wait(tasks)
return True return True
@ -318,13 +316,13 @@ class Alert(ToggleEntity):
"""Async Unacknowledge alert.""" """Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name) _LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False self._ack = False
await self.async_update_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Async Acknowledge alert.""" """Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name) _LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True self._ack = True
await self.async_update_ha_state() self.async_write_ha_state()
async def async_toggle(self, **kwargs): async def async_toggle(self, **kwargs):
"""Async toggle alert.""" """Async toggle alert."""

View file

@ -22,6 +22,10 @@ from homeassistant.const import (
) )
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect,
async_dispatcher_send,
)
_LOGGER = logging.getLogger(__name__) _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): def async_anthemav_update_callback(message):
"""Receive notification from transport that new data exists.""" """Receive notification from transport that new data exists."""
_LOGGER.debug("Received update callback from AVR: %s", message) _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( avr = await anthemav.Connection.create(
host=host, port=port, update_callback=async_anthemav_update_callback host=host, port=port, update_callback=async_anthemav_update_callback
@ -87,6 +91,12 @@ class AnthemAVR(MediaPlayerDevice):
def _lookup(self, propname, dval=None): def _lookup(self, propname, dval=None):
return getattr(self.avr.protocol, propname, dval) 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 @property
def supported_features(self): def supported_features(self):
"""Flag media player features that are supported.""" """Flag media player features that are supported."""

View file

@ -389,7 +389,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
pass pass
self._last_triggered = utcnow() self._last_triggered = utcnow()
await self.async_update_ha_state() self.async_write_ha_state()
async def async_will_remove_from_hass(self): async def async_will_remove_from_hass(self):
"""Remove listeners when removing automation from Home Assistant.""" """Remove listeners when removing automation from Home Assistant."""

View file

@ -33,6 +33,7 @@ from homeassistant.const import (
TIME_HOURS, TIME_HOURS,
UNIT_PERCENTAGE, UNIT_PERCENTAGE,
) )
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -260,7 +261,14 @@ class BrSensor(Entity):
self.type, 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.""" """Load the sensor with relevant data."""
# Find sensor # Find sensor

View file

@ -67,15 +67,12 @@ class BrData:
async def update_devices(self): async def update_devices(self):
"""Update all devices/sensors.""" """Update all devices/sensors."""
if self.devices: if not self.devices:
tasks = [] return
# Update all devices
for dev in self.devices:
if dev.load_data(self.data):
tasks.append(dev.async_update_ha_state())
if tasks: # Update all devices
await asyncio.wait(tasks) for dev in self.devices:
dev.data_updated(self.data)
async def schedule_update(self, minute=1): async def schedule_update(self, minute=1):
"""Schedule an update after minute minutes.""" """Schedule an update after minute minutes."""

View file

@ -271,7 +271,7 @@ async def async_setup(hass, config):
"""Update tokens of the entities.""" """Update tokens of the entities."""
for entity in component.entities: for entity in component.entities:
entity.async_update_token() 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) hass.helpers.event.async_track_time_interval(update_tokens, TOKEN_CHANGE_INTERVAL)

View file

@ -175,7 +175,7 @@ class DeviceTracker:
consider_home, consider_home,
) )
if device.track: if device.track:
await device.async_update_ha_state() device.async_write_ha_state()
return return
# Guard from calling see on entity registry entities. # Guard from calling see on entity registry entities.
@ -212,7 +212,7 @@ class DeviceTracker:
) )
if device.track: if device.track:
await device.async_update_ha_state() device.async_write_ha_state()
self.hass.bus.async_fire( self.hass.bus.async_fire(
EVENT_NEW_DEVICE, EVENT_NEW_DEVICE,
@ -259,7 +259,7 @@ class DeviceTracker:
async def async_init_single_device(dev): async def async_init_single_device(dev):
"""Init a single device_tracker entity.""" """Init a single device_tracker entity."""
await dev.async_added_to_hass() await dev.async_added_to_hass()
await dev.async_update_ha_state() dev.async_write_ha_state()
tasks = [] tasks = []
for device in self.devices.values(): for device in self.devices.values():

View file

@ -15,8 +15,12 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
TIME_HOURS, TIME_HOURS,
) )
from homeassistant.core import CoreState from homeassistant.core import CoreState, callback
import homeassistant.helpers.config_validation as cv 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 from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -109,12 +113,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities(devices) async_add_entities(devices)
def update_entities_telegram(telegram): update_entities_telegram = partial(async_dispatcher_send, hass, DOMAIN)
"""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())
# Creates an asyncio.Protocol factory for reading DSMR telegrams from # Creates an asyncio.Protocol factory for reading DSMR telegrams from
# serial and calls update_entities_telegram to update entities on arrival # serial and calls update_entities_telegram to update entities on arrival
@ -188,6 +187,18 @@ class DSMREntity(Entity):
self._config = config self._config = config
self.telegram = {} 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): def get_dsmr_object_attr(self, attribute):
"""Read attribute from last received telegram for this DSMR object.""" """Read attribute from last received telegram for this DSMR object."""
# Make sure telegram contains an object for this entities obis # Make sure telegram contains an object for this entities obis

View file

@ -334,7 +334,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity):
return return
self._target_temp = temperature self._target_temp = temperature
await self._async_control_heating(force=True) await self._async_control_heating(force=True)
await self.async_update_ha_state() self.async_write_ha_state()
@property @property
def min_temp(self): def min_temp(self):
@ -361,7 +361,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity):
self._async_update_temp(new_state) self._async_update_temp(new_state)
await self._async_control_heating() await self._async_control_heating()
await self.async_update_ha_state() self.async_write_ha_state()
@callback @callback
def _async_switch_changed(self, entity_id, old_state, new_state): 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 self._target_temp = self._saved_target_temp
await self._async_control_heating(force=True) await self._async_control_heating(force=True)
await self.async_update_ha_state() self.async_write_ha_state()

View file

@ -289,7 +289,7 @@ async def async_setup(hass, config):
need_update = True need_update = True
if need_update: if need_update:
await group.async_update_ha_state() group.async_write_ha_state()
return return
@ -538,7 +538,7 @@ class Group(Entity):
return return
self._async_update_group_state(new_state) self._async_update_group_state(new_state)
await self.async_update_ha_state() self.async_write_ha_state()
@property @property
def _tracking_states(self): def _tracking_states(self):

View file

@ -130,7 +130,7 @@ class ImapSensor(Entity):
try: try:
if await self.connection(): if await self.connection():
await self.refresh_email_count() await self.refresh_email_count()
await self.async_update_ha_state() self.async_write_ha_state()
idle = await self._connection.idle_start() idle = await self._connection.idle_start()
await self._connection.wait_server_push() await self._connection.wait_server_push()
@ -138,7 +138,7 @@ class ImapSensor(Entity):
with async_timeout.timeout(10): with async_timeout.timeout(10):
await idle await idle
else: else:
await self.async_update_ha_state() self.async_write_ha_state()
except (AioImapException, asyncio.TimeoutError): except (AioImapException, asyncio.TimeoutError):
self.disconnected() self.disconnected()

View file

@ -198,12 +198,12 @@ class InputBoolean(ToggleEntity, RestoreEntity):
async def async_turn_on(self, **kwargs): async def async_turn_on(self, **kwargs):
"""Turn the entity on.""" """Turn the entity on."""
self._state = True self._state = True
await self.async_update_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
self._state = False self._state = False
await self.async_update_ha_state() self.async_write_ha_state()
async def async_update_config(self, config: typing.Dict) -> None: async def async_update_config(self, config: typing.Dict) -> None:
"""Handle when the config is updated.""" """Handle when the config is updated."""

View file

@ -116,7 +116,7 @@ class KNXBinarySensor(BinarySensorDevice):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)

View file

@ -210,7 +210,7 @@ class KNXClimate(ClimateDevice):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)
self.device.mode.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: if temperature is None:
return return
await self.device.set_target_temperature(temperature) await self.device.set_target_temperature(temperature)
await self.async_update_ha_state() self.async_write_ha_state()
@property @property
def hvac_mode(self) -> Optional[str]: def hvac_mode(self) -> Optional[str]:
@ -304,7 +304,7 @@ class KNXClimate(ClimateDevice):
elif self.device.mode.supports_operation_mode: elif self.device.mode.supports_operation_mode:
knx_operation_mode = HVACOperationMode(OPERATION_MODES_INV.get(hvac_mode)) knx_operation_mode = HVACOperationMode(OPERATION_MODES_INV.get(hvac_mode))
await self.device.mode.set_operation_mode(knx_operation_mode) await self.device.mode.set_operation_mode(knx_operation_mode)
await self.async_update_ha_state() self.async_write_ha_state()
@property @property
def preset_mode(self) -> Optional[str]: def preset_mode(self) -> Optional[str]:
@ -334,4 +334,4 @@ class KNXClimate(ClimateDevice):
if self.device.mode.supports_operation_mode: if self.device.mode.supports_operation_mode:
knx_operation_mode = HVACOperationMode(PRESET_MODES_INV.get(preset_mode)) knx_operation_mode = HVACOperationMode(PRESET_MODES_INV.get(preset_mode))
await self.device.mode.set_operation_mode(knx_operation_mode) await self.device.mode.set_operation_mode(knx_operation_mode)
await self.async_update_ha_state() self.async_write_ha_state()

View file

@ -108,7 +108,7 @@ class KNXCover(CoverDevice):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)

View file

@ -154,7 +154,7 @@ class KNXLight(Light):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)

View file

@ -69,7 +69,7 @@ class KNXSensor(Entity):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)

View file

@ -65,7 +65,7 @@ class KNXSwitch(SwitchDevice):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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.register_device_updated_cb(after_update_callback)

View file

@ -74,21 +74,21 @@ class LcnOutputsCover(LcnDevice, CoverDevice):
state = pypck.lcn_defs.MotorStateModifier.DOWN state = pypck.lcn_defs.MotorStateModifier.DOWN
self.address_connection.control_motors_outputs(state) 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): async def async_open_cover(self, **kwargs):
"""Open the cover.""" """Open the cover."""
self._closed = False self._closed = False
state = pypck.lcn_defs.MotorStateModifier.UP state = pypck.lcn_defs.MotorStateModifier.UP
self.address_connection.control_motors_outputs(state, self.reverse_time) 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): async def async_stop_cover(self, **kwargs):
"""Stop the cover.""" """Stop the cover."""
self._closed = None self._closed = None
state = pypck.lcn_defs.MotorStateModifier.STOP state = pypck.lcn_defs.MotorStateModifier.STOP
self.address_connection.control_motors_outputs(state, self.reverse_time) 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): def input_received(self, input_obj):
"""Set cover states when LCN input object (command) is received.""" """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 = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.DOWN states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.DOWN
self.address_connection.control_motors_relays(states) 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): async def async_open_cover(self, **kwargs):
"""Open the cover.""" """Open the cover."""
@ -148,7 +148,7 @@ class LcnRelayCover(LcnDevice, CoverDevice):
states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4 states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.UP states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.UP
self.address_connection.control_motors_relays(states) 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): async def async_stop_cover(self, **kwargs):
"""Stop the cover.""" """Stop the cover."""
@ -156,7 +156,7 @@ class LcnRelayCover(LcnDevice, CoverDevice):
states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4 states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.STOP states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.STOP
self.address_connection.control_motors_relays(states) self.address_connection.control_motors_relays(states)
await self.async_update_ha_state() self.async_write_ha_state()
def input_received(self, input_obj): def input_received(self, input_obj):
"""Set cover states when LCN input object (command) is received.""" """Set cover states when LCN input object (command) is received."""

View file

@ -102,7 +102,7 @@ class LcnOutputLight(LcnDevice, Light):
transition = self._transition transition = self._transition
self.address_connection.dim_output(self.output.value, percent, 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): async def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
@ -117,7 +117,7 @@ class LcnOutputLight(LcnDevice, Light):
self._is_dimming_to_zero = bool(transition) self._is_dimming_to_zero = bool(transition)
self.address_connection.dim_output(self.output.value, 0, 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): def input_received(self, input_obj):
"""Set light state when LCN input object (command) is received.""" """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 states[self.output.value] = pypck.lcn_defs.RelayStateModifier.ON
self.address_connection.control_relays(states) self.address_connection.control_relays(states)
await self.async_update_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
@ -174,7 +174,7 @@ class LcnRelayLight(LcnDevice, Light):
states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF
self.address_connection.control_relays(states) self.address_connection.control_relays(states)
await self.async_update_ha_state() self.async_write_ha_state()
def input_received(self, input_obj): def input_received(self, input_obj):
"""Set light state when LCN input object (command) is received.""" """Set light state when LCN input object (command) is received."""

View file

@ -59,13 +59,13 @@ class LcnOutputSwitch(LcnDevice, SwitchDevice):
"""Turn the entity on.""" """Turn the entity on."""
self._is_on = True self._is_on = True
self.address_connection.dim_output(self.output.value, 100, 0) 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): async def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
self._is_on = False self._is_on = False
self.address_connection.dim_output(self.output.value, 0, 0) 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): def input_received(self, input_obj):
"""Set switch state when LCN input object (command) is received.""" """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 = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8
states[self.output.value] = pypck.lcn_defs.RelayStateModifier.ON states[self.output.value] = pypck.lcn_defs.RelayStateModifier.ON
self.address_connection.control_relays(states) self.address_connection.control_relays(states)
await self.async_update_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
@ -116,7 +116,7 @@ class LcnRelaySwitch(LcnDevice, SwitchDevice):
states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8 states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8
states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF states[self.output.value] = pypck.lcn_defs.RelayStateModifier.OFF
self.address_connection.control_relays(states) self.address_connection.control_relays(states)
await self.async_update_ha_state() self.async_write_ha_state()
def input_received(self, input_obj): def input_received(self, input_obj):
"""Set switch state when LCN input object (command) is received.""" """Set switch state when LCN input object (command) is received."""

View file

@ -435,7 +435,7 @@ class LIFXManager:
entity = self.entities[bulb.mac_addr] entity = self.entities[bulb.mac_addr]
_LOGGER.debug("%s unregister", entity.who) _LOGGER.debug("%s unregister", entity.who)
entity.registered = False entity.registered = False
self.hass.async_create_task(entity.async_update_ha_state()) entity.async_write_ha_state()
class AwaitAioLIFX: class AwaitAioLIFX:
@ -573,7 +573,7 @@ class LIFXLight(Light):
"""Request new status and push it to hass.""" """Request new status and push it to hass."""
self.postponed_update = None self.postponed_update = None
await self.async_update() await self.async_update()
await self.async_update_ha_state() self.async_write_ha_state()
async def update_during_transition(self, when): async def update_during_transition(self, when):
"""Update state at the start and end of a transition.""" """Update state at the start and end of a transition."""

View file

@ -96,7 +96,7 @@ async def async_setup(hass, config):
face.store[g_id] = {} face.store[g_id] = {}
entities[g_id] = MicrosoftFaceGroupEntity(hass, face, g_id, name) 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: except HomeAssistantError as err:
_LOGGER.error("Can't create group '%s' with error: %s", g_id, 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"] 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: except HomeAssistantError as err:
_LOGGER.error("Can't create person '%s' with error: %s", name, 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}") await face.call_api("delete", f"persongroups/{g_id}/persons/{p_id}")
face.store[g_id].pop(name) 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: except HomeAssistantError as err:
_LOGGER.error("Can't delete person '%s' with error: %s", p_id, err) _LOGGER.error("Can't delete person '%s' with error: %s", p_id, err)

View file

@ -92,7 +92,6 @@ class NetioApiView(HomeAssistantView):
@callback @callback
def get(self, request, host): def get(self, request, host):
"""Request handler.""" """Request handler."""
hass = request.app["hass"]
data = request.query data = request.query
states, consumptions, cumulated_consumptions, start_dates = [], [], [], [] states, consumptions, cumulated_consumptions, start_dates = [], [], [], []
@ -121,7 +120,7 @@ class NetioApiView(HomeAssistantView):
ndev.start_dates = start_dates ndev.start_dates = start_dates
for dev in DEVICES[host].entities: for dev in DEVICES[host].entities:
hass.async_create_task(dev.async_update_ha_state()) dev.async_write_ha_state()
return self.json(True) return self.json(True)

View file

@ -314,7 +314,7 @@ async def async_handle_waypoint(hass, name_base, waypoint):
) )
zone.hass = hass zone.hass = hass
zone.entity_id = entity_id zone.entity_id = entity_id
await zone.async_update_ha_state() zone.async_write_ha_state()
@HANDLERS.register("waypoint") @HANDLERS.register("waypoint")

View file

@ -498,7 +498,7 @@ class RflinkCommand(RflinkDevice):
await self._async_send_command(cmd, self._signal_repetitions) await self._async_send_command(cmd, self._signal_repetitions)
# Update state of entity # Update state of entity
await self.async_update_ha_state() self.async_write_ha_state()
def cancel_queued_send_commands(self): def cancel_queued_send_commands(self):
"""Cancel queued signal repetition commands. """Cancel queued signal repetition commands.

View file

@ -1,5 +1,4 @@
"""SAJ solar inverter interface.""" """SAJ solar inverter interface."""
import asyncio
from datetime import date from datetime import date
import logging import logging
@ -100,8 +99,6 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async def async_saj(): async def async_saj():
"""Update all the SAJ sensors.""" """Update all the SAJ sensors."""
tasks = []
values = await saj.read(sensor_def) values = await saj.read(sensor_def)
for sensor in hass_sensors: 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 not sensor.per_day_basis and not sensor.per_total_basis
): ):
state_unknown = True state_unknown = True
task = sensor.async_update_values(unknown_state=state_unknown) sensor.async_update_values(unknown_state=state_unknown)
if task:
tasks.append(task)
if tasks:
await asyncio.wait(tasks)
return values return values
def start_update_interval(event): def start_update_interval(event):
@ -237,7 +231,8 @@ class SAJsensor(Entity):
update = True update = True
self._state = None self._state = None
return self.async_update_ha_state() if update else None if update:
self.async_write_ha_state()
@property @property
def unique_id(self): def unique_id(self):

View file

@ -243,7 +243,7 @@ class ScriptEntity(ToggleEntity):
self.icon = icon self.icon = icon
self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.entity_id = ENTITY_ID_FORMAT.format(object_id)
self.script = Script( self.script = Script(
hass, sequence, name, self.async_update_ha_state, logger=_LOGGER hass, sequence, name, self.async_write_ha_state, logger=_LOGGER
) )
@property @property

View file

@ -1,5 +1,4 @@
"""SMA Solar Webconnect interface.""" """SMA Solar Webconnect interface."""
import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
@ -163,13 +162,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
return return
backoff_step = 0 backoff_step = 0
tasks = []
for sensor in hass_sensors: for sensor in hass_sensors:
task = sensor.async_update_values() sensor.async_update_values()
if task:
tasks.append(task)
if tasks:
await asyncio.wait(tasks)
interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=5) interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=5)
async_track_time_interval(hass, async_sma, interval) async_track_time_interval(hass, async_sma, interval)
@ -226,7 +220,8 @@ class SMAsensor(Entity):
update = True update = True
self._state = self._sensor.value self._state = self._sensor.value
return self.async_update_ha_state() if update else None if update:
self.async_write_ha_state()
@property @property
def unique_id(self): def unique_id(self):

View file

@ -159,21 +159,21 @@ class SongpalDevice(MediaPlayerDevice):
_LOGGER.debug("Volume changed: %s", volume) _LOGGER.debug("Volume changed: %s", volume)
self._volume = volume.volume self._volume = volume.volume
self._is_muted = volume.mute self._is_muted = volume.mute
await self.async_update_ha_state() self.async_write_ha_state()
async def _source_changed(content: ContentChange): async def _source_changed(content: ContentChange):
_LOGGER.debug("Source changed: %s", content) _LOGGER.debug("Source changed: %s", content)
if content.is_input: if content.is_input:
self._active_source = self._sources[content.source] self._active_source = self._sources[content.source]
_LOGGER.debug("New active source: %s", self._active_source) _LOGGER.debug("New active source: %s", self._active_source)
await self.async_update_ha_state() self.async_write_ha_state()
else: else:
_LOGGER.debug("Got non-handled content change: %s", content) _LOGGER.debug("Got non-handled content change: %s", content)
async def _power_changed(power: PowerChange): async def _power_changed(power: PowerChange):
_LOGGER.debug("Power changed: %s", power) _LOGGER.debug("Power changed: %s", power)
self._state = power.status self._state = power.status
await self.async_update_ha_state() self.async_write_ha_state()
async def _try_reconnect(connect: ConnectChange): async def _try_reconnect(connect: ConnectChange):
_LOGGER.error( _LOGGER.error(
@ -181,7 +181,7 @@ class SongpalDevice(MediaPlayerDevice):
) )
self._available = False self._available = False
self.dev.clear_notification_callbacks() 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 # Try to reconnect forever, a successful reconnect will initialize
# the websocket connection again. # the websocket connection again.

View file

@ -184,11 +184,11 @@ class TariffSelect(RestoreEntity):
) )
return return
self._current_tariff = tariff self._current_tariff = tariff
await self.async_update_ha_state() self.async_write_ha_state()
async def async_next_tariff(self): async def async_next_tariff(self):
"""Offset current index.""" """Offset current index."""
current_index = self._tariffs.index(self._current_tariff) current_index = self._tariffs.index(self._current_tariff)
new_index = (current_index + 1) % len(self._tariffs) new_index = (current_index + 1) % len(self._tariffs)
self._current_tariff = self._tariffs[new_index] self._current_tariff = self._tariffs[new_index]
await self.async_update_ha_state() self.async_write_ha_state()

View file

@ -217,7 +217,7 @@ class UtilityMeterSensor(RestoreEntity):
self._last_reset = dt_util.now() self._last_reset = dt_util.now()
self._last_period = str(self._state) self._last_period = str(self._state)
self._state = 0 self._state = 0
await self.async_update_ha_state() self.async_write_ha_state()
async def async_calibrate(self, value): async def async_calibrate(self, value):
"""Calibrate the Utility Meter with a given 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._unit_of_measurement = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
self._last_period = state.attributes.get(ATTR_LAST_PERIOD) self._last_period = state.attributes.get(ATTR_LAST_PERIOD)
self._last_reset = state.attributes.get(ATTR_LAST_RESET) 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: if state.attributes.get(ATTR_STATUS) == PAUSED:
# Fake cancellation function to init the meter paused # Fake cancellation function to init the meter paused
self._collecting = lambda: None self._collecting = lambda: None

View file

@ -38,7 +38,7 @@ class VeluxCover(CoverDevice):
async def after_update_callback(device): async def after_update_callback(device):
"""Call after device was updated.""" """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) self.node.register_device_updated_cb(after_update_callback)

View file

@ -96,11 +96,13 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
dev = [] dev = []
for sensor_type in config[CONF_MONITORED_CONDITIONS]: for sensor_type in config[CONF_MONITORED_CONDITIONS]:
dev.append(YrSensor(name, sensor_type)) dev.append(YrSensor(name, sensor_type))
async_add_entities(dev)
weather = YrData(hass, coordinates, forecast, 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() await weather.fetching_data()
async_add_entities(dev)
class YrSensor(Entity): class YrSensor(Entity):
@ -234,7 +236,6 @@ class YrData:
ordered_entries.sort(key=lambda item: item[0]) ordered_entries.sort(key=lambda item: item[0])
# Update all devices # Update all devices
tasks = []
if ordered_entries: if ordered_entries:
for dev in self.devices: for dev in self.devices:
new_state = None new_state = None
@ -274,7 +275,5 @@ class YrData:
# pylint: disable=protected-access # pylint: disable=protected-access
if new_state != dev._state: if new_state != dev._state:
dev._state = new_state dev._state = new_state
tasks.append(dev.async_update_ha_state()) if dev.hass:
dev.async_write_ha_state()
if tasks:
await asyncio.wait(tasks)

View file

@ -87,7 +87,7 @@ class ZWaveBaseEntity(Entity):
@callback @callback
def do_update(): def do_update():
"""Really 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 = False
self._update_scheduled = True self._update_scheduled = True

View file

@ -444,7 +444,7 @@ class EntityPlatform:
await entity.async_internal_added_to_hass() await entity.async_internal_added_to_hass()
await entity.async_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: async def async_reset(self) -> None:
"""Remove all entities and reset data. """Remove all entities and reset data.

View file

@ -36,7 +36,6 @@ from homeassistant.core import (
Context, Context,
HomeAssistant, HomeAssistant,
callback, callback,
is_callback,
) )
from homeassistant.helpers import ( from homeassistant.helpers import (
condition, condition,
@ -679,10 +678,7 @@ class Script:
def _changed(self): def _changed(self):
if self.change_listener: if self.change_listener:
if is_callback(self.change_listener): self._hass.async_run_job(self.change_listener)
self.change_listener()
else:
self._hass.async_add_job(self.change_listener)
@property @property
def is_running(self) -> bool: def is_running(self) -> bool:

View file

@ -13,6 +13,7 @@ import tests.mock.zwave as mock_zwave
async def test_maybe_schedule_update(hass, mock_openzwave): async def test_maybe_schedule_update(hass, mock_openzwave):
"""Test maybe schedule update.""" """Test maybe schedule update."""
base_entity = node_entity.ZWaveBaseEntity() base_entity = node_entity.ZWaveBaseEntity()
base_entity.entity_id = "zwave.bla"
base_entity.hass = hass base_entity.hass = hass
with patch.object(hass.loop, "call_later") as mock_call_later: 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() base_entity._schedule_update()
assert len(mock_call_later.mock_calls) == 1 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] do_update = mock_call_later.mock_calls[0][1][1]
with patch.object(hass, "async_add_job") as mock_add_job: do_update()
do_update() assert base_entity._update_scheduled is False
assert mock_add_job.called
base_entity._schedule_update() base_entity._schedule_update()
assert len(mock_call_later.mock_calls) == 2 assert len(mock_call_later.mock_calls) == 2

View file

@ -379,15 +379,16 @@ async def test_update_entity(hass):
"""Test that we can update an entity with the helper.""" """Test that we can update an entity with the helper."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
entity = MockEntity() entity = MockEntity()
entity.async_write_ha_state = Mock()
entity.async_update_ha_state = Mock(return_value=mock_coro()) entity.async_update_ha_state = Mock(return_value=mock_coro())
await component.async_add_entities([entity]) await component.async_add_entities([entity])
# Called as part of async_add_entities # 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) 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 assert entity.async_update_ha_state.mock_calls[-1][1][0] is True