applied changes from jahir (thank you)
This commit is contained in:
parent
31913b9fbc
commit
e4b1f69548
4 changed files with 39 additions and 25 deletions
|
@ -71,6 +71,7 @@ class DataIterator implements \Iterator, \Countable {
|
|||
|
||||
/**
|
||||
* Aggregate data
|
||||
* @return next aggregated tuple
|
||||
*/
|
||||
public function next() {
|
||||
if ( $this->packageSize == 1) { // return each row as single tuple
|
||||
|
@ -78,9 +79,7 @@ class DataIterator implements \Iterator, \Countable {
|
|||
}
|
||||
else { // summarize rows
|
||||
$package = array(0, 0, 0);
|
||||
for ($i = 0; $i < $this->packageSize && $this->rowKey < $this->rowCount; $i++) {
|
||||
$tuple = $this->stmt->fetch();
|
||||
|
||||
for ($i = 0; $i < $this->packageSize && $tuple = $this->stmt->fetch(); $i++) {
|
||||
$package[0] = $tuple[0];
|
||||
$package[1] += $tuple[1];
|
||||
$package[2] += $tuple[2];
|
||||
|
@ -96,8 +95,7 @@ class DataIterator implements \Iterator, \Countable {
|
|||
/**
|
||||
* Rewind the iterator
|
||||
*
|
||||
* Should only be called once
|
||||
* PDOStatement hasn't a rewind()
|
||||
* @internal Should only be called once: PDOStatement hasn't a rewind()
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->key = $this->rowKey = 0;
|
||||
|
@ -105,7 +103,7 @@ class DataIterator implements \Iterator, \Countable {
|
|||
}
|
||||
|
||||
public function valid() {
|
||||
return $this->key <= $this->tupleCount;
|
||||
return ($this->current[2] > 0); // current package contains at least 1 tuple
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,9 @@ use Doctrine\ORM;
|
|||
abstract class Interpreter {
|
||||
protected $channel;
|
||||
|
||||
/** @var Database connection */
|
||||
/**
|
||||
* @var Database connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
protected $from;
|
||||
|
@ -84,27 +86,37 @@ abstract class Interpreter {
|
|||
*/
|
||||
protected function getData() {
|
||||
// prepare sql
|
||||
$sql['from'] = ' FROM data';
|
||||
$sql['where'] = ' WHERE channel_id = ?' . self::buildDateTimeFilterSQL($this->from, $this->to);
|
||||
$sql['orderBy'] = ' ORDER BY timestamp ASC';
|
||||
$sqlWhere = ' WHERE channel_id = ?';
|
||||
|
||||
if ($this->groupBy && $sql['groupFields'] = self::buildGroupBySQL($this->groupBy)) {
|
||||
$sql['rowCount'] = 'SELECT COUNT(DISTINCT ' . $sql['groupFields'] . ')' . $sql['from'] . $sql['where'];
|
||||
$sql['fields'] = ' MAX(timestamp) AS timestamp, SUM(value) AS value, COUNT(timestamp) AS count';
|
||||
$sql['groupBy'] = ' GROUP BY ' . $sql['groupFields'];
|
||||
if ($this->groupBy && $sqlGroupFields = self::buildGroupBySQL($this->groupBy)) {
|
||||
$sqlRowCount = 'SELECT COUNT(DISTINCT ' . $sqlGroupFields . ') FROM data' . $sqlWhere;
|
||||
$sqlFields = ' MAX(timestamp) AS timestamp, SUM(value) AS value, COUNT(timestamp) AS count';
|
||||
|
||||
$sql = 'SELECT' . $sqlFields . '
|
||||
FROM data' .
|
||||
$sqlWhere .
|
||||
self::buildDateTimeFilterSQL($this->from, $this->to) .
|
||||
' GROUP BY ' . $sqlGroupFields;
|
||||
|
||||
$sqlParameters = array($this->channel->getId());
|
||||
}
|
||||
else {
|
||||
$sql['rowCount'] = 'SELECT COUNT(*)' . $sql['from'] . $sql['where'];
|
||||
$sql['fields'] = ' timestamp, value, 1';
|
||||
$sql['groupBy'] = '';
|
||||
$sqlRowCount = 'SELECT COUNT(*) FROM data' . $sqlWhere . self::buildDateTimeFilterSQL($this->from, $this->to);
|
||||
$sqlComon = 'SELECT timestamp, value, 1 FROM data' . $sqlWhere;
|
||||
|
||||
$sqlFirst = '(' . $sqlComon . ' AND timestamp <= ' . $this->from . ' ORDER BY timestamp DESC LIMIT 1) UNION ';
|
||||
$sqlMiddle = '(' . $sqlComon . self::buildDateTimeFilterSQL($this->from, $this->to) . ' ORDER BY timestamp ASC)';
|
||||
$sqlLast = ' UNION (' . $sqlComon . ' AND timestamp >= ' . $this->to . ' ORDER BY timestamp ASC LIMIT 2)'; // we need 2 tuples in MeterInterpreter
|
||||
|
||||
$sql = ((isset($this->from)) ? $sqlFirst : '') . $sqlMiddle . ((isset($this->to)) ? $sqlLast : '');
|
||||
$sqlParameters = array_fill(0, 1 + isset($this->from) + isset($this->to), $this->channel->getId());
|
||||
}
|
||||
|
||||
|
||||
// get total row count for grouping
|
||||
$this->rowCount = $this->conn->fetchColumn($sql['rowCount'], array($this->channel->getId()), 0);
|
||||
$this->rowCount = $this->conn->fetchColumn($sqlRowCount, array($this->channel->getId()), 0);
|
||||
|
||||
if ($this->rowCount > 0) {
|
||||
// query for data
|
||||
$stmt = $this->conn->executeQuery('SELECT ' . $sql['fields'] . $sql['from'] . $sql['where'] . $sql['groupBy'] . $sql['orderBy'], array($this->channel->getId()));
|
||||
$stmt = $this->conn->executeQuery($sql, $sqlParameters); // query for data
|
||||
|
||||
return new DataIterator($stmt, $this->rowCount, $this->tupleCount);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ class MeterInterpreter extends Interpreter {
|
|||
|
||||
protected $min = NULL;
|
||||
protected $max = NULL;
|
||||
protected $first = NULL;
|
||||
protected $last = NULL;
|
||||
|
||||
protected $pulseCount = NULL;
|
||||
protected $resolution;
|
||||
|
||||
|
@ -73,7 +76,8 @@ class MeterInterpreter extends Interpreter {
|
|||
* @return float 3600: 3600 s/h; 1000: ms -> s
|
||||
*/
|
||||
public function getAverage() {
|
||||
return (3600 * 1000 * $this->getConsumption()) / ($this->to - $this->from);
|
||||
$delta = ($this->getConsumption()) ? $this->last[0] - $this->first[0] : 1; // prevent division by zero
|
||||
return (3600 * 1000 * $this->getConsumption()) / $delta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,6 +113,9 @@ class MeterInterpreter extends Interpreter {
|
|||
$last = $next;
|
||||
$next = $pulses->next();
|
||||
}
|
||||
|
||||
$this->first = reset($tuples);
|
||||
$this->last = end($tuples);
|
||||
|
||||
return $tuples;
|
||||
}
|
||||
|
|
|
@ -33,9 +33,6 @@ use Volkszaehler\Util;
|
|||
|
||||
class SensorInterpreter extends Interpreter {
|
||||
|
||||
/**
|
||||
* @param string|integer $groupBy
|
||||
*/
|
||||
public function processData($callback) {
|
||||
$data = parent::getData();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue