diff --git a/bin/smartdata/Aggregators.php b/bin/smartdata/Aggregators.php index 06b5c6871a4209ae464f751b683d45fd33d0b85b..81e76f1678975ccca27c55977eca1a77798e73a0 100644 --- a/bin/smartdata/Aggregators.php +++ b/bin/smartdata/Aggregators.php @@ -25,6 +25,16 @@ final class Aggregator return new LowerThan($parameters); case 'higherThan': return new HigherThan($parameters); + case 'drift': + return new Drift($parameters); + case 'constantGain': + return new ConstantGain($parameters); + case 'constantBias': + return new ConstantBias($parameters); + case 'stuckAt': + return new StuckAt($parameters); + case 'allAnomalies': + return new AllAnomalies($parameters); case 'confidence': return new Confidence($parameters); case 'can': @@ -131,15 +141,15 @@ class Limit implements iAggregator $this->begin = $this->selected = null; if(isset($parameters->range) && $parameters->range > 0) { $this->range = $parameters->range; - switch ($parameters->name) { - case 'min': $this->limit = Limit::Min; break; - case 'max': $this->limit = Limit::Max; break; - default: - throw (new Exception\CantCreateException()); - break; - } } else { - throw (new Exception\CantCreateException()); + $this->range = 0; + } + switch ($parameters->name) { + case 'min': $this->limit = Limit::Min; break; + case 'max': $this->limit = Limit::Max; break; + default: + throw (new Exception\CantCreateException()); + break; } } @@ -181,7 +191,7 @@ class Mean implements iAggregator if(isset($parameters->range) && $parameters->range > 0) { $this->range = $parameters->range; } else { - throw (new Exception\CantCreateException()); + $this->range = 0; } } @@ -191,7 +201,7 @@ class Mean implements iAggregator if($this->begin == null) { $this->begin = $smartdata->time; } else { - if($smartdata->time > ($this->begin+$this->range)) { + if($smartdata->time >= ($this->begin+$this->range)) { $ret = clone $this->last; $ret->time = (int)($this->begin + $this->last->time)/2; $ret->value = $this->sum/$this->count; @@ -217,7 +227,403 @@ class Mean implements iAggregator private $count; } +class Drift implements iAggregator +{ + public function __construct($parameters) { + $this->begin = null; + $this->count = 0; + + if(isset($parameters->range) && $parameters->range >= 0) { + $this->range = $parameters->range; + } else { + $this->range = 0; + } + if (isset($parameters->parameter)) { + $this->slope = $parameters->parameter; + } else { + $this->slope = 0; + } + if (isset($parameters->offset) && $parameters->offset > 0) { + $this->offset = $parameters->offset; + } else { + $this->offset = 0; + } + if (isset($parameters->spacing) && $parameters->spacing > 0) { + $this->spacing = $parameters->spacing; + } else { + $this->spacing = 0; + } + } + + public function aggregate(SmartData $smartdata) { + $ret = null; + + if($this->begin == null) { + $this->begin = $smartdata->time + $this->offset; + } + if ($this->range === 0 && $smartdata->time >= $this->begin) { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + (float)($this->slope * ($this->count + 1)); + $this->count++; + } else { + if($smartdata->time > ($this->begin+$this->range) || $smartdata->time < $this->begin) { + $ret = clone $smartdata; + $this->count = 0; + if ($this->spacing > 0) { + if ($smartdata->time >= ($this->begin+$this->range+$this->spacing)) { + $this->begin = $smartdata->time; + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + (float)($this->slope * ($this->count + 1)); + $this->count++; + } + } + } else { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + (float)($this->slope * ($this->count + 1)); + $this->count++; + } + } + return $ret; + } + public function finish() { return null; } + + private $range; + private $begin; + private $offset; + private $spacing; + + private $slope; + private $count; +} + +class StuckAt implements iAggregator +{ + public function __construct($parameters) { + $this->begin = null; + $this->count = 0; + + if(isset($parameters->range) && $parameters->range >= 0) { + $this->range = $parameters->range; + $this->value = (float)0; + } else { + $this->range = 0; + $this->value = (float)0; + } + if (isset($parameters->offset) && $parameters->offset > 0) { + $this->offset = $parameters->offset; + } else { + $this->offset = 0; + } + if (isset($parameters->spacing) && $parameters->spacing > 0) { + $this->spacing = $parameters->spacing; + } else { + $this->spacing = 0; + } + } + + public function aggregate(SmartData $smartdata) { + $ret = null; + + if($this->begin == null) { + $this->begin = $smartdata->time + $this->offset; + $this->value = $smartdata->value; + } + if ($this->range === 0 && $smartdata->time >= $this->begin) { + $ret = clone $smartdata; + $ret->value = $this->value; + $this->count++; + } else { + if($smartdata->time > ($this->begin+$this->range) || $smartdata->time < $this->begin) { + $ret = clone $smartdata; + $this->count = 0; + $this->value = $smartdata->value; + if ($this->spacing > 0) { + if ($smartdata->time >= ($this->begin+$this->range+$this->spacing)) { + $this->begin = $smartdata->time; + $ret = clone $smartdata; + $ret->value = $this->value; + $this->count++; + } + } + } else { + $ret = clone $smartdata; + $ret->value = $this->value; + $this->count++; + } + } + + return $ret; + } + + public function finish() { return null; } + + private $range; + private $begin; + private $offset; + private $spacing; + + private $value; + private $count; +} + +class ConstantBias implements iAggregator +{ + public function __construct($parameters) { + $this->begin = null; + $this->count = 0; + if(isset($parameters->range) && $parameters->range > 0) { + $this->range = $parameters->range; + } else { + $this->range = 0; + } + if (isset($parameters->parameter)) { + $this->bias = (float)$parameters->parameter; + } else { + $this->bias = 0; + } + if (isset($parameters->offset) && $parameters->offset > 0) { + $this->offset = $parameters->offset; + } else { + $this->offset = 0; + } + if (isset($parameters->spacing) && $parameters->spacing > 0) { + $this->spacing = $parameters->spacing; + } else { + $this->spacing = 0; + } + } + + public function aggregate(SmartData $smartdata) { + $ret = null; + + if($this->begin == null) { + $this->begin = $smartdata->time + $this->offset; //seting a time window before applying the aggr + } + if ($this->range === 0 && $smartdata->time >= $this->begin) { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + ($this->bias); + $this->count++; + } else { + if($smartdata->time > ($this->begin+$this->range) || $smartdata->time < $this->begin) { + $ret = clone $smartdata; + $this->count = 0; + if ($this->spacing > 0) { + if ($smartdata->time >= ($this->begin+$this->range+$this->spacing)) { + $this->begin = $smartdata->time; + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + ($this->bias); + $this->count++; + } + } + } else { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + ($this->bias); + $this->count++; + } + } + + return $ret; + } + + public function finish() { return null; } + + private $range; + private $begin; + private $offset; + private $spacing; + + private $bias; + private $count; +} + +class ConstantGain implements iAggregator +{ + public function __construct($parameters) { + $this->begin = null; + $this->count = 0; + + if(isset($parameters->range) && $parameters->range > 0) { + $this->range = $parameters->range; + } else { + $this->range = 0; + } + if (isset($parameters->parameter)) { + $this->gain = (float)$parameters->parameter; + } else { + $this->gain = 0; + } + if (isset($parameters->offset) && $parameters->offset > 0) { + $this->offset = $parameters->offset; + } else { + $this->offset = 0; + } + if (isset($parameters->spacing) && $parameters->spacing > 0) { + $this->spacing = $parameters->spacing; + } else { + $this->spacing = 0; + } + } + + public function aggregate(SmartData $smartdata) { + $ret = null; + + if($this->begin == null) { + $this->begin = $smartdata->time + $this->offset; + } + if($this->range === 0 && $smartdata->time >= $this->begin) { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value * ($this->gain); + $this->count++; + } else { + if($smartdata->time > ($this->begin+$this->range) || $smartdata->time < $this->begin) { + $ret = clone $smartdata; + $this->count = 0; + if ($this->spacing > 0) { + if ($smartdata->time > ($this->begin+$this->range+$this->spacing)) { + $this->begin = $smartdata->time; + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value * ($this->gain); + $this->count++; + } + } + } else { + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value * ($this->gain); + $this->count++; + } + } + return $ret; + } + + public function finish() { return null; } + + private $range; + private $begin; + private $offset; + private $spacing; + + private $gain; + private $count; +} + +class AllAnomalies implements iAggregator +{ + public function __construct($parameters) { + $this->begin = null; + $this->count = 0; + $this->applied = 0; + if(isset($parameters->range) && $parameters->range >= 0) { + $this->range = $parameters->range; + } else { + $this->range = 0; + } + if (isset($parameters->drift) && $parameters->drift > 0) { + $this->slope = $parameters->drift; + } else { + $this->slope = 0; + } + if (isset($parameters->stuck) && $parameters->stuck > 0) { + $this->stuck = $parameters->stuck; + } else { + $this->stuck = 0; + } + if (isset($parameters->bias) && $parameters->bias > 0) { + $this->bias = $parameters->bias; + } else { + $this->bias = 0; + } + if (isset($parameters->gain) && $parameters->gain > 0) { + $this->gain = $parameters->gain; + } else { + $this->gain = 0; + } + if (isset($parameters->offset) && $parameters->offset > 0) { + $this->offset = $parameters->offset; + } else { + $this->offset = 0; + } + if (isset($parameters->spacing) && $parameters->spacing > 0) { + $this->spacing = $parameters->spacing; + } else { + $this->spacing = 0; + } + } + + public function aggregate(SmartData $smartdata) { + $ret = null; + + if($this->begin == null) { + $this->begin = $smartdata->time + $this->offset; + } + if($smartdata->time > ($this->begin+$this->range) || $smartdata->time < $this->begin) { + $ret = clone $smartdata; + $this->count = 0; + if($smartdata->time > ($this->begin+$this->range)) { + $this->begin = $smartdata->time + $this->spacing; + $this->applied++; + $this->count = 0; + $this->value = $smartdata->value; + } + } else { + if($this->applied == 0) { + //apply drift + if ($this->slope == 0) { + $this->applied++; + } + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + (float)($this->slope * ($this->count + 1)); + $this->count++; + } + if($this->applied == 1) { + //apply stuckAt + if ($this->stuck == 0) { + $this->applied++; + } + $ret = clone $smartdata; + $ret->value = $this->value; + $this->count++; + } + if($this->applied == 2) { + //apply constantBias + if ($this->bias == 0) { + $this->applied++; + } + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value + ($this->bias); + $this->count++; + } + if($this->applied == 3) { + //apply constantGain + if ($this->gain == 0) { + $this->applied++; + } + $ret = clone $smartdata; + $ret->value = (float)$smartdata->value * ($this->gain); + $this->count++; + } + if ($this->applied > 3) { + $ret = clone $smartdata; + } + } + return $ret; + } + public function finish() { return null; } + + private $range; + private $begin; + private $offset; + private $spacing; + + private $slope; + private $stuck; + private $bias; + private $gain; + private $count; + private $value; + + private $applied; +} diff --git a/lib/grafana/plugin/src/datasource.js b/lib/grafana/plugin/src/datasource.js index ab81dc24b485d5a2a494f4da3ed0ee794fb3431c..7b68fb5230421753f49a5aa0fd7d7a1476c88381 100644 --- a/lib/grafana/plugin/src/datasource.js +++ b/lib/grafana/plugin/src/datasource.js @@ -78,8 +78,8 @@ export class SmartDataDS { request_parameters['aggregator']['parameter'] = parseFloat(options.targets[target_index].aggregatorParameter); //add here the json - if ('aggregatorDelay' in options.targets[target_index] && options.targets[target_index].aggregatorDelay.length && options.targets[target_index].aggregator.length) - request_parameters['aggregator']['delay'] = parseInt(options.targets[target_index].aggregatorDelay); + if ('aggregatorOffset' in options.targets[target_index] && options.targets[target_index].aggregatorOffset.length && options.targets[target_index].aggregator.length) + request_parameters['aggregator']['offset'] = parseInt(options.targets[target_index].aggregatorOffset); if ('aggregatorSpacing' in options.targets[target_index] && options.targets[target_index].aggregatorSpacing.length && options.targets[target_index].aggregator.length) request_parameters['aggregator']['spacing'] = parseFloat(options.targets[target_index].aggregatorSpacing); diff --git a/lib/grafana/plugin/src/partials/query.editor.html b/lib/grafana/plugin/src/partials/query.editor.html index a4d892ce39d9d0158b7b03121bf129720f4e48e5..14f3da332daea46cb1920460fc1f54b262543695 100644 --- a/lib/grafana/plugin/src/partials/query.editor.html +++ b/lib/grafana/plugin/src/partials/query.editor.html @@ -144,15 +144,16 @@ <div class="clearfix"></div> </div> + <div class="gf-form"> <label class="gf-form-label width-6">Aggregator</label> <select class="gf-form-input ng-pristine ng-valid ng-not-empty width-8" - ng-model="ctrl.target.aggregator" ng-options="o for o in ['', 'min', 'mean', 'max', 'dbp', 'lowerThan','higherThan', 'lastValue', 'confidence', 'can', 'drift', 'stuckAt', 'constantGain', 'constantBias', 'allAnomalies']" ng-blur="ctrl.targetBlur()" on-change="ctrl.onChangeInternal()"/> + ng-model="ctrl.target.aggregator" ng-options="o for o in ['', 'min', 'mean', 'max', 'dbp', 'lowerThan','higherThan', 'lastValue', 'confidence', 'can', 'drift', 'stuckAt', 'constantGain', 'constantBias']" ng-blur="ctrl.targetBlur()" on-change="ctrl.onChangeInternal()"/> <label class="gf-form-label width-6">Range</label> - <input type="text" class="input-xxlarge gf-form-input" + <input type="text" class="input-small gf-form-input" ng-model="ctrl.target.aggregatorRange" spellcheck="false" ng-readonly="false" @@ -161,24 +162,17 @@ <label class="gf-form-label width-6">Parameter</label> - <input type="text" class="input-xxlarge gf-form-input" + <input type="text" class="input-small gf-form-input" ng-model="ctrl.target.aggregatorParameter" spellcheck="false" ng-readonly="false" ng-blur="ctrl.targetBlur()" on-change="ctrl.onChangeInternal()"> - <div class="clearfix"></div> - </div> - - <div class="gf-form"> - <!-- - add here the json (text input to the whole json) - --> - <label class="gf-form-label width-6">Delay</label> + <label class="gf-form-label width-6">Offset</label> - <input type="text" class="input-xxlarge gf-form-input" - ng-model="ctrl.target.aggregatorDelay" + <input type="text" class="input-small gf-form-input" + ng-model="ctrl.target.aggregatorOffset" spellcheck="false" ng-readonly="false" ng-blur="ctrl.targetBlur()" @@ -186,7 +180,7 @@ <label class="gf-form-label width-6">Spacing</label> - <input type="text" class="input-xxlarge gf-form-input" + <input type="text" class="input-small gf-form-input" ng-model="ctrl.target.aggregatorSpacing" spellcheck="false" ng-readonly="false" @@ -197,48 +191,8 @@ </div> - - <!-- <div class="gf-form"> - <label class="gf-form-label width-6">Drift</label> - - <input type="text" class="input-xxlarge gf-form-input" - ng-model="ctrl.target.aggregatorDrift" - spellcheck="false" - ng-readonly="false" - ng-blur="ctrl.targetBlur()" - on-change="ctrl.onChangeInternal()"> - - <label class="gf-form-label width-6">Stuck</label> - - <input type="text" class="input-xxlarge gf-form-input" - ng-model="ctrl.target.aggregatorStuck" - spellcheck="false" - ng-readonly="false" - ng-blur="ctrl.targetBlur()" - on-change="ctrl.onChangeInternal()"> - - <label class="gf-form-label width-6">Bias</label> - - <input type="text" class="input-xxlarge gf-form-input" - ng-model="ctrl.target.aggregatorBias" - spellcheck="false" - ng-readonly="false" - ng-blur="ctrl.targetBlur()" - on-change="ctrl.onChangeInternal()"> - - <label class="gf-form-label width-6">Gain</label> - - <input type="text" class="input-xxlarge gf-form-input" - ng-model="ctrl.target.aggregatorGain" - spellcheck="false" - ng-readonly="false" - ng-blur="ctrl.targetBlur()" - on-change="ctrl.onChangeInternal()"> - <div class="clearfix"></div> - </div> --> - <div class="gf-form"> - <label class="gf-form-label width-6">Extra</label> + <label class="gf-form-label width-6">Aggregators Extra</label> <input type="text" class="input-xxlarge gf-form-input" ng-model="ctrl.target.aggregatorExtra" diff --git a/lib/grafana/plugin/src/query_ctrl.js b/lib/grafana/plugin/src/query_ctrl.js index b6f60125dfce58fbf115ba676f04e29e24c12ecb..9d02d80e62fe4af31d73fa8a8ee51f002bc2662b 100644 --- a/lib/grafana/plugin/src/query_ctrl.js +++ b/lib/grafana/plugin/src/query_ctrl.js @@ -24,7 +24,7 @@ export class SmartDataDSQueryCtrl extends QueryCtrl { this.target.aggregator = this.target.aggregator || ''; this.target.aggregatorRange = this.target.aggregatorRange || ''; this.target.aggregatorParameter = this.target.aggregatorParameter || ''; - this.target.aggregatorDelay = this.target.aggregatorDelay || ''; + this.target.aggregatorOffset = this.target.aggregatorOffset || ''; this.target.aggregatorSpacing = this.target.aggregatorSpacing || ''; this.target.aggregatorExtra = this.target.aggregatorExtra || ''; // this.target.aggregatorDrift = this.target.aggregatorDrift || '';