function getNextChange()
{
    $dowMap = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
    if (isBoostActive()) {
        return "Boost end " . getBoostRemaining() . " min";
    }
    // Start from current point to end of week
    $minskip = date("i");
    $hourskip = date("G");
    $dayskip = date("N") - 1;
    for ($day = 0; $day < 7; $day++) {
        for ($hour = 0; $hour <= 23; $hour++) {
            for ($min = 0; $min <= 60; $min = $min + 15) {
                if ($day >= $dayskip && $hour >= $hourskip && $min >= $minskip) {
                    $minskip = 0;
                    $hourskip = 0;
                    $dayskip = 0;
                    $file = "schedule/" . $day . "-" . $hour . "-" . $min;
                    //echo $file . "\n";
                    if ($min == 0) {
                        $min = "00";
                    }
                    if (isHeatingActive()) {
                        if (!file_exists($file)) {
                            return "Off at {$hour}:{$min}";
                        }
                    } else {
                        if (file_exists($file)) {
                            return "On at {$hour}:{$min}";
                        }
                    }
                }
            }
        }
    }
    // Start from beginning of week to current point
    $minskip = date("i");
    $hourskip = date("G");
    $dayskip = date("N") - 1;
    for ($day = 0; $day < 7; $day++) {
        for ($hour = 0; $hour <= 23; $hour++) {
            for ($min = 0; $min <= 60; $min = $min + 15) {
                if ($day <= $dayskip && $hour <= $hourskip && $min <= $minskip) {
                    $minskip = 0;
                    $hourskip = 0;
                    $dayskip = 0;
                    $file = "schedule/" . $day . "-" . $hour . "-" . $min;
                    if ($min == 0) {
                        $min = "00";
                    }
                    if (isHeatingActive()) {
                        if (!file_exists($file)) {
                            return "Off at {$hour}:{$min} (" . $dowMap[$day] . ")";
                        }
                    } else {
                        if (file_exists($file)) {
                            return "On at {$hour}:{$min} (" . $dowMap[$day] . ")";
                        }
                    }
                }
            }
        }
    }
}
<?php

// manager.php
// Called every minuite via cron. Performs the logic to decide if heating should be turned on or off
chdir(dirname(__FILE__));
include "functions.php";
$heatingActive = isHeatingActive();
// Boost
$boostExit = "cancelled";
if (isBoostActive()) {
    $heatingBoost = true;
    if (getBoostRemaining() <= 0) {
        file_put_contents($logFile, date("d/m/y @ H:i") . " Boost Expired\n", FILE_APPEND);
        $boostExit = "expired";
        unlink("schedule/boost");
        $heatingBoost = false;
    }
} else {
    $heatingBoost = false;
}
// Timer
$now = date("N") - 1 . "-" . date("G") . "-" . floor(date("i") / 15) * 15;
if (file_exists("schedule/" . $now)) {
    $heating = true;
} else {
    $heating = false;
}
// Weather
$tempNow = getTemp();
$tempCold = getTempCold();
if ($tempNow <= $tempCold) {