mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add Chime Type select for UniFi Protect (#63993)
This commit is contained in:
parent
c6ef2bcdab
commit
6473069be1
@ -82,18 +82,6 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
|
|||||||
ufp_value="isp_settings.zoom_position",
|
ufp_value="isp_settings.zoom_position",
|
||||||
ufp_set_method="set_camera_zoom",
|
ufp_set_method="set_camera_zoom",
|
||||||
),
|
),
|
||||||
ProtectNumberEntityDescription(
|
|
||||||
key="duration",
|
|
||||||
name="Chime Duration",
|
|
||||||
icon="mdi:camera-timer",
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
ufp_min=0,
|
|
||||||
ufp_max=10000,
|
|
||||||
ufp_step=100,
|
|
||||||
ufp_required_field="feature_flags.has_chime",
|
|
||||||
ufp_value="chime_duration",
|
|
||||||
ufp_set_method="set_chime_duration",
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
|
LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
|
||||||
|
@ -19,6 +19,7 @@ from pyunifiprotect.data import (
|
|||||||
RecordingMode,
|
RecordingMode,
|
||||||
Viewer,
|
Viewer,
|
||||||
)
|
)
|
||||||
|
from pyunifiprotect.data.types import ChimeType
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||||
@ -45,6 +46,12 @@ INFRARED_MODES = [
|
|||||||
{"id": IRLEDMode.OFF.value, "name": "Always Disable"},
|
{"id": IRLEDMode.OFF.value, "name": "Always Disable"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CHIME_TYPES = [
|
||||||
|
{"id": ChimeType.NONE.value, "name": "None"},
|
||||||
|
{"id": ChimeType.MECHINCAL.value, "name": "Mechanical"},
|
||||||
|
{"id": ChimeType.DIGITAL.value, "name": "Digital"},
|
||||||
|
]
|
||||||
|
|
||||||
LIGHT_MODE_MOTION = "On Motion - Always"
|
LIGHT_MODE_MOTION = "On Motion - Always"
|
||||||
LIGHT_MODE_MOTION_DARK = "On Motion - When Dark"
|
LIGHT_MODE_MOTION_DARK = "On Motion - When Dark"
|
||||||
LIGHT_MODE_DARK = "When Dark"
|
LIGHT_MODE_DARK = "When Dark"
|
||||||
@ -212,6 +219,17 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
|
|||||||
ufp_options_callable=_get_doorbell_options,
|
ufp_options_callable=_get_doorbell_options,
|
||||||
ufp_set_method_fn=_set_doorbell_message,
|
ufp_set_method_fn=_set_doorbell_message,
|
||||||
),
|
),
|
||||||
|
ProtectSelectEntityDescription(
|
||||||
|
key="chime_type",
|
||||||
|
name="Chime Type",
|
||||||
|
icon="mdi:bell",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
ufp_required_field="feature_flags.has_chime",
|
||||||
|
ufp_options=CHIME_TYPES,
|
||||||
|
ufp_enum_type=ChimeType,
|
||||||
|
ufp_value="chime_type",
|
||||||
|
ufp_set_method="set_chime_type",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
LIGHT_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
|
LIGHT_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
|
||||||
|
@ -70,7 +70,6 @@ async def camera_fixture(
|
|||||||
camera_obj.channels[1]._api = mock_entry.api
|
camera_obj.channels[1]._api = mock_entry.api
|
||||||
camera_obj.channels[2]._api = mock_entry.api
|
camera_obj.channels[2]._api = mock_entry.api
|
||||||
camera_obj.name = "Test Camera"
|
camera_obj.name = "Test Camera"
|
||||||
camera_obj.feature_flags.has_chime = True
|
|
||||||
camera_obj.feature_flags.can_optical_zoom = True
|
camera_obj.feature_flags.can_optical_zoom = True
|
||||||
camera_obj.feature_flags.has_mic = True
|
camera_obj.feature_flags.has_mic = True
|
||||||
# has_wdr is an the inverse of has HDR
|
# has_wdr is an the inverse of has HDR
|
||||||
@ -78,7 +77,6 @@ async def camera_fixture(
|
|||||||
camera_obj.isp_settings.wdr = 0
|
camera_obj.isp_settings.wdr = 0
|
||||||
camera_obj.mic_volume = 0
|
camera_obj.mic_volume = 0
|
||||||
camera_obj.isp_settings.zoom_position = 0
|
camera_obj.isp_settings.zoom_position = 0
|
||||||
camera_obj.chime_duration = 0
|
|
||||||
|
|
||||||
mock_entry.api.bootstrap.reset_objects()
|
mock_entry.api.bootstrap.reset_objects()
|
||||||
mock_entry.api.bootstrap.cameras = {
|
mock_entry.api.bootstrap.cameras = {
|
||||||
@ -88,7 +86,7 @@ async def camera_fixture(
|
|||||||
await hass.config_entries.async_setup(mock_entry.entry.entry_id)
|
await hass.config_entries.async_setup(mock_entry.entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert_entity_counts(hass, Platform.NUMBER, 4, 4)
|
assert_entity_counts(hass, Platform.NUMBER, 3, 3)
|
||||||
|
|
||||||
yield camera_obj
|
yield camera_obj
|
||||||
|
|
||||||
@ -152,7 +150,6 @@ async def test_number_setup_camera_none(
|
|||||||
camera_obj.channels[1]._api = mock_entry.api
|
camera_obj.channels[1]._api = mock_entry.api
|
||||||
camera_obj.channels[2]._api = mock_entry.api
|
camera_obj.channels[2]._api = mock_entry.api
|
||||||
camera_obj.name = "Test Camera"
|
camera_obj.name = "Test Camera"
|
||||||
camera_obj.feature_flags.has_chime = False
|
|
||||||
camera_obj.feature_flags.can_optical_zoom = False
|
camera_obj.feature_flags.can_optical_zoom = False
|
||||||
camera_obj.feature_flags.has_mic = False
|
camera_obj.feature_flags.has_mic = False
|
||||||
# has_wdr is an the inverse of has HDR
|
# has_wdr is an the inverse of has HDR
|
||||||
@ -217,7 +214,7 @@ async def test_number_light_sensitivity(hass: HomeAssistant, light: Light):
|
|||||||
|
|
||||||
|
|
||||||
async def test_number_light_duration(hass: HomeAssistant, light: Light):
|
async def test_number_light_duration(hass: HomeAssistant, light: Light):
|
||||||
"""Test chime duration number entity for lights."""
|
"""Test auto-shutoff duration number entity for lights."""
|
||||||
|
|
||||||
description = LIGHT_NUMBERS[1]
|
description = LIGHT_NUMBERS[1]
|
||||||
|
|
||||||
|
@ -93,9 +93,11 @@ async def camera_fixture(
|
|||||||
camera_obj.channels[2]._api = mock_entry.api
|
camera_obj.channels[2]._api = mock_entry.api
|
||||||
camera_obj.name = "Test Camera"
|
camera_obj.name = "Test Camera"
|
||||||
camera_obj.feature_flags.has_lcd_screen = True
|
camera_obj.feature_flags.has_lcd_screen = True
|
||||||
|
camera_obj.feature_flags.has_chime = True
|
||||||
camera_obj.recording_settings.mode = RecordingMode.ALWAYS
|
camera_obj.recording_settings.mode = RecordingMode.ALWAYS
|
||||||
camera_obj.isp_settings.ir_led_mode = IRLEDMode.AUTO
|
camera_obj.isp_settings.ir_led_mode = IRLEDMode.AUTO
|
||||||
camera_obj.lcd_message = None
|
camera_obj.lcd_message = None
|
||||||
|
camera_obj.chime_duration = 0
|
||||||
|
|
||||||
mock_entry.api.bootstrap.reset_objects()
|
mock_entry.api.bootstrap.reset_objects()
|
||||||
mock_entry.api.bootstrap.cameras = {
|
mock_entry.api.bootstrap.cameras = {
|
||||||
@ -105,7 +107,7 @@ async def camera_fixture(
|
|||||||
await hass.config_entries.async_setup(mock_entry.entry.entry_id)
|
await hass.config_entries.async_setup(mock_entry.entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert_entity_counts(hass, Platform.SELECT, 3, 3)
|
assert_entity_counts(hass, Platform.SELECT, 4, 4)
|
||||||
|
|
||||||
yield camera_obj
|
yield camera_obj
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ async def light_fixture(
|
|||||||
await hass.config_entries.async_reload(mock_entry.entry.entry_id)
|
await hass.config_entries.async_reload(mock_entry.entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert_entity_counts(hass, Platform.SELECT, 5, 5)
|
assert_entity_counts(hass, Platform.SELECT, 6, 6)
|
||||||
|
|
||||||
yield light_obj
|
yield light_obj
|
||||||
|
|
||||||
@ -163,6 +165,7 @@ async def camera_none_fixture(
|
|||||||
camera_obj.channels[2]._api = mock_entry.api
|
camera_obj.channels[2]._api = mock_entry.api
|
||||||
camera_obj.name = "Test Camera"
|
camera_obj.name = "Test Camera"
|
||||||
camera_obj.feature_flags.has_lcd_screen = False
|
camera_obj.feature_flags.has_lcd_screen = False
|
||||||
|
camera_obj.feature_flags.has_chime = False
|
||||||
camera_obj.recording_settings.mode = RecordingMode.ALWAYS
|
camera_obj.recording_settings.mode = RecordingMode.ALWAYS
|
||||||
camera_obj.isp_settings.ir_led_mode = IRLEDMode.AUTO
|
camera_obj.isp_settings.ir_led_mode = IRLEDMode.AUTO
|
||||||
|
|
||||||
@ -235,7 +238,7 @@ async def test_select_setup_camera_all(
|
|||||||
"""Test select entity setup for camera devices (all features)."""
|
"""Test select entity setup for camera devices (all features)."""
|
||||||
|
|
||||||
entity_registry = er.async_get(hass)
|
entity_registry = er.async_get(hass)
|
||||||
expected_values = ("Always", "Auto", "Default Message (Welcome)")
|
expected_values = ("Always", "Auto", "Default Message (Welcome)", "None")
|
||||||
|
|
||||||
for index, description in enumerate(CAMERA_SELECTS):
|
for index, description in enumerate(CAMERA_SELECTS):
|
||||||
unique_id, entity_id = ids_from_device_description(
|
unique_id, entity_id = ids_from_device_description(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user