Skip to content

Commit b364c99

Browse files
committed
Add support for turning the Amcrest doorbell security light on/off
1 parent 03cff18 commit b364c99

File tree

8 files changed

+95
-8
lines changed

8 files changed

+95
-8
lines changed

custom_components/dahua/__init__.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,20 @@ def supports_security_light(self) -> bool:
466466
Returns true if this camera has the red/blue flashing security light feature. For example, the
467467
IPC-HDW3849HP-AS-PV does https://dahuawiki.com/Template:NameConvention
468468
"""
469-
return "-AS-PV" in self.model
469+
return "-AS-PV" in self.model or self.model == "AD410"
470470

471471
def is_doorbell(self) -> bool:
472472
"""
473473
Returns true if this is a doorbell (VTO)
474474
"""
475475
m = self.model.upper()
476-
return m.startswith("VTO") or m.startswith("DHI") or m.startswith("AD")
476+
return m.startswith("VTO") or m.startswith("DHI") or self.is_amcrest_doorbell()
477+
478+
def is_amcrest_doorbell(self) -> bool:
479+
"""
480+
Returns true if this is an Amcrest doorbell
481+
"""
482+
return self.model.upper().startswith("AD")
477483

478484
def supports_infrared_light(self) -> bool:
479485
"""
@@ -487,7 +493,7 @@ def supports_illuminator(self) -> bool:
487493
Returns true if this camera has an illuminator (white light for color cameras). For example, the
488494
IPC-HDW3849HP-AS-PV does
489495
"""
490-
return "table.Lighting_V2[{0}][0][0].Mode".format(self._channel) in self.data
496+
return not self.is_amcrest_doorbell() and "table.Lighting_V2[{0}][0][0].Mode".format(self._channel) in self.data
491497

492498
def is_motion_detection_enabled(self) -> bool:
493499
"""

custom_components/dahua/client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,22 @@ async def async_set_lighting_v2(self, channel: int, enabled: bool, brightness: i
375375
_LOGGER.debug("Turning light on: %s", url)
376376
return await self.get(url)
377377

378+
async def async_set_lighting_v2_for_amcrest_doorbells(self, mode: str) -> dict:
379+
"""
380+
async_set_lighting_v2_for_amcrest_doorbells will turn on or off the white light on Amcrest doorbells
381+
mode: On, Off, Flicker
382+
"""
383+
mode = mode.lower()
384+
cmd = "Off"
385+
if mode == "on":
386+
cmd = "ForceOn&Lighting_V2[0][0][1].State=On"
387+
elif mode == "strobe" or mode == "flicker":
388+
cmd = "ForceOn&Lighting_V2[0][0][1].State=Flicker"
389+
390+
url = "/cgi-bin/configManager.cgi?action=setConfig&Lighting_V2[0][0][1].Mode={cmd}".format(cmd=cmd)
391+
_LOGGER.debug("Turning doorbell light on: %s", url)
392+
return await self.get(url)
393+
378394
async def async_set_video_in_day_night_mode(self, channel: int, config_type: str, mode: str):
379395
"""
380396
async_set_video_in_day_night_mode will set the video dan/night config. For example to see it to Color or Black

custom_components/dahua/const.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
SWITCH = "switch"
2929
LIGHT = "light"
3030
CAMERA = "camera"
31-
PLATFORMS = [BINARY_SENSOR, SWITCH, LIGHT, CAMERA]
31+
SELECT = "select"
32+
PLATFORMS = [BINARY_SENSOR, SWITCH, LIGHT, CAMERA, SELECT]
3233

3334

3435
# Configuration and options

custom_components/dahua/entity.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from homeassistant.helpers.update_coordinator import CoordinatorEntity
44
from .const import DOMAIN, ATTRIBUTION
55

6-
6+
"""
7+
For a list of entity types, see https://developers.home-assistant.io/docs/core/entity/
8+
"""
79
class DahuaBaseEntity(CoordinatorEntity):
810
"""
911
DahuaBaseEntity is the base entity for all Dahua entities

custom_components/dahua/light.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ async def async_setup_entry(hass: HomeAssistant, entry, async_add_entities):
3030
if coordinator.supports_illuminator():
3131
entities.append(DahuaIlluminator(coordinator, entry, "Illuminator"))
3232

33-
if coordinator.supports_security_light():
33+
if coordinator.supports_security_light() and not coordinator.is_amcrest_doorbell():
34+
# The Amcrest doorbell works a little different and is added in select.py
3435
entities.append(DahuaSecurityLight(coordinator, entry, "Security Light"))
3536

3637
async_add_entities(entities)

custom_components/dahua/select.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
Select entity platform for dahua.
3+
https://developers.home-assistant.io/docs/core/entity/select
4+
Requires HomeAssistant 2021.7.0 or greater
5+
"""
6+
from homeassistant.core import HomeAssistant
7+
from homeassistant.components.select import SelectEntity
8+
from custom_components.dahua import DahuaDataUpdateCoordinator
9+
10+
from .const import DOMAIN
11+
from .entity import DahuaBaseEntity
12+
13+
14+
async def async_setup_entry(hass: HomeAssistant, entry, async_add_devices):
15+
"""Setup select platform."""
16+
coordinator: DahuaDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
17+
18+
devices = []
19+
20+
if coordinator.is_amcrest_doorbell() and coordinator.supports_security_light():
21+
devices.append(DahuaDoorbellLightSelect(coordinator, entry))
22+
23+
async_add_devices(devices)
24+
25+
26+
class DahuaDoorbellLightSelect(DahuaBaseEntity, SelectEntity):
27+
"""allows one to turn the doorbell light on/off/strobe"""
28+
29+
def __init__(self, coordinator: DahuaDataUpdateCoordinator, config_entry):
30+
DahuaBaseEntity.__init__(self, coordinator, config_entry)
31+
SelectEntity.__init__(self)
32+
self._coordinator = coordinator
33+
self._attr_name = f"{coordinator.get_device_name()} Security Light"
34+
self._attr_unique_id = f"{coordinator.get_serial_number()}_security_light"
35+
self._attr_options = ["Off", "On", "Strobe"]
36+
37+
@property
38+
def current_option(self) -> str:
39+
mode = self._coordinator.data.get("table.Lighting_V2[0][0][1].Mode", "")
40+
state = self._coordinator.data.get("table.Lighting_V2[0][0][1].State", "")
41+
42+
if mode == "ForceOn" and state == "On":
43+
return "On"
44+
45+
if mode == "ForceOn" and state == "Flicker":
46+
return "Strobe"
47+
48+
return "Off"
49+
50+
async def async_select_option(self, option: str) -> None:
51+
await self._coordinator.client.async_set_lighting_v2_for_amcrest_doorbells(option)
52+
await self._coordinator.async_refresh()
53+
54+
@property
55+
def name(self):
56+
return self._attr_name
57+
58+
@property
59+
def unique_id(self):
60+
""" https://developers.home-assistant.io/docs/entity_registry_index/#unique-id-requirements """
61+
return self._attr_unique_id

hacs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Dahua",
33
"hacs": "1.6.0",
4-
"homeassistant": "2021.4.0",
4+
"homeassistant": "2021.7.0",
55
"domains": [
66
"binary_sensor",
77
"switch",

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
homeassistant~=2021.5.3
1+
homeassistant~=2021.7.0
22
ha-ffmpeg==3.0.2
33
voluptuous~=0.12.1
44
aiohttp~=3.7.4.post0

0 commit comments

Comments
 (0)