# Dynamically adjusting schedy termperature based on proximity

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:

1. Enable the proximity integration in home assistant’s configuration.yaml:
``````proximity:
home:
devices:
- person.alge
tolerance: 50
unit_of_measurement: km
``````
1. 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

"""

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:
- 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)
"""

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))

if (self.get_state(self.proximity) is None):
self.log(f"Unable to look up proximity entity [{self.proximity}]", level="ERROR")
return

proximity_km=(int(self.get_state(self.proximity)) + self.km_offset) * self.km_multiplier
if (proximity_km >= 1):
``````

and add the app with parameters in apps.yaml:

``````tempadjuster:
interval: 30
proximity_entity: "proximity.home"
km_offset: -5
``````
1. Use this as a dynamic expression in the schedy schedule:
``````schedy_heating:
class: SchedyApp

actor_type: thermostat

schedule_prepend:
watched_entities:

rooms:
[....]
``````

Reason for posting this:

1. Is there a better way of achieving this?
2. Maybe someone finds it useful. (=

Personally, I wrote my own nodeRed code to dynamically control my thermostats. It adjusts the set point based off current outdoor temperature / the time (i like it colder when sleeping) / and home occupancy(proximity… – Added a 2nd Zone to HA and called it Almost home. This zone triggers the temp to adjust between away and home mode)
Here’s a sample of it selecting a setpoint – I’d be happy to go in depth if you like nodeRed and advanced functionality of your thermostat

``````if (flow.get(["current.outsideTemp"]) < 20)
{
if (flow.get(["current.occupancy"]) == "home")
{
flow.set(["target.setUp"], 60);
flow.set(["target.setDown"], 61);
}
else
{
flow.set(["target.setUp"], 54);
flow.set(["target.setDown"], 55);
}
flow.set(["target.modeUp"], "heat");
flow.set(["target.modeDown"], "heat");
}
else if ((flow.get(["current.outsideTemp"]) > 20) && (flow.get(["current.outsideTemp"]) < 41))
{
if (flow.get(["current.occupancy"]) == "home")
{
flow.set(["target.setUp"], 65);
flow.set(["target.setDown"], 66);
}
else
{
flow.set(["target.setUp"], 60);
flow.set(["target.setDown"], 61);
}
flow.set(["target.modeUp"], "heat");
flow.set(["target.modeDown"], "heat");
}
else if ((flow.get(["current.outsideTemp"]) > 40) && (flow.get(["current.outsideTemp"]) < 51))
{
if (flow.get(["current.occupancy"]) == "home")
{
flow.set(["target.setUp"], 67);
flow.set(["target.setDown"], 68);
}
else
{
flow.set(["target.setUp"], 63);
flow.set(["target.setDown"], 64);
}
flow.set(["target.modeUp"], "heat");
flow.set(["target.modeDown"], "heat");
}
else if ((flow.get(["current.outsideTemp"]) > 50) && (flow.get(["current.outsideTemp"]) < 66))
{
if (flow.get(["current.occupancy"]) == "home")
{
flow.set(["target.setUp"], 67);
flow.set(["target.setDown"], 68);
}
else
{
flow.set(["target.setUp"], 65);
flow.set(["target.setDown"], 66);
}
flow.set(["target.modeUp"], "heat");
flow.set(["target.modeDown"], "heat");
}

``````

Here’s a picture of nodeRed, it makes more sense visually.