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
1011import logging
1112import re
1213from datetime import date , datetime , time , timedelta
1314from threading import Timer
1415
15- import homeassistant .helpers .config_validation as cv
1616import 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+ )
1827from 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
2031from homeassistant .helpers .entity_component import EntityComponent
2132from homeassistant .helpers .sun import get_astral_event_date
33+ from homeassistant .loader import bind_hass
2234from homeassistant .util import dt
2335from transitions import Machine
2436from transitions .extensions import HierarchicalMachine as Machine
4052DEFAULT_BRIGHTNESS = 100
4153DEFAULT_NAME = "Entity Timer"
4254
55+ ATTR_COMMAND = "command"
56+
4357# CONF_NAME = 'slug'
4458CONF_CONTROL_ENTITIES = "entities"
4559CONF_CONTROL_ENTITY = "entity"
6983
7084_LOGGER = logging .getLogger (__name__ )
7185
72- devices = []
86+ DEVICES = []
7387MODE_SCHEMA = vol .Schema (
7488 {
7589 vol .Optional (CONF_SERVICE_DATA , default = None ): vol .Coerce (
116130
117131PLATFORM_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
120146async 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
394466class Model :
395467 """ Represents the transitions state machine model """
0 commit comments