Fix hdmi_cec entity race (#18753)
* Update shouldn't be called before adding the entity.
* Transitional states from
8adc786bac/include/cectypes.h (L458-L459)
Addressing https://github.com/home-assistant/home-assistant/issues/12846
This commit is contained in:
parent
eec4564c71
commit
debae6ad2e
3 changed files with 57 additions and 53 deletions
|
@ -320,26 +320,20 @@ def setup(hass: HomeAssistant, base_config):
|
|||
class CecDevice(Entity):
|
||||
"""Representation of a HDMI CEC device entity."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, device, logical) -> None:
|
||||
def __init__(self, device, logical) -> None:
|
||||
"""Initialize the device."""
|
||||
self._device = device
|
||||
self.hass = hass
|
||||
self._icon = None
|
||||
self._state = STATE_UNKNOWN
|
||||
self._logical_address = logical
|
||||
self.entity_id = "%s.%d" % (DOMAIN, self._logical_address)
|
||||
device.set_update_callback(self._update)
|
||||
|
||||
def update(self):
|
||||
"""Update device status."""
|
||||
self._update()
|
||||
|
||||
def _update(self, device=None):
|
||||
"""Update device status."""
|
||||
if device:
|
||||
device = self._device
|
||||
from pycec.const import STATUS_PLAY, STATUS_STOP, STATUS_STILL, \
|
||||
POWER_OFF, POWER_ON
|
||||
if device.power_status == POWER_OFF:
|
||||
if device.power_status in [POWER_OFF, 3]:
|
||||
self._state = STATE_OFF
|
||||
elif device.status == STATUS_PLAY:
|
||||
self._state = STATE_PLAYING
|
||||
|
@ -347,11 +341,18 @@ class CecDevice(Entity):
|
|||
self._state = STATE_IDLE
|
||||
elif device.status == STATUS_STILL:
|
||||
self._state = STATE_PAUSED
|
||||
elif device.power_status == POWER_ON:
|
||||
elif device.power_status in [POWER_ON, 4]:
|
||||
self._state = STATE_ON
|
||||
else:
|
||||
_LOGGER.warning("Unknown state: %d", device.power_status)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register HDMI callbacks after initialization."""
|
||||
self._device.set_update_callback(self._update)
|
||||
|
||||
def _update(self, device=None):
|
||||
"""Device status changed, schedule an update."""
|
||||
self.schedule_update_ha_state(True)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -13,7 +13,6 @@ from homeassistant.components.media_player import (
|
|||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, MediaPlayerDevice)
|
||||
from homeassistant.const import (
|
||||
STATE_IDLE, STATE_OFF, STATE_ON, STATE_PAUSED, STATE_PLAYING)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
DEPENDENCIES = ['hdmi_cec']
|
||||
|
||||
|
@ -26,20 +25,23 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
"""Find and return HDMI devices as +switches."""
|
||||
if ATTR_NEW in discovery_info:
|
||||
_LOGGER.info("Setting up HDMI devices %s", discovery_info[ATTR_NEW])
|
||||
add_entities(CecPlayerDevice(hass, hass.data.get(device),
|
||||
hass.data.get(device).logical_address) for
|
||||
device in discovery_info[ATTR_NEW])
|
||||
entities = []
|
||||
for device in discovery_info[ATTR_NEW]:
|
||||
hdmi_device = hass.data.get(device)
|
||||
entities.append(CecPlayerDevice(
|
||||
hdmi_device, hdmi_device.logical_address,
|
||||
))
|
||||
add_entities(entities, True)
|
||||
|
||||
|
||||
class CecPlayerDevice(CecDevice, MediaPlayerDevice):
|
||||
"""Representation of a HDMI device as a Media player."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, device, logical) -> None:
|
||||
def __init__(self, device, logical) -> None:
|
||||
"""Initialize the HDMI device."""
|
||||
CecDevice.__init__(self, hass, device, logical)
|
||||
CecDevice.__init__(self, device, logical)
|
||||
self.entity_id = "%s.%s_%s" % (
|
||||
DOMAIN, 'hdmi', hex(self._logical_address)[2:])
|
||||
self.update()
|
||||
|
||||
def send_keypress(self, key):
|
||||
"""Send keypress to CEC adapter."""
|
||||
|
@ -137,15 +139,15 @@ class CecPlayerDevice(CecDevice, MediaPlayerDevice):
|
|||
"""Cache state of device."""
|
||||
return self._state
|
||||
|
||||
def _update(self, device=None):
|
||||
def update(self):
|
||||
"""Update device status."""
|
||||
if device:
|
||||
device = self._device
|
||||
from pycec.const import STATUS_PLAY, STATUS_STOP, STATUS_STILL, \
|
||||
POWER_OFF, POWER_ON
|
||||
if device.power_status == POWER_OFF:
|
||||
if device.power_status in [POWER_OFF, 3]:
|
||||
self._state = STATE_OFF
|
||||
elif not self.support_pause:
|
||||
if device.power_status == POWER_ON:
|
||||
if device.power_status in [POWER_ON, 4]:
|
||||
self._state = STATE_ON
|
||||
elif device.status == STATUS_PLAY:
|
||||
self._state = STATE_PLAYING
|
||||
|
@ -155,7 +157,6 @@ class CecPlayerDevice(CecDevice, MediaPlayerDevice):
|
|||
self._state = STATE_PAUSED
|
||||
else:
|
||||
_LOGGER.warning("Unknown state: %s", device.status)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
|
|
|
@ -9,7 +9,6 @@ import logging
|
|||
from homeassistant.components.hdmi_cec import CecDevice, ATTR_NEW
|
||||
from homeassistant.components.switch import SwitchDevice, DOMAIN
|
||||
from homeassistant.const import STATE_OFF, STATE_STANDBY, STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
DEPENDENCIES = ['hdmi_cec']
|
||||
|
||||
|
@ -22,20 +21,23 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
"""Find and return HDMI devices as switches."""
|
||||
if ATTR_NEW in discovery_info:
|
||||
_LOGGER.info("Setting up HDMI devices %s", discovery_info[ATTR_NEW])
|
||||
add_entities(CecSwitchDevice(hass, hass.data.get(device),
|
||||
hass.data.get(device).logical_address) for
|
||||
device in discovery_info[ATTR_NEW])
|
||||
entities = []
|
||||
for device in discovery_info[ATTR_NEW]:
|
||||
hdmi_device = hass.data.get(device)
|
||||
entities.append(CecSwitchDevice(
|
||||
hdmi_device, hdmi_device.logical_address,
|
||||
))
|
||||
add_entities(entities, True)
|
||||
|
||||
|
||||
class CecSwitchDevice(CecDevice, SwitchDevice):
|
||||
"""Representation of a HDMI device as a Switch."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, device, logical) -> None:
|
||||
def __init__(self, device, logical) -> None:
|
||||
"""Initialize the HDMI device."""
|
||||
CecDevice.__init__(self, hass, device, logical)
|
||||
CecDevice.__init__(self, device, logical)
|
||||
self.entity_id = "%s.%s_%s" % (
|
||||
DOMAIN, 'hdmi', hex(self._logical_address)[2:])
|
||||
self.update()
|
||||
|
||||
def turn_on(self, **kwargs) -> None:
|
||||
"""Turn device on."""
|
||||
|
|
Loading…
Add table
Reference in a new issue