def test_device_name_room(): """Test a device name from the room name.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.DOORBELL", "parentRelations": [{ "parent": "some-structure-id", "displayName": "Some Room" }], }, auth=None, ) device_info = DeviceInfo(device) assert device_info.device_name == "Some Room" assert device_info.device_model == "Doorbell" assert device_info.device_brand == "Google Nest" assert device_info.device_info == { "identifiers": {("nest", "some-device-id")}, "name": "Some Room", "manufacturer": "Google Nest", "model": "Doorbell", }
def test_device_custom_name(): """Test a device name from an Info trait.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.DOORBELL", "traits": { "sdm.devices.traits.Info": { "customName": "My Doorbell", }, }, }, auth=None, ) device_info = NestDeviceInfo(device) assert device_info.device_name == "My Doorbell" assert device_info.device_model == "Doorbell" assert device_info.device_brand == "Google Nest" assert device_info.device_info == { ATTR_IDENTIFIERS: {("nest", "some-device-id")}, ATTR_NAME: "My Doorbell", ATTR_MANUFACTURER: "Google Nest", ATTR_MODEL: "Doorbell", ATTR_SUGGESTED_AREA: None, }
def test_suggested_area(): """Test the suggested area with different device name and room name.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.DOORBELL", "traits": { "sdm.devices.traits.Info": { "customName": "My Doorbell", }, }, "parentRelations": [{ "parent": "some-structure-id", "displayName": "Some Room" }], }, auth=None, ) device_info = NestDeviceInfo(device) assert device_info.device_name == "My Doorbell" assert device_info.device_model == "Doorbell" assert device_info.device_brand == "Google Nest" assert device_info.device_info == { ATTR_IDENTIFIERS: {("nest", "some-device-id")}, ATTR_NAME: "My Doorbell", ATTR_MANUFACTURER: "Google Nest", ATTR_MODEL: "Doorbell", ATTR_SUGGESTED_AREA: "Some Room", }
def test_device_invalid_type(): """Test a device with a type name that is not recognized.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.INVALID_TYPE", "traits": { "sdm.devices.traits.Info": { "customName": "My Doorbell", }, }, }, auth=None, ) device_info = NestDeviceInfo(device) assert device_info.device_name == "My Doorbell" assert device_info.device_model is None assert device_info.device_brand == "Google Nest" assert device_info.device_info == { ATTR_IDENTIFIERS: {("nest", "some-device-id")}, ATTR_NAME: "My Doorbell", ATTR_MANUFACTURER: "Google Nest", ATTR_MODEL: None, ATTR_SUGGESTED_AREA: None, }
def test_device_name_room(): """Test a device name from the room name.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.DOORBELL", "parentRelations": [{ "parent": "some-structure-id", "displayName": "Some Room" }], }, auth=None, ) device_info = NestDeviceInfo(device) assert device_info.device_name == "Some Room" assert device_info.device_model == "Doorbell" assert device_info.device_brand == "Google Nest" assert device_info.device_info == { ATTR_IDENTIFIERS: {("nest", "some-device-id")}, ATTR_NAME: "Some Room", ATTR_MANUFACTURER: "Google Nest", ATTR_MODEL: "Doorbell", ATTR_SUGGESTED_AREA: "Some Room", }
async def test_device_name_from_structure(hass): """Test a device without a custom name, inferring name from structure.""" devices = { "some-device-id": Device.MakeDevice( { "name": "some-device-id", "type": THERMOSTAT_TYPE, "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 25.2, }, }, "parentRelations": [{ "parent": "some-structure-id", "displayName": "Some Room" }], }, auth=None, ) } await async_setup_sensor(hass, devices) temperature = hass.states.get("sensor.some_room_temperature") assert temperature is not None assert temperature.state == "25.2"
def testNoTraits(self): raw = { "name": "my/device/name", } device = Device.MakeDevice(raw, auth=None) self.assertEqual("my/device/name", device.name) self.assertFalse("sdm.devices.traits.Info" in device.traits)
def testNoParentRelations(self): raw = { "name": "my/device/name", } device = Device.MakeDevice(raw, auth=None) self.assertEqual("my/device/name", device.name) self.assertEqual({}, device.parent_relations)
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")
def test_no_parent_relations(): raw = { "name": "my/device/name", } device = Device.MakeDevice(raw, auth=None) assert "my/device/name" == device.name assert {} == device.parent_relations
def test_no_traits(): raw = { "name": "my/device/name", } device = Device.MakeDevice(raw, auth=None) assert "my/device/name" == device.name assert not ("sdm.devices.traits.Info" in device.traits)
def test_device_custom_name(): """Test a device name from an Info trait.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.DOORBELL", "traits": { "sdm.devices.traits.Info": { "customName": "My Doorbell", }, }, }, auth=None, ) device_info = DeviceInfo(device) assert device_info.device_name == "My Doorbell" assert device_info.device_model == "Doorbell" assert device_info.device_brand == "Google Nest" assert device_info.device_info == { "identifiers": {("nest", "some-device-id")}, "name": "My Doorbell", "manufacturer": "Google Nest", "model": "Doorbell", }
def test_device_invalid_type(): """Test a device with a type name that is not recognized.""" device = Device.MakeDevice( { "name": "some-device-id", "type": "sdm.devices.types.INVALID_TYPE", "traits": { "sdm.devices.traits.Info": { "customName": "My Doorbell", }, }, }, auth=None, ) device_info = DeviceInfo(device) assert device_info.device_name == "My Doorbell" assert device_info.device_model is None assert device_info.device_brand == "Google Nest" assert device_info.device_info == { "identifiers": {("nest", "some-device-id")}, "name": "My Doorbell", "manufacturer": "Google Nest", "model": None, }
def test_device_id(): raw = { "name": "my/device/name", "type": "sdm.devices.types.SomeDeviceType", } device = Device.MakeDevice(raw, auth=None) assert "my/device/name" == device.name assert "sdm.devices.types.SomeDeviceType" == device.type
def create(self, raw_traits: dict[str, Any] = None, raw_data: dict[str, Any] = None) -> None: """Create a new device with the specifeid traits.""" data = copy.deepcopy(self.data) data.update(raw_data if raw_data else {}) data["traits"].update(raw_traits if raw_traits else {}) self.device_manager.add_device(Device.MakeDevice(data, auth=self.auth))
def testDeviceId(self): raw = { "name": "my/device/name", "type": "sdm.devices.types.SomeDeviceType", } device = Device.MakeDevice(raw, auth=None) self.assertEqual("my/device/name", device.name) self.assertEqual("sdm.devices.types.SomeDeviceType", device.type)
async def test_thermostat_device(hass): """Test a thermostat with temperature and humidity sensors.""" 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, }, "sdm.devices.traits.Humidity": { "ambientHumidityPercent": 35.0, }, }, }, auth=None, ) } await async_setup_sensor(hass, devices) temperature = hass.states.get("sensor.my_sensor_temperature") assert temperature is not None assert temperature.state == "25.1" assert temperature.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS assert temperature.attributes.get( ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE assert temperature.attributes.get( ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT humidity = hass.states.get("sensor.my_sensor_humidity") assert humidity is not None assert humidity.state == "35" assert humidity.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert humidity.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_HUMIDITY assert humidity.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT registry = er.async_get(hass) entry = registry.async_get("sensor.my_sensor_temperature") assert entry.unique_id == "some-device-id-temperature" assert entry.original_name == "My Sensor Temperature" assert entry.domain == "sensor" entry = registry.async_get("sensor.my_sensor_humidity") assert entry.unique_id == "some-device-id-humidity" assert entry.original_name == "My Sensor Humidity" assert entry.domain == "sensor" device_registry = dr.async_get(hass) device = device_registry.async_get(entry.device_id) assert device.name == "My Sensor" assert device.model == "Thermostat" assert device.identifiers == {("nest", "some-device-id")}
def test_doorbell_chime(): raw = { "name": "my/device/name", "traits": { "sdm.devices.traits.DoorbellChime": {}, }, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.DoorbellChime" in device.traits
def test_doorbell_chime_trait_hack_not_applied(): """The doorbell chime trait hack is not applied for other types.""" raw = { "name": "my/device/name", "type": "sdm.devices.types.CAMERA", "traits": {}, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.DoorbellChime" not in device.traits
def test_doorbell_chime_trait_hack(): """Adds the DoorbellChime trait even when missing from the API to fix an API bug.""" raw = { "name": "my/device/name", "type": "sdm.devices.types.DOORBELL", "traits": {}, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.DoorbellChime" in device.traits
def testCameraEventImageTraits(self): raw = { "name": "my/device/name", "traits": { "sdm.devices.traits.CameraEventImage": {}, }, } device = Device.MakeDevice(raw, auth=None) self.assertTrue("sdm.devices.traits.CameraEventImage" in device.traits)
def test_camera_event_image_traits(): raw = { "name": "my/device/name", "traits": { "sdm.devices.traits.CameraEventImage": {}, }, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.CameraEventImage" in device.traits
def test_camera_sound_traits(): raw = { "name": "my/device/name", "traits": { "sdm.devices.traits.CameraSound": {}, }, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.CameraSound" in device.traits
def testTemperatureTraits(self): raw = { "traits": { "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": "31.1", }, }, } device = Device.MakeDevice(raw, auth=None) self.assertEqual("31.1", device.ambient_temperature_celsius) self.assertEqual(["sdm.devices.traits.Temperature"], device.traits)
def testHumidityTraits(self): raw = { "traits": { "sdm.devices.traits.Humidity": { "ambientHumidityPercent": "25.3", }, }, } device = Device.MakeDevice(raw, auth=None) self.assertEqual("25.3", device.ambient_humidity_percent) self.assertEqual(["sdm.devices.traits.Humidity"], device.traits)
def testConnectivityTraits(self): raw = { "traits": { "sdm.devices.traits.Connectivity": { "status": "OFFLINE", }, }, } device = Device.MakeDevice(raw, auth=None) self.assertEqual("OFFLINE", device.status) self.assertEqual(["sdm.devices.traits.Connectivity"], device.traits)
async def test_entry_diagnostics(hass, hass_client): """Test config entry diagnostics.""" devices = { "some-device-id": Device.MakeDevice( { "name": "enterprises/project-id/devices/device-id", "type": "sdm.devices.types.THERMOSTAT", "assignee": "enterprises/project-id/structures/structure-id/rooms/room-id", "traits": { "sdm.devices.traits.Info": { "customName": "My Sensor", }, "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 25.1, }, "sdm.devices.traits.Humidity": { "ambientHumidityPercent": 35.0, }, }, "parentRelations": [{ "parent": "enterprises/project-id/structures/structure-id/rooms/room-id", "displayName": "Lobby", }], }, auth=None, ) } assert await async_setup_sdm_platform(hass, platform=None, devices=devices) entries = hass.config_entries.async_entries(DOMAIN) assert len(entries) == 1 config_entry = entries[0] assert config_entry.state is ConfigEntryState.LOADED # Test that only non identifiable device information is returned assert await get_diagnostics_for_config_entry( hass, hass_client, config_entry) == { "devices": [{ "traits": { "sdm.devices.traits.Humidity": { "ambientHumidityPercent": 35.0 }, "sdm.devices.traits.Temperature": { "ambientTemperatureCelsius": 25.1 }, }, "type": "sdm.devices.types.THERMOSTAT", }], }
def testNoTraits(self): raw = { "name": "my/device/name", } device = Device.MakeDevice(raw, auth=None) self.assertEqual("my/device/name", device.name) self.assertFalse(device.has_trait("sdm.devices.traits.Info")) self.assertFalse(hasattr(device, 'status')) self.assertFalse(hasattr(device, 'custom_name')) self.assertFalse(hasattr(device, 'ambient_humidity_percent')) self.assertFalse(hasattr(device, 'ambient_temperature_celsius')) self.assertFalse(hasattr(device, 'custom_name'))
def test_fan_traits_empty(): raw = { "name": "my/device/name", "traits": { "sdm.devices.traits.Fan": {}, }, } device = Device.MakeDevice(raw, auth=None) assert "sdm.devices.traits.Fan" in device.traits trait = device.traits["sdm.devices.traits.Fan"] assert trait.timer_mode is None assert trait.timer_timeout is None
async def async_setup_camera(hass, traits={}, auth=None): """Set up the platform and prerequisites.""" devices = {} if traits: devices[DEVICE_ID] = Device.MakeDevice( { "name": DEVICE_ID, "type": CAMERA_DEVICE_TYPE, "traits": traits, }, auth=auth, ) return await async_setup_sdm_platform(hass, PLATFORM, devices)