Skip to content

Commit

Permalink
feat: Add timers for each area (#649)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvgijssel authored Feb 21, 2024
1 parent 682c855 commit 8be3f4c
Show file tree
Hide file tree
Showing 20 changed files with 1,401 additions and 416 deletions.
5 changes: 5 additions & 0 deletions .changeset/occupancy_component-heavy-teachers-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"occupancy_component": minor
---

feat: Implement area with timer logic
12 changes: 6 additions & 6 deletions WORKSPACE.bzlmod
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
http_archive(
name = "tilt_linux_arm64",
build_file = "//tools/tilt:BUILD.repositories.bazel.tpl",
sha256 = "7b9d859439e063a9fb2701c1dee41e3455590afb436edc2c9a7fc633bb9d374a",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.10/tilt.0.33.10.linux.arm64.tar.gz",
sha256 = "49ce19981761b6102cf5fe3cb15d6cfdf6b56aa2be7a1178457955c7476bf21f",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.11/tilt.0.33.11.linux.arm64.tar.gz",
)

http_archive(
name = "tilt_linux_amd64",
build_file = "//tools/tilt:BUILD.repositories.bazel.tpl",
sha256 = "fdb62ab5f9e0cf2cb697f8b1e91f2909ee61ab14899f6b2c1a144c0d729d99a3",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.10/tilt.0.33.10.linux.x86_64.tar.gz",
sha256 = "b14cc9d33b18c8bdf69b543914696b252e553c9361f65d2ed0cded302698708d",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.11/tilt.0.33.11.linux.x86_64.tar.gz",
)

http_archive(
name = "tilt_darwin_arm64",
build_file = "//tools/tilt:BUILD.repositories.bazel.tpl",
sha256 = "b4b460b02eb4e261b512a7c793e8381bef1a5adb864ef46d3fcae3f6a30fcab3",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.10/tilt.0.33.10.mac.arm64.tar.gz",
sha256 = "dbb1716432a79a31b9c5f1842cfce02f2abbf9bcfa789d9afbc41d155e930855",
url = "https://github.com/tilt-dev/tilt/releases/download/v0.33.11/tilt.0.33.11.mac.arm64.tar.gz",
)

# ------------------------------------ pulumi ------------------------------------ #
Expand Down
1 change: 1 addition & 0 deletions devbox.lock
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
},
"[email protected]": {
"last_modified": "2024-01-27T14:55:31Z",
"plugin_version": "0.0.2",
"resolved": "github:NixOS/nixpkgs/160b762eda6d139ac10ae081f8f78d640dd523eb#python311Packages.pip",
"source": "devbox-search",
"version": "23.3.1",
Expand Down
4 changes: 4 additions & 0 deletions occupancy_component/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ py_library(
"custom_components/occupancy/__init__.py",
"custom_components/occupancy/binary_sensor.py",
"custom_components/occupancy/const.py",
"custom_components/occupancy/helpers.py",
"custom_components/occupancy/internal_state.py",
"custom_components/occupancy/select.py",
],
data = [
Expand All @@ -26,6 +28,8 @@ py_pytest_test(
srcs = [
"tests/conftest.py",
"tests/helpers.py",
"tests/test_area.py",
"tests/test_door.py",
"tests/test_init.py",
],
args = ["--asyncio-mode=auto"],
Expand Down
1 change: 1 addition & 0 deletions occupancy_component/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ FROM homeassistant/home-assistant:2024.2
RUN wget -O /usr/local/bin/wait-for https://github.com/eficode/wait-for/releases/download/v2.2.3/wait-for && chmod +x /usr/local/bin/wait-for

ADD configuration.yaml /config/configuration.yaml
ADD automations.yaml /config/automations.yaml
ADD custom_components /config/custom_components

# NOTE: this is a hack to bypass onboarding copied from here
Expand Down
1 change: 1 addition & 0 deletions occupancy_component/Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ docker_build(
".",
live_update=[
sync('configuration.yaml', '/config/configuration.yaml'),
sync('automations.yaml', '/config/automations.yaml'),
sync('custom_components', '/config/custom_components/'),
restart_container(),
]
Expand Down
62 changes: 62 additions & 0 deletions occupancy_component/automations.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
- id: "1707938841757"
alias: Control front door contact
description: ""
trigger:
- platform: state
entity_id:
- input_boolean.front_door_contact_simulate
condition: []
action:
- service: mqtt.publish
metadata: {}
data:
qos: "2"
retain: true
topic: home-assistant/front_door/contact
payload: "{{ trigger.to_state.state }}"
mode: single
- id: "1707939189264"
alias: Control front door motion occupancy
description: ""
trigger:
- platform: state
entity_id:
- input_button.front_door_motion_occupancy_simulate
condition: []
action:
- service: mqtt.publish
metadata: {}
data:
qos: "2"
retain: true
topic: home-assistant/front_door/motion_occupancy
payload: "on"
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- service: mqtt.publish
metadata: {}
data:
qos: "2"
retain: true
topic: home-assistant/front_door/motion_occupancy
payload: "off"
mode: single
- id: "1707942333572"
alias: Control hallway occupancy
description: ""
trigger:
- platform: state
entity_id:
- input_boolean.hallway_occupancy_simulate
condition: []
action:
- service: mqtt.publish
metadata: {}
data:
qos: "2"
retain: true
topic: home-assistant/hallway/occupancy
payload: "{{ trigger.to_state.state }}"
28 changes: 24 additions & 4 deletions occupancy_component/configuration.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Loads default set of integrations. Do not remove.
default_config:

automation: !include automations.yaml

homeassistant:
name: testing
latitude: 0
Expand All @@ -14,18 +16,36 @@ logger:
logs:
custom_components.occupancy: debug

input_boolean:
front_door_contact_simulate:
name: Simulate front door contact
icon: mdi:door
hallway_occupancy_simulate:
name: Simulate hallway occupancy
icon: mdi:home

input_button:
front_door_motion_occupancy_simulate:
name: Simulate front door motion occupancy
icon: mdi:motion-sensor

mqtt:
binary_sensor:
- name: front_door_contact
state_topic: "home-assistant/front_door/contact"
device_class: "door"
payload_on: "ON"
payload_off: "OFF"
payload_on: "on"
payload_off: "off"
- name: front_door_motion_occupancy
state_topic: "home-assistant/front_door/motion_occupancy"
device_class: "motion"
payload_on: "ON"
payload_off: "OFF"
payload_on: "on"
payload_off: "off"
- name: hallway_occupancy
state_topic: "home-assistant/hallway/occupancy"
device_class: "occupancy"
payload_on: "on"
payload_off: "off"

occupancy:
doors:
Expand Down
48 changes: 38 additions & 10 deletions occupancy_component/custom_components/occupancy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@
ATTR_AREAS,
ATTR_OCCUPANCY_SENSORS,
OCCUPANCY_DATA,
STATUS_ENTERING,
STATUS_ENTERING_CONFIRM,
STATUS_LEAVING,
STATUS_LEAVING_CONFIRM,
ATTR_ENTERING_TIMER,
ATTR_ENTERING_CONFIRM_TIMER,
ATTR_LEAVING_TIMER,
ATTR_LEAVING_CONFIRM_TIMER,
ATTR_TIMER_ENTITIES,
)
from custom_components.occupancy.helpers import create_timer

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.components.select import DOMAIN as SELECT_DOMAIN
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.timer import DOMAIN as TIMER_DOMAIN


CONFIG_SCHEMA = vol.Schema(
{
Expand Down Expand Up @@ -59,6 +69,12 @@
)


async def _create_area_timer(hass, area_id, state):
timer_id = f"{area_id}_{state}"
timer = await create_timer(hass, timer_id)
return timer


async def async_setup(hass: HomeAssistantType, config: dict) -> bool:
_LOGGER.debug("async_setup start %s", config)

Expand All @@ -78,14 +94,33 @@ async def async_setup(hass: HomeAssistantType, config: dict) -> bool:
)

for area_id, area_config in config[DOMAIN][ATTR_AREAS].items():
entering_timer = await _create_area_timer(hass, area_id, STATUS_ENTERING)
entering_confirm_timer = await _create_area_timer(
hass, area_id, STATUS_ENTERING_CONFIRM
)
leaving_timer = await _create_area_timer(hass, area_id, STATUS_LEAVING)
leaving_confirm_timer = await _create_area_timer(
hass, area_id, STATUS_LEAVING_CONFIRM
)

area_config = {
"occupancy_sensors": area_config[ATTR_OCCUPANCY_SENSORS],
ATTR_TIMER_ENTITIES: [
entering_timer,
entering_confirm_timer,
leaving_timer,
leaving_confirm_timer,
],
ATTR_OCCUPANCY_SENSORS: area_config[ATTR_OCCUPANCY_SENSORS],
# Adding the binary sensor domain to the door references. Maybe this
# also requires some validation for the user, so they know they shouldn't
# provide an entity reference but a door name.
"doors": [
ATTR_DOORS: [
f"{BINARY_SENSOR_DOMAIN}.{door}" for door in area_config[ATTR_DOORS]
],
ATTR_ENTERING_TIMER: entering_timer.entity_id,
ATTR_ENTERING_CONFIRM_TIMER: entering_confirm_timer.entity_id,
ATTR_LEAVING_TIMER: leaving_timer.entity_id,
ATTR_LEAVING_CONFIRM_TIMER: leaving_confirm_timer.entity_id,
}

data[ATTR_AREAS][area_id] = area_config
Expand All @@ -96,12 +131,5 @@ async def async_setup(hass: HomeAssistantType, config: dict) -> bool:
)
)

# TODO: this does not work for uknown reason
hass.async_create_task(
hass.helpers.discovery.async_load_platform(
"timer", DOMAIN, {"area_id": area_id}, config
)
)

_LOGGER.debug("async_setup done")
return True
Loading

0 comments on commit 8be3f4c

Please sign in to comment.