Use conn_made callback in MySensors (#47463)

This commit is contained in:
functionpointer 2021-03-05 20:21:24 +01:00 committed by GitHub
parent a547d0fea2
commit a2ee7d598b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 47 deletions

View file

@ -29,7 +29,6 @@ CONF_GATEWAY_TYPE_ALL: List[str] = [
DOMAIN: str = "mysensors"
MYSENSORS_GATEWAY_READY: str = "mysensors_gateway_ready_{}"
MYSENSORS_GATEWAY_START_TASK: str = "mysensors_gateway_start_task_{}"
MYSENSORS_GATEWAYS: str = "mysensors_gateways"
PLATFORM: str = "platform"

View file

@ -26,7 +26,6 @@ from .const import (
CONF_TOPIC_OUT_PREFIX,
CONF_VERSION,
DOMAIN,
MYSENSORS_GATEWAY_READY,
MYSENSORS_GATEWAY_START_TASK,
MYSENSORS_GATEWAYS,
GatewayId,
@ -36,7 +35,7 @@ from .helpers import discover_mysensors_platform, validate_child, validate_node
_LOGGER = logging.getLogger(__name__)
GATEWAY_READY_TIMEOUT = 15.0
GATEWAY_READY_TIMEOUT = 20.0
MQTT_COMPONENT = "mqtt"
@ -64,24 +63,16 @@ async def try_connect(hass: HomeAssistantType, user_input: Dict[str, str]) -> bo
if user_input[CONF_DEVICE] == MQTT_COMPONENT:
return True # dont validate mqtt. mqtt gateways dont send ready messages :(
try:
gateway_ready = asyncio.Future()
gateway_ready = asyncio.Event()
def gateway_ready_callback(msg):
msg_type = msg.gateway.const.MessageType(msg.type)
_LOGGER.debug("Received MySensors msg type %s: %s", msg_type.name, msg)
if msg_type.name != "internal":
return
internal = msg.gateway.const.Internal(msg.sub_type)
if internal.name != "I_GATEWAY_READY":
return
_LOGGER.debug("Received gateway ready")
gateway_ready.set_result(True)
def on_conn_made(_: BaseAsyncGateway) -> None:
gateway_ready.set()
gateway: Optional[BaseAsyncGateway] = await _get_gateway(
hass,
device=user_input[CONF_DEVICE],
version=user_input[CONF_VERSION],
event_callback=gateway_ready_callback,
event_callback=lambda _: None,
persistence_file=None,
baud_rate=user_input.get(CONF_BAUD_RATE),
tcp_port=user_input.get(CONF_TCP_PORT),
@ -92,12 +83,13 @@ async def try_connect(hass: HomeAssistantType, user_input: Dict[str, str]) -> bo
)
if gateway is None:
return False
gateway.on_conn_made = on_conn_made
connect_task = None
try:
connect_task = asyncio.create_task(gateway.start())
with async_timeout.timeout(20):
await gateway_ready
with async_timeout.timeout(GATEWAY_READY_TIMEOUT):
await gateway_ready.wait()
return True
except asyncio.TimeoutError:
_LOGGER.info("Try gateway connect failed with timeout")
@ -280,6 +272,12 @@ async def _gw_start(
hass: HomeAssistantType, entry: ConfigEntry, gateway: BaseAsyncGateway
):
"""Start the gateway."""
gateway_ready = asyncio.Event()
def gateway_connected(_: BaseAsyncGateway):
gateway_ready.set()
gateway.on_conn_made = gateway_connected
# Don't use hass.async_create_task to avoid holding up setup indefinitely.
hass.data[DOMAIN][
MYSENSORS_GATEWAY_START_TASK.format(entry.entry_id)
@ -294,21 +292,15 @@ async def _gw_start(
if entry.data[CONF_DEVICE] == MQTT_COMPONENT:
# Gatways connected via mqtt doesn't send gateway ready message.
return
gateway_ready = asyncio.Future()
gateway_ready_key = MYSENSORS_GATEWAY_READY.format(entry.entry_id)
hass.data[DOMAIN][gateway_ready_key] = gateway_ready
try:
with async_timeout.timeout(GATEWAY_READY_TIMEOUT):
await gateway_ready
await gateway_ready.wait()
except asyncio.TimeoutError:
_LOGGER.warning(
"Gateway %s not ready after %s secs so continuing with setup",
"Gateway %s not connected after %s secs so continuing with setup",
entry.data[CONF_DEVICE],
GATEWAY_READY_TIMEOUT,
)
finally:
hass.data[DOMAIN].pop(gateway_ready_key, None)
def _gw_callback_factory(

View file

@ -8,14 +8,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.util import decorator
from .const import (
CHILD_CALLBACK,
DOMAIN,
MYSENSORS_GATEWAY_READY,
NODE_CALLBACK,
DevId,
GatewayId,
)
from .const import CHILD_CALLBACK, NODE_CALLBACK, DevId, GatewayId
from .device import get_mysensors_devices
from .helpers import discover_mysensors_platform, validate_set_msg
@ -75,20 +68,6 @@ async def handle_sketch_version(
_handle_node_update(hass, gateway_id, msg)
@HANDLERS.register("I_GATEWAY_READY")
async def handle_gateway_ready(
hass: HomeAssistantType, gateway_id: GatewayId, msg: Message
) -> None:
"""Handle an internal gateway ready message.
Set asyncio future result if gateway is ready.
"""
gateway_ready = hass.data[DOMAIN].get(MYSENSORS_GATEWAY_READY.format(gateway_id))
if gateway_ready is None or gateway_ready.cancelled():
return
gateway_ready.set_result(True)
@callback
def _handle_child_update(
hass: HomeAssistantType, gateway_id: GatewayId, validated: Dict[str, List[DevId]]