From 46c11577c1394ff57efc45fca8332b238f35254f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 1 Aug 2011 01:59:34 +0200 Subject: [PATCH] improved handling of plotting style for powersensors (fixes #89) improved property handling in frontend --- htdocs/frontend/index.html | 7 --- htdocs/frontend/javascripts/entities.js | 2 - htdocs/frontend/javascripts/entity.js | 61 ++++++++++++++----- htdocs/frontend/javascripts/options.js | 1 - htdocs/frontend/javascripts/wui.js | 8 ++- lib/Controller/CapabilitiesController.php | 5 +- lib/Definition/Definition.php | 14 ++--- lib/Definition/EntityDefinition.json | 44 +++++--------- lib/Definition/EntityDefinition.php | 38 ++++++++++-- lib/Definition/PropertyDefinition.json | 73 ++++++++++++++++++----- lib/Definition/PropertyDefinition.php | 10 ++-- 11 files changed, 171 insertions(+), 92 deletions(-) diff --git a/htdocs/frontend/index.html b/htdocs/frontend/index.html index e9bb849..654b4d4 100644 --- a/htdocs/frontend/index.html +++ b/htdocs/frontend/index.html @@ -106,13 +106,6 @@ - - Darstellung - -   - - -
diff --git a/htdocs/frontend/javascripts/entities.js b/htdocs/frontend/javascripts/entities.js index 2c47eab..78411b2 100644 --- a/htdocs/frontend/javascripts/entities.js +++ b/htdocs/frontend/javascripts/entities.js @@ -97,9 +97,7 @@ vz.entities.showTable = function() { vz.entities.sort(Entity.compare); - var c = 0; // for colors this.each(function(entity, parent) { - entity.color = vz.options.plot.colors[c++ % vz.options.plot.colors.length]; $('#entity-list tbody').append(entity.getDOMRow(parent)); }, true); // recursive! diff --git a/htdocs/frontend/javascripts/entity.js b/htdocs/frontend/javascripts/entity.js index 4e8f742..c4935d4 100644 --- a/htdocs/frontend/javascripts/entity.js +++ b/htdocs/frontend/javascripts/entity.js @@ -29,17 +29,14 @@ */ var Entity = function(json) { this.parseJSON(json); - - if (this.active === undefined) { - this.active = true; // activate by default - } - - }; +Entity.colors = 0; + Entity.prototype.parseJSON = function(json) { $.extend(true, this, json); + // parse children if (this.children) { for (var i = 0; i < this.children.length; i++) { this.children[i].middleware = this.middleware; // children inherit parent middleware @@ -48,9 +45,27 @@ Entity.prototype.parseJSON = function(json) { this.children.sort(Entity.compare); } - + + // setting defaults if (this.type !== undefined) { this.definition = vz.capabilities.definitions.get('entities', this.type); + + if (this.style === undefined) { + if (this.definition.style) { + this.style = this.definition.style; + } + else { + this.style = (this.definition.interpreter == 'Volkszaehler\\Interpreter\\SensorInterpreter') ? 'lines' : 'steps'; + } + } + } + + if (this.active === undefined) { + this.active = true; // activate by default + } + + if (this.color === undefined) { + this.color = vz.options.plot.colors[Entity.colors++ % vz.options.plot.colors.length]; } }; @@ -143,14 +158,23 @@ Entity.prototype.getDOMDetails = function(edit) { var data = $(''); // general properties - var general = ['uuid', 'middleware', 'type', 'color', 'cookie']; + var general = ['title', 'type', 'uuid', 'middleware', 'color', 'style', 'active', 'cookie']; var sections = ['required', 'optional']; general.each(function(index, property) { + var definition = vz.capabilities.definitions.get('properties', property); + var title = (definition) ? definition.translation[vz.options.language] : property; + var value = this[property]; + switch(property) { case 'type': var title = 'Typ'; - var value = this.definition.translation[vz.options.language]; + var icon = $(''). + attr('src', 'images/types/' + this.definition.icon) + .css('margin-right', 4); + var value = $('') + .text(this.definition.translation[vz.options.language]) + .prepend(icon); break; case 'middleware': @@ -164,8 +188,11 @@ Entity.prototype.getDOMDetails = function(edit) { break; case 'color': - var title = 'Farbe'; - var value = '' + this.color + ''; + var value = $('') + .text(this.color) + .css('background-color', this.color) + .css('padding-left', 5) + .css('padding-right', 5); break; case 'cookie': @@ -173,9 +200,15 @@ Entity.prototype.getDOMDetails = function(edit) { value = '' + ((value) ? 'ja' : 'nein') + ''; break; case 'active': - var title = 'Aktiv'; var value = '' + ((this.active) ? 'ja' : 'nein') + ''; break; + case 'style': + switch (this.style) { + case 'lines': var value = 'Linien'; break; + case 'steps': var value = 'Stufen'; break; + case 'points': var value = 'Punkte'; break; + } + break; } data.append($('') @@ -191,10 +224,10 @@ Entity.prototype.getDOMDetails = function(edit) { ) ); }, this); - + sections.each(function(index, section) { this.definition[section].each(function(index, property) { - if (this.hasOwnProperty(property)) { + if (this.hasOwnProperty(property) && !general.contains(property)) { var definition = vz.capabilities.definitions.get('properties', property); var title = definition.translation[vz.options.language]; var value = this[property]; diff --git a/htdocs/frontend/javascripts/options.js b/htdocs/frontend/javascripts/options.js index f601633..c1d936b 100644 --- a/htdocs/frontend/javascripts/options.js +++ b/htdocs/frontend/javascripts/options.js @@ -29,7 +29,6 @@ vz.options = { language: 'de', precision: 2, // TODO update from middleware capabilities? tuples: null, // automatically determined by plot size - render: 'lines', refresh: false, minTimeout: 3000, // minimum refresh time in ms defaultInterval: 24*60*60*1000, // 1 day diff --git a/htdocs/frontend/javascripts/wui.js b/htdocs/frontend/javascripts/wui.js index f712afd..daddb30 100644 --- a/htdocs/frontend/javascripts/wui.js +++ b/htdocs/frontend/javascripts/wui.js @@ -458,10 +458,12 @@ vz.wui.drawPlot = function () { data: entity.data.tuples, color: entity.color, lines: { - show: (vz.options.render == 'lines'), - steps: (entity.definition.interpreter == 'Volkszaehler\\Interpreter\\MeterInterpreter') + show: (entity.style == 'lines' || entity.style == 'steps'), + steps: (entity.style == 'steps') }, - points: { show: (vz.options.render == 'points') } + points: { + show: (entity.style == 'points') + } }; series.push(serie); diff --git a/lib/Controller/CapabilitiesController.php b/lib/Controller/CapabilitiesController.php index 1953c97..d953d89 100644 --- a/lib/Controller/CapabilitiesController.php +++ b/lib/Controller/CapabilitiesController.php @@ -26,6 +26,7 @@ namespace Volkszaehler\Controller; use Volkszaehler\Model; use Volkszaehler\Util; use Volkszaehler\View; +use Volkszaehler\Definition; /** * Capabilities controller @@ -67,8 +68,8 @@ class CapabilitiesController extends Controller { $this->view->setCaching('expires', time()+2*7*24*60*60); // cache for 2 weeks } - $capabilities['definitions']['entities'] = \Volkszaehler\Definition\EntityDefinition::getJSON(); - $capabilities['definitions']['properties'] = \Volkszaehler\Definition\PropertyDefinition::getJSON(); + $capabilities['definitions']['entities'] = Definition\EntityDefinition::get(); + $capabilities['definitions']['properties'] = Definition\PropertyDefinition::get(); } if (count($capabilities) == 0) { diff --git a/lib/Definition/Definition.php b/lib/Definition/Definition.php index 661d940..bc2686d 100644 --- a/lib/Definition/Definition.php +++ b/lib/Definition/Definition.php @@ -33,12 +33,12 @@ abstract class Definition { /** * @var string discriminator for database column */ - protected $name; + public $name; /** * @var string title for UI */ - protected $translation; + public $translation; /** * Hide default constructor @@ -69,7 +69,7 @@ abstract class Definition { } if (is_null($name)) { - return static::$definitions; + return array_values(static::$definitions); } elseif (static::exists($name)) { return static::$definitions[$name]; @@ -98,16 +98,14 @@ abstract class Definition { */ protected static function load() { static::$definitions = array(); + + $json = Util\JSON::decode(file_get_contents(VZ_DIR . static::FILE)); - foreach (self::getJSON() as $property) { + foreach ($json as $property) { static::$definitions[$property->name] = new static($property); } } - public static function getJSON() { - return Util\JSON::decode(file_get_contents(VZ_DIR . static::FILE)); - } - /* * Setter & Getter */ diff --git a/lib/Definition/EntityDefinition.json b/lib/Definition/EntityDefinition.json index 6c5392e..8ceb69b 100644 --- a/lib/Definition/EntityDefinition.json +++ b/lib/Definition/EntityDefinition.json @@ -28,8 +28,6 @@ [ { "name" : "group", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "tolerance", "public"], "icon" : "folder.png", "interpreter" : "Volkszaehler\\Interpreter\\AggregatorInterpreter", "model" : "Volkszaehler\\Model\\Aggregator", @@ -41,8 +39,6 @@ }, { "name" : "user", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "tolerance", "public"], "icon" : "user.png", "interpreter" : "Volkszaehler\\Interpreter\\AggregatorInterpreter", "model" : "Volkszaehler\\Model\\Aggregator", @@ -54,8 +50,6 @@ }, { "name" : "building", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "tolerance", "public"], "icon" : "house.png", "interpreter" : "Volkszaehler\\Interpreter\\AggregatorInterpreter", "model" : "Volkszaehler\\Model\\Aggregator", @@ -67,8 +61,8 @@ }, { "name" : "power", - "required" : ["title", "resolution"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "cost", "public", "local"], + "required" : ["resolution"], + "optional" : ["tolerance", "cost", "local"], "icon" : "bolt.png", "unit" : "W", "interpreter" : "Volkszaehler\\Interpreter\\MeterInterpreter", @@ -81,11 +75,11 @@ }, { "name" : "powersensor", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "cost", "local"], "icon" : "bolt.png", "unit" : "W", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", + "style" : "steps", "model" : "Volkszaehler\\Model\\Channel", "translation" : { "de" : "Stromsensor", @@ -95,8 +89,8 @@ }, { "name" : "gas", - "required" : ["title", "resolution"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "cost", "public", "local"], + "required" : ["resolution"], + "optional" : ["tolerance", "cost", "local"], "icon" : "flame.png", "unit" : "m³/h", "interpreter" : "Volkszaehler\\Interpreter\\MeterInterpreter", @@ -109,8 +103,8 @@ }, { "name" : "water", - "required" : ["title", "resolution"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "cost", "public", "local"], + "required" : ["resolution"], + "optional" : ["tolerance", "cost", "local"], "icon" : "waterdrop.png", "unit" : "l/h", "interpreter" : "Volkszaehler\\Interpreter\\MeterInterpreter", @@ -123,8 +117,7 @@ }, { "name" : "temperature", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "local"], "icon" : "thermometer.png", "unit" : "°C", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -137,8 +130,7 @@ }, { "name" : "pressure", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "local"], "icon" : "cloud.png", "unit" : "hPa", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -151,8 +143,7 @@ }, { "name" : "humidity", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "local"], "icon" : "rain.png", "unit" : "%", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -165,8 +156,7 @@ }, { "name" : "windspeed", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "local"], "icon" : "propeller.png", "unit" : "km/h", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -179,8 +169,7 @@ }, { "name" : "radiation", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "resolution", "public", "local"], + "optional" : ["tolerance", "local", "resolution"], "icon" : "radioactivity.png", "unit" : "μSv", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -193,8 +182,7 @@ }, { "name" : "luminosity", - "required" : ["title"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "optional" : ["tolerance", "local"], "icon" : "sun.png", "unit" : "cd", "interpreter" : "Volkszaehler\\Interpreter\\SensorInterpreter", @@ -207,8 +195,8 @@ }, { "name" : "workinghours", - "required" : ["title", "resolution"], - "optional" : ["description", "details:", "owner:", "address:", "tolerance", "public", "local"], + "required" : ["resolution"], + "optional" : ["tolerance", "local"], "icon" : "clock.png", "unit" : "h", "interpreter" : "Volkszaehler\\Interpreter\\MeterInterpreter", diff --git a/lib/Definition/EntityDefinition.php b/lib/Definition/EntityDefinition.php index 4af9dea..43d564c 100644 --- a/lib/Definition/EntityDefinition.php +++ b/lib/Definition/EntityDefinition.php @@ -42,46 +42,72 @@ class EntityDefinition extends Definition { * * @var array */ - protected $required = array(); + public $required = array(); /** * List of optional properties * * @var array */ - protected $optional = array(); + public $optional = array(); /** * Classname of intepreter (see lib/Interpreter/) * * @var string */ - protected $interpreter; + public $interpreter; + + /** + * Style for plotting + * + * @var string (lines|points|steps) + */ + public $style; /** * Classname of model (see lib/Model/) * * @var string */ - protected $model; + public $model; /** * Optional for Aggregator class entities * * @var string */ - protected $unit; + public $unit; /** * Relative url to an icon * @var string */ - protected $icon; + public $icon; /** * @var array holds definitions */ protected static $definitions = NULL; + + /** + * Properties required/optional by default for all Entity types + * @var array + */ + static protected $defaultRequired = array('title'); + static protected $defaultOptional = array('description', 'public', 'color', 'active', 'style', 'details:', 'owner:', 'address:', 'link'); + + /** + * Constructor + * + * Adding default properties + */ + protected function __construct($object) { + parent::__construct($object); + + $this->required = array_merge($this->required, self::$defaultRequired); + $this->optional = array_merge($this->optional, self::$defaultOptional); + } /* * Setter & Getter diff --git a/lib/Definition/PropertyDefinition.json b/lib/Definition/PropertyDefinition.json index a7607b2..9b0bd3c 100644 --- a/lib/Definition/PropertyDefinition.json +++ b/lib/Definition/PropertyDefinition.json @@ -52,22 +52,6 @@ "en" : "Public" } }, - { - "name" : "active", - "type" : "boolean", - "translation" : { - "de" : "Aktiv", - "en" : "Active" - } - }, - { - "name" : "local", - "type" : "string", - "translation" : { - "de" : "Lokale Adresse", - "en" : "Local Address" - } - }, { "name" : "cost", "type" : "float", @@ -366,5 +350,62 @@ "de" : "Hyperlink", "en" : "Hyperlink" } + }, + { + "name" : "active", + "type" : "boolean", + "translation" : { + "de" : "Aktiv", + "en" : "Active" + } + }, + { + "name" : "color", + "type" : "multiple", + "options" : [ + "aqua", + "black", + "blue", + "fuchsia", + "gray", + "grey", + "green", + "lime", + "maroon", + "navy", + "olive", + "purple", + "red", + "silver", + "teal", + "white", + "yellow" + ], + "translation" : { + "de" : "Farbe", + "en" : "color" + } + }, + { + "name" : "style", + "type" : "multiple", + "options" : [ + "lines", + "steps", + "points" + ], + "translation" : { + "de" : "Style", + "en" : "Plotting style" + } + }, + { + "name" : "local", + "type" : "string", + "pattern" : "\/^(http?|ftp):\/\/[a-z0-9-.]+\\.[a-z]{2,6}(\/\\S*)?$\/i", // url + "translation" : { + "de" : "Lokale Adresse", + "en" : "Local Address" + } } ] diff --git a/lib/Definition/PropertyDefinition.php b/lib/Definition/PropertyDefinition.php index 177e566..894e016 100644 --- a/lib/Definition/PropertyDefinition.php +++ b/lib/Definition/PropertyDefinition.php @@ -40,14 +40,14 @@ class PropertyDefinition extends Definition { * * @var string */ - protected $type; + public $type; /** * Regex pattern to match if type == string * * @var string */ - protected $pattern; + public $pattern; /** * Minimal value if type == integer or type == float @@ -55,7 +55,7 @@ class PropertyDefinition extends Definition { * * @var integer|float */ - protected $min; + public $min; /** * Maximal value if type == integer or type == float @@ -63,7 +63,7 @@ class PropertyDefinition extends Definition { * * @var integer|float */ - protected $max; + public $max; /** * List of possible choices if type == multiple @@ -71,7 +71,7 @@ class PropertyDefinition extends Definition { * * @var array */ - protected $options = array(); + public $options = array(); /** * @var array holds definitions