From b23a36bad52d5317d6b7c2b043bb7a63205a4d4d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 28 Jul 2010 00:39:23 +0200 Subject: [PATCH] added & integrated new Logger API some small bugfixes --- backend/lib/Controller/DataController.php | 71 ++++++++----------- backend/lib/Controller/GroupController.php | 2 +- backend/lib/Logger/FluksoLogger.php | 8 ++- backend/lib/Logger/Logger.php | 33 ++++++++- backend/lib/Logger/PrototypeLogger.php | 79 ++++++++++++++++++++++ backend/lib/Logger/VzLogger.php | 59 ++++++++++++++++ backend/lib/Model/Channel.php | 26 +++---- backend/lib/Model/Data.php | 9 ++- backend/lib/Model/Group.php | 23 ++++++- 9 files changed, 246 insertions(+), 64 deletions(-) create mode 100644 backend/lib/Logger/PrototypeLogger.php create mode 100644 backend/lib/Logger/VzLogger.php diff --git a/backend/lib/Controller/DataController.php b/backend/lib/Controller/DataController.php index f277119..6f2a242 100644 --- a/backend/lib/Controller/DataController.php +++ b/backend/lib/Controller/DataController.php @@ -23,6 +23,8 @@ namespace Volkszaehler\Controller; +use Volkszaehler\Model; + use Volkszaehler\Util; /** @@ -41,18 +43,31 @@ class DataController extends Controller { * @todo use uuids for groups or channels */ public function get() { - $ids = explode(',', trim($this->view->request->getParameter('ids'))); + if ($ucid = $this->view->request->getParameter('ucid')) { + $entity = $this->em->getRepository('Volkszaehler\Model\Channel')->findOneBy(array('uuid' => $ucid)); + } + elseif ($ugid = $this->view->request->getParameter('ugid')) { + $entity = $this->em->getRepository('Volkszaehler\Model\Group')->findOneBy(array('uuid' => $ugid)); + } + else { + throw new \Exception('you have to specifiy an ugid or ucid paramter'); + } - $q = $this->em->createQuery('SELECT c FROM Volkszaehler\Model\Channel c WHERE c.id IN (' . implode(', ', $ids) . ')'); - $channels = $q->execute(); + if ($entity === FALSE) { + throw new \Exception('no group/channel found'); + } - $from = ($this->view->request->getParameter('from')) ? (int) $this->view->request->getParameter('from') : NULL; - $to = ($this->view->request->getParameter('to')) ? (int) $this->view->request->getParameter('to') : NULL; - $groupBy = ($this->view->request->getParameter('groupBy')) ? $this->view->request->getParameter('groupBy') : NULL; // get all readings by default + $from = $this->view->request->getParameter('from'); + $to = $this->view->request->getParameter('to'); + $groupBy = ($this->view->request->getParameter('groupBy')); // get all readings by default - foreach ($channels as $channel) { - $interpreter = $channel->getInterpreter($this->em); - $this->view->addChannel($channel, $interpreter->getValues($from, $to, $groupBy)); + $data = $entity->getInterpreter($this->em, $from, $to)->getValues($groupBy); + + if ($entity instanceof Model\Group) { + $this->view->addGroup($entity, $data); + } + elseif ($entity instanceof Model\Channel) { + $this->view->addChannel($entity, $data); } } @@ -62,41 +77,13 @@ class DataController extends Controller { * @todo authentification/indentification */ public function add() { - $ucid = $this->view->request->getParameter('ucid'); - $channel = $this->em->getRepository('Volkszaehler\Model\Channel\Channel')->findOneBy(array('uuid' => $ucid)); - - $value = (float) $this->view->request->getParameter('value'); - $ts = (int) $this->view->request->getParameter('timestamp'); - if ($ts == 0) { - $ts = microtime(TRUE) * 1000; + $loggerClassName = 'Volkszaehler\Logger\\' . ucfirst($this->view->request->getParameter('logger')) . 'Logger'; + if (!(Util\ClassLoader::classExists($loggerClassName)) || !is_subclass_of($loggerClassName, '\Volkszaehler\Logger\Logger')) { + throw new \Exception('\'' . $loggerClassName . '\' is not a valid controller'); } + $logger = new $loggerClassName($this->view->request, $this->em); - $data = new \Volkszaehler\Model\Data($channel, $value, $ts); - - $channel->addData($data); - - $this->em->persist($data); - $this->em->flush(); - } - - /** - * prune data from database - * - * @todo authentification/indentification - */ - public function delete() { - $dql = 'DELETE FROM \Volkszaehler\Model\Data WHERE channel_id = ' . $this->id; - - if ($this->view->request->getParameter('from')) { - $dql .= ' && timestamp > ' . (int) $this->view->request->getParameter('from'); - } - - if ($this->view->request->getParameter('to')) { - $dql .= ' && timestamp < ' . $this->view->request->getParameter('to'); - } - - $q = $em->createQuery($dql); - $q->execute(); + $logger->log(); } } diff --git a/backend/lib/Controller/GroupController.php b/backend/lib/Controller/GroupController.php index 18f519c..a1dba2b 100644 --- a/backend/lib/Controller/GroupController.php +++ b/backend/lib/Controller/GroupController.php @@ -42,7 +42,7 @@ class GroupController extends Controller { $dql = 'SELECT g, c, d FROM Volkszaehler\Model\Group g LEFT JOIN g.children c LEFT JOIN g.channels d'; // TODO fix this (depending on DDC-719) - if ($recursion = $this->view->request->getParameter('recursion')) { + if ($recursion = $this->view->request->getParameter('recursive')) { //$dql .= ' WHERE g.parents IS EMPTY'; } diff --git a/backend/lib/Logger/FluksoLogger.php b/backend/lib/Logger/FluksoLogger.php index 88a94cc..1a786ac 100644 --- a/backend/lib/Logger/FluksoLogger.php +++ b/backend/lib/Logger/FluksoLogger.php @@ -32,7 +32,13 @@ namespace Volkszaehler\Logger; * @author Steffen Vogel * @todo to be implemented */ -class FluksoLogger implements Logger { +class FluksoLogger extends Logger { + /** + * @return array of Model\Data + */ + public function getData(); + + public function getVersion(); } diff --git a/backend/lib/Logger/Logger.php b/backend/lib/Logger/Logger.php index 025a5d5..48ba52b 100644 --- a/backend/lib/Logger/Logger.php +++ b/backend/lib/Logger/Logger.php @@ -24,6 +24,8 @@ namespace Volkszaehler\Logger; use Volkszaehler\View\HTTP; +use Doctrine\ORM; +use Volkszaehler\Model; /** * interface for parsing diffrent logging APIs (google, flukso etc..) @@ -32,13 +34,38 @@ use Volkszaehler\View\HTTP; * @package default * @todo to be implemented */ -interface Logger { - public function __construct(HTTP\Request $request); +interface LoggerInterface { + public function __construct(HTTP\Request $request, ORM\EntityManager $em); /** - * @return \Volkszaehler\Model\Data $data the parsed data + * @return array of Model\Data */ public function getData(); + + public function getVersion(); +} + +abstract class Logger implements LoggerInterface { + protected $request; + protected $em; + + public function __construct(HTTP\Request $request, ORM\EntityManager $em) { + $this->request = $request; + $this->em = $em; + } + + public function log() { + $data = $this->getData(); + + if (!is_array($data)) { + $data = array($data); + } + + foreach ($data as $reading) { + $this->em->persist($reading); + } + $this->em->flush(); + } } ?> \ No newline at end of file diff --git a/backend/lib/Logger/PrototypeLogger.php b/backend/lib/Logger/PrototypeLogger.php new file mode 100644 index 0000000..638b52f --- /dev/null +++ b/backend/lib/Logger/PrototypeLogger.php @@ -0,0 +1,79 @@ +. + */ + +namespace Volkszaehler\Logger; + +use Volkszaehler\Model; +use Doctrine\ORM; + +/** + * logger for the the original volkszaehler.org prototype based on ethersex's watchasync + * + * @package default + * @link http://github.com/ethersex/ethersex/blob/master/services/watchasync + * @author Steffen Vogel + * @todo to be implemented + */ +class PrototypeLogger extends Logger { + /** + * @return array of Model\Data + */ + public function getData() { + $uuid = $this->request->getParameter('uuid'); + $port = $this->request->getParameter('port'); + + $channel = $this->em->getRepository('Volkszaehler\Model\Channel')->findOneBy(array( + 'description' => $uuid, + 'name' => $port + )); + + if ($channel) { + if (!($time = $this->request->getParameter('time'))) { + $time = (int) (microtime(TRUE) * 1000); + } + return new Model\Data($channel, 1, $time); + } + else { + return FALSE; + } + } + + /** + * the prototyp protocol doesn't have a version + */ + public function getVersion() { + return FALSE; + } +} + +/* + * just some documentation + * + * /httplog/httplog.php?port=&uuid=&time= + * + * = + * = timestamp in ms since 1970 + * + */ + +?> \ No newline at end of file diff --git a/backend/lib/Logger/VzLogger.php b/backend/lib/Logger/VzLogger.php new file mode 100644 index 0000000..6f0ab3d --- /dev/null +++ b/backend/lib/Logger/VzLogger.php @@ -0,0 +1,59 @@ +. + */ + +namespace Volkszaehler\Logger; + +use Volkszaehler\Model; + +use Doctrine\ORM; + +/** + * + * @author Steffen Vogel + * @package default + * + */ +class VzLogger extends Logger { + /** + * @return array of Model\Data + */ + public function getData() { + $ucid = $this->view->request->getParameter('ucid'); + $channel = $this->em->getRepository('Volkszaehler\Model\Channel\Channel')->findOneBy(array('uuid' => $ucid)); + + $value = (float) $this->view->request->getParameter('value'); + $ts = (int) $this->view->request->getParameter('timestamp'); + if ($ts == 0) { + $ts = microtime(TRUE) * 1000; + } + + $data = new Model\Data($channel, $value, $ts); + } + + public function getVersion() { + return $this->request->getParameter('version'); + } +} + + +?> \ No newline at end of file diff --git a/backend/lib/Model/Channel.php b/backend/lib/Model/Channel.php index ec5d579..8702570 100644 --- a/backend/lib/Model/Channel.php +++ b/backend/lib/Model/Channel.php @@ -62,10 +62,10 @@ class Channel extends Entity { * indicator => interpreter, unit mapping */ protected static $indicators = array( - 'power' => array('meter', 'kW/h'), - 'gas' => array('meter', 'qm/h'), - 'water' => array('meter', 'qm/h'), - 'temperature' => array('sensor', '° C'), + 'power' => array('meter', 'W'), + 'gas' => array('meter', 'm³'), + 'water' => array('meter', 'm³'), + 'temperature' => array('sensor', '°C'), 'pressure' => array('sensor', 'hPa'), 'humidity' => array('sensor', '%') ); @@ -76,7 +76,7 @@ class Channel extends Entity { public function __construct($indicator) { parent::__construct(); - if (!in_array($indicator, self::$indicators)) { + if (!in_array($indicator, array_keys(self::$indicators))) { throw new \Exception($indicator . ' is no known indicator'); } @@ -96,12 +96,9 @@ class Channel extends Entity { /** * obtain channels data interpreter to calculate statistical information */ - public function getInterpreter(\Doctrine\ORM\EntityManager $em) { - $interpreterClassName = 'Volkszaehler\Interpreter\\' . ucfirst(self::$indicators[$this->indicator][0]) . 'Interpreter'; - if (!(\Volkszaehler\Util\ClassLoader::classExists($interpreterClassName)) || !is_subclass_of($interpreterClassName, '\Volkszaehler\Interpreter\Interpreter')) { - throw new \Exception('\'' . $interpreterClassName . '\' is not a valid Interpreter'); - } - return new $interpreterClassName($this, $em); + public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to) { + $interpreterClassName = 'Volkszaehler\Interpreter\\' . ucfirst($this->getType()) . 'Interpreter'; + return new $interpreterClassName($this, $em, $from, $to); } /** @@ -111,12 +108,15 @@ class Channel extends Entity { public function setName($name) { $this->name = $name; } public function getDescription() { return $this->description; } public function setDescription($description) { $this->description = $description; } - public function getUnit() { return self::$indicators[$this->indicator][1]; } - public function getIndicator() { return $this->indicator; } + public function getResolution() { return $this->resolution; } public function setResolution($resolution) { $this->resolution = $resolution; } public function getCost() { return $this->cost; } public function setCost($cost) { $this->cost = $cost; } + + public function getType() { return self::$indicators[$this->indicator][0]; } + public function getUnit() { return self::$indicators[$this->indicator][1]; } + public function getIndicator() { return $this->indicator; } } ?> diff --git a/backend/lib/Model/Data.php b/backend/lib/Model/Data.php index ddb1e8a..a78ca50 100644 --- a/backend/lib/Model/Data.php +++ b/backend/lib/Model/Data.php @@ -24,6 +24,7 @@ namespace Volkszaehler\Model; use Doctrine\Common\Collections\ArrayCollection; +use Volkszaehler\Model; /** * Data entity @@ -56,12 +57,18 @@ class Data { */ protected $channel; - public function __construct(Channel\Channel $channel, $value, $timestamp) { + public function __construct(Model\Channel $channel, $value, $timestamp) { + $channel->addData($this); // bidirectional association $this->channel = $channel; + $this->value = $value; $this->timestamp = $timestamp; } + public function toArray() { + return array('channel' => $this->channel, 'timestamp' => $this->timestamp, 'value' => $this->value); + } + /** * setter & getter */ diff --git a/backend/lib/Model/Group.php b/backend/lib/Model/Group.php index 10f3a53..9e64c93 100644 --- a/backend/lib/Model/Group.php +++ b/backend/lib/Model/Group.php @@ -23,6 +23,10 @@ namespace Volkszaehler\Model; +use Volkszaehler\Interpreter; + +use Doctrine\ORM; + use Doctrine\Common\Collections; use Doctrine\Common\Collections\ArrayCollection; @@ -83,21 +87,31 @@ class Group extends Entity { * @param Group $child * @todo check against endless recursion * @todo check if the group is already member of the group + * @todo add bidirectional association */ public function addGroup(Group $child) { $this->children->add($child); } + public function removeGroup(Group $child) { + $this->children->removeElement($child); + } + /** * adds channel as new child * * @param Channel $child * @todo check if the channel is already member of the group + * @todo add bidrection association */ public function addChannel(Channel $child) { $this->channels->add($child); } + public function removeChannel(Channel $child) { + $this->channels->removeElement($child); + } + /** * getter & setter */ @@ -105,9 +119,12 @@ class Group extends Entity { public function setName($name) { $this->name = $name; } public function getDescription() { return $this->description; } public function setDescription($description) { $this->description = $description; } - public function getChildren() { return $this->children; } - public function getParents() { return $this->parents; } - public function getChannels() { return $this->channels; } + + public function getChildren() { return $this->children->toArray(); } + public function getParents() { return $this->parents->toArray(); } + public function getChannels() { return $this->channels->toArray(); } + + public function getInterpreter(ORM\EntityManager $em) { return new Interpreter\GroupInterpreter($this, $em); } } ?> \ No newline at end of file