Created
September 27, 2016 08:33
-
-
Save calcinai/801e4e805139cd18278e45c5da090340 to your computer and use it in GitHub Desktop.
Time-series aggregate readings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
public function getAggregateReadings(\DateTime $from, \DateTime $to, \DateInterval $interval) { | |
$from = clone $from; | |
$to = clone $to; | |
$seconds = date_create('@0')->add($interval)->getTimestamp(); | |
//Round to the correct block. | |
$to->setTimestamp(floor($to->getTimestamp() / $seconds) * $seconds); | |
$from->setTimestamp(floor($from->getTimestamp() / $seconds) * $seconds); | |
//Man, stupid UNIX ts bullshit in mysql not in UTC | |
$sql = ' | |
SELECT `timestamp`, FLOOR(UNIX_TIMESTAMP(CONVERT_TZ(`timestamp`, "+00:00", @@session.time_zone)) / :seconds) * :seconds AS rounded_timestamp, COUNT(`value`) / SUM(1 / `value`) AS average_value FROM sensor_reading | |
WHERE sensor_id = :sensor_id | |
AND `timestamp` BETWEEN :date_start AND :date_end | |
GROUP BY rounded_timestamp; | |
ORDER BY rounded_timestamp DESC'; | |
$stmt = DB::get()->getConnection()->prepare($sql); | |
$stmt->execute(['sensor_id' => $this->sensor_id, | |
'date_start' => $from->format('Y-m-d H:i:s'), | |
'date_end' => $to->format('Y-m-d H:i:s'), | |
'seconds' => $seconds]); | |
$readings = []; | |
while($row = $stmt->fetch()){ | |
$from->add($interval); | |
while($from->getTimestamp() < $row['rounded_timestamp']){ | |
$readings[] = ['timestamp' => $from->format('c'), 'value' => null]; | |
$from->add($interval); | |
} | |
$readings[] = ['timestamp' => $from->format('c'), 'value' => $row['average_value']]; | |
} | |
return $readings; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This will produce something like
It's useful for 'pinning' the readings to a date/time so they can be plotted against other readings even if they aren't specifically at the same time.