/** * Runs every hour and checks if, according to some math, the heating was ON at the measured interval. * * @return string */ public function isHeatingTest() { echo "<pre>\n"; $now = Carbon::now(); $logEntries = LogEntry::withLogValue('is_heating_check')->whereNull('is_heating_check.value')->withLogValue('ambient_temperature_c')->withLogValue('away')->take(100)->get(['log_entries.*', 'away.value as away', 'is_heating_check.value as is_heating_check', 'ambient_temperature_c.value as ambient_temperature_c']); echo 'Will check ' . $logEntries->count() . ' log entries for heating info.' . "\n"; /** @var LogEntry $logEntry */ foreach ($logEntries as $logEntry) { $end = clone $logEntry->time; $end->addMinutes(5)->addSeconds(30); /** @var LogEntry $nextLogEntry */ $nextLogEntry = LogEntry::where('device_id', $logEntry->device_id)->withLogValue('ambient_temperature_c')->withLogValue('target_temperature_c')->after($logEntry->time)->before($end)->first(['log_entries.*', 'ambient_temperature_c.value as ambient_temperature_c', 'target_temperature_c.value as target_temperature_c']); if ($nextLogEntry) { // get some values from both: $previous = floatval($logEntry->ambient_temperature_c); $homeStatus = $logEntry->away; $current = floatval($nextLogEntry->ambient_temperature_c); $target = floatval($nextLogEntry->target_temperature_c); echo 'Compared values: [' . $previous . '/' . $current . '/' . $target . '/' . $homeStatus . ']' . "\n"; // temp is higher than before and target is even higher. // temp difference must be half a degree. // // current ambient temperature must be higher or equal to previous ambient temperature (not lower) $ambientRising = $current >= $previous; // target temperature must be higher than previous ambient temperature: $highTarget = $target > $previous; // target temperature must be higher or equal to current ambient temperature (maintaining temp or about to be there) $wasHighTarget = $target >= $current; // must be at home (however, this fails to detect "pre-heating"). $isHome = $logEntry->away == 'home'; // temp diff between target and ambient must be > 0.5 //$tempDiff = $target - $current > 0.5; // ignored. if ($ambientRising && ($highTarget && $wasHighTarget) && $isHome) { // create LogValue LogValue::create(['log_entry_id' => $logEntry->id, 'name' => 'is_heating_on', 'value' => 1]); echo 'Entry #' . $logEntry->id . ' was heating [' . $homeStatus . '/' . $current . '/' . $target . '].' . "\n"; } else { LogValue::create(['log_entry_id' => $logEntry->id, 'name' => 'is_heating_on', 'value' => 0]); echo 'Entry #' . $logEntry->id . ' was NOT heating. [' . $homeStatus . '/' . $current . '/' . $target . ']' . "\n"; } LogValue::create(['log_entry_id' => $logEntry->id, 'name' => 'is_heating_check', 'value' => 1]); echo 'Entry #' . $logEntry->id . ' checked.' . "\n"; } else { echo 'Entry #' . $logEntry->id . ' has no comparison.' . "\n"; // only create an is_heating_check entry // when it has been 24 hours. if ($logEntry->time->diffInDays($now, true) > 1) { LogValue::create(['log_entry_id' => $logEntry->id, 'name' => 'is_heating_check', 'value' => 1]); echo 'Entry #' . $logEntry->id . ' checked.' . "\n"; } else { echo 'Will recheck #' . $logEntry->id . ' (day difference is ' . $logEntry->time->diffInDays($now, true) . ')' . "\n"; } } } return ''; }
/** * @param Device $device * * @return \Illuminate\Http\JsonResponse */ public function gauge(Device $device) { /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); $city = City::findCity($device->structure->postal_code, $device->structure->country_code); $chart->addColumn('Label', 'string'); $chart->addColumn('Value', 'number'); // get latest temp inside / target: $temps = LogEntry::withLogValue('target_temperature_c')->withLogValue('ambient_temperature_c')->where('log_entries.device_id', $device->id)->orderBy('log_entries.time', 'DESC')->first(['target_temperature_c.value AS target_temperature_c', 'ambient_temperature_c.value AS ambient_temperature_c']); // latest weather: // get outside temperature for this hour: $outside = Report::withReportValue('main.temp')->where('reports.city_id', $city->id)->orderBy('reports.time', 'DESC')->first(['main_temp.value as main_temp']); $chart->addRow('Inside', floatval($temps->ambient_temperature_c)); $chart->addRow('Target', floatval($temps->target_temperature_c)); $chart->addRow('Outside', floatval($outside->main_temp)); $chart->generate(); return Response::json($chart->getData()); }