Skip to content
Browse files

Updated source code documentation

  • Loading branch information...
1 parent 47ff1b7 commit ddb8b20f7e86fd55b22a9028c734eb64ef67a3bb @berwinter committed Feb 19, 2013
View
BIN doc/t_names
Binary file not shown.
View
11 js/main.js
@@ -1,9 +1,8 @@
var currentTime = new Date();
+var selectedItem = null;
-// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
-var selectedItem = null;
function checkBrowser()
{
@@ -256,7 +255,6 @@ function fetchLineChartData() {
function drawLineChart(object)
{
- // Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Time');
@@ -272,10 +270,9 @@ function drawLineChart(object)
}
data.addRows(object.data);
-
-
+
unit = selectedItem["unit"];
- // Instantiate and draw our chart, passing in some options.
+
lineChart.draw(data,
{
height: 500,
@@ -320,7 +317,6 @@ function fetchBarChartData() {
function drawBarChart(object)
{
- // Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
@@ -333,7 +329,6 @@ function drawBarChart(object)
data.addRows(object.data);
- // Instantiate and draw our chart, passing in some options.
barChart.draw(data,
{
height: 500,
View
12 lib/backend/constants.inc.php
@@ -1,12 +0,0 @@
-<?php
-const CAN_MODE = "\xDC";
-const DL_MODE = "\xA8";
-const DL2_MODE = "\xD1";
-const GET_MODE = "\x81";
-const GET_HEADER = "\xAA";
-const GET_LATEST = 0xAB;
-const READ_DATA = 0xAC;
-const END_READ = "\xAD";
-const RESET_DATA = "\xAF";
-const WAIT_TIME = 186;
-const MAX_RETRYS = 4;
View
357 lib/backend/database.inc.php
@@ -1,46 +1,73 @@
<?php
+/**
+ * Database Connection (Singleton)
+ *
+ * Provides access to the database which stores the datasets and chart settings
+ *
+ * @copyright Copyright (c) Bertram Winter bertram.winter@gmail.com
+ * @license GPLv3 License
+ */
include_once("lib/config.inc.php");
class Database
{
-
+ /**
+ * Singleton Interface
+ */
public static $instance;
-
- private $config;
- private $mysqli;
-
public static function getInstance()
{
if (null == self::$instance) {
self::$instance = new self;
}
-
return self::$instance;
}
- private function __construct(array $options=array())
+ /**
+ * Privates
+ */
+ private $config;
+ private $mysqli;
+
+ /**
+ * Constructor
+ * Uses Config class to set up a MySQL connection
+ */
+ private function __construct()
{
$this->config = Config::getInstance()->mysql;
- $this->mysqli = new mysqli($this->config->server,$this->config->user,$this->config->password,$this->config->database);
+ $this->mysqli = new mysqli($this->config->server,
+ $this->config->user,
+ $this->config->password,
+ $this->config->database);
$this->mysqli->set_charset("utf8");
}
+ /**
+ * Inserts a Dataset from the Parser into the database
+ * @param Parser $data
+ * @param string $frame
+ */
public function insterDataset($data, $frame)
- {
+ {
+ // create dataset with date
$id = $this->insertDate($data->date);
- for($i=1; $i<=16; $i++)
- {
+ // analog values
+ for($i=1; $i<=16; $i++) {
$name = "analog".$i;
$this->insertAnalog($data->$name, $id, $name, $frame);
}
-
- for($i=1; $i<=16; $i++)
- {
+
+ // digital values and speeds
+ // digital1 -> speed1
+ // digital2 -> speed2
+ // digital6 -> speed3
+ // digital7 -> speed4
+ for($i=1; $i<=16; $i++) {
$name = "digital".$i;
$speed = NULL;
- switch($i)
- {
+ switch($i) {
case 1:
$speed = $data->speed1;
break;
@@ -55,277 +82,369 @@ public function insterDataset($data, $frame)
break;
}
-
$this->insertDigital($data->$name, $id, $name, $frame, $speed);
}
-
- for($i=1; $i<=2; $i++)
- {
+
+ // energy values
+ for($i=1; $i<=2; $i++) {
$name = "energy".$i;
$this->insertEnergy($data->$name, $id, $name, $frame);
}
-
- for($i=1; $i<=2; $i++)
- {
+
+ // power values
+ for($i=1; $i<=2; $i++) {
$name = "power".$i;
$this->insertPower($data->$name, $id, $name, $frame);
}
}
+ /**
+ * Inserts a new dataset with given date in the database and
+ * returns the id of the new dataset
+ * @param Date $date
+ * @return id
+ */
private function insertDate($date)
{
- // insert
- $statement = $this->mysqli->prepare("INSERT IGNORE INTO t_datasets (date) VALUES (?)");
+ // insert dataset
+ $statement = $this->mysqli->prepare("INSERT IGNORE INTO t_datasets (date) ".
+ "VALUES (?);");
$statement->bind_param('s', $date);
$statement->execute();
$statement->close();
- // get id
- $statement = $this->mysqli->prepare("SELECT id FROM t_datasets WHERE date = ?;");
+ // get id back
+ $statement = $this->mysqli->prepare("SELECT id FROM t_datasets ".
+ "WHERE date = ?;");
$statement->bind_param('s', $date);
$statement->bind_result($id);
$statement->execute();
$statement->fetch();
-
return $id;
}
+ /**
+ * Inserts an analog value to a dataset id
+ * @param float $value
+ * @param int $id
+ * @param string $name
+ * @param string $frame
+ */
private function insertAnalog($value, $id, $name, $frame)
{
- $statement = $this->mysqli->prepare("REPLACE INTO t_analogs (dataset, value, frame, type) VALUES (?,?,?,?)");
+ $statement = $this->mysqli->prepare("REPLACE INTO t_analogs ".
+ "(dataset, value, frame, type)".
+ "VALUES (?,?,?,?);");
$statement->bind_param('idss', $id, $value, $frame, $name);
$statement->execute();
$statement->close();
}
+ /**
+ * Inserts a digital value to a dataset id and
+ * if exists add a speed value to digital
+ * @param int $value
+ * @param int $id
+ * @param string $name
+ * @param string $frame
+ * @param int $speed
+ */
private function insertDigital($value, $id, $name, $frame, $speed=NULL)
{
- $statement = $this->mysqli->prepare("REPLACE INTO t_digitals (dataset, value, frame, type) VALUES (?,?,?,?)");
+ $statement = $this->mysqli->prepare("REPLACE INTO t_digitals ".
+ "(dataset, value, frame, type)".
+ "VALUES (?,?,?,?);");
$statement->bind_param('iiss', $id, $value, $frame, $name);
$statement->execute();
- if(isset($speed))
- {
+ if(isset($speed)) {
$this->insertSpeed($statement->insert_id, $speed);
}
$statement->close();
}
+ /**
+ * Inserts a speed value to a digital
+ * @param int $value
+ * @param int $id
+ */
private function insertSpeed($value, $id)
{
- $statement = $this->mysqli->prepare("REPLACE INTO t_speeds (digital, value) VALUES (?,?)");
+ $statement = $this->mysqli->prepare("REPLACE INTO t_speeds ".
+ "(digital, value) ".
+ "VALUES (?,?);");
$statement->bind_param('ii', $value, $id);
$statement->execute();
$statement->close();
}
+ /**
+ * Inserts an energy value to a dataset id
+ * @param float $value
+ * @param int $id
+ * @param string $name
+ * @param string $frame
+ */
private function insertEnergy($value, $id, $name, $frame)
{
- $statement = $this->mysqli->prepare("REPLACE INTO t_energies (dataset, value, frame, type) VALUES (?,?,?,?)");
+ $statement = $this->mysqli->prepare("REPLACE INTO t_energies ".
+ "(dataset, value, frame, type) ".
+ "VALUES (?,?,?,?);");
$statement->bind_param('idss', $id, $value, $frame, $name);
-
$statement->execute();
$statement->close();
}
+ /**
+ * Inserts a power value to a dataset id
+ * @param float $value
+ * @param int $id
+ * @param string $name
+ * @param string $frame
+ */
private function insertPower($value, $id, $name, $frame)
{
- $statement = $this->mysqli->prepare("REPLACE INTO t_powers (dataset, value, frame, type) VALUES (?,?,?,?)");
+ $statement = $this->mysqli->prepare("REPLACE INTO t_powers ".
+ "(dataset, value, frame, type) ".
+ "VALUES (?,?,?,?);");
$statement->bind_param('idss', $id, $value, $frame, $name);
-
$statement->execute();
$statement->close();
}
- public function testSql()
- {
- if($result = $this->mysqli->query("SELECT * FROM t_datasets;"))
- {
- while($row = $result->fetch_object())
- {
- print_r($row);
- }
- }
- }
-
+ /**
+ * Query the analog chart with given id and date
+ * @param Date $date
+ * @param int $chartId
+ * @return Array
+ */
public function queryAnalog($date, $chartId)
{
- $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names INNER JOIN t_names_of_charts ON (t_names.id = t_names_of_charts.name_id) WHERE t_names_of_charts.chart_id=?;");
+ // get the columns of a chart
+ $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names ".
+ "INNER JOIN t_names_of_charts ".
+ "ON (t_names.id = t_names_of_charts.name_id) ".
+ "WHERE t_names_of_charts.chart_id=?;");
$statement->bind_param('i', $chartId);
$statement->execute();
$statement->bind_result($frame, $name);
$columns = array();
$joins = array();
-
$i = 1;
- while($statement->fetch())
- {
+ // build chart query
+ while($statement->fetch()) {
$columns[] = sprintf("FORMAT(d%02d.value,1) AS c%d",$i,$i);
- $joins[] = sprintf("INNER JOIN t_analogs AS d%02d ON (t_datasets.id = d%02d.dataset AND d%02d.frame = \"%s\" AND d%02d.type = \"%s\")",$i,$i,$i,$frame,$i,$name);
+ $joins[] = sprintf("INNER JOIN t_analogs AS d%02d ".
+ "ON (t_datasets.id = d%02d.dataset ".
+ "AND d%02d.frame = \"%s\" AND d%02d.type = \"%s\")",
+ $i, $i, $i, $frame, $i, $name);
$i++;
}
$sql = "SELECT UNIX_TIMESTAMP(t_datasets.date) AS date, ";
$sql .= join(", ", $columns);
$sql .= " FROM t_datasets ";
$sql .= join(" ", $joins);
- $sql .= sprintf(" WHERE t_datasets.date > \"%s\" AND t_datasets.date < DATE_ADD(\"%s\", INTERVAL 1 DAY);",$date,$date);
+ $sql .= sprintf(" WHERE t_datasets.date > \"%s\" ".
+ "AND t_datasets.date < DATE_ADD(\"%s\", INTERVAL 1 DAY);",
+ $date, $date);
$statement->close();
-
- $result = $this->mysqli->query($sql);
-
+ // fetch chart data
+ $result = $this->mysqli->query($sql);
$rows = array();
while($r = $result->fetch_array(MYSQLI_NUM)) {
$rows[] = $r;
}
return $rows;
}
+ /**
+ * Query the power chart with given id and date
+ * @param Date $date
+ * @param int $chartId
+ * @return Array
+ */
public function queryPower($date, $chartId)
- {
- $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names INNER JOIN t_names_of_charts ON (t_names.id = t_names_of_charts.name_id) WHERE t_names_of_charts.chart_id=?;");
+ {
+ // get the columns of a chart
+ $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names ".
+ "INNER JOIN t_names_of_charts ".
+ "ON (t_names.id = t_names_of_charts.name_id) ".
+ "WHERE t_names_of_charts.chart_id=?;");
$statement->bind_param('i', $chartId);
-
$statement->execute();
$statement->bind_result($frame, $name);
-
$columns = array();
$joins = array();
-
- $i = 1;
- while($statement->fetch())
- {
+ $i = 1;
+ // build chart query
+ while($statement->fetch()) {
$columns[] = sprintf("FORMAT(d%02d.value,3) AS c%d",$i,$i);
- $joins[] = sprintf("INNER JOIN t_powers AS d%02d ON (t_datasets.id = d%02d.dataset AND d%02d.frame = \"%s\" AND d%02d.type = \"%s\")",$i,$i,$i,$frame,$i,$name);
+ $joins[] = sprintf("INNER JOIN t_powers AS d%02d ".
+ "ON (t_datasets.id = d%02d.dataset ".
+ "AND d%02d.frame = \"%s\" AND d%02d.type = \"%s\")",
+ $i, $i, $i, $frame, $i, $name);
$i++;
}
$sql = "SELECT UNIX_TIMESTAMP(t_datasets.date) AS date, ";
$sql .= join(", ", $columns);
$sql .= " FROM t_datasets ";
$sql .= join(" ", $joins);
- $sql .= sprintf(" WHERE t_datasets.date > \"%s\" AND t_datasets.date < DATE_ADD(\"%s\", INTERVAL 1 DAY);",$date,$date);
-
- $statement->close();
-
+ $sql .= sprintf(" WHERE t_datasets.date > \"%s\" ".
+ "AND t_datasets.date < DATE_ADD(\"%s\", INTERVAL 1 DAY);",
+ $date, $date);
+ $statement->close();
+
+ // fetch chart data
$result = $this->mysqli->query($sql);
-
-
$rows = array();
while($r = $result->fetch_array(MYSQLI_NUM)) {
$rows[] = $r;
}
return $rows;
}
+ /**
+ * Query the energy chart with given id and date
+ * @param Date $date
+ * @param int $chartId
+ * @return Array
+ */
public function queryEnergy($date, $chartId)
- {
- $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names INNER JOIN t_names_of_charts ON (t_names.id = t_names_of_charts.name_id) WHERE t_names_of_charts.chart_id=?;");
+ {
+ // get the columns of a chart
+ $statement = $this->mysqli->prepare("SELECT frame, type FROM t_names ".
+ "INNER JOIN t_names_of_charts ".
+ "ON (t_names.id = t_names_of_charts.name_id) ".
+ "WHERE t_names_of_charts.chart_id=?;");
$statement->bind_param('i', $chartId);
-
$statement->execute();
$statement->bind_result($frame, $name);
$columns = array();
$joins = array();
-
- $i = 1;
- while($statement->fetch())
- {
- $columns[] = sprintf("FORMAT(d%02dmax.value-d%02dmin.value,1) AS c%d",$i,$i,$i);
- $joins[] = sprintf("INNER JOIN t_energies AS d%02dmin ON (tmp.minId = d%02dmin.dataset AND d%02dmin.frame = \"%s\" AND d%02dmin.type = \"%s\")",$i,$i,$i,$frame,$i,$name);
- $joins[] = sprintf("INNER JOIN t_energies AS d%02dmax ON (tmp.maxId = d%02dmax.dataset AND d%02dmax.frame = \"%s\" AND d%02dmax.type = \"%s\")",$i,$i,$i,$frame,$i,$name);
+ $i = 1;
+ // build chart query
+ while($statement->fetch()) {
+ $columns[] = sprintf("FORMAT(d%02dmax.value-d%02dmin.value,1) AS c%d",
+ $i, $i, $i);
+ $joins[] = sprintf("INNER JOIN t_energies AS d%02dmin ".
+ "ON (tmp.minId = d%02dmin.dataset AND d%02dmin.frame = \"%s\" ".
+ "AND d%02dmin.type = \"%s\")", $i, $i, $i, $frame, $i, $name);
+ $joins[] = sprintf("INNER JOIN t_energies AS d%02dmax ".
+ "ON (tmp.maxId = d%02dmax.dataset AND d%02dmax.frame = \"%s\" ".
+ "AND d%02dmax.type = \"%s\")", $i, $i, $i, $frame, $i, $name);
$i++;
}
$sql = "SELECT DATE_FORMAT(tmp.date, '%d-%m') AS date, ";
$sql .= join(", ", $columns);
- $sql .= sprintf(" FROM (
- SELECT t_datasets.date AS date, MIN(t_datasets.id) AS minId, MAX(t_datasets.id) AS maxId
- FROM t_datasets
- WHERE t_datasets.date < DATE_ADD(\"%s\",INTERVAL 1 DAY) AND t_datasets.date > DATE_SUB(\"%s\", INTERVAL 10 DAY) GROUP BY DATE(date)
- ) AS tmp ",$date,$date);
+ $sql .= sprintf(" FROM (SELECT t_datasets.date AS date,".
+ "MIN(t_datasets.id) AS minId, MAX(t_datasets.id) AS maxId ".
+ "FROM t_datasets ".
+ "WHERE t_datasets.date < DATE_ADD(\"%s\",INTERVAL 1 DAY) ".
+ "AND t_datasets.date > DATE_SUB(\"%s\", INTERVAL 10 DAY) ".
+ "GROUP BY DATE(date)) AS tmp ", $date, $date);
$sql .= join(" ", $joins);
- $statement->close();
-
- $result = $this->mysqli->query($sql);
-
+ $statement->close();
+
+ // fetch chart data
+ $result = $this->mysqli->query($sql);
$rows = array();
while($r = $result->fetch_array(MYSQLI_NUM)) {
$rows[] = $r;
}
return $rows;
}
+ /**
+ * Query the date of the last dataset in the database
+ * @return number
+ */
public function lastDataset()
{
$result = $this->mysqli->query("SELECT MAX(date) FROM t_datasets;");
$last = $result->fetch_array();
return strtotime($last[0]);
}
+ /**
+ * Get the chart and menu configuration
+ * @return Array
+ */
public function getAppConfig()
{
- $statement = $this->mysqli->prepare("SELECT id, name, type, t_menu.schema, unit FROM t_menu ORDER BY t_menu.order;");
+ // get menu items
+ $statement = $this->mysqli->prepare("SELECT id, name, type, t_menu.schema, unit ".
+ "FROM t_menu ORDER BY t_menu.order;");
$statement->execute();
$statement->bind_result($id, $name, $type, $schema, $unit);
- $rows = array("menu" => array(), "values" => array());
-
+ $rows = array("menu" => array(),
+ "values" => array());
+
+ // build menu array
while($statement->fetch()) {
- if($type == "schema" && $schema!=NULL)
- {
- $rows["menu"][] = array("id" => $id, "name" => $name, "type" => $type, "schema" => $schema);
+ if($type == "schema" && $schema!=NULL) {
+ $rows["menu"][] = array("id" => $id,
+ "name" => $name,
+ "type" => $type,
+ "schema" => $schema);
}
- else
- {
- $rows["menu"][] = array("id" => $id, "name" => $name, "type" => $type, "unit" => $unit);
+ else {
+ $rows["menu"][] = array("id" => $id,
+ "name" => $name,
+ "type" => $type,
+ "unit" => $unit);
}
}
$statement->close();
- for($i=0; $i < count($rows["menu"]); $i++)
- {
- if($rows["menu"][$i]["type"] != "schema")
- {
- $statement = $this->mysqli->prepare("SELECT name FROM t_names INNER JOIN t_names_of_charts ON (t_names.id = t_names_of_charts.name_id) WHERE t_names_of_charts.chart_id=?;");
- echo $this->mysqli->error;
+ // get chart configuration
+ for($i=0; $i < count($rows["menu"]); $i++) {
+ if($rows["menu"][$i]["type"] != "schema") {
+ $statement = $this->mysqli->prepare("SELECT name FROM t_names ".
+ "INNER JOIN t_names_of_charts ".
+ "ON (t_names.id = t_names_of_charts.name_id) ".
+ "WHERE t_names_of_charts.chart_id=?;");
$statement->bind_param('i', $rows["menu"][$i]["id"]);
$statement->execute();
- $statement->bind_result($name);
- $columns = array();
- while($statement->fetch())
- {
+ $statement->bind_result($name);
+
+ $columns = array();
+
+ while($statement->fetch()) {
$columns[] = $name;
}
$statement->close();
$rows["menu"][$i]["columns"] = $columns;
}
}
-
- $statement = $this->mysqli->prepare("SELECT path, frame, type, format FROM t_schema;");
+ // get schema configuration
+ $statement = $this->mysqli->prepare("SELECT path, frame, type, format ".
+ "FROM t_schema;");
$statement->execute();
$statement->bind_result($path, $frame, $type, $format);
-
- while($statement->fetch())
- {
- $rows["values"][] = array("path" => $path, "frame" => $frame, "type" => $type, "format" => $format);
+ while($statement->fetch()) {
+ $rows["values"][] = array("path" => $path,
+ "frame" => $frame,
+ "type" => $type,
+ "format" => $format);
}
- $statement->close();
-
+ $statement->close();
return $rows;
-
}
}
View
161 lib/backend/parser.inc.php
@@ -1,110 +1,169 @@
<?php
-
+/**
+ * Parses a binary string containing a dataset
+ *
+ * Provides access to the values of a dataset as object properties
+ *
+ * @copyright Copyright (c) Bertram Winter bertram.winter@gmail.com
+ * @license GPLv3 License
+ */
class Parser
{
+ /**
+ * Parser constant
+ */
+ const SIGN_BIT = 0x8000;
+ const POSITIVE_VALUE_MASK = 0x00000FFF;
+ const NEGATIVE_VALUE_MASK = 0xFFFFF000;
+ const DIGITAL_ON = 1;
+ const DIGITAL_OFF = 0;
+ const SPEED_ACTIVE = 0x80;
+ const SPEED_MASK = 0x1F;
+
+ /**
+ * Constructor
+ * Parses thourgh the dataset and add values as properties
+ * @param string $data binary string containing the dataset
+ */
public function __construct($data)
{
- if(strlen($data) == 61)
- {
- $package = unpack("C55/Cseconds/Cminutes/Chours/Cdays/Cmonths/Cyears",$data);
- $this->date = sprintf("20%02d-%02d-%02d %02d:%02d:%02d", $package["years"], $package["months"], $package["days"],$package["hours"], $package["minutes"],$package["seconds"]);
+ // check if dataset contains time information
+ // (fetched from bootloader storage)
+ if(strlen($data) == 61) {
+ $package = unpack("C55/Cseconds/Cminutes/"
+ ."Chours/Cdays/Cmonths/Cyears",$data);
+ $this->date = sprintf("20%02d-%02d-%02d %02d:%02d:%02d",
+ $package["years"], $package["months"],
+ $package["days"], $package["hours"],
+ $package["minutes"], $package["seconds"]);
}
- $package = unpack("v16analog/Sdigital/C4speed/Cactive/Vpower1/Venergy1/Vpower2/Venergy2",$data);
+ // unpack binary string
+ $package = unpack("v16analog/Sdigital/C4speed/Cactive".
+ "/Vpower1/Venergy1/Vpower2/Venergy2",$data);
- for($i=1; $i<=16; $i++)
- {
+ // 16 Analog channels
+ for($i=1; $i<=16; $i++) {
$key = ("analog".$i);
$this->$key = self::convertAnalog($package["analog".$i]);
}
- for($i=1; $i<=16; $i++)
- {
+ // 16 Digital channels (only 13 in use)
+ for($i=1; $i<=16; $i++) {
$key = ("digital".$i);
$this->$key = self::convertDigital($package["digital"],$i);
}
- for($i=1; $i<=4; $i++)
- {
+ // 4 speeds
+ for($i=1; $i<=4; $i++) {
$key = ("speed".$i);
$this->$key = self::convertSpeed($package["speed".$i]);
}
- for($i=1; $i<=2; $i++)
- {
+ // 2 energy values
+ for($i=1; $i<=2; $i++) {
$key = ("energy".$i);
- $this->$key = self::convertEnergy($package["energy".$i],$package["active"],$i);
+ $this->$key = self::convertEnergy($package["energy".$i],
+ $package["active"], $i);
}
- for($i=1; $i<=2; $i++)
- {
+ // 2 power values
+ for($i=1; $i<=2; $i++) {
$key = ("power".$i);
- $this->$key = self::convertPower($package["power".$i],$package["active"],$i);
+ $this->$key = self::convertPower($package["power".$i],
+ $package["active"], $i);
}
}
+ /**
+ * Provides access to the configuration properties
+ * @param string $name Property name
+ * @throws Exception Property not found
+ */
public function __get($name)
{
- throw new Exception('call to undefined property: ' . $name);
+ throw new Exception('call to undefined property: '.$name);
}
+ /**
+ * Convert the int value to a float
+ * @param int $value
+ * @return number
+ */
private static function convertAnalog($value)
{
- if($value & 0x8000)
- {
- return (($value | 0xFFFFF000)/10);
+ if($value & self::SIGN_BIT) {
+ return (($value | self::NEGATIVE_VALUE_MASK)/10);
}
- else
- {
- return (($value & 0xFFF)/10);
+ else {
+ return (($value & self::POSITIVE_VALUE_MASK)/10);
}
}
-
- private static function convertDigital($value, $i)
+
+ /**
+ * Check if bit is set on a given position
+ * @param int $value
+ * @param int $position
+ * @return number
+ */
+ private static function convertDigital($value, $position)
{
- if($value & (0x1<<($i-1)))
- {
- return 1;
+ if($value & (0x1<<($position-1))) {
+ return self::DIGITAL_ON;
}
- else
- {
- return 0;
+ else {
+ return self::DIGITAL_OFF;
}
}
-
+
+ /**
+ * Check if speed is activated and returns its actual value
+ * @param int $value
+ * @return NULL|boolean
+ */
private static function convertSpeed($value)
{
- if($value & 0x80)
- {
+ if($value & self::SPEED_ACTIVE) {
return NULL;
}
- else
- {
- return ($value & 0x1F);
+ else {
+ return ($value & self::SPEED_MASK);
}
}
-
- private static function convertEnergy($value, $active, $i)
+
+ /**
+ * Checks if heat meter is activated on a given position
+ * and returns its energy
+ * @param int $value
+ * @param int $active
+ * @param int $position
+ * @return number|NULL
+ */
+ private static function convertEnergy($value, $active, $position)
{
- if($active & $i)
- {
+ if($active & $position) {
return ($value/10);
}
- else
- {
+ else{
return NULL;
}
}
-
- private static function convertPower($value, $active, $i)
+
+ /**
+ * Checks if heat meter is activated on a given position
+ * and returns its power
+ * @param int $value
+ * @param int $active
+ * @param int $position
+ * @return number|NULL
+ */
+ private static function convertPower($value, $active, $position)
{
- if($active & $i)
- {
+ if($active & $position) {
return ($value/2560);
}
- else
- {
+ else {
return NULL;
}
}
View
291 lib/backend/uvr1611-connection.inc.php
@@ -1,13 +1,50 @@
<?php
+/**
+ * Uvr1611 Connection (Singleton)
+ *
+ * Provides access to the bootloader for stored datasets and actuell values
+ *
+ * @copyright Copyright (c) Bertram Winter bertram.winter@gmail.com
+ * @license GPLv3 License
+ */
include_once("lib/config.inc.php");
include_once("lib/backend/parser.inc.php");
-include_once("lib/backend/constants.inc.php");
class Uvr1611
{
-
+ /**
+ * Constants for the UVR Communication
+ */
+ const CAN_MODE = "\xDC";
+ const DL_MODE = "\xA8";
+ const DL2_MODE = "\xD1";
+ const GET_MODE = "\x81";
+ const GET_HEADER = "\xAA";
+ const GET_LATEST = 0xAB;
+ const READ_DATA = 0xAC;
+ const END_READ = "\xAD";
+ const RESET_DATA = "\xAF";
+ const WAIT_TIME = 0xBA;
+ const MAX_RETRYS = 4;
+ const DATASET_SIZE = 61;
+ const LATEST_SIZE = 56;
+
+
+ /**
+ * Singleton Interface
+ */
public static $instance;
+ public static function getInstance()
+ {
+ if (null == self::$instance) {
+ self::$instance = new self;
+ }
+ return self::$instance;
+ }
+ /**
+ * Privates
+ */
private $config;
private $sock;
private $count=0;
@@ -17,42 +54,38 @@ class Uvr1611
private $actualSize = 57;
private $fetchSize = 65;
private $canFrames = 1;
-
- public static function getInstance()
- {
- if (null == self::$instance) {
- self::$instance = new self;
- }
- return self::$instance;
- }
-
- private function __construct(array $options=array())
+
+ /**
+ * Constructor
+ */
+ private function __construct()
{
$this->config = Config::getInstance()->uvr1611;
- $this->checkMode();
-
+ $this->checkMode();
}
-
+
+ /**
+ * Get the actuell values from the bootloader
+ * @throws Exception
+ * @return Parser
+ */
public function getLatest()
{
$this->getCount();
create_pid();
-
- $cmd = pack("C2",GET_LATEST,1);
-
- for($i=0; $i<MAX_RETRYS; $i++)
- {
+ // build command
+ $cmd = pack("C2",self::GET_LATEST,1);
+ // try 4 times to get values
+ for($i=0; $i<self::MAX_RETRYS; $i++) {
$data = $this->query($cmd, $this->actualSize);
- if($this->checksum($data))
- {
+ if($this->checksum($data)) {
$binary = unpack("C*",$data);
- if($binary[1] == WAIT_TIME)
- {
+ if($binary[1] == self::WAIT_TIME) {
+ // wait some seconds for data
sleep($binary[2]);
}
- else
- {
+ else {
close_pid();
return $this->splitLatest($data);
}
@@ -62,6 +95,9 @@ public function getLatest()
throw new Exception("Could not get latest data!");
}
+ /**
+ * Reset memory on the bootloader
+ */
public function resetData()
{
create_pid();
@@ -70,25 +106,30 @@ public function resetData()
close_pid();
}
-
+
+ /**
+ * Fetch datasets from bootloader memory
+ * @throws Exception Checksum error
+ * @return Parser
+ */
public function fetchData()
{
- if($this->count > 0)
- {
+ if($this->count > 0) {
create_pid();
+ // build address for bootloader
$address1 = $this->address & 0xFF;
$address2 = ($this->address & 0x7F00)>>7;
$address3 = ($this->address & 0xFF8000)>>15;
- $cmd = pack("C6", READ_DATA, $address1, $address2, $address3, 1,
- READ_DATA + 1 + $address1 + $address2 + $address3);
+ // build command
+ $cmd = pack("C6", self::READ_DATA, $address1, $address2, $address3, 1,
+ self::READ_DATA + 1 + $address1 + $address2 + $address3);
$data = $this->query($cmd, $this->fetchSize);
- if($this->checksum($data))
- {
-
+ if($this->checksum($data)) {
+ // increment address
$this->address += $this->addressInc;
$this->count--;
close_pid();
@@ -99,111 +140,143 @@ public function fetchData()
}
}
+ /**
+ * Get the number of datasets in the bootloader memory
+ * @return number
+ */
public function getCount()
{
- if($this->count == 0)
- {
+ if($this->count == 0) {
create_pid();
- $data = $this->query(GET_HEADER, 21);
+ $data = $this->query(self::GET_HEADER, 21);
- if($this->checksum($data))
- {
- switch($this->mode)
- {
- case CAN_MODE:
+ if($this->checksum($data)) {
+ switch($this->mode) {
+ case self::CAN_MODE:
$binary = unpack("C5/CnumberOfFrames/C*",$data);
- $binary = unpack("Ctype/Cversion/C3timestamp/CnumberOfFrames/C".$binary["numberOfFrames"]."/C3startaddress/C3endaddress/Cchecksum",$data);
+ $binary = unpack("Ctype/Cversion/C3timestamp/CnumberOfFrames/C".
+ $binary["numberOfFrames"].
+ "/C3startaddress/C3endaddress/Cchecksum", $data);
$this->addressInc = 64 * $binary["numberOfFrames"];
$this->canFrames = $binary["numberOfFrames"];
$this->actualSize = 57;
$this->fetchSize = 4+61*$this->canFrames;
break;
- case DL_MODE:
- $binary = unpack("C5/Cdevice1/C3startaddress/C3endaddress/Cchecksum",$data);
+ case self::DL_MODE:
+ $binary = unpack("C5/Cdevice1/C3startaddress/C3endaddress/Cchecksum",
+ $data);
$this->addressInc = 64;
$this->actualSize = 57;
$this->fetchSize = 65;
break;
- case DL2_MODE:
- $binary = unpack("C5/Cdevice1/Cdevice2/C3startaddress/C3endaddress/Cchecksum",$data);
+ case self::DL2_MODE:
+ $binary = unpack("C5/Cdevice1/Cdevice2/C3startaddress/C3endaddress/Cchecksum",
+ $data);
$this->addressInc = 128;
$this->actualSize = 113;
$this->fetchSize = 126;
break;
-
}
+ // check if address is valid (!= 0xFFFFFF)
if($binary["startaddress3"] != 0xFF ||
$binary["startaddress2"] != 0xFF ||
$binary["startaddress1"] != 0xFF ||
$binary["endaddress3"] != 0xFF ||
$binary["endaddress2"] != 0xFF ||
$binary["endaddress1"] != 0xFF)
{
- $startaddress = ($binary["startaddress3"] << 15) + ($binary["startaddress2"] << 7) + $binary["startaddress1"];
- $endaddress = ($binary["endaddress3"] << 15) + ($binary["endaddress2"] << 7) + $binary["endaddress1"];
- $this->count = (($endaddress - $startaddress) / $this->addressInc) + 1;
+ // fix addresses
+ $startaddress = ($binary["startaddress3"] << 15)
+ + ($binary["startaddress2"] << 7)
+ + $binary["startaddress1"];
+ $endaddress = ($binary["endaddress3"] << 15)
+ + ($binary["endaddress2"] << 7)
+ + $binary["endaddress1"];
+ // calculate count
+ $this->count = (($endaddress - $startaddress)
+ / $this->addressInc) + 1;
$this->address = $startaddress;
}
}
close_pid();
}
-
return $this->count;
}
+ /**
+ * Check if Bootloader Mode is supported
+ * @throws Exception Mode not supported
+ */
private function checkMode()
- {
+ {
+ $this->mode = $this->query(self::GET_MODE, 1);
- $this->mode = $this->query(GET_MODE, 1);
- switch($this->mode)
- {
- case CAN_MODE:
- case DL_MODE:
- case DL2_MODE:
+ switch($this->mode) {
+ case self::CAN_MODE:
+ case self::DL_MODE:
+ case self::DL2_MODE:
return;
}
throw new Exception('BL-Net mode is not supported!');
}
+ /**
+ * Connect via TCP to the bootloader
+ */
private function connect()
{
$this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- socket_connect($this->sock, $this->config->address, $this->config->port);
+ socket_connect($this->sock,
+ $this->config->address,
+ $this->config->port);
}
+ /**
+ * Disconnect from the bootloader
+ */
private function disconnect()
{
socket_close($this->sock);
}
+ /**
+ * Verify the checksum
+ * @param string $data Binary string to check
+ * @return boolean
+ */
private function checksum($data)
{
$binary = unpack("C*",$data);
-
$sum = 0;
+ // pop checksum from string
$checksum = array_pop($binary);
-
- foreach($binary as $byte)
- {
+ // sum up all bytes
+ foreach($binary as $byte) {
$sum += $byte;
}
-
-
- if(($sum % 256) == $checksum)
- {
+ // verify the checksum
+ if(($sum % 256) == $checksum) {
return true;
}
return false;
}
+ /**
+ * Send a command to the bootloader and wait for the response
+ * if response is less then 32 bytes long return immediately
+ * @param string $cmd
+ * @param int $length
+ * @throws Exception
+ * @return string Binary
+ */
private function query($cmd, $length)
{
$this->connect();
-
- if(strlen($cmd) == socket_write($this->sock, $cmd, strlen($cmd)))
- {
+ // send command
+ if(strlen($cmd) == socket_write($this->sock, $cmd, strlen($cmd))) {
$data = "";
+ // get response until length or less 32 bytes
do {
$return = socket_read($this->sock, $length, PHP_BINARY_READ);
$data .= $return;
@@ -216,75 +289,85 @@ private function query($cmd, $length)
$this->disconnect();
throw new Exception('Error while querying command!\nCommand: '.bin2hex($cmd));
-
}
+ /**
+ * Split a binary string in datasets and parse it (Datasets values)
+ * @param string $data
+ * @return Parser
+ */
private function splitDatasets($data)
{
$frames = array();
- switch($this->mode)
- {
- case CAN_MODE:
- for($i=0;$i<$this->canFrames;$i++)
- {
- $frames["frame".($i+1)] = new Parser(substr($data, 3+61*$i, 61));
+ switch($this->mode) {
+ case self::CAN_MODE:
+ for($i=0;$i<$this->canFrames;$i++) {
+ $frames["frame".($i+1)] = new Parser(substr($data, 3+self::DATASET_SIZE*$i, self::DATASET_SIZE));
}
break;
- case DL_MODE:
- $frames["frame1"] = new Parser(substr($data, 0, 61));
+ case self::DL_MODE:
+ $frames["frame1"] = new Parser(substr($data, 0, self::DATASET_SIZE));
break;
- case DL2_MODE:
- $frames["frame1"] = new Parser(substr($data, 0, 61));
- $frames["frame2"] = new Parser(substr($data, 3+61, 61));
+ case self::DL2_MODE:
+ $frames["frame1"] = new Parser(substr($data, 0, self::DATASET_SIZE));
+ $frames["frame2"] = new Parser(substr($data, 3+self::DATASET_SIZE, self::DATASET_SIZE));
break;
}
-
return $frames;
}
+ /**
+ * Split a binary string in datasets and parse it (Actuell values)
+ * @param string $data
+ * @return Parser
+ */
private function splitLatest($data)
{
$frames = array();
-
- switch($this->mode)
- {
- case CAN_MODE:
- for($i=0;$i<$this->canFrames;$i++)
- {
- $frames["frame".($i+1)] = new Parser(substr($data, 1+56*$i, 56));
+ switch($this->mode) {
+ case self::CAN_MODE:
+ for($i=0;$i<$this->canFrames;$i++) {
+ $frames["frame".($i+1)] = new Parser(substr($data, 1+self::LATEST_SIZE*$i, self::LATEST_SIZE));
}
break;
- case DL_MODE:
- $frames["frame1"] = new Parser(substr($data, 1, 56));
+ case self::DL_MODE:
+ $frames["frame1"] = new Parser(substr($data, 1, self::LATEST_SIZE));
break;
- case DL2_MODE:
- $frames["frame1"] = new Parser(substr($data, 1, 56));
- $frames["frame2"] = new Parser(substr($data,1+56, 56));
+ case self::DL2_MODE:
+ $frames["frame1"] = new Parser(substr($data, 1, self::LATEST_SIZE));
+ $frames["frame2"] = new Parser(substr($data,1+self::LATEST_SIZE, self::LATEST_SIZE));
break;
}
return $frames;
}
}
-
-function create_pid() {
+/**
+ * Create a PID file
+ * @throws Exception
+ */
+function create_pid()
+{
$path = '/tmp/uvr1611-logger.pid';
- if(file_exists($path))
- {
+ if(file_exists($path)) {
+ // if PID is older than an hour remove it
if(time() > (filemtime($path) + 3600)) {
$pid = file_get_contents($path);
exec("kill $pid");
}
- else
- {
+ else {
throw new Exception("Another process is accessing the bl-net!");
}
}
file_put_contents($path, getmypid());
}
-
-function close_pid() {
+
+/**
+ * Remove the PID file
+ */
+function close_pid()
+{
unlink('/tmp/uvr1611-logger.pid');
}
View
51 lib/commonChart.inc.php
@@ -1,40 +1,43 @@
<?php
+/**
+ * Basic access for the charts
+ *
+ * @copyright Copyright (c) Bertram Winter bertram.winter@gmail.com
+ * @license GPLv3 License
+ */
include_once("lib/backend/uvr1611-connection.inc.php");
include_once("lib/backend/database.inc.php");
-
+
+// set json header
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');
-
+
+// get date for chart
$date = date("Y-m-d");
-$chartId = 2;
-
-if(isset($_GET["date"]))
-{
+if(isset($_GET["date"])) {
$date = date("Y-m-d", strtotime($_GET["date"]));
}
-
-if(isset($_GET["id"]))
-{
+
+// get chart id
+$chartId = 1;
+if(isset($_GET["id"])) {
$chartId = $_GET["id"];
}
-
+// connect to database
$database = Database::getInstance();
-
-if($date == date("Y-m-d"))
-{
- if(($database->lastDataset() + 600) < time())
- {
- $uvr = Uvr1611::getInstance();
- while($uvr->getCount())
- {
- $data = $uvr->fetchData();
- while ($frame = current($data) )
- {
- $database->insterDataset($frame, key($data));
- next($data);
- }
+
+// check if required date is today and last update is older than 10 minutes
+// -> so we need to fetch new values
+if($date == date("Y-m-d") && ($database->lastDataset() + 600) < time()) {
+ $uvr = Uvr1611::getInstance();
+ while($uvr->getCount()) {
+ // fetch a set of dataframes and insert them into the database
+ $data = $uvr->fetchData();
+ while ($frame = current($data)) {
+ $database->insterDataset($frame, key($data));
+ next($data);
}
}
}
View
43 lib/config.inc.php
@@ -1,49 +1,68 @@
<?php
+/**
+ * Configuration Class of the Application (Singleton)
+ *
+ * Reads the configuration from an ini file and provides the values as properties
+ *
+ * @copyright Copyright (c) Bertram Winter bertram.winter@gmail.com
+ * @license GPLv3 License
+ */
+
class Config
{
+ /**
+ * Config location constant
+ */
const DEFAULT_CONFIG_FILE = 'config/config.ini';
+ /**
+ * Singleton Interface
+ */
public static $instance;
-
public static function getInstance()
{
if (null == self::$instance) {
self::$instance = new self;
}
-
return self::$instance;
}
+ /**
+ * Constructor
+ * @param array $options predefined options
+ */
private function __construct(array $options=array())
{
if (empty($options)) {
- $options = parse_ini_file(
- self::DEFAULT_CONFIG_FILE,
- true
- );
+ $options = parse_ini_file(self::DEFAULT_CONFIG_FILE,true);
}
-
$this->setConfig($options);
}
+ /**
+ * Sets a array of confif options as properties of this class
+ * @param array $options
+ * @return Config
+ */
private function setConfig(array $options=array())
{
foreach ($options as $key => $value) {
-
if (is_array($value) && !empty($value)) {
$value = new self($value);
}
-
$this->$key = $value;
}
-
return $this;
}
-
+ /**
+ * Provides access to the configuration properties
+ * @param string $name Property name
+ * @throws Exception Property not found
+ */
public function __get($name)
{
- throw new Exception('call to undefined property: ' . $name);
+ throw new Exception('call to undefined property: '.$name);
}
}
View
6 test.php
@@ -1,8 +1,4 @@
<?php
include_once("lib/backend/uvr1611-connection.inc.php");
$uvr = Uvr1611::getInstance();
-while($uvr->getCount())
-{
- $data = $uvr->fetchData();
- print_r($data);
-}
+echo $uvr->getCount();

0 comments on commit ddb8b20

Please sign in to comment.
Something went wrong with that request. Please try again.