-
Notifications
You must be signed in to change notification settings - Fork 21
Scheduling temperature changes
Most FRITZ!Boxes support switching back and forth between two defined temperatures, "saving" and "comfort". In situations where three or more values need to be orchestrated, one can achieve the desired behavior by scripting those changes.
- A system running a Linux distribution of your favorite flavor.
Its init system should be
systemd
. A Raspberry Pi with a recent Raspbian will work just fine. -
fritzctl
installed and configured. Tested withfritzctl 1.4.20
. - Some text editor like
vi
ornano
.
Check that systemd
is OK:
systemctl status
Check that fritzctl
is OK
fritzctl ping
-
For simplicity we work with one thermostat,
myThermostat
. Everything below can be generalized to multiple devices or groups. -
Schedule Mo-Fri
Time Temperature 23:00 - 6:00 "night-time" 18°C 6:00 - 7:30 "morning" 21°C 7:30 - 17:30 "work" 19°C 17:30 - 23:00 "at-home" 22°C -
Schedule Sat, Sun
Time Temperature 23:00 - 6:00 "night-time" 18°C 6:00 - 23:00 "at-home" 22°C -
We assume the heating season to span from October through March. During April-September heating should be turned off.
In our scenario we implement the schedule using systemd.timers. A timer is usually coupled to a systemd.service. In simple terms the service represents "what to run" and the timer "when to run".
Here we should work with 5 units, switching temperature to 18°C, 19°C, 21°C, 22°C and "off" respectively. To this end, create five files ("unit files") with the following content:
-
/etc/systemd/system/night-time-temperature.service
[Unit] Description=Apply "night-time" Temperature [Service] Type=oneshot ExecStart=/usr/bin/fritzctl temperature 18 myThermostat
- 3 more analogous unit files
/etc/systemd/system/morning-temperature.service
,/etc/systemd/system/work-time-temperature.service
,/etc/systemd/system/at-home-temperature.service
. -
/etc/systemd/system/temperature-off.service
[Unit] Description=Switch off thermostats [Service] Type=oneshot ExecStart=/usr/bin/fritzctl temperature off myThermostat
Note that one needs to specify the absolute path (here /usr/bin/fritzctl
) to the executable, otherwise systemd
will refuse to accept the units.
After saving these units, check that they are known to systemd
sudo systemctl daemon-reload
systemctl status night-time-temperature.service
● night-time-temperature.service - Apply "night-time" Temperature
Loaded: loaded (/etc/systemd/system/night-time-temperature.service; static; vendor preset: enabled)
Active: inactive (dead)
We have now completed the "what to run" sector.
Six timers do the trick here,
- "start the night scenario",
- "start the morning scenario (working day)",
- "start the work scenario",
- "start the at-home scenario (working day)",
- "start the at-home scenario (weekend)",
- "switch off at the end of heating season".
We start by modelling the night-time and save a file to /etc/systemd/system/night-time-temperature.timer
:
[Unit]
Description=Schedule temperatures at night
[Timer]
OnCalendar=*-10,11,12,01,02,03-* 23:00:00
Unit=night-time-temperature.service
The OnCalendar
syntax is quite powerful, see systemd.time.
Here we use the "OnCalendar=Year-Month-Day Hour:Minute:Second" notation, which reads "every year, in the months 10 (October), 11, ... 03 (March), every day at 23:00:00".
Run
sudo systemctl enable night-time-temperature.timer
sudo systemctl start night-time-temperature.timer
to make the timer active, also after reboots. Check that it worked
systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
...
Mon 2018-10-01 23:00:00 CEST 5 months 27 days left n/a n/a night-time-temperature.timer night-time-temperature.service
...
Create the other timers analogously with the following OnCalendar
sections:
-
morning-working-day-temperature.timer
should haveOnCalendar=Mon,Tue,Wed,Thu,Fri *-10,11,12,01,02,03-* 06:00:00
. The "Year-Month-Day Hour:Minute:Second" is prefixed by days-of-week, translating into "every year, from October to March, every day at 06:00:00 BUT ONLY IF the day is a Monday, Tuesday, ..., Friday". In some versions ofsystemd
one can writeMon-Fri
orMon..Fri
. In case of doubt, checkman systemd.time
. Listing the days asMon,Tue,Wed,Thu,Fri
should work across all versions. -
away-working-day-temperature.timer
should haveOnCalendar=Mon,Tue,Wed,Thu,Fri *-10,11,12,01,02,03-* 07:30:00
analogous tomorning-working-day-temperature.timer
. -
at-home-working-day-temperature.timer
should haveOnCalendar=Mon,Tue,Wed,Thu,Fri *-10,11,12,01,02,03-* 17:30:00
. -
at-home-weekend-temperature.timer
should haveOnCalendar=Sat,Sun *-10,11,12,01,02,03-* 06:00:00
. -
no-heating.timer
should haveOnCalendar=*-04-01 06:00:00
, reading "every year, on April 1st, at 06:00:00".
Enable and start all the timers and we're done. When changing timers (or units in general), it is recommended to run
sudo systemctl daemon-reload
sudo systemctl restart <timer>
Test the setup.
Every service can be tested by running it once with e.g. sudo systemctl start night-time-temperature.service
and checked for correctness with e.g. systemctl status night-time-temperature.service
or journalctl --unit night-time-temperature.service
.
Check the output of systemctl list-timers
, especially NEXT
and LAST
, for sanity.
Provide meaningful descriptions in unit files. Communicate the intent of a timer or a service to your future self.
Monitor the setup.
At least until there is compelling evidence for it to be correct.
Failing timers can trigger notifications e.g. with sendmail
see ArchWiki
Beware the complexity. It is easy to get carried away with too many timers, it is a challenge to maintain them. Try not to entangle the build-in FRITZ!Box scheduling with self-made timers too much.