generalized Group entity

updated proxies
renamed Definition class
improved JSON definitions of entities and properties
This commit is contained in:
Steffen Vogel 2010-08-28 03:27:14 +02:00
parent f90a9a9b8b
commit 0305a6ce3b
30 changed files with 608 additions and 427 deletions

View file

@ -23,7 +23,7 @@
namespace Volkszaehler\Controller;
use \Volkszaehler\Model;
use Volkszaehler\Model;
/**
* Channel controller
@ -43,15 +43,7 @@ class ChannelController extends Controller {
$dql = 'SELECT c, p FROM Volkszaehler\Model\Channel c LEFT JOIN c.properties p';
if ($uuid = $this->view->request->getParameter('uuid')) {
// TODO add conditions
}
if ($ugid = $this->view->request->getParameter('ugid')) {
// TODO add conditions
}
if ($indicator = $this->view->request->getParameter('indicator')) {
// TODO add conditions
$dql .= ' WHERE c.uuid = \'' . $uuid . '\'';
}
$q = $this->em->createQuery($dql);
@ -64,17 +56,17 @@ class ChannelController extends Controller {
/**
* Add channel
*
* @todo validate input and throw exceptions
*/
public function add() {
$channel = new Model\Channel($this->view->request->getParameter('indicator'));
$properties = array();
$channel->setName($this->view->request->getParameter('name'));
$channel->setDescription($this->view->request->getParameter('description'));
foreach ($this->view->request->getParameters() as $parameter => $value) {
if (Model\PropertyDefinition::exists($parameter)) {
$properties[] = new Model\Property($parameter, $value);
}
}
$channel->setResolution($this->view->request->getParameter('resolution'));
$channel->setCost($this->view->request->getParameter('cost'));
$channel = new Model\Channel($this->view->request->getParameter('type'), $properties);
$this->em->persist($channel);
$this->em->flush();

View file

@ -42,14 +42,11 @@ class DataController extends Controller {
* @todo use uuids for groups or channels
*/
public function get() {
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));
if ($uuid = $this->view->request->getParameter('uuid')) {
$entity = $this->em->getRepository('Volkszaehler\Model\Entity')->findOneBy(array('uuid' => $uuid));
}
else {
throw new \Exception('you have to specifiy an ugid or ucid paramter');
throw new \Exception('you have to specifiy the uuid parameter');
}
if ($entity === FALSE) {
@ -62,8 +59,8 @@ class DataController extends Controller {
$data = $entity->getInterpreter($this->em, $from, $to)->getValues($groupBy);
if ($entity instanceof Model\Group) {
$this->view->addGroup($entity, $data);
if ($entity instanceof Model\Aggregator) {
$this->view->addAggregator($entity, $data);
}
elseif ($entity instanceof Model\Channel) {
$this->view->addChannel($entity, $data);

View file

@ -39,7 +39,7 @@ class GroupController extends Controller {
* @todo filter to root groups when using recursion
*/
public function get() {
$dql = 'SELECT g, c, d FROM Volkszaehler\Model\Group g LEFT JOIN g.children c LEFT JOIN g.channels d';
$dql = 'SELECT g, c, d FROM Volkszaehler\Model\Aggregator g LEFT JOIN g.children c LEFT JOIN g.channels d';
// TODO fix this (depending on DDC-719)
if ($recursion = $this->view->request->getParameter('recursive')) {
@ -58,7 +58,7 @@ class GroupController extends Controller {
$groups = $q->getResult();
foreach ($groups as $group) {
$this->view->addGroup($group, $recursion);
$this->view->addAggregator($group, $recursion);
}
}
@ -69,19 +69,19 @@ class GroupController extends Controller {
*/
public function add() {
$ugid = $this->view->request->getParameter('ugid');
$parent = $this->em->getRepository('Volkszaehler\Model\Group')->findOneBy(array('uuid' => $ugid));
$parent = $this->em->getRepository('Volkszaehler\Model\Aggregator')->findOneBy(array('uuid' => $ugid));
if ($parent == FALSE) {
throw new \Exception('every group needs a parent');
}
$group = new Model\Group();
$group = new Model\Aggregator();
$group->setName($this->view->request->getParameter('name'));
$group->setDescription($this->view->request->getParameter('description'));
$this->em->persist($group);
$parent->addGroup($group);
$parent->addAggregator($group);
$this->em->flush();
@ -93,7 +93,7 @@ class GroupController extends Controller {
*/
public function delete() {
$ugid = $this->view->request->getParameter('ugid');
$group = $this->em->getRepository('Volkszaehler\Model\Group')->findOneBy(array('uuid' => $ugid));
$group = $this->em->getRepository('Volkszaehler\Model\Aggregator')->findOneBy(array('uuid' => $ugid));
$this->em->remove($group);
$this->em->flush();
@ -102,7 +102,7 @@ class GroupController extends Controller {
/**
* edit group properties
*
* @todo implement Controller\Group::edit()
* @todo implement Controller\Aggregator::edit()
*/
public function edit() {

View file

@ -27,29 +27,35 @@ use Doctrine\ORM;
use Volkszaehler\Model;
/**
* Group interpreter
* Interpreter too aggregate several other Channels or Aggregators
*
* The GroupInterpreter is used to aggregate multiple channels with the same
* The AggregatorInterpreter is used to aggregate multiple channels with the same
* indicator
*
* @author Steffen Vogel <info@steffenvogel.de>
* @package default
*
*/
class GroupInterpreter {
protected $channelInterpreter;
class AggregatorInterpreter {
/**
* @var array of Interpreter
*/
protected $channelInterpreter = array();
/**
* Constructor
*
* @param Model\Group $group should only contain channels of the same indicator
* @param Model\Aggregator $group should only contain channels of the same indicator
* @param ORM\EntityManager $em
* @param integer $from timestamp in ms since 1970
* @param integer $to timestamp in ms since 1970
* @todo handle channels in nested aggregators
*/
public function __construct(Model\Group $group, ORM\EntityManager $em, $from, $to) {
foreach ($group->getChannels() as $channel) {
if (isset($indicator) && $indicator != $channel->getIndicator) {
public function __construct(Model\Aggregator $aggregator, ORM\EntityManager $em, $from, $to) {
$indicator = NULL;
foreach ($aggregator->getChannels() as $channels) {
if (isset($indicator) && $indicator != $channel->getIndicator()) {
throw new \Exception('we only can aggregate channels of the same indicator');
}
else {

View file

@ -29,6 +29,8 @@ namespace Volkszaehler\Interpreter;
* @author Steffen Vogel <info@steffenvogel.de>
*
*/
use Volkszaehler\Iterator;
use Volkszaehler;
use Doctrine\ORM\Query;
@ -106,11 +108,11 @@ abstract class Interpreter implements InterpreterInterface {
// return iterators
if ($sqlGroupBy || is_null($groupBy)) { // aggregation by sql or skip it
return new DataIterator($stmt, $rowCount);
return new Iterator\DataIterator($stmt, $rowCount);
}
elseif (is_numeric($groupBy) ) { // aggregation by php
$tuples = (int) $groupBy;
return new DataAggregationIterator($stmt, $rowCount, $tuples);
return new Iterator\DataAggregationIterator($stmt, $rowCount, $tuples);
}
else {
throw new \Exception('invalid groupBy parameter');

View file

@ -131,7 +131,7 @@ class MeterInterpreter extends Interpreter {
return array(
(int) ($next[0] - $delta / 2), // timestamp
$next[1] * (3600000 / (($this->channel->getResolution() / 1000) * $delta)), // value
$next[1] * (3600000 / (($this->channel->getProperty('resolution')->getValue() / 1000) * $delta)), // value
(isset($next[2])) ? $next[2] : 1
);
}

View file

@ -21,7 +21,7 @@
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Volkszaehler\Interpreter;
namespace Volkszaehler\Iterator;
use Doctrine\DBAL;

View file

@ -21,7 +21,7 @@
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Volkszaehler\Interpreter;
namespace Volkszaehler\Iterator;
use Doctrine\DBAL;

View file

@ -29,14 +29,15 @@ use Doctrine\Common\Collections;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Group entity
* Aggregator entity
*
* @author Steffen Vogel <info@steffenvogel.de>
* @package default
* @todo use nested sets: http://github.com/blt04/doctrine2-nestedset
*
* @Entity
*/
class Group extends Entity {
class Aggregator extends Entity {
/**
* @ManyToMany(targetEntity="Channel", inversedBy="groups")
* @JoinTable(name="groups_channel",
@ -47,7 +48,7 @@ class Group extends Entity {
protected $channels = NULL;
/**
* @ManyToMany(targetEntity="Group", inversedBy="parents")
* @ManyToMany(targetEntity="Aggregator", inversedBy="parents")
* @JoinTable(name="groups_groups",
* joinColumns={@JoinColumn(name="parent_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="child_id", referencedColumnName="id")}
@ -56,7 +57,7 @@ class Group extends Entity {
protected $children = NULL;
/**
* @ManyToMany(targetEntity="Group", mappedBy="children")
* @ManyToMany(targetEntity="Aggregator", mappedBy="children")
*/
protected $parents = NULL;
@ -74,16 +75,16 @@ class Group extends Entity {
/**
* Adds group as new child
*
* @param Group $child
* @param Aggregator $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) {
public function addAggregator(Aggregator $child) {
$this->children->add($child);
}
public function removeGroup(Group $child) {
public function removeAggregator(Aggregator $child) {
$this->children->removeElement($child);
}
@ -101,22 +102,6 @@ class Group extends Entity {
public function removeChannel(Channel $child) {
$this->channels->removeElement($child);
}
/**
* Getter & setter
*
* @todo change to new property model
*/
public function getName() { return $this->name; }
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->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); }
}
?>

View file

@ -40,14 +40,14 @@ class Channel extends Entity {
*/
protected $data = NULL;
/** @ManyToMany(targetEntity="Group", mappedBy="channels") */
protected $groups;
/** @ManyToMany(targetEntity="Aggregator", mappedBy="channels") */
protected $aggregators;
/**
* Constructor
*/
public function __construct($properties = array()) {
parent::__construct($properties);
public function __construct($type, $properties = array()) {
parent::__construct($type, $properties);
$this->data = new ArrayCollection();
$this->groups = new ArrayCollection();
@ -60,45 +60,6 @@ class Channel extends Entity {
public function addData(\Volkszaehler\Model\Data $data) {
$this->data->add($data);
}
/**
* Obtain channel interpreter to obtain data and statistical information for a given time interval
*
* @param Doctrine\ORM\EntityManager $em
* @param integer $from timestamp in ms since 1970
* @param integer $to timestamp in ms since 1970
* @return Interpreter
*/
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to) {
$interpreterClassName = 'Volkszaehler\Interpreter\\' . ucfirst($this->getType()) . 'Interpreter';
return new $interpreterClassName($this, $em, $from, $to);
}
/**
* Validate
*
* @PrePersist @PreUpdate
*/
protected function validate() {
if ($this->getResolution() <= 0 && $this->getType() == 'meter') {
throw new Exception('resolution has to be a positive integer');
}
}
/**
* getter & setter
*
* @todo change to new property model
*/
public function getName() { return $this->name; }
public function setName($name) { $this->name = $name; }
public function getDescription() { return $this->description; }
public function setDescription($description) { $this->description = $description; }
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; }
}
?>

View file

@ -46,7 +46,7 @@ class Data {
protected $id;
/**
* ending timestamp of period in ms since 1970
* Ending timestamp of period in ms since 1970
*
* @Column(type="bigint")
*/

View file

@ -27,7 +27,7 @@ use Doctrine\Common\Collections;
use Volkszaehler\Util;
/**
* Entity superclass for all models with database persistance
* Entity superclass for all objects referenced by a UUID
*
* @author Steffen Vogel <info@steffenvogel.de>
* @package default
@ -35,8 +35,12 @@ use Volkszaehler\Util;
* @Entity
* @Table(name="entities")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({"channel" = "Channel", "group" = "Group"})
* @DiscriminatorColumn(name="class", type="string")
* @DiscriminatorMap({
* "channel" = "Channel",
* "group" = "Aggregator"
* })
* @HasLifecycleCallbacks
*/
abstract class Entity {
/**
@ -49,6 +53,9 @@ abstract class Entity {
/** @Column(type="string", length=36, nullable=false, unique=true) */
protected $uuid;
/** @Column(type="string", nullable=false) */
protected $type;
/**
* @OneToMany(targetEntity="Token", mappedBy="entity")
*/
@ -63,75 +70,122 @@ abstract class Entity {
/**
* Constructor
*
* @param string $type
* @param array $properties of Model\Property
*/
public function __construct($properties = array()) {
public function __construct($type, $properties = NULL) {
if (!EntityDefinition::exists($type)) {
throw new \Exception('unknown entity type');
}
$this->type = $type;
$this->uuid = Util\UUID::mint();
$this->tokens = new Collections\ArrayCollection();
$this->properties = new Collections\ArrayCollection();
if (isset($properties)) {
foreach($properties as $property) {
$this->properies->add($property);
}
}
}
/**
* Getter & setter
* Checks for optional and required properties according to share/entities.json
*
* Throws an exception if something is incorrect
*
* @PrePersist
* @PreUpdate
* @PostLoad
* @todo to be implemented
*/
protected function validate() {
}
/**
* Get a property by name
*
* @param string $name
* @return Model\Property
*/
public function getProperty($name) {
return $this->properties->filter(function($property) use ($name) {
return $property->getName() == $name;
})->first();
}
public function getProperties() {
return $this->properties;
/**
* Get all properties or properties by prefix
*
* @param string $prefix
*/
public function getProperties($prefix = NULL) {
if (is_null($prefix)) {
return $this->properties;
}
else {
return $this->properties->filter(function($property) use ($prefix) {
return substr($property->getName(), 0, strlen($prefix) + 1) == $prefix . ':';
});
}
}
/**
* @param string $name of the property
* @param string|integer|float $value of the property
* @todo to be implemented
*/
public function setProperty($name, $value) {
}
/**
* @param string $name of the property
* @todo to be implemented
*/
public function unsetProperty($name) {
}
/*
* Setter & Getter
*/
public function getId() { return $this->id; } // read only
public function getUuid() { return $this->uuid; } // read only
public function getType() { return $this->type; } // read only
public function getDefinition() { return EntityDefinition::get($this->type); }
/**
* Get interpreter to obtain data and statistical information for a given time interval
*
* @param Doctrine\ORM\EntityManager $em
* @param integer $from timestamp in ms since 1970
* @param integer $to timestamp in ms since 1970
* @return Interpreter
*/
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to) {
$interpreterClassName = 'Volkszaehler\Interpreter\\' . $this->getDefinition()->getInterpreter();
return new $interpreterClassName($this, $em, $from, $to);
}
}
class EntityDefiniton extends Util\JSONDefinition {
/**
* File containing the JSON definitons
*
* @var string
*/
class EntityDefinition extends Util\Definition {
/** @var string File containing the JSON definitons */
const FILE = '/share/entities.json';
/**
* List of required properties
* Allowed properties = optional + required
* @var array
*/
/** @var array list of required properties */
protected $required = array();
/**
* List of optional properties
* Allowed properties = optional + required
* @var array
*/
/** @var array list of optional properties */
protected $optional = array();
/**
* Classname of intepreter (see backend/lib/Interpreter/)
* @var string
*/
/** @var string classname of intepreter (see backend/lib/Interpreter/) */
protected $interpreter;
/**
* Not required for group entity
* @var string
*/
/** @var string optional for Aggregator class entities */
protected $unit;
/**
@ -140,15 +194,11 @@ class EntityDefiniton extends Util\JSONDefinition {
*/
protected $icon;
/**
* Check for required and optional properties
*
* @return boolean
/*
* Setter & Getter
*/
public function checkProperties() {
}
public function getInterpreter() { return $this->interpreter; }
public function getUnit() { return $this->unit; }
}
?>

View file

@ -33,7 +33,13 @@ use Volkszaehler\Model;
* @package default
*
* @Entity
* @Table(name="properties")
* @Table(
* name="properties",
* uniqueConstraints={
* @UniqueConstraint(name="unique_properties", columns={"id", "name"})
* }
* )
* @HasLifecycleCallbacks
*/
class Property {
/**
@ -54,15 +60,6 @@ class Property {
/** @ManyToOne(targetEntity="Entity", inversedBy="properties") */
protected $entity;
/**
* Property definition
*
* Used to validate
*
* @var Model\PropertyDefinition
*/
protected $definition;
/**
* Constructor
*
@ -70,18 +67,30 @@ class Property {
* @param string $value
*/
public function __construct($name, $value) {
$this->definition = Model\PropertyDefinition::get($name);
$this->setName($name);
$this->setValue($value);
}
/**
* Validate property name & value
*
* Throws an exception if something is incorrect
*
* @PrePersist
* @PreUpdate
* @PostLoad
* @todo to be implemented
*/
function validate() {
}
/*
* Setter & Getter
*/
public function getName() { return $this->name; }
public function getValue() { return $this->value; }
public function getDefinition() { return PropertyDefinition::get($name); }
public function setValue($value) {
if (!$this->definition->validate($value)) {
@ -97,80 +106,4 @@ class Property {
protected function setName($name) { $this->name = $name; }
}
class PropertyDefinition extends Util\JSONDefinition {
/** One of: string, numeric, multiple */
public $type;
/**
* Regex pattern to match if type == string
*
* @var string
*/
protected $pattern;
/**
* Minimal value if type == numeric
* Required string length if type == string
*
* @var integer|float
*/
protected $min;
/**
* Maximal value if type == numeric
* Allowed string length if type == string
*
* @var integer|float
*/
protected $max;
/**
* List of possible choices if type == multiple
* (type as in javascript: 1.2 => numeric, "test" => string)
*
* @var array
*/
protected $choices = array();
/**
* File containing the JSON definitons
*
* @var string
*/
const FILE = '/share/properties.json';
/**
* Validate value according to $this->type
*
* @param mixed $value
* @return boolean
*/
public function validate($value) {
switch ($this->type) {
case 'string':
$invalid = !is_string($value);
$invalid |= isset($this->pattern) && !preg_match($this->pattern, $value);
$invalid |= isset($this->min) && strlen($value) < $this->min;
$invalid |= isset($this->max) && strlen($value) > $this->max;
break;
case 'numeric':
$invalid = !is_numeric($value);
$invalid |= isset($this->min) && $value < $this->min;
$invalid |= isset($this->max) && $value > $this->max;
break;
case 'multiple':
$invalid = !in_array($value, $this->choices, TRUE);
break;
default:
throw new \Exception('unknown property type');
}
return !$invalid;
}
}
?>

View file

@ -0,0 +1,107 @@
<?php
/**
* @copyright Copyright (c) 2010, The volkszaehler.org project
* @package default
* @license http://www.opensource.org/licenses/gpl-license.php GNU Public License
*/
/*
* This file is part of volkzaehler.org
*
* volkzaehler.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* volkzaehler.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Volkszaehler\Model;
use Volkszaehler\Util;
class PropertyDefinition extends Util\Definition {
/** One of: string, numeric, multiple */
public $type;
/** @var string regex pattern to match if type == string */
protected $pattern;
/**
* Minimal value if type == integer or type == float
* Required string length if type == string
*
* @var integer|float
*/
protected $min;
/**
* Maximal value if type == integer or type == float
* Allowed string length if type == string
*
* @var integer|float
*/
protected $max;
/**
* List of possible choices if type == multiple
* (type as in javascript: 1.2 => float, 5 => integer, "test" => string)
*
* @var array
*/
protected $choices = array();
/**
* File containing the JSON definitons
*
* @var string
*/
const FILE = '/share/properties.json';
/**
* Validate value according to $this->type
*
* @param string|numeric $value
* @return boolean
*/
public function validateValue($value) {
switch ($this->type) {
case 'string':
$invalid = !is_string($value);
$invalid |= isset($this->pattern) && !preg_match($this->pattern, $value);
$invalid |= isset($this->min) && strlen($value) < $this->min;
$invalid |= isset($this->max) && strlen($value) > $this->max;
break;
case 'integer':
$invalid = !is_int($value);
break;
case 'float':
$invalid = !is_float($value);
break;
case 'multiple':
$invalid = !in_array($value, $this->choices, TRUE);
break;
default:
throw new \Exception('unknown property type');
}
if ($type == 'integer' || $type == 'float') {
$invalid |= isset($this->min) && $value < $this->min;
$invalid |= isset($this->max) && $value > $this->max;
}
return !$invalid;
}
}
?>

View file

@ -1,11 +1,11 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
*/
class VolkszaehlerModelGroupProxy extends \Volkszaehler\Model\Group implements \Doctrine\ORM\Proxy\Proxy
class VolkszaehlerModelAggregatorProxy extends \Volkszaehler\Model\Aggregator implements \Doctrine\ORM\Proxy\Proxy
{
private $_entityPersister;
private $_identifier;
@ -27,16 +27,16 @@ class VolkszaehlerModelGroupProxy extends \Volkszaehler\Model\Group implements \
}
public function addGroup(\Volkszaehler\Model\Group $child)
public function addAggregator(\Volkszaehler\Model\Aggregator $child)
{
$this->_load();
return parent::addGroup($child);
return parent::addAggregator($child);
}
public function removeGroup(\Volkszaehler\Model\Group $child)
public function removeAggregator(\Volkszaehler\Model\Aggregator $child)
{
$this->_load();
return parent::removeGroup($child);
return parent::removeAggregator($child);
}
public function addChannel(\Volkszaehler\Model\Channel $child)
@ -51,54 +51,6 @@ class VolkszaehlerModelGroupProxy extends \Volkszaehler\Model\Group implements \
return parent::removeChannel($child);
}
public function getName()
{
$this->_load();
return parent::getName();
}
public function setName($name)
{
$this->_load();
return parent::setName($name);
}
public function getDescription()
{
$this->_load();
return parent::getDescription();
}
public function setDescription($description)
{
$this->_load();
return parent::setDescription($description);
}
public function getChildren()
{
$this->_load();
return parent::getChildren();
}
public function getParents()
{
$this->_load();
return parent::getParents();
}
public function getChannels()
{
$this->_load();
return parent::getChannels();
}
public function getInterpreter(\Doctrine\ORM\EntityManager $em)
{
$this->_load();
return parent::getInterpreter($em);
}
public function getProperty($name)
{
$this->_load();
@ -135,9 +87,21 @@ class VolkszaehlerModelGroupProxy extends \Volkszaehler\Model\Group implements \
return parent::getUuid();
}
public function getDefinition()
{
$this->_load();
return parent::getDefinition();
}
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to)
{
$this->_load();
return parent::getInterpreter($em, $from, $to);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'uuid', 'tokens', 'properties', 'channels', 'children', 'parents');
return array('__isInitialized__', 'id', 'uuid', 'type', 'tokens', 'properties', 'channels', 'children', 'parents');
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
@ -33,60 +33,6 @@ class VolkszaehlerModelChannelProxy extends \Volkszaehler\Model\Channel implemen
return parent::addData($data);
}
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to)
{
$this->_load();
return parent::getInterpreter($em, $from, $to);
}
public function getName()
{
$this->_load();
return parent::getName();
}
public function setName($name)
{
$this->_load();
return parent::setName($name);
}
public function getDescription()
{
$this->_load();
return parent::getDescription();
}
public function setDescription($description)
{
$this->_load();
return parent::setDescription($description);
}
public function getResolution()
{
$this->_load();
return parent::getResolution();
}
public function setResolution($resolution)
{
$this->_load();
return parent::setResolution($resolution);
}
public function getCost()
{
$this->_load();
return parent::getCost();
}
public function setCost($cost)
{
$this->_load();
return parent::setCost($cost);
}
public function getProperty($name)
{
$this->_load();
@ -123,9 +69,21 @@ class VolkszaehlerModelChannelProxy extends \Volkszaehler\Model\Channel implemen
return parent::getUuid();
}
public function getDefinition()
{
$this->_load();
return parent::getDefinition();
}
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to)
{
$this->_load();
return parent::getInterpreter($em, $from, $to);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'uuid', 'tokens', 'properties', 'data', 'groups');
return array('__isInitialized__', 'id', 'uuid', 'type', 'tokens', 'properties', 'data', 'aggregators');
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.

View file

@ -1,6 +1,6 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
@ -63,9 +63,21 @@ class VolkszaehlerModelEntityProxy extends \Volkszaehler\Model\Entity implements
return parent::getUuid();
}
public function getDefinition()
{
$this->_load();
return parent::getDefinition();
}
public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to)
{
$this->_load();
return parent::getInterpreter($em, $from, $to);
}
public function __sleep()
{
return array('__isInitialized__', 'id', 'uuid', 'tokens', 'properties');
return array('__isInitialized__', 'id', 'uuid', 'type', 'tokens', 'properties');
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
@ -27,6 +27,12 @@ class VolkszaehlerModelPropertyProxy extends \Volkszaehler\Model\Property implem
}
public function validate()
{
$this->_load();
return parent::validate();
}
public function getName()
{
$this->_load();
@ -39,6 +45,12 @@ class VolkszaehlerModelPropertyProxy extends \Volkszaehler\Model\Property implem
return parent::getValue();
}
public function getDefinition()
{
$this->_load();
return parent::getDefinition();
}
public function setValue($value)
{
$this->_load();

View file

@ -1,6 +1,6 @@
<?php
namespace Volkszaehler\Model\Proxies;
namespace Volkszaehler\Model\Proxy;
/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.

View file

@ -56,7 +56,7 @@ class CSV extends View {
$this->csv = array_merge($this->csv, $data);
}
public function addGroup(Model\Group $group) {
public function addAggregator(Model\Aggregator $aggregator) {
}

View file

@ -65,9 +65,9 @@ class Request {
*/
public function getHeader($header) { return $this->headers[$header]; }
public function getMethod() { return $this->method; }
public function getParameter($name, $method = 'get') {
return (isset($this->parameters[$method][$name])) ? $this->parameters[$method][$name] : NULL;
}
public function getParameter($name, $method = 'get') { return (isset($this->parameters[$method][$name])) ? $this->parameters[$method][$name] : NULL; }
public function getParameters($method = 'get') { return $this->parameters[$method]; }
}
?>

View file

@ -71,8 +71,8 @@ class JSON extends View {
$this->json['channels'][] = $jsonChannel;
}
public function addGroup(Model\Group $group, $recursive = FALSE) {
$this->json['groups'][] = self::convertJson($group, $recursive);
public function addAggregator(Model\Aggregator $aggregator, $recursive = FALSE) {
$this->json['groups'][] = self::convertJson($aggregator, $recursive);
}
public function addDebug(Util\Debug $debug) {
@ -97,27 +97,27 @@ class JSON extends View {
);
}
protected static function convertGroup(Model\Group $group, $recursive = FALSE) {
$jsonGroup = array();
protected static function convertAggregator(Model\Aggregator $aggregator, $recursive = FALSE) {
$jsonAggregator = array();
$jsonGroup['uuid'] = (string) $group->getUuid();
$jsonGroup['name'] = $group->getName();
$jsonGroup['description'] = $group->getDescription();
$jsonGroup['channels'] = array();
$jsonAggregator['uuid'] = (string) $aggregator->getUuid();
$jsonAggregator['name'] = $aggregator->getName();
$jsonAggregator['description'] = $aggregator->getDescription();
$jsonAggregator['channels'] = array();
foreach ($group->getChannels() as $channel) {
$jsonGroup['channels'][] = (string) $channel->getUuid();
foreach ($aggregator->getChannels() as $channel) {
$jsonAggregator['channels'][] = (string) $channel->getUuid();
}
if ($recursive) {
$jsonGroup['children'] = array();
$jsonAggregator['children'] = array();
foreach ($group->getChildren() as $subGroup) {
$jsonGroup['children'][] = $this->toJson($subGroup, $recursive); // recursion
foreach ($aggregator->getChildren() as $subAggregator) {
$jsonAggregator['children'][] = $this->toJson($subAggregator, $recursive); // recursion
}
}
return $jsonGroup;
return $jsonAggregator;
}
protected static function convertData($data) {

View file

@ -26,9 +26,9 @@ namespace Volkszaehler\View;
use Volkszaehler\Model;
use Volkszaehler\Util;
require_once \Volkszaehler\BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph.php';
require_once \Volkszaehler\BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph_scatter.php';
require_once \Volkszaehler\BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph_date.php';
require_once VZ_BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph.php';
require_once VZ_BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph_scatter.php';
require_once VZ_BACKEND_DIR . '/lib/vendor/JpGraph/jpgraph_date.php';
/**
* Plotting and graphing of data on the server side
@ -106,7 +106,7 @@ class JpGraph extends View {
// Create the scatter plot
$plot = new \ScatterPlot($yData, $xData);
$plot->setLegend($channel->getName() . ': ' . $channel->getDescription() . ' [' . $channel->getUnit() . ']');
$plot->setLegend($channel->getProperty('name')->getValue() . ': ' . $channel->getProperty('description')->getValue() . ' [' . $channel->getDefinition()->getUnit() . ']');
$plot->SetLinkPoints(TRUE, self::$colors[$count]);
$plot->mark->SetColor(self::$colors[$count]);
@ -132,10 +132,10 @@ class JpGraph extends View {
/**
* adds all channel of group as new plots to the graph
*
* @param Model\Group $group
* @param Model\Aggregator $aggregator
*/
public function addGroup(Model\Group $group) {
foreach ($group->getChannels() as $child) {
public function addAggregator(Model\Aggregator $aggregator) {
foreach ($aggregator->getChannels() as $child) {
$this->addChannel($child);
}
}
@ -157,24 +157,25 @@ class JpGraph extends View {
* check weather a axis for the indicator of $channel exists
*
* @param \Volkszaehler\Model\Channel $channel
* @todo call getType() only once
*/
protected function getAxisIndex(\Volkszaehler\Model\Channel $channel) {
if (!in_array($channel->getIndicator(), array_keys($this->axes))) {
if (!in_array($channel->getType(), array_keys($this->axes))) {
$count =count($this->axes);
if ($count == 0) {
$this->axes[$channel->getIndicator()] = -1;
$this->axes[$channel->getType()] = -1;
$yaxis = $this->graph->yaxis;
}
else {
$this->axes[$channel->getIndicator()] = $count - 1;
$this->axes[$channel->getType()] = $count - 1;
$this->graph->SetYScale($this->axes[$channel->getIndicator()],'lin');
$this->graph->SetYScale($this->axes[$channel->getType()],'lin');
$yaxis = $this->graph->ynaxis[$this->axes[$channel->getIndicator()]];
$yaxis = $this->graph->ynaxis[$this->axes[$channel->getType()]];
}
$yaxis->title->Set($channel->getUnit());
$yaxis->title->Set($channel->getDefinition()->getUnit());
$yaxis->SetFont(FF_ARIAL);
$yaxis->title->SetFont(FF_ARIAL);
@ -182,7 +183,7 @@ class JpGraph extends View {
$yaxis->SetTitleMargin('50');
}
return $this->axes[$channel->getIndicator()];
return $this->axes[$channel->getType()];
}
/**

View file

@ -51,8 +51,8 @@ class PlainText extends View {
var_dump($data);
}
public function addGroup(Model\Group $group) {
var_dump($group);
public function addAggregator(Model\Aggregator $aggregator) {
var_dump($aggregator);
}
public function addDebug(Util\Debug $debug) {

View file

@ -35,7 +35,7 @@ use Volkszaehler\Util;
*/
interface ViewInterface {
public function addChannel(Model\Channel $channel, array $data = NULL);
function addGroup(Model\Group $group);
function addAggregator(Model\Aggregator $aggregator);
function addDebug(Util\Debug $debug);
}
@ -73,13 +73,16 @@ abstract class View implements ViewInterface {
$code = ($exception->getCode() == 0 && HTTP\Response::getCodeDescription($exception->getCode())) ? 400 : $exception->getCode();
$this->response->setCode($code);
$this->sendResponse();
echo $exception;
//$this->sendResponse();
die();
}
public function sendResponse() {
if (Util\Debug::isActivated()) {
$this->addDebug(Util\Debug::getInstance());
}
$this->renderResponse();
$this->response->send();
}

View file

@ -37,7 +37,7 @@ class XML extends View {
protected $xmlDoc = NULL;
protected $xmlRoot = NULL;
protected $xmlChannels = NULL;
protected $xmlGroups = NULL;
protected $xmlAggregators = NULL;
public function __construct(HTTP\Request $request, HTTP\Response $response) {
parent::__construct($request, $response);
@ -88,32 +88,32 @@ class XML extends View {
$this->xmlChannels->appendChild($xmlChannel);
}
public function addGroup(Model\Group $group, $recursive = FALSE) {
if (!isset($this->xmlGroups)) {
$this->xmlGroups = $this->xmlDoc->createElement('groups');
$this->xmlRoot->appendChild($this->xmlGroups);
public function addAggregator(Model\Aggregator $aggregator, $recursive = FALSE) {
if (!isset($this->xmlAggregators)) {
$this->xmlAggregators = $this->xmlDoc->createElement('groups');
$this->xmlRoot->appendChild($this->xmlAggregators);
}
$this->xmlGroups->appendChild($this->toXml($group, $recursive));
$this->xmlAggregators->appendChild($this->toXml($aggregator, $recursive));
}
public function toXml(Model\Group $group, $recursive = FALSE) {
$xmlGroup = $this->xmlDoc->createElement('group');
$xmlGroup->setAttribute('uuid', $group->getUuid());
$xmlGroup->appendChild($this->xmlDoc->createElement('name', $group->getName()));
$xmlGroup->appendChild($this->xmlDoc->createElement('description', $group->getDescription()));
public function toXml(Model\Aggregator $aggregator, $recursive = FALSE) {
$xmlAggregator = $this->xmlDoc->createElement('group');
$xmlAggregator->setAttribute('uuid', $aggregator->getUuid());
$xmlAggregator->appendChild($this->xmlDoc->createElement('name', $aggregator->getName()));
$xmlAggregator->appendChild($this->xmlDoc->createElement('description', $aggregator->getDescription()));
if ($recursive) {
$xmlChildren = $this->xmlDoc->createElement('children');
foreach ($group->getChildren() as $child) {
foreach ($aggregator->getChildren() as $child) {
$xmlChildren->appendChild($this->toXml($child, $recursive));
}
$xmlGroup->appendChild($xmlChildren);
$xmlAggregator->appendChild($xmlChildren);
}
return $xmlGroup;
return $xmlAggregator;
}
public function addDebug(Util\Debug $debug) {

View file

@ -28,14 +28,21 @@
[
{
"name" : "group",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "tolerance"],
"interpreter" : "GroupInterpreter",
"interpreter" : "AggregatorInterpreter",
"icon" : "" // TODO look for an icon
},
{
"name" : "user",
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "tolerance"],
"interpreter" : "AggregatorInterpreter",
"icon" : "" // TODO look for an icon
},
{
"name" : "power",
"required" : ["name", "resolution"],
"required" : ["title", "resolution"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "MeterInterpreter",
"unit" : "kW/h",
@ -43,7 +50,7 @@
},
{
"name" : "gas",
"required" : ["name", "resolution"],
"required" : ["title", "resolution"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "MeterInterpreter",
"unit" : "m³/h",
@ -51,7 +58,7 @@
},
{
"name" : "water",
"required" : ["name", "resolution"],
"required" : ["title", "resolution"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "MeterInterpreter",
"unit" : "m³/h",
@ -59,7 +66,7 @@
},
{
"name" : "temperature",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"unit" : "°C",
@ -67,7 +74,7 @@
},
{
"name" : "pressure",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"unit" : "hPa",
@ -75,7 +82,7 @@
},
{
"name" : "humidity",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"unit" : "%",
@ -83,7 +90,7 @@
},
{
"name" : "windspeed",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"unit" : "km/h",
@ -91,16 +98,16 @@
},
{
"name" : "radition",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"icon" : "" // TODO look for an icon
},
{
"name" : "luminosity",
"required" : ["name"],
"required" : ["title"],
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
"interpreter" : "SensorInterpreter",
"icon" : "" // TODO look for an icon
},
}
]

View file

@ -27,7 +27,7 @@
[
{
"name" : "name",
"name" : "title",
"type" : "string",
"pattern" : "/[a-z0-9 ]/",
"min": 3,
@ -41,29 +41,29 @@
},
{
"name" : "cost",
"type" : "numeric",
"type" : "float",
"min" : 0
},
{
"name" : "resolution",
"type" : "numeric",
"type" : "integer",
"min" : 1
},
{
"name" : "tolerance",
"type" : "numeric",
"type" : "float",
"min" : 0,
"max" : 1
},
{
"name" : "address:lat",
"type" : "numeric",
"type" : "float",
"min" : -90,
"max" : 90
},
{
"name" : "address:lon",
"type" : "numeric",
"type" : "float",
"min" : -90,
"max" : 90
},
@ -82,7 +82,198 @@
},
{
"name" : "address:state",
"type" : "string"
"type" : "multiple",
"choices" : [
"Albania",
"Algeria",
"Andorra",
"Angola",
"Anguilla",
"Antigua and Barbuda",
"Argentina",
"Armenia",
"Aruba",
"Australia",
"Austria",
"Azerbaijan Republic",
"Bahamas",
"Bahrain",
"Barbados",
"Belgium",
"Belize",
"Benin",
"Bermuda",
"Bhutan",
"Bolivia",
"Bosnia and Herzegovina",
"Botswana",
"Brazil",
"British Virgin Islands",
"Brunei",
"Bulgaria",
"Burkina Faso",
"Burundi",
"Cambodia",
"Canada",
"Cape Verde",
"Cayman Islands",
"Chad",
"Chile",
"China Worldwide",
"Colombia",
"Comoros",
"Cook Islands",
"Costa Rica",
"Croatia",
"Cyprus",
"Czech Republic",
"Democratic Republic of the Congo",
"Denmark",
"Djibouti",
"Dominica",
"Dominican Republic",
"Ecuador",
"El Salvador",
"Eritrea",
"Estonia",
"Ethiopia",
"Falkland Islands",
"Faroe Islands",
"Federated States of Micronesia",
"Fiji",
"Finland",
"France",
"French Guiana",
"French Polynesia",
"Gabon Republic",
"Gambia",
"Germany",
"Gibraltar",
"Greece",
"Greenland",
"Grenada",
"Guadeloupe",
"Guatemala",
"Guinea",
"Guinea Bissau",
"Guyana",
"Honduras",
"Hong Kong",
"Hungary",
"Iceland",
"India",
"Indonesia",
"Ireland",
"Israel",
"Italy",
"Jamaica",
"Japan",
"Jordan",
"Kazakhstan",
"Kenya",
"Kiribati",
"Kuwait",
"Kyrgyzstan",
"Laos",
"Latvia",
"Lesotho",
"Liechtenstein",
"Lithuania",
"Luxembourg",
"Madagascar",
"Malawi",
"Malaysia",
"Maldives",
"Mali",
"Malta",
"Marshall Islands",
"Martinique",
"Mauritania",
"Mauritius",
"Mayotte",
"Mexico",
"Mongolia",
"Montserrat",
"Morocco",
"Mozambique",
"Namibia",
"Nauru",
"Nepal",
"Netherlands",
"Netherlands Antilles",
"New Caledonia",
"New Zealand",
"Nicaragua",
"Niger",
"Niue",
"Norfolk Island",
"Norway",
"Oman",
"Palau",
"Panama",
"Papua New Guinea",
"Peru",
"Philippines",
"Pitcairn Islands",
"Poland",
"Portugal",
"Qatar",
"Republic of the Congo",
"Reunion",
"Romania",
"Russia",
"Rwanda",
"Saint Vincent and the Grenadines",
"Samoa",
"San Marino",
"São Tomé and Príncipe",
"Saudi Arabia",
"Senegal",
"Seychelles",
"Sierra Leone",
"Singapore",
"Slovakia",
"Slovenia",
"Solomon Islands",
"Somalia",
"South Africa",
"South Korea",
"Spain",
"Sri Lanka",
"St. Helena",
"St. Kitts and Nevis",
"St. Lucia",
"St. Pierre and Miquelon",
"Suriname",
"Svalbard and Jan Mayen Islands",
"Swaziland",
"Sweden",
"Switzerland",
"Taiwan",
"Tajikistan",
"Tanzania",
"Thailand",
"Togo",
"Tonga",
"Trinidad and Tobago",
"Tunisia",
"Turkey",
"Turkmenistan",
"Turks and Caicos Islands",
"Tuvalu",
"Uganda",
"Ukraine",
"United Arab Emirates",
"United Kingdom",
"Uruguay",
"Vanuatu",
"Vatican City State",
"Venezuela",
"Vietnam",
"Wallis and Futuna Islands",
"Yemen",
"Zambia"
]
},
{
"name" : "address:country",