Convert zerproc to use new upstream async api (#44357)

This commit is contained in:
Emily Mills 2020-12-19 09:35:47 -06:00 committed by GitHub
parent 896f51fd82
commit 9de393d116
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 42 deletions

View file

@ -14,7 +14,7 @@ _LOGGER = logging.getLogger(__name__)
async def _async_has_devices(hass) -> bool:
"""Return if there are devices that can be discovered."""
try:
devices = await hass.async_add_executor_job(pyzerproc.discover)
devices = await pyzerproc.discover()
return len(devices) > 0
except pyzerproc.ZerprocException:
_LOGGER.error("Unable to discover nearby Zerproc devices", exc_info=True)

View file

@ -28,25 +28,10 @@ SUPPORT_ZERPROC = SUPPORT_BRIGHTNESS | SUPPORT_COLOR
DISCOVERY_INTERVAL = timedelta(seconds=60)
PARALLEL_UPDATES = 0
def connect_lights(lights: List[pyzerproc.Light]) -> List[pyzerproc.Light]:
"""Attempt to connect to lights, and return the connected lights."""
connected = []
for light in lights:
try:
light.connect()
connected.append(light)
except pyzerproc.ZerprocException:
_LOGGER.debug("Unable to connect to '%s'", light.address, exc_info=True)
return connected
def discover_entities(hass: HomeAssistant) -> List[Entity]:
async def discover_entities(hass: HomeAssistant) -> List[Entity]:
"""Attempt to discover new lights."""
lights = pyzerproc.discover()
lights = await pyzerproc.discover()
# Filter out already discovered lights
new_lights = [
@ -54,8 +39,13 @@ def discover_entities(hass: HomeAssistant) -> List[Entity]:
]
entities = []
for light in connect_lights(new_lights):
# Double-check the light hasn't been added in another thread
for light in new_lights:
try:
await light.connect()
except pyzerproc.ZerprocException:
_LOGGER.debug("Unable to connect to '%s'", light.address, exc_info=True)
continue
# Double-check the light hasn't been added in the meantime
if light.address not in hass.data[DOMAIN]["addresses"]:
hass.data[DOMAIN]["addresses"].add(light.address)
entities.append(ZerprocLight(light))
@ -68,7 +58,7 @@ async def async_setup_entry(
config_entry: ConfigEntry,
async_add_entities: Callable[[List[Entity], bool], None],
) -> None:
"""Set up Abode light devices."""
"""Set up Zerproc light devices."""
if DOMAIN not in hass.data:
hass.data[DOMAIN] = {}
if "addresses" not in hass.data[DOMAIN]:
@ -80,7 +70,7 @@ async def async_setup_entry(
"""Wrap discovery to include params."""
nonlocal warned
try:
entities = await hass.async_add_executor_job(discover_entities, hass)
entities = await discover_entities(hass)
async_add_entities(entities, update_before_add=True)
warned = False
except pyzerproc.ZerprocException:
@ -117,11 +107,11 @@ class ZerprocLight(LightEntity):
async def async_will_remove_from_hass(self) -> None:
"""Run when entity will be removed from hass."""
await self.hass.async_add_executor_job(self._light.disconnect)
await self._light.disconnect()
def on_hass_shutdown(self, event):
async def on_hass_shutdown(self, event):
"""Execute when Home Assistant is shutting down."""
self._light.disconnect()
await self._light.disconnect()
@property
def name(self):
@ -172,7 +162,7 @@ class ZerprocLight(LightEntity):
"""Return True if entity is available."""
return self._available
def turn_on(self, **kwargs):
async def async_turn_on(self, **kwargs):
"""Instruct the light to turn on."""
if ATTR_BRIGHTNESS in kwargs or ATTR_HS_COLOR in kwargs:
default_hs = (0, 0) if self._hs_color is None else self._hs_color
@ -182,20 +172,20 @@ class ZerprocLight(LightEntity):
brightness = kwargs.get(ATTR_BRIGHTNESS, default_brightness)
rgb = color_util.color_hsv_to_RGB(*hue_sat, brightness / 255 * 100)
self._light.set_color(*rgb)
await self._light.set_color(*rgb)
else:
self._light.turn_on()
await self._light.turn_on()
def turn_off(self, **kwargs):
async def async_turn_off(self, **kwargs):
"""Instruct the light to turn off."""
self._light.turn_off()
await self._light.turn_off()
def update(self):
async def async_update(self):
"""Fetch new state data for this light."""
try:
if not self._light.connected:
self._light.connect()
state = self._light.get_state()
if not await self._light.is_connected():
await self._light.connect()
state = await self._light.get_state()
except pyzerproc.ZerprocException:
if self._available:
_LOGGER.warning("Unable to connect to %s", self.entity_id)

View file

@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/zerproc",
"requirements": [
"pyzerproc==0.3.0"
"pyzerproc==0.4.3"
],
"codeowners": [
"@emlove"

View file

@ -1904,7 +1904,7 @@ pyxeoma==1.4.1
pyzbar==0.1.7
# homeassistant.components.zerproc
pyzerproc==0.3.0
pyzerproc==0.4.3
# homeassistant.components.qnap
qnapstats==0.3.0

View file

@ -939,7 +939,7 @@ pywemo==0.5.3
pywilight==0.0.65
# homeassistant.components.zerproc
pyzerproc==0.3.0
pyzerproc==0.4.3
# homeassistant.components.rachio
rachiopy==1.0.3

View file

@ -44,7 +44,7 @@ async def mock_light(hass, mock_entry):
light = MagicMock(spec=pyzerproc.Light)
light.address = "AA:BB:CC:DD:EE:FF"
light.name = "LEDBlue-CCDDEEFF"
light.connected = False
light.is_connected.return_value = False
mock_state = pyzerproc.LightState(False, (0, 0, 0))
@ -57,7 +57,7 @@ async def mock_light(hass, mock_entry):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
light.connected = True
light.is_connected.return_value = True
return light
@ -71,12 +71,12 @@ async def test_init(hass, mock_entry):
mock_light_1 = MagicMock(spec=pyzerproc.Light)
mock_light_1.address = "AA:BB:CC:DD:EE:FF"
mock_light_1.name = "LEDBlue-CCDDEEFF"
mock_light_1.connected = True
mock_light_1.is_connected.return_value = True
mock_light_2 = MagicMock(spec=pyzerproc.Light)
mock_light_2.address = "11:22:33:44:55:66"
mock_light_2.name = "LEDBlue-33445566"
mock_light_2.connected = True
mock_light_2.is_connected.return_value = True
mock_state_1 = pyzerproc.LightState(False, (0, 0, 0))
mock_state_2 = pyzerproc.LightState(True, (0, 80, 255))
@ -144,7 +144,7 @@ async def test_connect_exception(hass, mock_entry):
mock_light = MagicMock(spec=pyzerproc.Light)
mock_light.address = "AA:BB:CC:DD:EE:FF"
mock_light.name = "LEDBlue-CCDDEEFF"
mock_light.connected = False
mock_light.is_connected.return_value = False
with patch(
"homeassistant.components.zerproc.light.pyzerproc.discover",