Initial work on a presence tracker. Inspired by @helto4real
This commit is contained in:
parent
3e61dcda71
commit
7305d719ee
79
appdaemon/apps/presence.py
Normal file
79
appdaemon/apps/presence.py
Normal file
@ -0,0 +1,79 @@
|
||||
from entities import Entities
|
||||
from timers import Timers
|
||||
|
||||
class Presence(Timers, Entities):
|
||||
|
||||
HOME = 'home'
|
||||
AWAY = 'not_home'
|
||||
ARRIVED = 'just_arrived'
|
||||
LEFT = 'just_left'
|
||||
TIMEOUT = 300
|
||||
|
||||
def initialize(self):
|
||||
super().initialize()
|
||||
|
||||
attr = self.args.get('attributes', {})
|
||||
|
||||
self.register_entity('tracker', self.args['name'], managed=True, default="not_home", attributes=self.args.get('attributes',{}))
|
||||
self.tracker = self.e['tracker']
|
||||
if(self.tracker.state in [self.ARRIVED, self.LEFT]):
|
||||
self.tracker.state = self.AWAY
|
||||
|
||||
self.devices = []
|
||||
for i,d in enumerate(self.args['devices']):
|
||||
name = f"device{i}"
|
||||
self.register_entity(name, d);
|
||||
self.e[name].listen(self.update, {"name": name})
|
||||
self.devices.append(self.e[name])
|
||||
|
||||
self.update()
|
||||
|
||||
def update(self, old=None, new=None, kwarg=None):
|
||||
if not old or isinstance(old, str):
|
||||
timeout = False
|
||||
elif old is None:
|
||||
timeout = False
|
||||
else:
|
||||
timeout = old.get('trigger', False)
|
||||
new_state = self.is_home()
|
||||
old_state = self.tracker.state
|
||||
if new_state:
|
||||
if old_state == self.AWAY:
|
||||
self.run_in('timeout', self.update, self.TIMEOUT, trigger = "timeout")
|
||||
state = self.ARRIVED
|
||||
elif old_state == self.LEFT:
|
||||
self.cancel_timer('timeout')
|
||||
state = self.HOME
|
||||
elif old_state == self.ARRIVED and timeout:
|
||||
state = self.HOME
|
||||
else:
|
||||
state = old_state
|
||||
else:
|
||||
if old_state == self.HOME:
|
||||
self.run_in('timeout', self.update, self.TIMEOUT, trigger = "timeout")
|
||||
state = self.LEFT
|
||||
elif old_state == self.ARRIVED:
|
||||
self.cancel_timer('timeout')
|
||||
state = self.AWAY
|
||||
elif old_state == self.LEFT and timeout:
|
||||
state = self.AWAY
|
||||
else:
|
||||
state = old_state
|
||||
|
||||
self.tracker.state = state
|
||||
self.tracker.push()
|
||||
|
||||
def is_home(self):
|
||||
for d in self.devices:
|
||||
if d.domain == 'device_tracker':
|
||||
if d.attr['source_type'] in ['router']:
|
||||
if d.state == 'home':
|
||||
return True
|
||||
if d.domain == 'sensor':
|
||||
if d.state != 'unknown' and int(d.state) > 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
37
appdaemon/apps/presence.yaml
Normal file
37
appdaemon/apps/presence.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
presence_thomas:
|
||||
module: presence
|
||||
class: Presence
|
||||
global_dependencies:
|
||||
- entities
|
||||
- timers
|
||||
dependencies:
|
||||
- entity_manager
|
||||
|
||||
name: device_tracker.thomas_presence
|
||||
attributes: {}
|
||||
|
||||
devices:
|
||||
- device_tracker.thomas_iphone_beta
|
||||
- device_tracker.thomas_iphone_2
|
||||
- sensor.thomas_iphone_bt
|
||||
- sensor.thomas_iphone_bt2
|
||||
|
||||
presence_anneli:
|
||||
module: presence
|
||||
class: Presence
|
||||
global_depencencies:
|
||||
- entities
|
||||
- timers
|
||||
dependencies:
|
||||
- entity_manager
|
||||
|
||||
name: device_tracker.anneli_presence
|
||||
attributes: {}
|
||||
|
||||
devices:
|
||||
- device_tracker.anneli_lovn
|
||||
- device_tracker.anneli_loven
|
||||
- sensor.anneli_iphone_bt
|
||||
- sensor.anneli_iphone_bt2
|
||||
# - sensor.anneli_klocka_bt
|
||||
# - sensor.anneli_klocka_bt2
|
@ -21,6 +21,43 @@ popup_cards:
|
||||
- type: history-graph
|
||||
entities: *door_entities
|
||||
|
||||
device_tracker.thomas_presence:
|
||||
title: Thomas
|
||||
large: true
|
||||
card:
|
||||
type: vertical-stack
|
||||
cards:
|
||||
- type: entities
|
||||
entities: &thomas_entities
|
||||
- device_tracker.thomas_iphone_beta
|
||||
- device_tracker.thomas_iphone_2
|
||||
- sensor.thomas_iphone_bt
|
||||
- sensor.thomas_iphone_bt2
|
||||
- type: history-graph
|
||||
entities:
|
||||
- device_tracker.thomas_presence
|
||||
- type: history-graph
|
||||
entities: *thomas_entities
|
||||
|
||||
device_tracker.anneli_presence:
|
||||
title: Anneli
|
||||
large: true
|
||||
card:
|
||||
type: vertical-stack
|
||||
cards:
|
||||
- type: entities
|
||||
entities: &anneli_entities
|
||||
- device_tracker.anneli_lovn
|
||||
- device_tracker.anneli_loven
|
||||
- sensor.anneli_iphone_bt
|
||||
- sensor.anneli_iphone_bt2
|
||||
- sensor.anneli_klocka_bt
|
||||
- sensor.anneli_klocka_bt2
|
||||
- type: history-graph
|
||||
entities:
|
||||
- device_tracker.anneli_presence
|
||||
- type: history-graph
|
||||
entities: *anneli_entities
|
||||
cards:
|
||||
- type: custom:layout-card
|
||||
layout: vertical
|
||||
@ -56,10 +93,22 @@ cards:
|
||||
- break
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: picture
|
||||
image: /local/images/thomas_clr.jpg
|
||||
- type: picture
|
||||
image: /local/images/anneli_clr.png
|
||||
- type: picture-entity
|
||||
entity: device_tracker.thomas_presence
|
||||
image: /local/images/thomas_bw.jpg
|
||||
show_name: false
|
||||
show_state: false
|
||||
state_image:
|
||||
"home": /local/images/thomas_clr.jpg
|
||||
"just_arrived": /local/images/thomas_clr.jpg
|
||||
- type: picture-entity
|
||||
entity: device_tracker.anneli_presence
|
||||
image: /local/images/anneli_bw.png
|
||||
show_name: false
|
||||
show_state: false
|
||||
state_image:
|
||||
"home": /local/images/anneli_clr.png
|
||||
"just_arrived": /local/images/anneli_clr.png
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: entity-button
|
||||
|
37
packages/presence.yaml
Normal file
37
packages/presence.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
homeassistant:
|
||||
customize:
|
||||
package.node_anchors:
|
||||
common: &common
|
||||
package: 'security'
|
||||
|
||||
binary_sensor.home_occupied:
|
||||
<<: *common
|
||||
automation.adm_rescan_monitor_on_restart:
|
||||
<<: *common
|
||||
|
||||
binary_sensor:
|
||||
- platform: template
|
||||
sensors:
|
||||
home_occupied:
|
||||
friendly_name: Anyone home
|
||||
value_template: >-
|
||||
{{ (is_state('device_tracker.thomas_presence', 'home') or
|
||||
is_state('device_tracker.anneli_presence', 'home')) }}
|
||||
|
||||
device_tracker:
|
||||
- platform: unifi
|
||||
host: unifi
|
||||
username: !secret unifi_username
|
||||
password: !secret unifi_password
|
||||
verify_ssl: false
|
||||
ssid_filter: !secret unifi_ssids
|
||||
|
||||
automation:
|
||||
- alias: ADM - Rescan monitor on restart
|
||||
trigger:
|
||||
platform: homeassistant
|
||||
event: start
|
||||
action:
|
||||
- service: mqtt.publish
|
||||
data:
|
||||
topic: "monitor/scan/restart"
|
Loading…
x
Reference in New Issue
Block a user