Add Ring Intercom support (#109819)
* Add button entity * Add support for Ring intercom ("other" device type) * description * format * - Tests - Fallback when intercom devices arent inside response * Fix ring button * Update library * Fix button after merge * Move names to strings.json * Remove button entity_category * Add wifi sensors to other * Add last_ sensors to other * Fix tests * Add button test * Add new sensors tests * Revert "Add last_ sensors to other" This reverts commit5c03bba5a1
. * Update library * Revert "Revert "Add last_ sensors to other"" This reverts commit27631978d0
. * Fix tests * Remove default list for other Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com> * Copy mock to conftest * Fix history test * Change time skip * Remove button * Fix history test --------- Co-authored-by: Martin Pham <tuyentq2009@gmail.com> Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com>
This commit is contained in:
parent
30d1f70468
commit
360f7dea75
12 changed files with 412 additions and 15 deletions
|
@ -31,7 +31,7 @@ BINARY_SENSOR_TYPES: tuple[RingBinarySensorEntityDescription, ...] = (
|
||||||
RingBinarySensorEntityDescription(
|
RingBinarySensorEntityDescription(
|
||||||
key="ding",
|
key="ding",
|
||||||
translation_key="ding",
|
translation_key="ding",
|
||||||
category=["doorbots", "authorized_doorbots"],
|
category=["doorbots", "authorized_doorbots", "other"],
|
||||||
device_class=BinarySensorDeviceClass.OCCUPANCY,
|
device_class=BinarySensorDeviceClass.OCCUPANCY,
|
||||||
),
|
),
|
||||||
RingBinarySensorEntityDescription(
|
RingBinarySensorEntityDescription(
|
||||||
|
@ -56,7 +56,7 @@ async def async_setup_entry(
|
||||||
|
|
||||||
entities = [
|
entities = [
|
||||||
RingBinarySensor(ring, device, notifications_coordinator, description)
|
RingBinarySensor(ring, device, notifications_coordinator, description)
|
||||||
for device_type in ("doorbots", "authorized_doorbots", "stickup_cams")
|
for device_type in ("doorbots", "authorized_doorbots", "stickup_cams", "other")
|
||||||
for description in BINARY_SENSOR_TYPES
|
for description in BINARY_SENSOR_TYPES
|
||||||
if device_type in description.category
|
if device_type in description.category
|
||||||
for device in devices[device_type]
|
for device in devices[device_type]
|
||||||
|
|
|
@ -13,6 +13,15 @@
|
||||||
"volume": {
|
"volume": {
|
||||||
"default": "mdi:bell-ring"
|
"default": "mdi:bell-ring"
|
||||||
},
|
},
|
||||||
|
"doorbell_volume": {
|
||||||
|
"default": "mdi:bell-ring"
|
||||||
|
},
|
||||||
|
"mic_volume": {
|
||||||
|
"default": "mdi:microphone"
|
||||||
|
},
|
||||||
|
"voice_volume": {
|
||||||
|
"default": "mdi:account-voice"
|
||||||
|
},
|
||||||
"wifi_signal_category": {
|
"wifi_signal_category": {
|
||||||
"default": "mdi:wifi"
|
"default": "mdi:wifi"
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,7 +40,13 @@ async def async_setup_entry(
|
||||||
|
|
||||||
entities = [
|
entities = [
|
||||||
description.cls(device, devices_coordinator, description)
|
description.cls(device, devices_coordinator, description)
|
||||||
for device_type in ("chimes", "doorbots", "authorized_doorbots", "stickup_cams")
|
for device_type in (
|
||||||
|
"chimes",
|
||||||
|
"doorbots",
|
||||||
|
"authorized_doorbots",
|
||||||
|
"stickup_cams",
|
||||||
|
"other",
|
||||||
|
)
|
||||||
for description in SENSOR_TYPES
|
for description in SENSOR_TYPES
|
||||||
if device_type in description.category
|
if device_type in description.category
|
||||||
for device in devices[device_type]
|
for device in devices[device_type]
|
||||||
|
@ -72,6 +78,12 @@ class RingSensor(RingEntity, SensorEntity):
|
||||||
sensor_type = self.entity_description.key
|
sensor_type = self.entity_description.key
|
||||||
if sensor_type == "volume":
|
if sensor_type == "volume":
|
||||||
return self._device.volume
|
return self._device.volume
|
||||||
|
if sensor_type == "doorbell_volume":
|
||||||
|
return self._device.doorbell_volume
|
||||||
|
if sensor_type == "mic_volume":
|
||||||
|
return self._device.mic_volume
|
||||||
|
if sensor_type == "voice_volume":
|
||||||
|
return self._device.voice_volume
|
||||||
|
|
||||||
if sensor_type == "battery":
|
if sensor_type == "battery":
|
||||||
return self._device.battery_life
|
return self._device.battery_life
|
||||||
|
@ -156,7 +168,7 @@ class RingSensorEntityDescription(SensorEntityDescription):
|
||||||
SENSOR_TYPES: tuple[RingSensorEntityDescription, ...] = (
|
SENSOR_TYPES: tuple[RingSensorEntityDescription, ...] = (
|
||||||
RingSensorEntityDescription(
|
RingSensorEntityDescription(
|
||||||
key="battery",
|
key="battery",
|
||||||
category=["doorbots", "authorized_doorbots", "stickup_cams"],
|
category=["doorbots", "authorized_doorbots", "stickup_cams", "other"],
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
@ -166,14 +178,14 @@ SENSOR_TYPES: tuple[RingSensorEntityDescription, ...] = (
|
||||||
RingSensorEntityDescription(
|
RingSensorEntityDescription(
|
||||||
key="last_activity",
|
key="last_activity",
|
||||||
translation_key="last_activity",
|
translation_key="last_activity",
|
||||||
category=["doorbots", "authorized_doorbots", "stickup_cams"],
|
category=["doorbots", "authorized_doorbots", "stickup_cams", "other"],
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
cls=HistoryRingSensor,
|
cls=HistoryRingSensor,
|
||||||
),
|
),
|
||||||
RingSensorEntityDescription(
|
RingSensorEntityDescription(
|
||||||
key="last_ding",
|
key="last_ding",
|
||||||
translation_key="last_ding",
|
translation_key="last_ding",
|
||||||
category=["doorbots", "authorized_doorbots"],
|
category=["doorbots", "authorized_doorbots", "other"],
|
||||||
kind="ding",
|
kind="ding",
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
cls=HistoryRingSensor,
|
cls=HistoryRingSensor,
|
||||||
|
@ -192,17 +204,35 @@ SENSOR_TYPES: tuple[RingSensorEntityDescription, ...] = (
|
||||||
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams"],
|
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams"],
|
||||||
cls=RingSensor,
|
cls=RingSensor,
|
||||||
),
|
),
|
||||||
|
RingSensorEntityDescription(
|
||||||
|
key="doorbell_volume",
|
||||||
|
translation_key="doorbell_volume",
|
||||||
|
category=["other"],
|
||||||
|
cls=RingSensor,
|
||||||
|
),
|
||||||
|
RingSensorEntityDescription(
|
||||||
|
key="mic_volume",
|
||||||
|
translation_key="mic_volume",
|
||||||
|
category=["other"],
|
||||||
|
cls=RingSensor,
|
||||||
|
),
|
||||||
|
RingSensorEntityDescription(
|
||||||
|
key="voice_volume",
|
||||||
|
translation_key="voice_volume",
|
||||||
|
category=["other"],
|
||||||
|
cls=RingSensor,
|
||||||
|
),
|
||||||
RingSensorEntityDescription(
|
RingSensorEntityDescription(
|
||||||
key="wifi_signal_category",
|
key="wifi_signal_category",
|
||||||
translation_key="wifi_signal_category",
|
translation_key="wifi_signal_category",
|
||||||
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams"],
|
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams", "other"],
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
cls=HealthDataRingSensor,
|
cls=HealthDataRingSensor,
|
||||||
),
|
),
|
||||||
RingSensorEntityDescription(
|
RingSensorEntityDescription(
|
||||||
key="wifi_signal_strength",
|
key="wifi_signal_strength",
|
||||||
translation_key="wifi_signal_strength",
|
translation_key="wifi_signal_strength",
|
||||||
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams"],
|
category=["chimes", "doorbots", "authorized_doorbots", "stickup_cams", "other"],
|
||||||
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||||
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
|
|
@ -60,6 +60,15 @@
|
||||||
"volume": {
|
"volume": {
|
||||||
"name": "Volume"
|
"name": "Volume"
|
||||||
},
|
},
|
||||||
|
"doorbell_volume": {
|
||||||
|
"name": "Doorbell volume"
|
||||||
|
},
|
||||||
|
"mic_volume": {
|
||||||
|
"name": "Mic volume"
|
||||||
|
},
|
||||||
|
"voice_volume": {
|
||||||
|
"name": "Voice volume"
|
||||||
|
},
|
||||||
"wifi_signal_category": {
|
"wifi_signal_category": {
|
||||||
"name": "Wi-Fi signal category"
|
"name": "Wi-Fi signal category"
|
||||||
},
|
},
|
||||||
|
|
|
@ -96,7 +96,7 @@ def requests_mock_fixture():
|
||||||
re.compile(
|
re.compile(
|
||||||
r"https:\/\/api\.ring\.com\/clients_api\/doorbots\/\d+\/history"
|
r"https:\/\/api\.ring\.com\/clients_api\/doorbots\/\d+\/history"
|
||||||
),
|
),
|
||||||
text=load_fixture("doorbots.json", "ring"),
|
text=load_fixture("doorbot_history.json", "ring"),
|
||||||
)
|
)
|
||||||
# Mocks the response for getting the health of a device
|
# Mocks the response for getting the health of a device
|
||||||
mock.get(
|
mock.get(
|
||||||
|
@ -115,6 +115,15 @@ def requests_mock_fixture():
|
||||||
status_code=200,
|
status_code=200,
|
||||||
json={"url": "http://127.0.0.1/foo"},
|
json={"url": "http://127.0.0.1/foo"},
|
||||||
)
|
)
|
||||||
|
mock.get(
|
||||||
|
"https://api.ring.com/groups/v1/locations/mock-location-id/groups",
|
||||||
|
text=load_fixture("groups.json", "ring"),
|
||||||
|
)
|
||||||
|
# Mocks the response for getting the history of the intercom
|
||||||
|
mock.get(
|
||||||
|
"https://api.ring.com/clients_api/doorbots/185036587/history",
|
||||||
|
text=load_fixture("intercom_history.json", "ring"),
|
||||||
|
)
|
||||||
# Mocks the response for setting properties in settings (i.e. motion_detection)
|
# Mocks the response for setting properties in settings (i.e. motion_detection)
|
||||||
mock.patch(
|
mock.patch(
|
||||||
re.compile(
|
re.compile(
|
||||||
|
|
|
@ -378,5 +378,92 @@
|
||||||
"subscribed_motions": true,
|
"subscribed_motions": true,
|
||||||
"time_zone": "America/New_York"
|
"time_zone": "America/New_York"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"other": [
|
||||||
|
{
|
||||||
|
"id": 185036587,
|
||||||
|
"kind": "intercom_handset_audio",
|
||||||
|
"description": "Ingress",
|
||||||
|
"location_id": "mock-location-id",
|
||||||
|
"schema_id": null,
|
||||||
|
"is_sidewalk_gateway": false,
|
||||||
|
"created_at": "2023-12-01T18:05:25Z",
|
||||||
|
"deactivated_at": null,
|
||||||
|
"owner": {
|
||||||
|
"id": 762490876,
|
||||||
|
"first_name": "",
|
||||||
|
"last_name": "",
|
||||||
|
"email": ""
|
||||||
|
},
|
||||||
|
"device_id": "124ba1b3fe1a",
|
||||||
|
"time_zone": "Europe/Rome",
|
||||||
|
"firmware_version": "Up to Date",
|
||||||
|
"owned": true,
|
||||||
|
"ring_net_id": null,
|
||||||
|
"settings": {
|
||||||
|
"features_confirmed": 5,
|
||||||
|
"show_recordings": true,
|
||||||
|
"recording_ttl": 180,
|
||||||
|
"recording_enabled": false,
|
||||||
|
"keep_alive": null,
|
||||||
|
"keep_alive_auto": 45.0,
|
||||||
|
"doorbell_volume": 8,
|
||||||
|
"enable_chime": 1,
|
||||||
|
"theft_alarm_enable": 0,
|
||||||
|
"use_cached_domain": 1,
|
||||||
|
"use_server_ip": 0,
|
||||||
|
"server_domain": "fw.ring.com",
|
||||||
|
"server_ip": null,
|
||||||
|
"enable_log": 1,
|
||||||
|
"forced_keep_alive": null,
|
||||||
|
"mic_volume": 11,
|
||||||
|
"chime_settings": {
|
||||||
|
"enable": true,
|
||||||
|
"type": 2,
|
||||||
|
"duration": 10
|
||||||
|
},
|
||||||
|
"intercom_settings": {
|
||||||
|
"ring_to_open": false,
|
||||||
|
"predecessor": "{\"make\":\"Comelit\",\"model\":\"2738W\",\"wires\":2}",
|
||||||
|
"config": "{\"intercom_type\": 2, \"number_of_wires\": 2, \"autounlock_enabled\": false, \"speaker_gain\": [-49, -35, -25, -21, -16, -9, -6, -3, 0, 3, 6, 9], \"digital\": {\"audio_amp\": 0, \"chg_en\": false, \"fast_chg\": false, \"bypass\": false, \"idle_lvl\": 32, \"ext_audio\": false, \"ext_audio_term\": 0, \"off_hk_tm\": 0, \"unlk_ka\": false, \"unlock\": {\"cap_tm\": 1000, \"rpl_tm\": 1500, \"gain\": 1000, \"cmp_thr\": 4000, \"lvl\": 25000, \"thr\": 30, \"thr2\": 0, \"offln\": false, \"ac\": true, \"bias\": \"h\", \"tx_pin\": \"TXD2\", \"ack\": 0, \"prot\": \"Comelit_SB2\", \"ask\": {\"f\": 25000, \"b\": 333}}, \"ring\": {\"cap_tm\": 40, \"rpl_tm\": 200, \"gain\": 2000, \"cmp_thr\": 4500, \"lvl\": 28000, \"thr\": 30, \"thr2\": 0, \"offln\": false, \"ac\": true, \"bias\": \"m\", \"tx_pin\": \"TXD2\", \"ack\": 0, \"prot\": \"Comelit_SB2\", \"ask\": {\"f\": 25000, \"b\": 333}}, \"hook_off\": {\"cap_tm\": 1000, \"rpl_tm\": 1500, \"gain\": 1000, \"cmp_thr\": 4000, \"lvl\": 25000, \"thr\": 30, \"thr2\": 0, \"offln\": false, \"ac\": true, \"bias\": \"h\", \"tx_pin\": \"TXD2\", \"ack\": 0, \"prot\": \"Comelit_SB2\", \"ask\": {\"f\": 25000, \"b\": 333}}, \"hook_on\": {\"cap_tm\": 1000, \"rpl_tm\": 1500, \"gain\": 1000, \"cmp_thr\": 4000, \"lvl\": 25000, \"thr\": 30, \"thr2\": 0, \"offln\": false, \"ac\": true, \"bias\": \"h\", \"tx_pin\": \"TXD2\", \"ack\": 0, \"prot\": \"Comelit_SB2\", \"ask\": {\"f\": 25000, \"b\": 333}}}}",
|
||||||
|
"intercom_type": "DF",
|
||||||
|
"replication": 1,
|
||||||
|
"unlock_mode": 0
|
||||||
|
},
|
||||||
|
"voice_volume": 11
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"connection": "online",
|
||||||
|
"ota_status": "timeout"
|
||||||
|
},
|
||||||
|
"function": {
|
||||||
|
"name": null
|
||||||
|
},
|
||||||
|
"subscribed": false,
|
||||||
|
"battery_life": "52",
|
||||||
|
"features": {
|
||||||
|
"cfes_eligible": false,
|
||||||
|
"motion_zone_recommendation": false,
|
||||||
|
"motions_enabled": true,
|
||||||
|
"show_recordings": true,
|
||||||
|
"show_vod_settings": true,
|
||||||
|
"rich_notifications_eligible": false,
|
||||||
|
"show_offline_motion_events": false,
|
||||||
|
"sheila_camera_eligible": null,
|
||||||
|
"sheila_camera_processing_eligible": null,
|
||||||
|
"dynamic_network_switching_eligible": false,
|
||||||
|
"chime_auto_detect_capable": false,
|
||||||
|
"missing_key_delivery_address": false,
|
||||||
|
"show_24x7_lite": false,
|
||||||
|
"recording_24x7_eligible": null
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"ethernet": false,
|
||||||
|
"legacy_fw_migrated": true,
|
||||||
|
"imported_from_amazon": false,
|
||||||
|
"is_sidewalk_gateway": false,
|
||||||
|
"key_access_point_associated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
24
tests/components/ring/fixtures/groups.json
Normal file
24
tests/components/ring/fixtures/groups.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"device_groups": [
|
||||||
|
{
|
||||||
|
"device_group_id": "mock-group-id",
|
||||||
|
"location_id": "mock-location-id",
|
||||||
|
"name": "Landscape",
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"doorbot_id": 12345678,
|
||||||
|
"location_id": "mock-location-id",
|
||||||
|
"type": "beams_ct200_transformer",
|
||||||
|
"mac_address": null,
|
||||||
|
"hardware_id": "1234567890",
|
||||||
|
"name": "Mock Transformer",
|
||||||
|
"deleted_at": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"created_at": "2020-11-03T22:07:05Z",
|
||||||
|
"updated_at": "2020-11-19T03:52:59Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"external_id": "12345678-1234-5678-90ab-1234567890ab"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
116
tests/components/ring/fixtures/intercom_history.json
Normal file
116
tests/components/ring/fixtures/intercom_history.json
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 7330963245622279024,
|
||||||
|
"created_at": "2024-02-02T11:21:24.000Z",
|
||||||
|
"answered": false,
|
||||||
|
"events": [],
|
||||||
|
"kind": "ding",
|
||||||
|
"favorite": false,
|
||||||
|
"snapshot_url": "",
|
||||||
|
"recording": {
|
||||||
|
"status": "ready"
|
||||||
|
},
|
||||||
|
"duration": 40.0,
|
||||||
|
"cv_properties": {
|
||||||
|
"person_detected": null,
|
||||||
|
"stream_broken": false,
|
||||||
|
"detection_type": null,
|
||||||
|
"cv_triggers": null,
|
||||||
|
"detection_types": null,
|
||||||
|
"security_alerts": null
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"is_alexa": false,
|
||||||
|
"is_sidewalk": false,
|
||||||
|
"is_autoreply": false
|
||||||
|
},
|
||||||
|
"doorbot": {
|
||||||
|
"id": 185036587,
|
||||||
|
"description": "Ingresso",
|
||||||
|
"type": "intercom_handset_audio"
|
||||||
|
},
|
||||||
|
"device_placement": null,
|
||||||
|
"geolocation": null,
|
||||||
|
"last_location": null,
|
||||||
|
"siren": null,
|
||||||
|
"is_e2ee": false,
|
||||||
|
"had_subscription": false,
|
||||||
|
"owner_id": "762490876"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7323267080901445808,
|
||||||
|
"created_at": "2024-01-12T17:36:28.000Z",
|
||||||
|
"answered": true,
|
||||||
|
"events": [],
|
||||||
|
"kind": "on_demand",
|
||||||
|
"favorite": false,
|
||||||
|
"snapshot_url": "",
|
||||||
|
"recording": {
|
||||||
|
"status": "ready"
|
||||||
|
},
|
||||||
|
"duration": 13.0,
|
||||||
|
"cv_properties": {
|
||||||
|
"person_detected": null,
|
||||||
|
"stream_broken": false,
|
||||||
|
"detection_type": null,
|
||||||
|
"cv_triggers": null,
|
||||||
|
"detection_types": null,
|
||||||
|
"security_alerts": null
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"is_alexa": false,
|
||||||
|
"is_sidewalk": false,
|
||||||
|
"is_autoreply": false
|
||||||
|
},
|
||||||
|
"doorbot": {
|
||||||
|
"id": 185036587,
|
||||||
|
"description": "Ingresso",
|
||||||
|
"type": "intercom_handset_audio"
|
||||||
|
},
|
||||||
|
"device_placement": null,
|
||||||
|
"geolocation": null,
|
||||||
|
"last_location": null,
|
||||||
|
"siren": null,
|
||||||
|
"is_e2ee": false,
|
||||||
|
"had_subscription": false,
|
||||||
|
"owner_id": "762490876"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7307399027047288688,
|
||||||
|
"created_at": "2023-12-01T18:44:28.000Z",
|
||||||
|
"answered": true,
|
||||||
|
"events": [],
|
||||||
|
"kind": "on_demand",
|
||||||
|
"favorite": false,
|
||||||
|
"snapshot_url": "",
|
||||||
|
"recording": {
|
||||||
|
"status": "ready"
|
||||||
|
},
|
||||||
|
"duration": 43.0,
|
||||||
|
"cv_properties": {
|
||||||
|
"person_detected": null,
|
||||||
|
"stream_broken": false,
|
||||||
|
"detection_type": null,
|
||||||
|
"cv_triggers": null,
|
||||||
|
"detection_types": null,
|
||||||
|
"security_alerts": null
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"is_alexa": false,
|
||||||
|
"is_sidewalk": false,
|
||||||
|
"is_autoreply": false
|
||||||
|
},
|
||||||
|
"doorbot": {
|
||||||
|
"id": 185036587,
|
||||||
|
"description": "Ingresso",
|
||||||
|
"type": "intercom_handset_audio"
|
||||||
|
},
|
||||||
|
"device_placement": null,
|
||||||
|
"geolocation": null,
|
||||||
|
"last_location": null,
|
||||||
|
"siren": null,
|
||||||
|
"is_e2ee": false,
|
||||||
|
"had_subscription": false,
|
||||||
|
"owner_id": "762490876"
|
||||||
|
}
|
||||||
|
]
|
|
@ -577,6 +577,91 @@
|
||||||
'subscribed_motions': True,
|
'subscribed_motions': True,
|
||||||
'time_zone': 'America/New_York',
|
'time_zone': 'America/New_York',
|
||||||
}),
|
}),
|
||||||
|
dict({
|
||||||
|
'alerts': dict({
|
||||||
|
'connection': 'online',
|
||||||
|
'ota_status': 'timeout',
|
||||||
|
}),
|
||||||
|
'battery_life': '52',
|
||||||
|
'created_at': '2023-12-01T18:05:25Z',
|
||||||
|
'deactivated_at': None,
|
||||||
|
'description': '**REDACTED**',
|
||||||
|
'device_id': '**REDACTED**',
|
||||||
|
'features': dict({
|
||||||
|
'cfes_eligible': False,
|
||||||
|
'chime_auto_detect_capable': False,
|
||||||
|
'dynamic_network_switching_eligible': False,
|
||||||
|
'missing_key_delivery_address': False,
|
||||||
|
'motion_zone_recommendation': False,
|
||||||
|
'motions_enabled': True,
|
||||||
|
'recording_24x7_eligible': None,
|
||||||
|
'rich_notifications_eligible': False,
|
||||||
|
'sheila_camera_eligible': None,
|
||||||
|
'sheila_camera_processing_eligible': None,
|
||||||
|
'show_24x7_lite': False,
|
||||||
|
'show_offline_motion_events': False,
|
||||||
|
'show_recordings': True,
|
||||||
|
'show_vod_settings': True,
|
||||||
|
}),
|
||||||
|
'firmware_version': 'Up to Date',
|
||||||
|
'function': dict({
|
||||||
|
'name': None,
|
||||||
|
}),
|
||||||
|
'id': '**REDACTED**',
|
||||||
|
'is_sidewalk_gateway': False,
|
||||||
|
'kind': 'intercom_handset_audio',
|
||||||
|
'location_id': '**REDACTED**',
|
||||||
|
'metadata': dict({
|
||||||
|
'ethernet': False,
|
||||||
|
'imported_from_amazon': False,
|
||||||
|
'is_sidewalk_gateway': False,
|
||||||
|
'key_access_point_associated': True,
|
||||||
|
'legacy_fw_migrated': True,
|
||||||
|
}),
|
||||||
|
'owned': True,
|
||||||
|
'owner': dict({
|
||||||
|
'email': '',
|
||||||
|
'first_name': '',
|
||||||
|
'id': '**REDACTED**',
|
||||||
|
'last_name': '',
|
||||||
|
}),
|
||||||
|
'ring_net_id': None,
|
||||||
|
'schema_id': None,
|
||||||
|
'settings': dict({
|
||||||
|
'chime_settings': dict({
|
||||||
|
'duration': 10,
|
||||||
|
'enable': True,
|
||||||
|
'type': 2,
|
||||||
|
}),
|
||||||
|
'doorbell_volume': 8,
|
||||||
|
'enable_chime': 1,
|
||||||
|
'enable_log': 1,
|
||||||
|
'features_confirmed': 5,
|
||||||
|
'forced_keep_alive': None,
|
||||||
|
'intercom_settings': dict({
|
||||||
|
'config': '{"intercom_type": 2, "number_of_wires": 2, "autounlock_enabled": false, "speaker_gain": [-49, -35, -25, -21, -16, -9, -6, -3, 0, 3, 6, 9], "digital": {"audio_amp": 0, "chg_en": false, "fast_chg": false, "bypass": false, "idle_lvl": 32, "ext_audio": false, "ext_audio_term": 0, "off_hk_tm": 0, "unlk_ka": false, "unlock": {"cap_tm": 1000, "rpl_tm": 1500, "gain": 1000, "cmp_thr": 4000, "lvl": 25000, "thr": 30, "thr2": 0, "offln": false, "ac": true, "bias": "h", "tx_pin": "TXD2", "ack": 0, "prot": "Comelit_SB2", "ask": {"f": 25000, "b": 333}}, "ring": {"cap_tm": 40, "rpl_tm": 200, "gain": 2000, "cmp_thr": 4500, "lvl": 28000, "thr": 30, "thr2": 0, "offln": false, "ac": true, "bias": "m", "tx_pin": "TXD2", "ack": 0, "prot": "Comelit_SB2", "ask": {"f": 25000, "b": 333}}, "hook_off": {"cap_tm": 1000, "rpl_tm": 1500, "gain": 1000, "cmp_thr": 4000, "lvl": 25000, "thr": 30, "thr2": 0, "offln": false, "ac": true, "bias": "h", "tx_pin": "TXD2", "ack": 0, "prot": "Comelit_SB2", "ask": {"f": 25000, "b": 333}}, "hook_on": {"cap_tm": 1000, "rpl_tm": 1500, "gain": 1000, "cmp_thr": 4000, "lvl": 25000, "thr": 30, "thr2": 0, "offln": false, "ac": true, "bias": "h", "tx_pin": "TXD2", "ack": 0, "prot": "Comelit_SB2", "ask": {"f": 25000, "b": 333}}}}',
|
||||||
|
'intercom_type': 'DF',
|
||||||
|
'predecessor': '{"make":"Comelit","model":"2738W","wires":2}',
|
||||||
|
'replication': 1,
|
||||||
|
'ring_to_open': False,
|
||||||
|
'unlock_mode': 0,
|
||||||
|
}),
|
||||||
|
'keep_alive': None,
|
||||||
|
'keep_alive_auto': 45.0,
|
||||||
|
'mic_volume': 11,
|
||||||
|
'recording_enabled': False,
|
||||||
|
'recording_ttl': 180,
|
||||||
|
'server_domain': 'fw.ring.com',
|
||||||
|
'server_ip': None,
|
||||||
|
'show_recordings': True,
|
||||||
|
'theft_alarm_enable': 0,
|
||||||
|
'use_cached_domain': 1,
|
||||||
|
'use_server_ip': 0,
|
||||||
|
'voice_volume': 11,
|
||||||
|
}),
|
||||||
|
'subscribed': False,
|
||||||
|
'time_zone': 'Europe/Rome',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
|
|
@ -33,6 +33,10 @@ async def test_binary_sensor(
|
||||||
assert motion_state.state == "on"
|
assert motion_state.state == "on"
|
||||||
assert motion_state.attributes["device_class"] == "motion"
|
assert motion_state.attributes["device_class"] == "motion"
|
||||||
|
|
||||||
ding_state = hass.states.get("binary_sensor.front_door_ding")
|
front_ding_state = hass.states.get("binary_sensor.front_door_ding")
|
||||||
assert ding_state is not None
|
assert front_ding_state is not None
|
||||||
assert ding_state.state == "off"
|
assert front_ding_state.state == "off"
|
||||||
|
|
||||||
|
ingress_ding_state = hass.states.get("binary_sensor.ingress_ding")
|
||||||
|
assert ingress_ding_state is not None
|
||||||
|
assert ingress_ding_state.state == "off"
|
||||||
|
|
|
@ -40,13 +40,19 @@ async def test_sensor(hass: HomeAssistant, requests_mock: requests_mock.Mocker)
|
||||||
assert downstairs_volume_state is not None
|
assert downstairs_volume_state is not None
|
||||||
assert downstairs_volume_state.state == "2"
|
assert downstairs_volume_state.state == "2"
|
||||||
|
|
||||||
front_door_last_activity_state = hass.states.get("sensor.front_door_last_activity")
|
|
||||||
assert front_door_last_activity_state is not None
|
|
||||||
|
|
||||||
downstairs_wifi_signal_strength_state = hass.states.get(
|
downstairs_wifi_signal_strength_state = hass.states.get(
|
||||||
"sensor.downstairs_wifi_signal_strength"
|
"sensor.downstairs_wifi_signal_strength"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ingress_mic_volume_state = hass.states.get("sensor.ingress_mic_volume")
|
||||||
|
assert ingress_mic_volume_state.state == "11"
|
||||||
|
|
||||||
|
ingress_doorbell_volume_state = hass.states.get("sensor.ingress_doorbell_volume")
|
||||||
|
assert ingress_doorbell_volume_state.state == "8"
|
||||||
|
|
||||||
|
ingress_voice_volume_state = hass.states.get("sensor.ingress_voice_volume")
|
||||||
|
assert ingress_voice_volume_state.state == "11"
|
||||||
|
|
||||||
if not WIFI_ENABLED:
|
if not WIFI_ENABLED:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -66,6 +72,24 @@ async def test_sensor(hass: HomeAssistant, requests_mock: requests_mock.Mocker)
|
||||||
assert front_door_wifi_signal_strength_state.state == "-58"
|
assert front_door_wifi_signal_strength_state.state == "-58"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_history(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
requests_mock: requests_mock.Mocker,
|
||||||
|
) -> None:
|
||||||
|
"""Test history derived sensors."""
|
||||||
|
await setup_platform(hass, Platform.SENSOR)
|
||||||
|
freezer.tick(SCAN_INTERVAL)
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done(True)
|
||||||
|
|
||||||
|
front_door_last_activity_state = hass.states.get("sensor.front_door_last_activity")
|
||||||
|
assert front_door_last_activity_state.state == "2017-03-05T15:03:40+00:00"
|
||||||
|
|
||||||
|
ingress_last_activity_state = hass.states.get("sensor.ingress_last_activity")
|
||||||
|
assert ingress_last_activity_state.state == "unknown"
|
||||||
|
|
||||||
|
|
||||||
async def test_only_chime_devices(
|
async def test_only_chime_devices(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
requests_mock: requests_mock.Mocker,
|
requests_mock: requests_mock.Mocker,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue