示例#1
0
async def test_doorbell_event_thread(hass, subscriber, setup_platform):
    """Test a series of pubsub messages in the same thread."""
    events = async_capture_events(hass, NEST_EVENT)
    await setup_platform()
    registry = er.async_get(hass)
    entry = registry.async_get("camera.front")
    assert entry is not None

    event_message_data = {
        "eventId": "some-event-id-ignored",
        "resourceUpdate": {
            "name": DEVICE_ID,
            "events": {
                "sdm.devices.events.CameraMotion.Motion": {
                    "eventSessionId": EVENT_SESSION_ID,
                    "eventId": "n:1",
                },
                "sdm.devices.events.CameraClipPreview.ClipPreview": {
                    "eventSessionId": EVENT_SESSION_ID,
                    "previewUrl": "image-url-1",
                },
            },
        },
        "eventThreadId": "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
        "resourcegroup": [DEVICE_ID],
    }

    # Publish message #1 that starts the event thread
    timestamp1 = utcnow()
    message_data_1 = event_message_data.copy()
    message_data_1.update(
        {
            "timestamp": timestamp1.isoformat(timespec="seconds"),
            "eventThreadState": "STARTED",
        }
    )
    await subscriber.async_receive_event(EventMessage(message_data_1, auth=None))

    # Publish message #2 that sends a no-op update to end the event thread
    timestamp2 = timestamp1 + datetime.timedelta(seconds=1)
    message_data_2 = event_message_data.copy()
    message_data_2.update(
        {
            "timestamp": timestamp2.isoformat(timespec="seconds"),
            "eventThreadState": "ENDED",
        }
    )
    await subscriber.async_receive_event(EventMessage(message_data_2, auth=None))
    await hass.async_block_till_done()

    # The event is only published once
    assert len(events) == 1
    assert event_view(events[0].data) == {
        "device_id": entry.device_id,
        "type": "camera_motion",
        "timestamp": timestamp1.replace(microsecond=0),
    }
示例#2
0
async def test_thermostat_target_temp(hass, auth):
    """Test a thermostat changing hvac modes and affected on target temps."""
    subscriber = await setup_climate(
        hass,
        {
            "sdm.devices.traits.ThermostatHvac": {
                "status": "HEATING",
            },
            "sdm.devices.traits.ThermostatMode": {
                "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                "mode": "HEAT",
            },
            "sdm.devices.traits.Temperature": {
                "ambientTemperatureCelsius": 20.1,
            },
            "sdm.devices.traits.ThermostatTemperatureSetpoint": {
                "heatCelsius": 23.0,
            },
        },
        auth=auth,
    )

    assert len(hass.states.async_all()) == 1
    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_HEAT
    assert thermostat.attributes[ATTR_TEMPERATURE] == 23.0
    assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] is None
    assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] is None

    # Simulate pubsub message changing modes
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": "some-device-id",
                "traits": {
                    "sdm.devices.traits.ThermostatMode": {
                        "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                        "mode": "HEATCOOL",
                    },
                    "sdm.devices.traits.ThermostatTemperatureSetpoint": {
                        "heatCelsius": 22.0,
                        "coolCelsius": 28.0,
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_HEAT_COOL
    assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 22.0
    assert thermostat.attributes[ATTR_TARGET_TEMP_HIGH] == 28.0
    assert thermostat.attributes[ATTR_TEMPERATURE] is None
示例#3
0
def make_motion_event(
    event_id: str = MOTION_EVENT_ID,
    event_session_id: str = EVENT_SESSION_ID,
    timestamp: datetime.datetime = None,
) -> EventMessage:
    """Create an EventMessage for a motion event."""
    if not timestamp:
        timestamp = utcnow()
    return EventMessage(
        {
            "eventId":
            "some-event-id",  # Ignored; we use the resource updated event id below
            "timestamp": timestamp.isoformat(timespec="seconds"),
            "resourceUpdate": {
                "name": DEVICE_ID,
                "events": {
                    "sdm.devices.events.CameraMotion.Motion": {
                        "eventSessionId": event_session_id,
                        "eventId": event_id,
                    },
                },
            },
        },
        auth=None,
    )
示例#4
0
文件: test_events.py 项目: 2Fake/core
async def test_structure_update_event(hass):
    """Test a pubsub message for a new device being added."""
    events = async_capture_events(hass, NEST_EVENT)
    subscriber = await async_setup_devices(
        hass,
        "sdm.devices.types.DOORBELL",
        create_device_traits(["sdm.devices.traits.DoorbellChime"]),
    )

    # Entity for first device is registered
    registry = er.async_get(hass)
    assert registry.async_get("camera.front")

    new_device = Device.MakeDevice(
        {
            "name": "device-id-2",
            "type": "sdm.devices.types.CAMERA",
            "traits": {
                "sdm.devices.traits.Info": {
                    "customName": "Back",
                },
                "sdm.devices.traits.CameraLiveStream": {},
            },
        },
        auth=None,
    )
    device_manager = await subscriber.async_get_device_manager()
    device_manager.add_device(new_device)

    # Entity for new devie has not yet been loaded
    assert not registry.async_get("camera.back")

    # Send a message that triggers the device to be loaded
    message = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": utcnow().isoformat(timespec="seconds"),
            "relationUpdate": {
                "type": "CREATED",
                "subject": "enterprise/example/foo",
                "object": "enterprise/example/devices/some-device-id2",
            },
        },
        auth=None,
    )
    with patch(
        "homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation"
    ), patch("homeassistant.components.nest.PLATFORMS", [PLATFORM]), patch(
        "homeassistant.components.nest.api.GoogleNestSubscriber",
        return_value=subscriber,
    ):
        await subscriber.async_receive_event(message)
        await hass.async_block_till_done()

    # No home assistant events published
    assert not events

    assert registry.async_get("camera.front")
    # Currently need a manual reload to detect the new entity
    assert not registry.async_get("camera.back")
