I’ve recently set up schedy ( Schedy — hass-apps 0.20200319.0 documentation ) to control my home thermostats. I’ve always wanted my thermostats to adjust down (I only use heating) based on how far away I am to home. I’ve found the natural logarithm of the distance works well, i.e. if I’m 100km away it can adjust down the temperature by 4 degrees. This is my probaby sub-optimal way of achieving it:
- Enable the proximity integration in home assistant’s configuration.yaml:
proximity:
home:
devices:
- person.alge
tolerance: 50
unit_of_measurement: km
- Create an AppDaemon app which publishes an adjustment based on the proximity:
(place this in apps directory:)
tempadjust.py (place in apps directory in appdaemon config):
import hassapi as hass
import math
"""
Adjust temperature based on proximity.
Uses the "proximity" integration (or any other entity which has state in km),
and outputs an adjustment value based on the logarithm of the distance.
Arguments:
- event: Entity name when publishing event (e.g. 'tempadjuster.adjustment')
- proximity: Entity name for proximity in km (e.g. 'proximity.home')
- km_offset: optional integer: Added to proximity km before calulation (e.g. km_offset=-10 to force proximity of within 10 km to not cause any adjustment)
- km_multiplier: optional float: Multiplied with proximity km after offsetting (e.g. km_multiplier=2.0 to make adjustments more aggressive)
- adjustment_multiplier: optional float: Multiplied with calculated adjustment (e.g. adjustment_multiplier=0.5 to make adjustments less aggressive)
"""
class TempAdjuster(hass.Hass):
def initialize(self):
self.entity = self.args["event"]
self.proximity = self.args["proximity_entity"]
self.km_offset = int(self.args.get('km_offset', 0))
self.km_multiplier = float(self.args.get('km_multiplier', 1.0))
self.adjustment_multiplier = float(self.args.get('adjustment_multiplier', 1.0))
if (self.get_state(self.proximity) is None):
self.log(f"Unable to look up proximity entity [{self.proximity}]", level="ERROR")
return
self.listen_state(self.updateState, self.proximity)
self.updateState()
def updateState(self, kwargs=None):
proximity_km=(int(self.get_state(self.proximity)) + self.km_offset) * self.km_multiplier
adjustment = 0
if (proximity_km >= 1):
adjustment = -int(math.log(proximity_km)) * self.adjustment_multiplier
self.log(f"proximity is {proximity_km}, adjustment is{adjustment}", level="INFO")
self.set_state(self.entity, state=int(adjustment))
and add the app with parameters in apps.yaml:
tempadjuster:
module: tempadjuster
class: TempAdjuster
interval: 30
proximity_entity: "proximity.home"
km_offset: -5
event: "tempadjuster.adjustment"
- Use this as a dynamic expression in the schedy schedule:
schedy_heating:
module: hass_apps_loader
class: SchedyApp
actor_type: thermostat
schedule_prepend:
- x: "Add(int(state('tempadjuster.adjustment')))"
watched_entities:
- "tempadjuster.adjustment"
rooms:
[....]
Reason for posting this:
- Is there a better way of achieving this?
- Maybe someone finds it useful. (=