Skip to content

Commit

Permalink
Add HACS Eufy Security integration + automations
Browse files Browse the repository at this point in the history
  • Loading branch information
bachya committed Jul 15, 2022
1 parent b8b2400 commit 0ab356e
Show file tree
Hide file tree
Showing 24 changed files with 3,463 additions and 0 deletions.
13 changes: 13 additions & 0 deletions docker-compose.yml
Expand Up @@ -15,6 +15,18 @@ services:
- 8080:8080/tcp
restart: unless-stopped

eufy-security-ws:
environment:
PASSWORD: ${EUFY_SECURITY_WS_PASSWORD}
TRUSTED_DEVICE_NAME: eufy-security-ws
USERNAME: ${EUFY_SECURITY_WS_USERNAME}
image: bropat/eufy-security-ws:${EUFY_SECURITY_WS_VERSION}
ports:
- 127.0.0.1:3001:3000/tcp
restart: unless-stopped
volumes:
- eufy-security-ws-data:/data

esphome:
environment:
PASSWORD: "${ESPHOME_PASSWORD}"
Expand Down Expand Up @@ -102,4 +114,5 @@ services:
volumes:
hass-config:
hass-db-data:
eufy-security-ws-data:
zwave-js-config:
10 changes: 10 additions & 0 deletions hass/settings/conf/packages/presence.yaml
Expand Up @@ -41,6 +41,11 @@ automation:
- automation.security_notify_when_the_house_is_empty_and_insecure
- automation.security_notify_when_the_overall_security_status_changes
- automation.security_simulate_someone_being_home

- alias: "Set the Eufy base station to 'Away' mode"
service: alarm_control_panel.alarm_arm_away
target:
entity_id: alarm_control_panel.eufy_base_station
else:
- parallel:
- alias: "Turn various entities off"
Expand All @@ -65,6 +70,11 @@ automation:
- switch.guardian_b4e62d98118d_valve
- switch.humidistat_switchbot

- alias: "Set the Eufy base station to 'Home' mode"
service: alarm_control_panel.alarm_arm_home
target:
entity_id: alarm_control_panel.eufy_base_station

group:
people:
name: People
Expand Down
34 changes: 34 additions & 0 deletions hass/settings/conf/packages/security.yaml
Expand Up @@ -405,6 +405,40 @@ automation:
target:
entity_id: "{{ repeat.item.entity }}"

- alias: "Security: Turn on front patio light with nighttime motion"
id: "security_turn_on_front_patio_light_with_nighttime_motion"
mode: restart

trigger:
- platform: state
entity_id: binary_sensor.doorbell_motion_sensor
to: "on"
for: "00:00:10"

condition:
- condition: state
entity_id: binary_sensor.is_dark_outside
state: "on"

action:
- alias: "Is the light off?"
condition: state
entity_id: switch.front_patio_light
state: "off"

- alias: "Turn the light on"
service: switch.turn_on
target:
entity_id: switch.front_patio_light

- alias: "Keep the light on for 2 minutes"
delay: "00:02:00"

- alias: "Turn the light off"
service: switch.turn_off
target:
entity_id: switch.front_patio_light

group:
security_devices:
entities:
Expand Down
89 changes: 89 additions & 0 deletions hass/settings/custom_components/eufy_security/__init__.py
@@ -0,0 +1,89 @@
import asyncio
from datetime import timedelta
import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant
from homeassistant.helpers.event import async_track_time_interval

from .const import CAPTCHA_CONFIG, COORDINATOR, DOMAIN, PLATFORMS, CaptchaConfig
from .coordinator import EufySecurityDataUpdateCoordinator

_LOGGER: logging.Logger = logging.getLogger(__package__)


async def async_setup(hass: HomeAssistant, config: Config):
if DOMAIN not in hass.data:
hass.data[DOMAIN] = {}

async def async_handle_send_message(call):
coordinator: EufySecurityDataUpdateCoordinator = hass.data[DOMAIN][COORDINATOR]
_LOGGER.debug(f"{DOMAIN} - send_message - call.data: {call.data}")
message = call.data.get("message")
_LOGGER.debug(f"{DOMAIN} - end_message - message: {message}")
await coordinator.async_send_message(message)

async def async_force_sync(call):
coordinator: EufySecurityDataUpdateCoordinator = hass.data[DOMAIN][COORDINATOR]
await coordinator.async_refresh()

async def async_driver_connect(call):
coordinator: EufySecurityDataUpdateCoordinator = hass.data[DOMAIN][COORDINATOR]
await coordinator.async_driver_connect()

hass.services.async_register(DOMAIN, "driver_connect", async_driver_connect)
hass.services.async_register(DOMAIN, "force_sync", async_force_sync)
hass.services.async_register(DOMAIN, "send_message", async_handle_send_message)
return True


async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})
captcha_config = hass.data[DOMAIN].get(CAPTCHA_CONFIG, CaptchaConfig())
coordinator = hass.data[DOMAIN].get(
COORDINATOR,
EufySecurityDataUpdateCoordinator(hass, config_entry, captcha_config),
)
hass.data[DOMAIN][COORDINATOR] = coordinator
hass.data[DOMAIN][CAPTCHA_CONFIG] = captcha_config

await coordinator.initialize()
await coordinator.async_refresh()
for platform in PLATFORMS:
coordinator.platforms.append(platform)
hass.async_add_job(
hass.config_entries.async_forward_entry_setup(config_entry, platform)
)

async def update(event_time_utc):
coordinator.async_set_updated_data(coordinator.data)

coordinator.update_listener = async_track_time_interval(
hass, update, timedelta(seconds=1)
)
config_entry.add_update_listener(async_reload_entry)
return True


async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
coordinator = hass.data[DOMAIN][COORDINATOR]
unloaded = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(config_entry, platform)
for platform in PLATFORMS
if platform in coordinator.platforms
]
)
)
coordinator.update_listener()
if unloaded:
hass.data[DOMAIN] = {}

return unloaded


async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
await async_unload_entry(hass, config_entry)
await async_setup_entry(hass, config_entry)

0 comments on commit 0ab356e

Please sign in to comment.