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):
"""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):

View File

@ -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."""

View File

@ -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."""

View File

@ -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."""

View File

@ -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

View File

@ -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."""

View File

@ -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)

View File

@ -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():

View File

@ -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

View File

@ -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()

View File

@ -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):

View File

@ -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()

View File

@ -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."""

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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."""

View File

@ -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."""

View File

@ -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."""

View File

@ -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."""

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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.

View File

@ -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):

View File

@ -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

View File

@ -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):

View File

@ -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.

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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