Skip to content

Commit d1912b4

Browse files
authored
feat: basic services and control
Implements Basic Services and Control
2 parents 1f266b8 + 8a7070a commit d1912b4

File tree

3 files changed

+97
-18
lines changed

3 files changed

+97
-18
lines changed

custom_components/entity_controller/__init__.py

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,30 @@
77
* YAML configuration (for the misbehaving entity)
88
* log entries at time of error and at time of initialisation
99
"""
10+
import functools as ft
1011
import logging
1112
import re
1213
from datetime import date, datetime, time, timedelta
1314
from threading import Timer
1415

15-
import homeassistant.helpers.config_validation as cv
1616
import voluptuous as vol
17-
from homeassistant.const import CONF_NAME, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET
17+
18+
from homeassistant.const import (
19+
CONF_NAME,
20+
SERVICE_TOGGLE,
21+
SERVICE_TURN_OFF,
22+
SERVICE_TURN_ON,
23+
STATE_ON,
24+
SUN_EVENT_SUNRISE,
25+
SUN_EVENT_SUNSET,
26+
)
1827
from homeassistant.core import callback
19-
from homeassistant.helpers import entity, event, service
28+
from homeassistant.helpers import config_validation as cv
29+
from homeassistant.helpers import event, service
30+
from homeassistant.helpers.entity import ToggleEntity
2031
from homeassistant.helpers.entity_component import EntityComponent
2132
from homeassistant.helpers.sun import get_astral_event_date
33+
from homeassistant.loader import bind_hass
2234
from homeassistant.util import dt
2335
from transitions import Machine
2436
from transitions.extensions import HierarchicalMachine as Machine
@@ -40,6 +52,8 @@
4052
DEFAULT_BRIGHTNESS = 100
4153
DEFAULT_NAME = "Entity Timer"
4254

55+
ATTR_COMMAND = "command"
56+
4357
# CONF_NAME = 'slug'
4458
CONF_CONTROL_ENTITIES = "entities"
4559
CONF_CONTROL_ENTITY = "entity"
@@ -69,7 +83,7 @@
6983

7084
_LOGGER = logging.getLogger(__name__)
7185

72-
devices = []
86+
DEVICES = []
7387
MODE_SCHEMA = vol.Schema(
7488
{
7589
vol.Optional(CONF_SERVICE_DATA, default=None): vol.Coerce(
@@ -116,6 +130,18 @@
116130

117131
PLATFORM_SCHEMA = cv.schema_with_slug_keys(ENTITY_SCHEMA)
118132

133+
EC_SERVICE_ACTIVITY_SCHEMA = cv.make_entity_service_schema({})
134+
135+
@bind_hass
136+
def is_on(hass, entity_id):
137+
"""Return if the controller is on based on the state machine."""
138+
return hass.states.is_state(entity_id, STATE_ON)
139+
140+
@bind_hass
141+
def is_on(hass, entity_id):
142+
"""Return if the controller is on based on the state machine."""
143+
return hass.states.is_state(entity_id, STATE_ON)
144+
119145

120146
async def async_setup(hass, config):
121147
"""Load graph configurations."""
@@ -291,18 +317,36 @@ async def async_setup(hass, config):
291317
m = EntityController(hass, config, machine)
292318
# machine.add_model(m.model)
293319
# m.model.after_model(config)
294-
devices.append(m)
320+
DEVICES.append(m)
321+
322+
await component.async_add_entities(DEVICES)
323+
324+
component.async_register_entity_service(
325+
SERVICE_TURN_OFF, EC_SERVICE_ACTIVITY_SCHEMA, "async_turn_off"
326+
)
327+
328+
component.async_register_entity_service(
329+
SERVICE_TURN_ON, EC_SERVICE_ACTIVITY_SCHEMA, "async_turn_on"
330+
)
295331

296-
await component.async_add_entities(devices)
332+
component.async_register_entity_service(
333+
SERVICE_TOGGLE, EC_SERVICE_ACTIVITY_SCHEMA, "async_toggle"
334+
)
335+
336+
component.async_register_entity_service(
337+
"control",
338+
{vol.Required(ATTR_COMMAND): vol.All(cv.ensure_list, [cv.string])},
339+
"async_service_control",
340+
)
297341

298342
_LOGGER.info("The %s component is ready!", DOMAIN)
299343

300344
return True
301345

302-
303-
class EntityController(entity.Entity):
346+
class EntityController(ToggleEntity):
304347
def __init__(self, hass, config, machine):
305348
self.attributes = {}
349+
self._is_enabled
306350
self.may_update = False
307351
self.model = None
308352
self.friendly_name = config.get(CONF_NAME, "Motion Light")
@@ -316,6 +360,23 @@ def __init__(self, hass, config, machine):
316360
)
317361
event.async_call_later(hass, 1, self.do_update)
318362

363+
@property
364+
def is_on(self) -> bool:
365+
"""Return True if entity controller is enabled."""
366+
return self._is_enabled
367+
368+
def turn_on(self, **kwargs) -> None:
369+
"""Enable the entity controller."""
370+
self._is_enabled = True
371+
# TODO: IMPLEMENT A TURN_ON FUNCTION TO ENABLE CONTROLLER.
372+
raise NotImplementedError()
373+
374+
def turn_off(self, **kwargs) -> None:
375+
"""Disable the entity controller."""
376+
self._is_enabled = False
377+
# TODO: IMPLEMENT A TURN_OFF FUNCTION TO DISABLE CONTROLLER.
378+
raise NotImplementedError()
379+
319380
@property
320381
def state(self):
321382
"""Return the state of the entity."""
@@ -390,6 +451,17 @@ async def async_added_to_hass(self):
390451
"""Register update dispatcher."""
391452
self.may_update = True
392453

454+
def service_control(self, command, **kwargs):
455+
"""Executes service control on entity controller."""
456+
_LOGGER.info("Service Control Called on %s with data %r", self.name, command)
457+
# TODO: IMPLEMENT ACTUAL CONTROLS.
458+
459+
async def async_service_control(self, command, **kwargs):
460+
"""Executes service control on entity controller."""
461+
return self.hass.async_add_executor_job(
462+
ft.partial(self.service_control, command, **kwargs)
463+
)
464+
393465

394466
class Model:
395467
""" Represents the transitions state machine model """
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
{
2-
"domain": "entity_controller",
3-
"name": "Entity Contoller",
4-
"documentation": "https://github.com/danobot/entity-controller/blob/master/README.md",
5-
"requirements": [
6-
"transitions==0.6.9"
7-
],
8-
"dependencies": [
9-
],
10-
"codeowners": ["@danobot"],
11-
"homeassistant": "0.102.3"
2+
"domain": "entity_controller",
3+
"name": "Entity Contoller",
4+
"documentation": "https://github.com/danobot/entity-controller/blob/master/README.md",
5+
"requirements": ["transitions==0.6.9"],
6+
"dependencies": [],
7+
"codeowners": ["@danobot"],
8+
"homeassistant": "0.102.3",
129
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
control:
3+
description: Manual control of an entity_controller device from an external automation or service call.
4+
fields:
5+
entity_id:
6+
description: Name(s) of the entities to control
7+
example: 'entity_controller.hallway_motion'
8+
command:
9+
description: Control action to perform on the entity controller.
10+
example: 'enable'

0 commit comments

Comments
 (0)