mirror of https://github.com/home-assistant/core
0.56.1 (#10035)
* Version bump to 0.56.1 * Fix device update / entity_id with names (#10029) * Fix device update * Add tests * add test for disabled warning * fix temperature/humidity sensors valid values (#10024)
This commit is contained in:
parent
ead4e44cd6
commit
106bf467f8
|
@ -67,6 +67,10 @@ class XiaomiSensor(XiaomiDevice):
|
|||
if value is None:
|
||||
return False
|
||||
value = float(value)
|
||||
if self._data_key in ['temperature', 'humidity', 'pressure']:
|
||||
value /= 100
|
||||
elif self._data_key in ['illumination']:
|
||||
value = max(value - 300, 0)
|
||||
if self._data_key == 'temperature' and (value < -20 or value > 60):
|
||||
return False
|
||||
elif self._data_key == 'humidity' and (value <= 0 or value > 100):
|
||||
|
@ -75,9 +79,5 @@ class XiaomiSensor(XiaomiDevice):
|
|||
return False
|
||||
elif self._data_key == 'pressure' and value == 0:
|
||||
return False
|
||||
if self._data_key in ['temperature', 'humidity', 'pressure']:
|
||||
value /= 100
|
||||
elif self._data_key in ['illumination']:
|
||||
value = max(value - 300, 0)
|
||||
self._state = round(value, 2)
|
||||
return True
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 56
|
||||
PATCH_VERSION = '0'
|
||||
PATCH_VERSION = '1'
|
||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||
|
|
|
@ -200,34 +200,11 @@ class Entity(object):
|
|||
|
||||
# update entity data
|
||||
if force_refresh:
|
||||
if self._update_staged:
|
||||
return
|
||||
self._update_staged = True
|
||||
|
||||
# Process update sequential
|
||||
if self.parallel_updates:
|
||||
yield from self.parallel_updates.acquire()
|
||||
|
||||
update_warn = self.hass.loop.call_later(
|
||||
SLOW_UPDATE_WARNING, _LOGGER.warning,
|
||||
"Update of %s is taking over %s seconds", self.entity_id,
|
||||
SLOW_UPDATE_WARNING
|
||||
)
|
||||
|
||||
try:
|
||||
if hasattr(self, 'async_update'):
|
||||
# pylint: disable=no-member
|
||||
yield from self.async_update()
|
||||
else:
|
||||
yield from self.hass.async_add_job(self.update)
|
||||
yield from self.async_device_update()
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Update for %s fails", self.entity_id)
|
||||
return
|
||||
finally:
|
||||
self._update_staged = False
|
||||
update_warn.cancel()
|
||||
if self.parallel_updates:
|
||||
self.parallel_updates.release()
|
||||
|
||||
start = timer()
|
||||
|
||||
|
@ -304,6 +281,39 @@ class Entity(object):
|
|||
"""Schedule a update ha state change task."""
|
||||
self.hass.async_add_job(self.async_update_ha_state(force_refresh))
|
||||
|
||||
def async_device_update(self, warning=True):
|
||||
"""Process 'update' or 'async_update' from entity.
|
||||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
if self._update_staged:
|
||||
return
|
||||
self._update_staged = True
|
||||
|
||||
# Process update sequential
|
||||
if self.parallel_updates:
|
||||
yield from self.parallel_updates.acquire()
|
||||
|
||||
if warning:
|
||||
update_warn = self.hass.loop.call_later(
|
||||
SLOW_UPDATE_WARNING, _LOGGER.warning,
|
||||
"Update of %s is taking over %s seconds", self.entity_id,
|
||||
SLOW_UPDATE_WARNING
|
||||
)
|
||||
|
||||
try:
|
||||
if hasattr(self, 'async_update'):
|
||||
# pylint: disable=no-member
|
||||
yield from self.async_update()
|
||||
else:
|
||||
yield from self.hass.async_add_job(self.update)
|
||||
finally:
|
||||
self._update_staged = False
|
||||
if warning:
|
||||
update_warn.cancel()
|
||||
if self.parallel_updates:
|
||||
self.parallel_updates.release()
|
||||
|
||||
def remove(self) -> None:
|
||||
"""Remove entity from HASS."""
|
||||
run_coroutine_threadsafe(
|
||||
|
|
|
@ -210,6 +210,15 @@ class EntityComponent(object):
|
|||
|
||||
entity.hass = self.hass
|
||||
|
||||
# Update properties before we generate the entity_id
|
||||
if update_before_add:
|
||||
try:
|
||||
yield from entity.async_device_update(warning=False)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
self.logger.exception("Error on device update!")
|
||||
return False
|
||||
|
||||
# Write entity_id to entity
|
||||
if getattr(entity, 'entity_id', None) is None:
|
||||
object_id = entity.name or DEVICE_DEFAULT_NAME
|
||||
|
||||
|
@ -234,7 +243,7 @@ class EntityComponent(object):
|
|||
if hasattr(entity, 'async_added_to_hass'):
|
||||
yield from entity.async_added_to_hass()
|
||||
|
||||
yield from entity.async_update_ha_state(update_before_add)
|
||||
yield from entity.async_update_ha_state()
|
||||
|
||||
return True
|
||||
|
||||
|
@ -361,12 +370,14 @@ class EntityPlatform(object):
|
|||
|
||||
def add_entities(self, new_entities, update_before_add=False):
|
||||
"""Add entities for a single platform."""
|
||||
# That avoid deadlocks
|
||||
if update_before_add:
|
||||
for entity in new_entities:
|
||||
entity.update()
|
||||
self.component.logger.warning(
|
||||
"Call 'add_entities' with update_before_add=True "
|
||||
"only inside tests or you can run into a deadlock!")
|
||||
|
||||
run_coroutine_threadsafe(
|
||||
self.async_add_entities(list(new_entities), False),
|
||||
self.async_add_entities(list(new_entities), update_before_add),
|
||||
self.component.hass.loop).result()
|
||||
|
||||
@asyncio.coroutine
|
||||
|
|
|
@ -193,6 +193,30 @@ def test_warn_slow_update_with_exception(hass):
|
|||
assert update_call
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_warn_slow_device_update_disabled(hass):
|
||||
"""Disable slow update warning with async_device_update."""
|
||||
update_call = False
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update():
|
||||
"""Mock async update."""
|
||||
nonlocal update_call
|
||||
update_call = True
|
||||
|
||||
mock_entity = entity.Entity()
|
||||
mock_entity.hass = hass
|
||||
mock_entity.entity_id = 'comp_test.test_entity'
|
||||
mock_entity.async_update = async_update
|
||||
|
||||
with patch.object(hass.loop, 'call_later', MagicMock()) \
|
||||
as mock_call:
|
||||
yield from mock_entity.async_device_update(warning=False)
|
||||
|
||||
assert not mock_call.called
|
||||
assert update_call
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_async_schedule_update_ha_state(hass):
|
||||
"""Warn we log when entity update takes a long time and trow exception."""
|
||||
|
|
|
@ -208,30 +208,6 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
|||
assert 1 == len(self.hass.states.entity_ids())
|
||||
assert not ent.update.called
|
||||
|
||||
def test_adds_entities_with_update_befor_add_true_deadlock_protect(self):
|
||||
"""Test if call update before add to state machine.
|
||||
|
||||
It need to run update inside executor and never call
|
||||
async_add_entities with True
|
||||
"""
|
||||
call = []
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_add_entities_fake(entities, update_befor_add):
|
||||
"""Fake add_entities_call."""
|
||||
call.append(update_befor_add)
|
||||
component._platforms['core'].async_add_entities = \
|
||||
async_add_entities_fake
|
||||
|
||||
ent = EntityTest()
|
||||
ent.update = Mock(spec_set=True)
|
||||
component.add_entities([ent], True)
|
||||
|
||||
assert ent.update.called
|
||||
assert len(call) == 1
|
||||
assert not call[0]
|
||||
|
||||
def test_not_adding_duplicate_entities(self):
|
||||
"""Test for not adding duplicate entities."""
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
@ -654,3 +630,24 @@ def test_pararell_updates_sync_platform(hass):
|
|||
handle = list(component._platforms.values())[-1]
|
||||
|
||||
assert handle.parallel_updates is not None
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_raise_error_on_update(hass):
|
||||
"""Test the add entity if they raise an error on update."""
|
||||
updates = []
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
entity1 = EntityTest(name='test_1')
|
||||
entity2 = EntityTest(name='test_2')
|
||||
|
||||
def _raise():
|
||||
"""Helper to raise a exception."""
|
||||
raise AssertionError
|
||||
|
||||
entity1.update = _raise
|
||||
entity2.update = lambda: updates.append(1)
|
||||
|
||||
yield from component.async_add_entities([entity1, entity2], True)
|
||||
|
||||
assert len(updates) == 1
|
||||
assert 1 in updates
|
||||
|
|
Loading…
Reference in New Issue