Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Scheduling temperature changes

bpicode edited this page Apr 4, 2018 · 1 revision

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.

Prerequisites

What you will need

  • 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 with fritzctl 1.4.20.
  • Some text editor like vi or nano.

Test that everything is in place

Check that systemd is OK:

systemctl status

Check that fritzctl is OK

fritzctl ping

Schedule

Assumptions

  • 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.

systemd timers

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".

Service files

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.

Timers

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 have OnCalendar=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 of systemd one can write Mon-Fri or Mon..Fri. In case of doubt, check man systemd.time. Listing the days as Mon,Tue,Wed,Thu,Fri should work across all versions.
  • away-working-day-temperature.timer should have OnCalendar=Mon,Tue,Wed,Thu,Fri *-10,11,12,01,02,03-* 07:30:00 analogous to morning-working-day-temperature.timer.
  • at-home-working-day-temperature.timer should have OnCalendar=Mon,Tue,Wed,Thu,Fri *-10,11,12,01,02,03-* 17:30:00.
  • at-home-weekend-temperature.timer should have OnCalendar=Sat,Sun *-10,11,12,01,02,03-* 06:00:00.
  • no-heating.timer should have OnCalendar=*-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>

Recommendations

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.