async def test_get_conditions_set_tilt_pos(hass, device_reg, entity_reg): """Test we get the expected conditions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() ent = platform.ENTITIES[2] config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", ent.unique_id, device_id=device_entry.id) assert await async_setup_component(hass, DOMAIN, {DOMAIN: { CONF_PLATFORM: "test" }}) expected_conditions = [ { "condition": "device", "domain": DOMAIN, "type": "is_open", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "condition": "device", "domain": DOMAIN, "type": "is_closed", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "condition": "device", "domain": DOMAIN, "type": "is_opening", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "condition": "device", "domain": DOMAIN, "type": "is_closing", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "condition": "device", "domain": DOMAIN, "type": "is_tilt_position", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, ] conditions = await async_get_device_automations(hass, "condition", device_entry.id) assert_lists_same(conditions, expected_conditions)
async def test_get_triggers(hass): """Test triggers work.""" data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) device_id = gateway.events[0].device_id triggers = await async_get_device_automations(hass, "trigger", device_id) expected_triggers = [ { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_SHORT_PRESS, "subtype": device_trigger.CONF_TURN_ON, }, { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_LONG_PRESS, "subtype": device_trigger.CONF_TURN_ON, }, { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_LONG_RELEASE, "subtype": device_trigger.CONF_TURN_ON, }, { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_SHORT_PRESS, "subtype": device_trigger.CONF_TURN_OFF, }, { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_LONG_PRESS, "subtype": device_trigger.CONF_TURN_OFF, }, { "device_id": device_id, "domain": "deconz", "platform": "device", "type": device_trigger.CONF_LONG_RELEASE, "subtype": device_trigger.CONF_TURN_OFF, }, { "device_id": device_id, "domain": "sensor", "entity_id": "sensor.tradfri_on_off_switch_battery_level", "platform": "device", "type": "battery_level", }, ] assert_lists_same(triggers, expected_triggers)
async def test_get_triggers(hass, aioclient_mock): """Test triggers work.""" data = { "sensors": { "1": { "config": { "alert": "none", "battery": 60, "group": "10", "on": True, "reachable": True, }, "ep": 1, "etag": "1b355c0b6d2af28febd7ca9165881952", "manufacturername": "IKEA of Sweden", "mode": 1, "modelid": "TRADFRI on/off switch", "name": "TRÅDFRI on/off switch ", "state": {"buttonevent": 2002, "lastupdated": "2019-09-07T07:39:39"}, "swversion": "1.4.018", "type": "ZHASwitch", "uniqueid": "d0:cf:5e:ff:fe:71:a4:3a-01-1000", } } } with patch.dict(DECONZ_WEB_REQUEST, data): await setup_deconz_integration(hass, aioclient_mock) device_registry = await hass.helpers.device_registry.async_get_registry() device = device_registry.async_get_device( identifiers={(DECONZ_DOMAIN, "d0:cf:5e:ff:fe:71:a4:3a")} ) triggers = await async_get_device_automations(hass, "trigger", device.id) expected_triggers = [ { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_SHORT_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_RELEASE, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_SHORT_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_RELEASE, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: SENSOR_DOMAIN, ATTR_ENTITY_ID: "sensor.tradfri_on_off_switch_battery_level", CONF_PLATFORM: "device", CONF_TYPE: ATTR_BATTERY_LEVEL, }, ] assert_lists_same(triggers, expected_triggers)
async def test_get_triggers_button(hass): """Test we get the expected triggers from a shelly button.""" await async_setup_component(hass, "shelly", {}) config_entry = MockConfigEntry( domain=DOMAIN, data={ "sleep_period": 43200, "model": "SHBTN-1", "host": "1.2.3.4" }, unique_id="12345678", ) config_entry.add_to_hass(hass) device = Mock( blocks=None, settings=None, shelly=None, update=AsyncMock(), initialized=False, ) hass.data[DOMAIN] = {DATA_CONFIG_ENTRY: {}} hass.data[DOMAIN][DATA_CONFIG_ENTRY][config_entry.entry_id] = {} coap_wrapper = hass.data[DOMAIN][DATA_CONFIG_ENTRY][ config_entry.entry_id][BLOCK] = BlockDeviceWrapper( hass, config_entry, device) coap_wrapper.async_setup() expected_triggers = [ { CONF_PLATFORM: "device", CONF_DEVICE_ID: coap_wrapper.device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "single", CONF_SUBTYPE: "button", }, { CONF_PLATFORM: "device", CONF_DEVICE_ID: coap_wrapper.device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "double", CONF_SUBTYPE: "button", }, { CONF_PLATFORM: "device", CONF_DEVICE_ID: coap_wrapper.device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "triple", CONF_SUBTYPE: "button", }, { CONF_PLATFORM: "device", CONF_DEVICE_ID: coap_wrapper.device_id, CONF_DOMAIN: DOMAIN, CONF_TYPE: "long", CONF_SUBTYPE: "button", }, ] triggers = await async_get_device_automations(hass, "trigger", coap_wrapper.device_id) assert_lists_same(triggers, expected_triggers)
async def test_get_triggers_set_pos(opp, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected triggers from a cover.""" platform = getattr(opp.components, f"test.{DOMAIN}") platform.init() ent = platform.ENTITIES[1] config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_opp(opp) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", ent.unique_id, device_id=device_entry.id) assert await async_setup_component(opp, DOMAIN, {DOMAIN: { CONF_PLATFORM: "test" }}) expected_triggers = [ { "platform": "device", "domain": DOMAIN, "type": "opened", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "platform": "device", "domain": DOMAIN, "type": "closed", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "platform": "device", "domain": DOMAIN, "type": "opening", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "platform": "device", "domain": DOMAIN, "type": "closing", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, { "platform": "device", "domain": DOMAIN, "type": "position", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_{ent.unique_id}", }, ] triggers = await async_get_device_automations(opp, "trigger", device_entry.id) assert_lists_same(triggers, expected_triggers)
async def test_get_maximum_conditions(opp, device_reg, entity_reg): """Test we get the expected conditions from a alarm_control_panel.""" config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_opp(opp) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) opp.states.async_set("alarm_control_panel.test_5678", "attributes", {"supported_features": 31}) expected_conditions = [ { "condition": "device", "domain": DOMAIN, "type": "is_disarmed", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "condition": "device", "domain": DOMAIN, "type": "is_triggered", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "condition": "device", "domain": DOMAIN, "type": "is_armed_home", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "condition": "device", "domain": DOMAIN, "type": "is_armed_away", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "condition": "device", "domain": DOMAIN, "type": "is_armed_night", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "condition": "device", "domain": DOMAIN, "type": "is_armed_custom_bypass", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, ] conditions = await async_get_device_automations(opp, "condition", device_entry.id) assert_lists_same(conditions, expected_conditions)
async def test_discover_bad_triggers( hass, device_reg, entity_reg, mqtt_mock, setup_tasmota ): """Test exception handling when discovering trigger.""" config = copy.deepcopy(DEFAULT_CONFIG) config["swc"][0] = 0 mac = config["mac"] # Trigger an exception when the entity is discovered with patch( "hatasmota.discovery.get_switch_triggers", return_value=[object()], ): async_fire_mqtt_message( hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config) ) await hass.async_block_till_done() device_entry = device_reg.async_get_device( set(), {(dr.CONNECTION_NETWORK_MAC, mac)} ) triggers = await async_get_device_automations(hass, "trigger", device_entry.id) assert_lists_same(triggers, []) # Trigger an exception when the entity is discovered class FakeTrigger(TasmotaSwitchTriggerConfig): """Bad TasmotaSwitchTriggerConfig to cause exceptions.""" @property def is_active(self): return True with patch( "hatasmota.discovery.get_switch_triggers", return_value=[ FakeTrigger( event=None, idx=1, mac=None, source=None, subtype=None, switchname=None, trigger_topic=None, type=None, ) ], ): async_fire_mqtt_message( hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config) ) await hass.async_block_till_done() device_entry = device_reg.async_get_device( set(), {(dr.CONNECTION_NETWORK_MAC, mac)} ) triggers = await async_get_device_automations(hass, "trigger", device_entry.id) assert_lists_same(triggers, []) # Rediscover without exception async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() expected_triggers = [ { "platform": "device", "domain": DOMAIN, "device_id": device_entry.id, "discovery_id": "00000049A3BC_switch_1_TOGGLE", "type": "button_short_press", "subtype": "switch_1", }, ] triggers = await async_get_device_automations(hass, "trigger", device_entry.id) assert_lists_same(triggers, expected_triggers)
async def test_get_triggers(hass, device_reg, entity_reg): """Test we get the expected triggers from an alarm_control_panel.""" config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) device_entry = device_reg.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) hass.states.async_set("alarm_control_panel.test_5678", "attributes", {"supported_features": 15}) expected_triggers = [ { "platform": "device", "domain": DOMAIN, "type": "disarmed", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "platform": "device", "domain": DOMAIN, "type": "triggered", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "platform": "device", "domain": DOMAIN, "type": "arming", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "platform": "device", "domain": DOMAIN, "type": "armed_home", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "platform": "device", "domain": DOMAIN, "type": "armed_away", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, { "platform": "device", "domain": DOMAIN, "type": "armed_night", "device_id": device_entry.id, "entity_id": f"{DOMAIN}.test_5678", }, ] triggers = await async_get_device_automations(hass, "trigger", device_entry.id) assert_lists_same(triggers, expected_triggers)
async def test_get_triggers(hass): """Test triggers work.""" data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) config_entry = await setup_deconz_integration(hass, get_state_response=data) gateway = get_gateway_from_config_entry(hass, config_entry) device_id = gateway.events[0].device_id triggers = await async_get_device_automations(hass, "trigger", device_id) expected_triggers = [ { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_SHORT_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_RELEASE, CONF_SUBTYPE: device_trigger.CONF_TURN_ON, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_SHORT_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_PRESS, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DECONZ_DOMAIN, CONF_PLATFORM: "device", CONF_TYPE: device_trigger.CONF_LONG_RELEASE, CONF_SUBTYPE: device_trigger.CONF_TURN_OFF, }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: SENSOR_DOMAIN, ATTR_ENTITY_ID: "sensor.tradfri_on_off_switch_battery_level", CONF_PLATFORM: "device", CONF_TYPE: ATTR_BATTERY_LEVEL, }, ] assert_lists_same(triggers, expected_triggers)
async def test_alerts_change( hass: HomeAssistant, hass_ws_client, aioclient_mock: AiohttpClientMocker, ha_version: str, fixture_1: str, expected_alerts_1: list[tuple(str, str)], fixture_2: str, expected_alerts_2: list[tuple(str, str)], ) -> None: """Test creating issues based on alerts.""" fixture_1_content = load_fixture(fixture_1, "homeassistant_alerts") aioclient_mock.clear_requests() aioclient_mock.get( "https://alerts.home-assistant.io/alerts.json", text=fixture_1_content, ) for alert in json.loads(fixture_1_content): stub_alert(aioclient_mock, alert["filename"]) activated_components = ( "aladdin_connect", "darksky", "hikvision", "hikvisioncam", "hive", "homematicip_cloud", "logi_circle", "neato", "nest", "senseme", "sochain", ) for domain in activated_components: hass.config.components.add(domain) with patch( "homeassistant.components.homeassistant_alerts.__version__", ha_version, ): assert await async_setup_component(hass, DOMAIN, {}) now = dt_util.utcnow() client = await hass_ws_client(hass) await client.send_json({"id": 1, "type": "repairs/list_issues"}) msg = await client.receive_json() assert msg["success"] assert_lists_same( msg["result"]["issues"], [{ "breaks_in_ha_version": None, "created": ANY, "dismissed_version": None, "domain": "homeassistant_alerts", "ignored": False, "is_fixable": False, "issue_id": f"{alert}_{integration}", "issue_domain": integration, "learn_more_url": None, "severity": "warning", "translation_key": "alert", "translation_placeholders": { "title": f"Title for {alert}", "description": f"Content for {alert}", }, } for alert, integration in expected_alerts_1], ) fixture_2_content = load_fixture(fixture_2, "homeassistant_alerts") aioclient_mock.clear_requests() aioclient_mock.get( "https://alerts.home-assistant.io/alerts.json", text=fixture_2_content, ) for alert in json.loads(fixture_2_content): stub_alert(aioclient_mock, alert["filename"]) future = now + UPDATE_INTERVAL + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() await client.send_json({"id": 2, "type": "repairs/list_issues"}) msg = await client.receive_json() assert msg["success"] assert_lists_same( msg["result"]["issues"], [{ "breaks_in_ha_version": None, "created": ANY, "dismissed_version": None, "domain": "homeassistant_alerts", "ignored": False, "is_fixable": False, "issue_id": f"{alert}_{integration}", "issue_domain": integration, "learn_more_url": None, "severity": "warning", "translation_key": "alert", "translation_placeholders": { "title": f"Title for {alert}", "description": f"Content for {alert}", }, } for alert, integration in expected_alerts_2], )
async def test_get_triggers(hass, device_reg): """Test we get the expected triggers from a lutron pico.""" config_entry_id = await _async_setup_lutron_with_picos(hass, device_reg) dr_button_devices = hass.data[DOMAIN][config_entry_id][BUTTON_DEVICES] device_id = list(dr_button_devices)[0] expected_triggers = [ { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "on", CONF_TYPE: "press", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "stop", CONF_TYPE: "press", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "off", CONF_TYPE: "press", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "raise", CONF_TYPE: "press", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "lower", CONF_TYPE: "press", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "on", CONF_TYPE: "release", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "stop", CONF_TYPE: "release", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "off", CONF_TYPE: "release", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "raise", CONF_TYPE: "release", }, { CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, CONF_PLATFORM: "device", CONF_SUBTYPE: "lower", CONF_TYPE: "release", }, ] triggers = await async_get_device_automations(hass, "trigger", device_id) assert_lists_same(triggers, expected_triggers)
async def test_get_triggers_for_alarm_event(hass, aioclient_mock): """Test triggers work.""" data = { "sensors": { "1": { "config": { "battery": 95, "enrolled": 1, "on": True, "pending": [], "reachable": True, }, "ep": 1, "etag": "5aaa1c6bae8501f59929539c6e8f44d6", "lastseen": "2021-07-25T18:07Z", "manufacturername": "lk", "modelid": "ZB-KeypadGeneric-D0002", "name": "Keypad", "state": { "action": "armed_stay", "lastupdated": "2021-07-25T18:02:51.172", "lowbattery": False, "panel": "exit_delay", "seconds_remaining": 55, "tampered": False, }, "swversion": "3.13", "type": "ZHAAncillaryControl", "uniqueid": "00:00:00:00:00:00:00:00-00", } } } with patch.dict(DECONZ_WEB_REQUEST, data): await setup_deconz_integration(hass, aioclient_mock) device_registry = dr.async_get(hass) device = device_registry.async_get_device( identifiers={(DECONZ_DOMAIN, "00:00:00:00:00:00:00:00")} ) triggers = await async_get_device_automations( hass, DeviceAutomationType.TRIGGER, device.id ) expected_triggers = [ { CONF_DEVICE_ID: device.id, CONF_DOMAIN: BINARY_SENSOR_DOMAIN, ATTR_ENTITY_ID: "binary_sensor.keypad_low_battery", CONF_PLATFORM: "device", CONF_TYPE: CONF_BAT_LOW, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: BINARY_SENSOR_DOMAIN, ATTR_ENTITY_ID: "binary_sensor.keypad_low_battery", CONF_PLATFORM: "device", CONF_TYPE: CONF_NOT_BAT_LOW, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: BINARY_SENSOR_DOMAIN, ATTR_ENTITY_ID: "binary_sensor.keypad_tampered", CONF_PLATFORM: "device", CONF_TYPE: CONF_TAMPERED, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: BINARY_SENSOR_DOMAIN, ATTR_ENTITY_ID: "binary_sensor.keypad_tampered", CONF_PLATFORM: "device", CONF_TYPE: CONF_NOT_TAMPERED, }, { CONF_DEVICE_ID: device.id, CONF_DOMAIN: SENSOR_DOMAIN, ATTR_ENTITY_ID: "sensor.keypad_battery", CONF_PLATFORM: "device", CONF_TYPE: ATTR_BATTERY_LEVEL, }, ] assert_lists_same(triggers, expected_triggers)
async def test_update_remove_triggers(hass, device_reg, entity_reg, mqtt_mock): """Test triggers can be updated and removed.""" config1 = { "automation_type": "trigger", "device": { "identifiers": ["0AFFD2"] }, "payload": "short_press", "topic": "foobar/triggers/button1", "type": "button_short_press", "subtype": "button_1", } config1["some_future_option_1"] = "future_option_1" data1 = json.dumps(config1) config2 = { "automation_type": "trigger", "device": { "identifiers": ["0AFFD2"] }, "payload": "short_press", "topic": "foobar/triggers/button1", "type": "button_short_press", "subtype": "button_2", } config2["topic"] = "foobar/tag_scanned2" data2 = json.dumps(config2) async_fire_mqtt_message(hass, "homeassistant/device_automation/bla/config", data1) await hass.async_block_till_done() device_entry = device_reg.async_get_device({("mqtt", "0AFFD2")}) expected_triggers1 = [ { "platform": "device", "domain": DOMAIN, "device_id": device_entry.id, "discovery_id": "bla", "type": "button_short_press", "subtype": "button_1", }, ] expected_triggers2 = [dict(expected_triggers1[0])] expected_triggers2[0]["subtype"] = "button_2" triggers = await async_get_device_automations(hass, DeviceAutomationType.TRIGGER, device_entry.id) assert_lists_same(triggers, expected_triggers1) # Update trigger async_fire_mqtt_message(hass, "homeassistant/device_automation/bla/config", data2) await hass.async_block_till_done() triggers = await async_get_device_automations(hass, DeviceAutomationType.TRIGGER, device_entry.id) assert_lists_same(triggers, expected_triggers2) # Remove trigger async_fire_mqtt_message(hass, "homeassistant/device_automation/bla/config", "") await hass.async_block_till_done() device_entry = device_reg.async_get_device({("mqtt", "0AFFD2")}) assert device_entry is None
async def test_automation_breakpoints(hass, hass_ws_client): """Test automation breakpoints.""" id = 1 def next_id(): nonlocal id id += 1 return id async def assert_last_action(automation_id, expected_action, expected_state): await client.send_json({"id": next_id(), "type": "automation/trace/list"}) response = await client.receive_json() assert response["success"] trace = _find_traces_for_automation(response["result"], automation_id)[-1] assert trace["last_action"] == expected_action assert trace["state"] == expected_state return trace["run_id"] sun_config = { "id": "sun", "trigger": {"platform": "event", "event_type": "test_event"}, "action": [ {"event": "event0"}, {"event": "event1"}, {"event": "event2"}, {"event": "event3"}, {"event": "event4"}, {"event": "event5"}, {"event": "event6"}, {"event": "event7"}, {"event": "event8"}, ], } assert await async_setup_component( hass, "automation", { "automation": [ sun_config, ] }, ) with patch.object(config, "SECTIONS", ["automation"]): await async_setup_component(hass, "config", {}) client = await hass_ws_client() await client.send_json( { "id": next_id(), "type": "automation/debug/breakpoint/set", "automation_id": "sun", "node": "1", } ) response = await client.receive_json() assert not response["success"] await client.send_json( {"id": next_id(), "type": "automation/debug/breakpoint/list"} ) response = await client.receive_json() assert response["success"] assert response["result"] == [] subscription_id = next_id() await client.send_json( {"id": subscription_id, "type": "automation/debug/breakpoint/subscribe"} ) response = await client.receive_json() assert response["success"] await client.send_json( { "id": next_id(), "type": "automation/debug/breakpoint/set", "automation_id": "sun", "node": "action/1", } ) response = await client.receive_json() assert response["success"] await client.send_json( { "id": next_id(), "type": "automation/debug/breakpoint/set", "automation_id": "sun", "node": "action/5", } ) response = await client.receive_json() assert response["success"] await client.send_json( {"id": next_id(), "type": "automation/debug/breakpoint/list"} ) response = await client.receive_json() assert response["success"] assert_lists_same( response["result"], [ {"node": "action/1", "run_id": "*", "automation_id": "sun"}, {"node": "action/5", "run_id": "*", "automation_id": "sun"}, ], ) # Trigger "sun" automation hass.bus.async_fire("test_event") response = await client.receive_json() run_id = await assert_last_action("sun", "action/1", "running") assert response["event"] == { "automation_id": "sun", "node": "action/1", "run_id": run_id, } await client.send_json( { "id": next_id(), "type": "automation/debug/step", "automation_id": "sun", "run_id": run_id, } ) response = await client.receive_json() assert response["success"] response = await client.receive_json() run_id = await assert_last_action("sun", "action/2", "running") assert response["event"] == { "automation_id": "sun", "node": "action/2", "run_id": run_id, } await client.send_json( { "id": next_id(), "type": "automation/debug/continue", "automation_id": "sun", "run_id": run_id, } ) response = await client.receive_json() assert response["success"] response = await client.receive_json() run_id = await assert_last_action("sun", "action/5", "running") assert response["event"] == { "automation_id": "sun", "node": "action/5", "run_id": run_id, } await client.send_json( { "id": next_id(), "type": "automation/debug/stop", "automation_id": "sun", "run_id": run_id, } ) response = await client.receive_json() assert response["success"] await hass.async_block_till_done() await assert_last_action("sun", "action/5", "stopped")
async def test_breakpoints(hass, hass_ws_client, domain, prefix): """Test script and automation breakpoints.""" id = 1 def next_id(): nonlocal id id += 1 return id async def assert_last_step(item_id, expected_action, expected_state): await client.send_json({ "id": next_id(), "type": "trace/list", "domain": domain }) response = await client.receive_json() assert response["success"] trace = _find_traces(response["result"], domain, item_id)[-1] assert trace["last_step"] == expected_action assert trace["state"] == expected_state return trace["run_id"] sun_config = { "id": "sun", "trigger": { "platform": "event", "event_type": "test_event" }, "action": [ { "event": "event0" }, { "event": "event1" }, { "event": "event2" }, { "event": "event3" }, { "event": "event4" }, { "event": "event5" }, { "event": "event6" }, { "event": "event7" }, { "event": "event8" }, ], } await _setup_automation_or_script(hass, domain, [sun_config]) client = await hass_ws_client() await client.send_json({ "id": next_id(), "type": "trace/debug/breakpoint/set", "domain": domain, "item_id": "sun", "node": "1", }) response = await client.receive_json() assert not response["success"] await client.send_json({ "id": next_id(), "type": "trace/debug/breakpoint/list" }) response = await client.receive_json() assert response["success"] assert response["result"] == [] subscription_id = next_id() await client.send_json({ "id": subscription_id, "type": "trace/debug/breakpoint/subscribe" }) response = await client.receive_json() assert response["success"] await client.send_json({ "id": next_id(), "type": "trace/debug/breakpoint/set", "domain": domain, "item_id": "sun", "node": f"{prefix}/1", }) response = await client.receive_json() assert response["success"] await client.send_json({ "id": next_id(), "type": "trace/debug/breakpoint/set", "domain": domain, "item_id": "sun", "node": f"{prefix}/5", }) response = await client.receive_json() assert response["success"] await client.send_json({ "id": next_id(), "type": "trace/debug/breakpoint/list" }) response = await client.receive_json() assert response["success"] assert_lists_same( response["result"], [ { "node": f"{prefix}/1", "run_id": "*", "domain": domain, "item_id": "sun" }, { "node": f"{prefix}/5", "run_id": "*", "domain": domain, "item_id": "sun" }, ], ) # Trigger "sun" automation / run "sun" script await _run_automation_or_script(hass, domain, sun_config, "test_event") response = await client.receive_json() run_id = await assert_last_step("sun", f"{prefix}/1", "running") assert response["event"] == { "domain": domain, "item_id": "sun", "node": f"{prefix}/1", "run_id": run_id, } await client.send_json({ "id": next_id(), "type": "trace/debug/step", "domain": domain, "item_id": "sun", "run_id": run_id, }) response = await client.receive_json() assert response["success"] response = await client.receive_json() run_id = await assert_last_step("sun", f"{prefix}/2", "running") assert response["event"] == { "domain": domain, "item_id": "sun", "node": f"{prefix}/2", "run_id": run_id, } await client.send_json({ "id": next_id(), "type": "trace/debug/continue", "domain": domain, "item_id": "sun", "run_id": run_id, }) response = await client.receive_json() assert response["success"] response = await client.receive_json() run_id = await assert_last_step("sun", f"{prefix}/5", "running") assert response["event"] == { "domain": domain, "item_id": "sun", "node": f"{prefix}/5", "run_id": run_id, } await client.send_json({ "id": next_id(), "type": "trace/debug/stop", "domain": domain, "item_id": "sun", "run_id": run_id, }) response = await client.receive_json() assert response["success"] await hass.async_block_till_done() await assert_last_step("sun", f"{prefix}/5", "stopped")