improved scene detect
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,4 +7,5 @@ secrets.yaml
|
|||||||
|
|
||||||
*.ipynb
|
*.ipynb
|
||||||
|
|
||||||
logs/
|
logs/
|
||||||
|
*.json
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
hello_world:
|
|
||||||
module: hello_world
|
|
||||||
class: HelloWorld
|
|
||||||
|
|
||||||
rich_logging:
|
rich_logging:
|
||||||
module: console
|
module: console
|
||||||
global: true
|
global: true
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from appdaemon.plugins.hass.hassapi import Hass
|
|
||||||
|
|
||||||
|
|
||||||
class HelloWorld(Hass):
|
|
||||||
def initialize(self):
|
|
||||||
self.log('Hello World')
|
|
||||||
|
|
||||||
now: datetime = self.get_now()
|
|
||||||
eid = self.args['eid']
|
|
||||||
self.log(eid)
|
|
||||||
self.listen_state(self.my_callback, eid)
|
|
||||||
self.set_state(eid, state=now.isoformat(), attributes=dict(name='Test Fade Start'))
|
|
||||||
self.log(f'Set state to {now.time()}')
|
|
||||||
|
|
||||||
def my_callback(self, entity, attribute, old, new, kwargs):
|
|
||||||
new = self.convert_time(new)
|
|
||||||
old = self.convert_time(old)
|
|
||||||
self.log(f'{attribute} {old} -> {new}')
|
|
||||||
|
|
||||||
def convert_time(self, time_str: str) -> datetime:
|
|
||||||
dt = datetime.fromisoformat(time_str)
|
|
||||||
try:
|
|
||||||
dt = self.AD.tz.localize(dt)
|
|
||||||
except ValueError:
|
|
||||||
dt = dt.astimezone(self.AD.tz)
|
|
||||||
finally:
|
|
||||||
return dt
|
|
||||||
49
apps/hello_world/hello.py
Normal file
49
apps/hello_world/hello.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
|
||||||
|
from appdaemon.adapi import ADAPI
|
||||||
|
from appdaemon.plugins.hass.hassapi import Hass
|
||||||
|
|
||||||
|
|
||||||
|
class HelloWorld(Hass):
|
||||||
|
def initialize(self):
|
||||||
|
self.log('Hello World')
|
||||||
|
# self.listen_state(
|
||||||
|
# callback=self.temp_callback,
|
||||||
|
# entity_id='sensor.temperature_nest',
|
||||||
|
# attribute='state',
|
||||||
|
# threshold=65.0,
|
||||||
|
# )
|
||||||
|
# self.listen_state(
|
||||||
|
# callback=self.temp_callback,
|
||||||
|
# entity_id='light.living_room',
|
||||||
|
# attribute='state',
|
||||||
|
# threshold=65.0,
|
||||||
|
# )
|
||||||
|
|
||||||
|
async def temp_callback(self, entity, attribute, old, new, kwargs):
|
||||||
|
self.log('Temp callback')
|
||||||
|
temp = await self.get_state('sensor.temperature_nest')
|
||||||
|
# self.log(json.dumps(temp, indent=4))
|
||||||
|
self.AD.loop.create_task(self.unreliable_call())
|
||||||
|
if float(temp) <= kwargs['threshold']:
|
||||||
|
self.log(f'{entity} is below the threshold')
|
||||||
|
self.AD.loop.create_task(self.unreliable_call())
|
||||||
|
|
||||||
|
self.log('Doing some other, more reliable stuff')
|
||||||
|
await asyncio.sleep(2.0)
|
||||||
|
self.log(f'{entity} done')
|
||||||
|
|
||||||
|
async def unreliable_call(self):
|
||||||
|
self.log('Calling unreliable cloud service....')
|
||||||
|
await asyncio.sleep(5.0)
|
||||||
|
# await self.call_service('climate/set_temperature', entity_id='climate.living_room', temperature=70)
|
||||||
|
self.log('Cloud service returned')
|
||||||
|
|
||||||
|
def entities_ending_with(self, ending_str: str):
|
||||||
|
entities = [
|
||||||
|
entity_id
|
||||||
|
for entity_id, state in self.get_state().items()
|
||||||
|
if entity_id.endswith(ending_str)
|
||||||
|
]
|
||||||
|
return entities
|
||||||
3
apps/hello_world/hello.yaml
Normal file
3
apps/hello_world/hello.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
HelloWorld:
|
||||||
|
module: hello
|
||||||
|
class: HelloWorld
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
from appdaemon.plugins.hass.hassapi import Hass
|
from appdaemon.plugins.hass.hassapi import Hass
|
||||||
|
from room_control import Motion
|
||||||
|
|
||||||
|
|
||||||
class SceneDetector(Hass):
|
class SceneDetector(Hass):
|
||||||
@@ -15,25 +19,27 @@ class SceneDetector(Hass):
|
|||||||
)
|
)
|
||||||
self.log(f'Waiting for {self.scene_entity.friendly_name} to activate')
|
self.log(f'Waiting for {self.scene_entity.friendly_name} to activate')
|
||||||
|
|
||||||
def event_callback(self, event_name, data, cb_args):
|
async def event_callback(self, event_name, data, cb_args):
|
||||||
entity_id = data['service_data']['entity_id']
|
entity_id = data['service_data']['entity_id']
|
||||||
if entity_id == self.scene_entity.entity_id:
|
if entity_id == self.scene_entity.entity_id:
|
||||||
self.scene_detected()
|
await self.scene_detected()
|
||||||
|
|
||||||
def scene_detected(self):
|
async def scene_detected(self):
|
||||||
self.log(f'Detected scene activation: {self.scene_entity.friendly_name}')
|
self.log(f'Detected scene activation: {self.scene_entity.friendly_name}')
|
||||||
|
|
||||||
|
|
||||||
class MotionCanceller(SceneDetector):
|
class MotionCanceller(SceneDetector):
|
||||||
def scene_detected(self):
|
async def scene_detected(self):
|
||||||
super().scene_detected()
|
await super().scene_detected()
|
||||||
app = self.get_app(self.args['app'])
|
app: Motion = await self.get_app(self.args['app'])
|
||||||
try:
|
all_callbacks = await self.get_callback_entries()
|
||||||
self.run_in(callback=lambda *args, **kwargs: app.cancel_motion_callback(), delay=0.5)
|
app_callbacks = all_callbacks[app.name]
|
||||||
except Exception:
|
|
||||||
self.log(
|
for handle, info in app_callbacks.items():
|
||||||
f'Error cancelling motion callback for {self.args["app"]}',
|
if info['entity'] == app.sensor.entity_id and 'new=off' in info['kwargs']:
|
||||||
level='ERROR',
|
self.log(f'Cancelling motion callback for {app.name}')
|
||||||
)
|
await self.AD.state.cancel_state_callback(handle, app.name)
|
||||||
|
# self.log(json.dumps(info, indent=4))
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
self.log('Cancelled motion callback')
|
self.log('Did not cancel anything', level='WARNING')
|
||||||
|
|||||||
Reference in New Issue
Block a user