From c9b2b5778d0b614e71d622b249363b8eb3806704 Mon Sep 17 00:00:00 2001
From: Markus Grigull
Date: Thu, 22 Oct 2015 14:17:39 -0400
Subject: [PATCH] Add control of data flow through context broker
---
app/adapters/application.js | 22 +-
app/controllers/lab-mashup.js | 51 +++-
app/models/data-file-control.js | 7 +
app/routes/lab-mashup.js | 10 +
app/serializers/application.js | 264 ++++++++++++--------
app/templates/lab-mashup.hbs | 2 +-
tests/unit/models/data-file-control-test.js | 12 +
7 files changed, 263 insertions(+), 105 deletions(-)
create mode 100644 app/models/data-file-control.js
create mode 100644 tests/unit/models/data-file-control-test.js
diff --git a/app/adapters/application.js b/app/adapters/application.js
index dc78fa0..815c08e 100644
--- a/app/adapters/application.js
+++ b/app/adapters/application.js
@@ -15,7 +15,12 @@ export default DS.RESTAdapter.extend({
type: 'ElectricalGridMonitoring',
isPattern: true,
id: 'S?_ElectricalGrid'
- }
+ },
+ {
+ type: 'DataFileControl',
+ isPattern: false,
+ id: 'DataFileControl'
+ }
]
};
@@ -29,7 +34,12 @@ export default DS.RESTAdapter.extend({
type: 'ElectricalGridMonitoring',
isPattern: false,
id: id
- }
+ },
+ {
+ type: 'DataFileControl',
+ isPattern: false,
+ id: 'DataFileControl'
+ }
]
};
@@ -41,6 +51,14 @@ export default DS.RESTAdapter.extend({
},
updateRecord: function(store, type, snapshot) {
+ var requestBody = {};
+ var serializer = store.serializerFor(type.modelName);
+
+ serializer.serializeIntoHash(requestBody, type, snapshot);
+ console.log(requestBody);
+ var url = this.host + '/' + this.namespace + '/updateContext';
+
+ return this.ajax(url, 'POST', { data: requestBody });
}
});
diff --git a/app/controllers/lab-mashup.js b/app/controllers/lab-mashup.js
index fad2de5..bdcb1cd 100644
--- a/app/controllers/lab-mashup.js
+++ b/app/controllers/lab-mashup.js
@@ -2,11 +2,14 @@ import Ember from 'ember';
export default Ember.Controller.extend({
state: 1,
- redZone: [{from: 50, to: 60}],
- yellowZone: [{from: 40, to: 50}],
+ freq575GreenZones: [{from: 49.5, to: 50.5}],
+ freq575YellowZones: [{from: 47.5, to: 49.5}, {from: 50.5, to: 52.5}],
+ freq575RedZones: [{from: 45.0, to: 47.5}, {from: 52.5, to: 55}],
init: function() {
this.set('dataSet', this.get('dataSetOne'));
+
+ this._updateButtons();
},
S1Entity: function() {
@@ -42,6 +45,50 @@ export default Ember.Controller.extend({
return this.get('state') === 2;
}.property('state'),
+ _updateButtons: function() {
+ var control = this.store.peekRecord('data-file-control', 'DataFileControl');
+ var updated = false;
+
+ if (control.get('Filename') === 'm1_S1_ElectricalGrid_data.txt') {
+ if (this.get('state') !== 1) {
+ his.set('state', 1);
+ updated = true;
+ }
+ } else {
+ if (this.get('state') !== 2) {
+ this.set('state', 2);
+ updated = true;
+ }
+ }
+
+ if (control.get('Status') === 'EOF') {
+ if (this.get('state') === 1) {
+ control.set('ForceReload', true);
+ } else {
+ control.set('Filename', 'm1_S1_ElectricalGrid_data.txt');
+ }
+
+ updated = true;
+ }
+
+ if (updated) {
+ control.save();
+ }
+ },
+
+ _updateDataFileControl: function() {
+ var control = this.store.peekRecord('data-file-control', 'DataFileControl');
+
+ if (this.get('state') === 1) {
+ control.set('Filename', 'm1_S1_ElectricalGrid_data.txt');
+ } else {
+ control.set('Filename', 'm2_S1_ElectricalGrid_data.txt');
+ }
+
+ control.set('ForceReload', true);
+ control.save();
+ }.observes('state'),
+
actions: {
resetData: function() {
this.set('state', 1);
diff --git a/app/models/data-file-control.js b/app/models/data-file-control.js
new file mode 100644
index 0000000..0aa02a3
--- /dev/null
+++ b/app/models/data-file-control.js
@@ -0,0 +1,7 @@
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ Filename: DS.attr('string'),
+ ForceReload: DS.attr('boolean'),
+ Status: DS.attr('string')
+});
diff --git a/app/routes/lab-mashup.js b/app/routes/lab-mashup.js
index 8845ccb..ae704f0 100644
--- a/app/routes/lab-mashup.js
+++ b/app/routes/lab-mashup.js
@@ -7,6 +7,11 @@ export default Ember.Route.extend({
id: 'S1_ElectricalGrid',
isPattern: false,
type: ''
+ },
+ {
+ id: 'DataFileControl',
+ isPattern: false,
+ type: 'DataFileControl'
}
]});
//return this.store.findAll('entity');
@@ -26,6 +31,11 @@ export default Ember.Route.extend({
id: 'S1_ElectricalGrid',
isPattern: false,
type: ''
+ },
+ {
+ id: 'DataFileControl',
+ isPattern: false,
+ type: 'DataFileControl'
}
]});
//this.store.findAll('entity');
diff --git a/app/serializers/application.js b/app/serializers/application.js
index 7e18fae..5189860 100644
--- a/app/serializers/application.js
+++ b/app/serializers/application.js
@@ -11,6 +11,8 @@ export default DS.RESTSerializer.extend({
json.data.push(item);
} else if (item.type === 'property') {
_this._updateProperty(item);
+ } else if (item.type === 'data-file-control') {
+ _this._updateDataFileControl(item);
}
return true;
@@ -29,6 +31,8 @@ export default DS.RESTSerializer.extend({
json.data = item;
} else if (item.type === 'property') {
_this._updateProperty(item);
+ } else if (item.type === 'data-file-control') {
+ _this._updateDataFileControl(item);
}
return true;
@@ -47,6 +51,8 @@ export default DS.RESTSerializer.extend({
json.data.push(item);
} else if (item.type === 'property') {
_this._updateProperty(item);
+ } else if (item.type === 'data-file-control') {
+ _this._updateDataFileControl(item);
}
return true;
@@ -55,6 +61,30 @@ export default DS.RESTSerializer.extend({
return json;
},
+ serializeIntoHash: function(hash, typeClass, snapshot, options) {
+ hash.contextElements = [
+ {
+ id: snapshot.id,
+ type: 'DataFileControl',
+ isPattern: false,
+ attributes: []
+ }
+ ];
+ hash.updateAction = "APPEND";
+
+ for (var name in snapshot._attributes) {
+ hash.contextElements[0].attributes.push({
+ name: name,
+ value: snapshot._attributes[name]
+ });
+ }
+ },
+
+ modelNameFromPayloadKey: function(payloadKey) {
+ console.log(payloadKey);
+ return this._super(payloadKey);
+ },
+
_normalizePayload: function(payload, handleItem) {
var propertyIndex = 0;
@@ -63,116 +93,139 @@ export default DS.RESTSerializer.extend({
payload.contextResponses.forEach(function(item) {
// check if item has context element
if (item.contextElement) {
- // create new entity object
- var entity = {
- type: 'entity',
- id: item.contextElement.id,
- attributes: {
- type: item.contextElement.type
- },
- relationships: {
- properties: {
- data: []
- }
- }
- }
-
- if (item.contextElement.attributes) {
- var timestamp = 0;
-
- item.contextElement.attributes.forEach(function(attribute) {
- if (attribute.name === 'timestamp') {
- timestamp = attribute.value;
+ if (item.contextElement.type === 'DataFileControl') {
+ var dataFileControl = {
+ type: 'data-file-control',
+ id: item.contextElement.id,
+ attributes: {
}
- });
+ };
- item.contextElement.attributes.forEach(function(attribute) {
- if (attribute.id !== 'timestamp') {
- // find metadata
- var source = "";
- var minValue;
- var maxValue;
-
- if (attribute.metadatas) {
- attribute.metadatas.forEach(function(metadata) {
- if (metadata.name === 'timestamp') {
- timestamp = Date.parse(metadata.value);
- } else if (metadata.name === 'source') {
- source = metadata.value;
- } else if (metadata.name === 'min') {
- minValue = metadata.value;
- } else if (metadata.name === 'max') {
- maxValue = metadata.value;
- }
- });
+ if (item.contextElement.attributes) {
+ item.contextElement.attributes.forEach(function(attribute) {
+ if (attribute.name === 'Filename') {
+ dataFileControl.attributes.Filename = attribute.value;
+ } else if (attribute.name === 'ForceReload') {
+ dataFileControl.attributes.ForceReload = attribute.value;
+ } else if (attribute.name === 'Status') {
+ dataFileControl.attributes.Status = attribute.value;
}
+ });
+ }
- if (timestamp === 0) {
- timestamp = (new Date()).getTime();
- }
+ handleItem(dataFileControl);
+ } else {
+ // create new entity object
+ var entity = {
+ type: 'entity',
+ id: item.contextElement.id,
+ attributes: {
+ type: item.contextElement.type
+ },
+ relationships: {
+ properties: {
+ data: []
+ }
+ }
+ }
- // create property
- var property = {
- type: 'property',
- id: 'property_' + propertyIndex++,
- attributes: {
- name: attribute.name,
- type: attribute.type,
- timestamp: timestamp,
- visible: false,
- source: source,
- minValue: minValue,
- maxValue: maxValue,
- values: []
- },
- relationships: {
- entity: {
- data: { type: 'entity', id: entity.id }
- }
- }
- }
+ if (item.contextElement.attributes) {
+ var timestamp = 0;
- // add values
- if (attribute.value) {
- if ($.isArray(attribute.value)) {
- attribute.value.forEach(function (value) {
- // fix for second to millisecond
- value[0] = +value[0] * 1000;
-
- property.attributes.values.push(value);
- });
- } else {
- property.attributes.values.push([timestamp, attribute.value]);
- }
- }
+ item.contextElement.attributes.forEach(function(attribute) {
+ if (attribute.name === 'timestamp') {
+ timestamp = attribute.value;
+ }
+ });
- entity.relationships.properties.data.push({ type: 'property', id: property.id });
+ item.contextElement.attributes.forEach(function(attribute) {
+ if (attribute.name !== 'timestamp') {
+ // find metadata
+ var source = "";
+ var minValue;
+ var maxValue;
- handleItem(property);
- } else {
- var category = {
- type: 'category',
- id: 'category_' + propertyIndex++,
- attributes: {
- name: attribute.name,
- },
- relationships: {
- entity: {
- data: { type: 'entity', id: entity.id }
- }
- }
- }
+ if (attribute.metadatas) {
+ attribute.metadatas.forEach(function(metadata) {
+ if (metadata.name === 'timestamp') {
+ timestamp = Date.parse(metadata.value);
+ } else if (metadata.name === 'source') {
+ source = metadata.value;
+ } else if (metadata.name === 'min') {
+ minValue = metadata.value;
+ } else if (metadata.name === 'max') {
+ maxValue = metadata.value;
+ }
+ });
+ }
- handleItem(category);
- }
- });
- }
+ if (timestamp === 0) {
+ timestamp = (new Date()).getTime();
+ }
- // pass entity to caller function
- if (handleItem(entity) == false) {
- // if false returned the caller needs no more entites
- return;
- }
+ // create property
+ var property = {
+ type: 'property',
+ id: 'property_' + propertyIndex++,
+ attributes: {
+ name: attribute.name,
+ type: attribute.type,
+ timestamp: timestamp,
+ visible: false,
+ source: source,
+ minValue: minValue,
+ maxValue: maxValue,
+ values: []
+ },
+ relationships: {
+ entity: {
+ data: { type: 'entity', id: entity.id }
+ }
+ }
+ }
+
+ // add values
+ if (attribute.value) {
+ if ($.isArray(attribute.value)) {
+ attribute.value.forEach(function (value) {
+ // fix for second to millisecond
+ value[0] = +value[0] * 1000;
+
+ property.attributes.values.push(value);
+ });
+ } else {
+ property.attributes.values.push([timestamp, attribute.value]);
+ }
+ }
+
+ entity.relationships.properties.data.push({ type: 'property', id: property.id });
+
+ handleItem(property);
+ } else {
+ var category = {
+ type: 'category',
+ id: 'category_' + propertyIndex++,
+ attributes: {
+ name: attribute.name,
+ },
+ relationships: {
+ entity: {
+ data: { type: 'entity', id: entity.id }
+ }
+ }
+ }
+
+ handleItem(category);
+ }
+ });
+ }
+
+ // pass entity to caller function
+ if (handleItem(entity) == false) {
+ // if false returned the caller needs no more entites
+ return;
+ }
+ }
}
});
}
@@ -193,5 +246,16 @@ export default DS.RESTSerializer.extend({
// add new item
this.store.push(item);
}
+ },
+
+ _updateDataFileControl: function(item) {
+ var record = this.store.peekRecord('data-file-control', item.id);
+ if (record) {
+ record.set('Filename', item.attributes.Filename);
+ record.set('ForceReload', item.attributes.ForceReload);
+ record.set('Status', item.attributes.Status);
+ } else {
+ this.store.push(item);
+ }
}
});
diff --git a/app/templates/lab-mashup.hbs b/app/templates/lab-mashup.hbs
index cfa6b08..3446c90 100644
--- a/app/templates/lab-mashup.hbs
+++ b/app/templates/lab-mashup.hbs
@@ -33,7 +33,7 @@
- {{d3-gauge label="Frequency" value=Freq575Value maxValue=60 minorTicks=4 redZones=redZone yellowZones=yellowZone}}
+ {{d3-gauge label="Frequency" value=Freq575Value minValue=45 maxValue=55 minorTicks=4 greenZones=freq575GreenZones yellowZones=freq575YellowZones redZones=freq575RedZones}}
diff --git a/tests/unit/models/data-file-control-test.js b/tests/unit/models/data-file-control-test.js
new file mode 100644
index 0000000..a3f35ef
--- /dev/null
+++ b/tests/unit/models/data-file-control-test.js
@@ -0,0 +1,12 @@
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('data-file-control', 'Unit | Model | data file control', {
+ // Specify the other units that are required for this test.
+ needs: []
+});
+
+test('it exists', function(assert) {
+ var model = this.subject();
+ // var store = this.store();
+ assert.ok(!!model);
+});
|