示例#5
0
def create_event_message(event_id, event_data, timestamp):
    """Create an EventMessage for a single event type."""
    return EventMessage(
        {
            "eventId": f"{event_id}-{timestamp}",
            "timestamp": timestamp.isoformat(timespec="seconds"),
            "resourceUpdate": {
                "name": DEVICE_ID,
                "events": event_data,
            },
        },
        auth=None,
    )
def create_events(events, device_id=DEVICE_ID):
    """Create an EventMessage for events."""
    return EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": utcnow().isoformat(timespec="seconds"),
            "resourceUpdate": {
                "name": device_id,
                "events": events,
            },
        },
        auth=None,
    )
示例#7
0
 async def create_event(traits: dict[str, Any]) -> None:
     await subscriber.async_receive_event(
         EventMessage(
             {
                 "eventId": EVENT_ID,
                 "timestamp": "2019-01-01T00:00:01Z",
                 "resourceUpdate": {
                     "name": DEVICE_ID,
                     "traits": traits,
                 },
             },
             auth=auth,
         ))
     await hass.async_block_till_done()
示例#8
0
def create_event_message(event_data, timestamp, device_id=None):
    """Create an EventMessage for a single event type."""
    if device_id is None:
        device_id = DEVICE_ID
    return EventMessage(
        {
            "eventId": f"{EVENT_ID}-{timestamp}",
            "timestamp": timestamp.isoformat(timespec="seconds"),
            "resourceUpdate": {
                "name": device_id,
                "events": event_data,
            },
        },
        auth=None,
    )
