mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Fix potential deadlock in platform setup that waits for MQTT
This commit is contained in:
parent
3c60bff7dc
commit
451ca92df9
@ -120,10 +120,15 @@ async def async_setup_platform(
|
||||
) -> None:
|
||||
"""Set up the ARWN platform."""
|
||||
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
async def _async_setup_mqtt() -> None:
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
|
||||
await mqtt.async_subscribe(hass, TOPIC, async_sensor_event_received, 0)
|
||||
|
||||
hass.create_task(_async_setup_mqtt(), "arwn setup")
|
||||
|
||||
@callback
|
||||
def async_sensor_event_received(msg: mqtt.ReceiveMessage) -> None:
|
||||
@ -167,8 +172,6 @@ async def async_setup_platform(
|
||||
)
|
||||
store[sensor.name].set_event(event)
|
||||
|
||||
await mqtt.async_subscribe(hass, TOPIC, async_sensor_event_received, 0)
|
||||
|
||||
|
||||
class ArwnSensor(SensorEntity):
|
||||
"""Representation of an ARWN sensor."""
|
||||
|
@ -199,34 +199,38 @@ async def async_setup_platform(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up the manual MQTT alarm platform."""
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the alarm_control_panel platform setup
|
||||
# also will be triggered when mqtt is loading the `alarm_control_panel` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
add_entities(
|
||||
[
|
||||
ManualMQTTAlarm(
|
||||
hass,
|
||||
config[CONF_NAME],
|
||||
config.get(CONF_CODE),
|
||||
config.get(CONF_CODE_TEMPLATE),
|
||||
config.get(CONF_DISARM_AFTER_TRIGGER, DEFAULT_DISARM_AFTER_TRIGGER),
|
||||
config.get(mqtt.CONF_STATE_TOPIC),
|
||||
config.get(mqtt.CONF_COMMAND_TOPIC),
|
||||
config.get(mqtt.CONF_QOS),
|
||||
config.get(CONF_CODE_ARM_REQUIRED),
|
||||
config.get(CONF_PAYLOAD_DISARM),
|
||||
config.get(CONF_PAYLOAD_ARM_HOME),
|
||||
config.get(CONF_PAYLOAD_ARM_AWAY),
|
||||
config.get(CONF_PAYLOAD_ARM_NIGHT),
|
||||
config.get(CONF_PAYLOAD_ARM_VACATION),
|
||||
config.get(CONF_PAYLOAD_ARM_CUSTOM_BYPASS),
|
||||
config,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
async def _async_setup_entities() -> None:
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the alarm_control_panel platform setup
|
||||
# also will be triggered when mqtt is loading the `alarm_control_panel` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
add_entities(
|
||||
[
|
||||
ManualMQTTAlarm(
|
||||
hass,
|
||||
config[CONF_NAME],
|
||||
config.get(CONF_CODE),
|
||||
config.get(CONF_CODE_TEMPLATE),
|
||||
config.get(CONF_DISARM_AFTER_TRIGGER, DEFAULT_DISARM_AFTER_TRIGGER),
|
||||
config.get(mqtt.CONF_STATE_TOPIC),
|
||||
config.get(mqtt.CONF_COMMAND_TOPIC),
|
||||
config.get(mqtt.CONF_QOS),
|
||||
config.get(CONF_CODE_ARM_REQUIRED),
|
||||
config.get(CONF_PAYLOAD_DISARM),
|
||||
config.get(CONF_PAYLOAD_ARM_HOME),
|
||||
config.get(CONF_PAYLOAD_ARM_AWAY),
|
||||
config.get(CONF_PAYLOAD_ARM_NIGHT),
|
||||
config.get(CONF_PAYLOAD_ARM_VACATION),
|
||||
config.get(CONF_PAYLOAD_ARM_CUSTOM_BYPASS),
|
||||
config,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
hass.create_task(_async_setup_entities(), "manual_mqtt setup")
|
||||
|
||||
|
||||
class ManualMQTTAlarm(AlarmControlPanelEntity):
|
||||
|
@ -48,13 +48,27 @@ async def async_setup_scanner(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> bool:
|
||||
"""Set up the MQTT JSON tracker."""
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the device_tracker platform setup
|
||||
# also will be triggered when mqtt is loading the `device_tracker` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return False
|
||||
|
||||
async def _async_wait_for_mqtt_and_set_up() -> None:
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the device_tracker platform setup
|
||||
# also will be triggered when mqtt is loading the `device_tracker` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
|
||||
await _async_setup_scanner(hass, config, async_see)
|
||||
|
||||
hass.create_task(_async_wait_for_mqtt_and_set_up(), "mqtt_json setup")
|
||||
return True
|
||||
|
||||
|
||||
async def _async_setup_scanner(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
async_see: AsyncSeeCallback,
|
||||
) -> None:
|
||||
"""Set up MQTT JSON tracker."""
|
||||
devices = config[CONF_DEVICES]
|
||||
qos = config[CONF_QOS]
|
||||
|
||||
@ -83,8 +97,6 @@ async def async_setup_scanner(
|
||||
|
||||
await mqtt.async_subscribe(hass, topic, async_message_received, qos)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _parse_see_args(dev_id, data):
|
||||
"""Parse the payload location parameters, into the format see expects."""
|
||||
|
@ -81,24 +81,28 @@ async def async_setup_platform(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up MQTT room Sensor."""
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the sensor platform setup
|
||||
# also will be triggered when mqtt is loading the `sensor` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
async_add_entities(
|
||||
[
|
||||
MQTTRoomSensor(
|
||||
config.get(CONF_NAME),
|
||||
config[CONF_STATE_TOPIC],
|
||||
config[CONF_DEVICE_ID],
|
||||
config[CONF_TIMEOUT],
|
||||
config[CONF_AWAY_TIMEOUT],
|
||||
config.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
async def _async_setup_entities() -> None:
|
||||
# Make sure MQTT integration is enabled and the client is available
|
||||
# We cannot count on dependencies as the sensor platform setup
|
||||
# also will be triggered when mqtt is loading the `sensor` platform
|
||||
if not await mqtt.async_wait_for_mqtt_client(hass):
|
||||
_LOGGER.error("MQTT integration is not available")
|
||||
return
|
||||
async_add_entities(
|
||||
[
|
||||
MQTTRoomSensor(
|
||||
config.get(CONF_NAME),
|
||||
config[CONF_STATE_TOPIC],
|
||||
config[CONF_DEVICE_ID],
|
||||
config[CONF_TIMEOUT],
|
||||
config[CONF_AWAY_TIMEOUT],
|
||||
config.get(CONF_UNIQUE_ID),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
hass.create_task(_async_setup_entities(), "mqtt_room setup")
|
||||
|
||||
|
||||
class MQTTRoomSensor(SensorEntity):
|
||||
|
@ -103,7 +103,7 @@ async def test_no_pending(
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
entity_id = "alarm_control_panel.test"
|
||||
|
||||
@ -155,7 +155,7 @@ async def test_no_pending_when_code_not_req(
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
entity_id = "alarm_control_panel.test"
|
||||
|
||||
@ -206,7 +206,7 @@ async def test_with_pending(
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
entity_id = "alarm_control_panel.test"
|
||||
|
||||
|
@ -65,7 +65,7 @@ async def test_setup_fails_without_mqtt_being_setup(
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: topic}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert "MQTT integration is not available" in caplog.text
|
||||
|
||||
@ -95,7 +95,7 @@ async def test_ensure_device_tracker_platform_validation(hass: HomeAssistant) ->
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: topic}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert mock_sp.call_count == 1
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ async def test_json_message(hass: HomeAssistant) -> None:
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: topic}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
async_fire_mqtt_message(hass, topic, location)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("device_tracker.zanzito")
|
||||
@ -131,7 +131,7 @@ async def test_non_json_message(
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: topic}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
caplog.set_level(logging.ERROR)
|
||||
caplog.clear()
|
||||
@ -153,7 +153,7 @@ async def test_incomplete_message(
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: topic}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
caplog.set_level(logging.ERROR)
|
||||
caplog.clear()
|
||||
@ -177,7 +177,7 @@ async def test_single_level_wildcard_topic(hass: HomeAssistant) -> None:
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: subscription}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
async_fire_mqtt_message(hass, topic, location)
|
||||
await hass.async_block_till_done()
|
||||
@ -198,7 +198,7 @@ async def test_multi_level_wildcard_topic(hass: HomeAssistant) -> None:
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: subscription}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
async_fire_mqtt_message(hass, topic, location)
|
||||
await hass.async_block_till_done()
|
||||
@ -220,7 +220,7 @@ async def test_single_level_wildcard_topic_not_matching(hass: HomeAssistant) ->
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: subscription}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
async_fire_mqtt_message(hass, topic, location)
|
||||
await hass.async_block_till_done()
|
||||
@ -240,7 +240,7 @@ async def test_multi_level_wildcard_topic_not_matching(hass: HomeAssistant) -> N
|
||||
DT_DOMAIN,
|
||||
{DT_DOMAIN: {CONF_PLATFORM: "mqtt_json", "devices": {dev_id: subscription}}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
async_fire_mqtt_message(hass, topic, location)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -78,7 +78,7 @@ async def test_no_mqtt(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) ->
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
state = hass.states.get(SENSOR_STATE)
|
||||
assert state is None
|
||||
assert "MQTT integration is not available" in caplog.text
|
||||
@ -100,7 +100,7 @@ async def test_room_update(hass: HomeAssistant, mqtt_mock: MqttMockHAClient) ->
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
await send_message(hass, BEDROOM_TOPIC, FAR_MESSAGE)
|
||||
await assert_state(hass, BEDROOM)
|
||||
@ -141,7 +141,7 @@ async def test_unique_id_is_set(
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
state = hass.states.get(SENSOR_STATE)
|
||||
assert state.state is not None
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user