thingsboard-memoizeit

Details

diff --git a/ui/src/app/api/datasource.service.js b/ui/src/app/api/datasource.service.js
index dd1a34f..2792151 100644
--- a/ui/src/app/api/datasource.service.js
+++ b/ui/src/app/api/datasource.service.js
@@ -104,6 +104,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
     var listeners = [];
     var datasourceType = datasourceSubscription.datasourceType;
     var datasourceData = {};
+    var dataSourceOrigData = {};
     var dataKeys = {};
     var subscribers = [];
     var history = datasourceSubscription.subscriptionTimewindow &&
@@ -140,7 +141,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                 }
             } else {
                 if (dataKey.postFuncBody && !dataKey.postFunc) {
-                    dataKey.postFunc = new Function("time", "value", "prevValue", dataKey.postFuncBody);
+                    dataKey.postFunc = new Function("time", "value", "prevValue", "timePrev", "prevOrigValue", dataKey.postFuncBody);
                 }
             }
             if (datasourceType === types.datasourceType.entity || datasourceSubscription.type === types.widgetType.timeseries.value) {
@@ -165,6 +166,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                 };
                 dataKeys[key] = dataKey;
             }
+            dataSourceOrigData = angular.copy(datasourceData);
             dataKey.key = key;
         }
         if (datasourceType === types.datasourceType.function) {
@@ -678,27 +680,36 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                     var dataKey = dataKeyList[keyIndex];
                     var data = [];
                     var prevSeries;
+                    var prevOrigSeries;
                     var datasourceKeyData;
+                    var datasourceOrigKeyData;
                     var update = false;
                     if (realtime) {
                         datasourceKeyData = [];
+                        datasourceOrigKeyData = [];
                     } else {
                         datasourceKeyData = datasourceData[datasourceKey].data;
+                        datasourceOrigKeyData = dataSourceOrigData[datasourceKey].data;
                     }
                     if (datasourceKeyData.length > 0) {
                         prevSeries = datasourceKeyData[datasourceKeyData.length - 1];
+                        prevOrigSeries = datasourceOrigKeyData[datasourceOrigKeyData.length -1];
                     } else {
                         prevSeries = [0, 0];
+                        prevOrigSeries = [0, 0];
                     }
+                    dataSourceOrigData[datasourceKey].data = [];
                     if (datasourceSubscription.type === types.widgetType.timeseries.value) {
                         var series, time, value;
                         for (var i = 0; i < keyData.length; i++) {
                             series = keyData[i];
                             time = series[0];
+                            dataSourceOrigData[datasourceKey].data.push(series);
                             value = convertValue(series[1]);
                             if (dataKey.postFunc) {
-                                value = dataKey.postFunc(time, value, prevSeries[1]);
+                                value = dataKey.postFunc(time, value, prevSeries[1], prevOrigSeries[0], prevOrigSeries[1]);
                             }
+                            prevOrigSeries = series;
                             series = [time, value];
                             data.push(series);
                             prevSeries = series;
@@ -708,9 +719,10 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
                         if (keyData.length > 0) {
                             series = keyData[0];
                             time = series[0];
+                            dataSourceOrigData[datasourceKey].data.push(series);
                             value = convertValue(series[1]);
                             if (dataKey.postFunc) {
-                                value = dataKey.postFunc(time, value, prevSeries[1]);
+                                value = dataKey.postFunc(time, value, prevSeries[1], prevOrigSeries[0], prevOrigSeries[1]);
                             }
                             series = [time, value];
                             data.push(series);
diff --git a/ui/src/app/components/datakey-config.tpl.html b/ui/src/app/components/datakey-config.tpl.html
index f9126e6..ff94f1a 100644
--- a/ui/src/app/components/datakey-config.tpl.html
+++ b/ui/src/app/components/datakey-config.tpl.html
@@ -75,9 +75,16 @@
         </md-checkbox>		
 		<tb-js-func ng-if="model.usePostProcessing"
 		         ng-model="model.postFuncBody"
-				 function-args="{{ ['time', 'value', 'prevValue'] }}"
-				 validation-args="{{ [[1, 1, 1],[1, '1', '1']] }}"
+				 function-args="{{ ['time', 'value', 'prevValue', 'timePrev', 'prevOrigValue'] }}"
+				 validation-args="{{ [[1, 1, 1, 1, 1],[1, '1', '1', 1, '1']] }}"
 				 result-type="any">
 		</tb-js-func>
+		<label ng-if="model.usePostProcessing" class="tb-title" style="margin-left: 15px;">
+			time - {{ 'datakey.time-description' | translate }}</br>
+			value - {{ 'datakey.value-description' | translate }}</br>
+			prevValue - {{ 'datakey.prev-value-description' | translate }}</br>
+			timePrev - {{ 'datakey.time-prev-description' | translate }}</br>
+			prevOrigValue - {{ 'datakey.prev-orig-value-description' | translate }}
+		</label>
 	</section>
 </md-content>
\ No newline at end of file
diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json
index 1fde4b6..9f326c7 100644
--- a/ui/src/app/locale/locale.constant-en_US.json
+++ b/ui/src/app/locale/locale.constant-en_US.json
@@ -555,7 +555,12 @@
         "alarm-fields-required": "Alarm fields are required.",
         "function-types": "Function types",
         "function-types-required": "Function types are required.",
-        "maximum-function-types": "Maximum { count, plural, 1 {1 function type is allowed.} other {# function types are allowed} }"
+        "maximum-function-types": "Maximum { count, plural, 1 {1 function type is allowed.} other {# function types are allowed} }",
+        "time-description": "timestamp of the current value;",
+        "value-description": "the current value;",
+        "prev-value-description": "result of the previous function call;",
+        "time-prev-description": "timestamp of the previous value;",
+        "prev-orig-value-description": "original previous value;"
     },
     "datasource": {
         "type": "Datasource type",