async def test_event_updates_sensor(hass):
    """Test a pubsub message received by subscriber to update temperature."""
    devices = {
        "some-device-id":
        Device.MakeDevice(
            {
                "name": "some-device-id",
                "type": THERMOSTAT_TYPE,
                "traits": {
                    "sdm.devices.traits.Info": {
                        "customName": "My Sensor",
                    },
                    "sdm.devices.traits.Temperature": {
                        "ambientTemperatureCelsius": 25.1,
                    },
                },
            },
            auth=None,
        )
    }
    subscriber = await async_setup_sensor(hass, devices)

    temperature = hass.states.get("sensor.my_sensor_temperature")
    assert temperature is not None
    assert temperature.state == "25.1"

    # Simulate a pubsub message received by the subscriber with a trait update
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": "some-device-id",
                "traits": {
                    "sdm.devices.traits.Temperature": {
                        "ambientTemperatureCelsius": 26.2,
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    temperature = hass.states.get("sensor.my_sensor_temperature")
    assert temperature is not None
    assert temperature.state == "26.2"
示例#10
0
async def test_event_message_without_device_event(hass, subscriber, setup_platform):
    """Test a pubsub message for an unknown event type."""
    events = async_capture_events(hass, NEST_EVENT)
    await setup_platform()
    timestamp = utcnow()
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": timestamp.isoformat(timespec="seconds"),
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()

    assert len(events) == 0
示例#11
0
async def test_subscriber_automation(
    hass: HomeAssistant,
    calls: list,
    create_device: CreateDevice,
    setup_platform: PlatformSetup,
    subscriber: FakeSubscriber,
) -> None:
    """Test end to end subscriber triggers automation."""
    create_device.create(raw_data=make_camera(
        device_id=DEVICE_ID,
        traits={
            "sdm.devices.traits.CameraMotion": {},
        },
    ))
    await setup_platform()

    device_registry = dr.async_get(hass)
    device_entry = device_registry.async_get_device({("nest", DEVICE_ID)})

    assert await setup_automation(hass, device_entry.id, "camera_motion")

    # Simulate a pubsub message received by the subscriber with a motion event
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": DEVICE_ID,
                "events": {
                    "sdm.devices.events.CameraMotion.Motion": {
                        "eventSessionId": "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
                        "eventId": "FWWVQVUdGNUlTU2V4MGV2aTNXV...",
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].data == DATA_MESSAGE
示例#12
0
async def test_event_updates_sensor(
    hass: HomeAssistant,
    subscriber: FakeSubscriber,
    create_device: CreateDevice,
    setup_platform: PlatformSetup,
) -> None:
    """Test a pubsub message received by subscriber to update temperature."""
    create_device.create(
        {
            "sdm.devices.traits.Temperature": {
                "ambientTemperatureCelsius": 25.1,
            },
        }
    )
    await setup_platform()

    temperature = hass.states.get("sensor.my_sensor_temperature")
    assert temperature is not None
    assert temperature.state == "25.1"

    # Simulate a pubsub message received by the subscriber with a trait update
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": DEVICE_ID,
                "traits": {
                    "sdm.devices.traits.Temperature": {
                        "ambientTemperatureCelsius": 26.2,
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    temperature = hass.states.get("sensor.my_sensor_temperature")
    assert temperature is not None
    assert temperature.state == "26.2"
示例#13
0
async def test_event_message_without_device_event(hass):
    """Test a pubsub message for an unknown event type."""
    events = async_capture_events(hass, NEST_EVENT)
    subscriber = await async_setup_devices(
        hass,
        "sdm.devices.types.DOORBELL",
        create_device_traits("sdm.devices.traits.DoorbellChime"),
    )
    timestamp = utcnow()
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": timestamp.isoformat(timespec="seconds"),
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()

    assert len(events) == 0
async def test_subscriber_automation(hass, calls):
    """Test end to end subscriber triggers automation."""
    camera = make_camera(
        device_id=DEVICE_ID,
        traits={
            "sdm.devices.traits.CameraMotion": {},
        },
    )
    subscriber = await async_setup_camera(hass, {DEVICE_ID: camera})

    device_registry = await hass.helpers.device_registry.async_get_registry()
    device_entry = device_registry.async_get_device({("nest", DEVICE_ID)},
                                                    connections={})

    assert await setup_automation(hass, device_entry.id, "camera_motion")

    # Simulate a pubsub message received by the subscriber with a motion event
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": DEVICE_ID,
                "events": {
                    "sdm.devices.events.CameraMotion.Motion": {
                        "eventSessionId": "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
                        "eventId": "FWWVQVUdGNUlTU2V4MGV2aTNXV...",
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].data == DATA_MESSAGE
def MakeEvent(raw_data: dict) -> EventMessage:
    return EventMessage(raw_data, auth=None)
示例#16
0
async def test_thermostat_set_eco_preset(hass, auth):
    """Test a thermostat put into eco mode."""
    subscriber = await setup_climate(
        hass,
        {
            "sdm.devices.traits.ThermostatHvac": {
                "status": "OFF"
            },
            "sdm.devices.traits.ThermostatEco": {
                "availableModes": ["MANUAL_ECO", "OFF"],
                "mode": "OFF",
                "heatCelsius": 15.0,
                "coolCelsius": 28.0,
            },
            "sdm.devices.traits.ThermostatMode": {
                "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                "mode": "OFF",
            },
        },
        auth=auth,
    )

    assert len(hass.states.async_all()) == 1
    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_OFF
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
    assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE

    # Turn on eco mode
    await common.async_set_preset_mode(hass, PRESET_ECO)
    await hass.async_block_till_done()

    assert auth.method == "post"
    assert auth.url == "some-device-id:executeCommand"
    assert auth.json == {
        "command": "sdm.devices.commands.ThermostatEco.SetMode",
        "params": {
            "mode": "MANUAL_ECO"
        },
    }

    # Local state does not reflect the update
    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_OFF
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
    assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE

    # Simulate pubsub message when mode changes
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": "some-device-id",
                "traits": {
                    "sdm.devices.traits.ThermostatEco": {
                        "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                        "mode": "MANUAL_ECO",
                        "heatCelsius": 15.0,
                        "coolCelsius": 28.0,
                    },
                },
            },
        },
        auth=auth,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_OFF
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
    assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO

    # Turn off eco mode
    await common.async_set_preset_mode(hass, PRESET_NONE)
    await hass.async_block_till_done()

    assert auth.method == "post"
    assert auth.url == "some-device-id:executeCommand"
    assert auth.json == {
        "command": "sdm.devices.commands.ThermostatEco.SetMode",
        "params": {
            "mode": "OFF"
        },
    }
示例#17
0
async def test_thermostat_set_hvac_mode(hass, auth):
    """Test a thermostat changing hvac modes."""
    subscriber = await setup_climate(
        hass,
        {
            "sdm.devices.traits.ThermostatHvac": {
                "status": "OFF"
            },
            "sdm.devices.traits.ThermostatMode": {
                "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                "mode": "OFF",
            },
        },
        auth=auth,
    )

    assert len(hass.states.async_all()) == 1
    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_OFF
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF

    await common.async_set_hvac_mode(hass, HVAC_MODE_HEAT)
    await hass.async_block_till_done()

    assert auth.method == "post"
    assert auth.url == "some-device-id:executeCommand"
    assert auth.json == {
        "command": "sdm.devices.commands.ThermostatMode.SetMode",
        "params": {
            "mode": "HEAT"
        },
    }

    # Local state does not reflect the update
    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_OFF
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF

    # Simulate pubsub message when mode changes
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": "some-device-id",
                "traits": {
                    "sdm.devices.traits.ThermostatMode": {
                        "availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
                        "mode": "HEAT",
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_HEAT
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF

    # Simulate pubsub message when the thermostat starts heating
    event = EventMessage(
        {
            "eventId": "some-event-id",
            "timestamp": "2019-01-01T00:00:01Z",
            "resourceUpdate": {
                "name": "some-device-id",
                "traits": {
                    "sdm.devices.traits.ThermostatHvac": {
                        "status": "HEATING",
                    },
                },
            },
        },
        auth=None,
    )
    await subscriber.async_receive_event(event)
    await hass.async_block_till_done()  # Process dispatch/update signal

    thermostat = hass.states.get("climate.my_thermostat")
    assert thermostat is not None
    assert thermostat.state == HVAC_MODE_HEAT
    assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_HEAT