diff --git a/app/adapters/simulation-data.js b/app/adapters/simulation-data.js deleted file mode 100644 index 7fba6e0..0000000 --- a/app/adapters/simulation-data.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * File: simulation-data.js - * Author: Markus Grigull - * Date: 20.07.2016 - * Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ - -import Ember from 'ember'; -import DS from 'ember-data'; -import ENV from '../config/environment'; - -export default DS.Adapter.extend({ - host: 'ws://' + ENV.APP.LIVE_HOST, - namespace: '', - - socket: null, - - findRecord(store, type, id, snapshot) { - this._init(); - - return new Ember.RSVP.Promise(function(resolve, reject) { - //reject(new Error('no record')); - reject(); - }); - }, - - _init() { - if (this.socket === null) { - // create new websocket - this.socket = new WebSocket(this.host + this.namespace); - this.socket.binaryType = 'arraybuffer'; - - // register event callbacks - var self = this; - this.socket.onopen = function(event) { - self.open.apply(self, [event]); - }; - - this.socket.onmessage = function(event) { - self.message.apply(self, [event]); - }; - - this.socket.onerror = function(event) { - self.error.apply(self, [event]); - }; - - this.socket.onclose = function(event) { - self.close.apply(self, [event]); - }; - } - }, - - open(event) { - Ember.debug('websocket opened'); - }, - - close(event) { - Ember.debug('websocket closed: ' + event.code); - }, - - message(event) { - // read the message into JSON - var message = this._messageToJSON(event.data); - var id = 0; - - var simulationData = this.store.peekRecord('simulation-data', id); - if (simulationData != null) { - simulationData.set('sequence', message.sequence); - simulationData.set('values', message.values); - } else { - this.store.createRecord('simulation-data', { - sequence: message.sequence, - values: message.values, - id: id - }); - } - }, - - error(err) { - Ember.debug('websocket error'); - }, - - _messageToJSON(blob) { - var data = new DataView(blob); - - let OFFSET_ENDIAN = 1; - let OFFSET_TYPE = 2; - let OFFSET_VERSION = 4; - - var bits = data.getUint8(0); - var endian = (bits >> OFFSET_ENDIAN) & 0x1 ? 0 : 1; - var length = data.getUint16(0x02, endian); - - var values = new Float32Array(data.buffer, data.byteOffset + 0x10, length); - - return { - endian: endian, - version: (bits >> OFFSET_VERSION) & 0xF, - type: (bits >> OFFSET_TYPE) & 0x3, - length: length, - sequence: data.getUint32(0x04, endian), - timestamp: data.getUint32(0x08, endian) * 1e3 + data.getUint32(0x0C, endian) * 1e-6, - values: values - }; - } -}); diff --git a/app/controllers/simulation-model/edit.js b/app/controllers/simulation-model/edit.js index 55ff9aa..e38e81d 100644 --- a/app/controllers/simulation-model/edit.js +++ b/app/controllers/simulation-model/edit.js @@ -1,4 +1,21 @@ import Ember from 'ember'; export default Ember.Controller.extend({ + sequence: function() { + return this.get('model.sequence'); + }.property('model.sequence'), + + values: function() { + return this.get('model.values'); + }.property('model.values.@each'), + + _updateModel: function() { + if (this.get('model') === null) { + Ember.run.later(this, function() { + var simulationData = this.store.peekRecord('simulation-data', 1); + this.set('model', simulationData); + this.notifyPropertyChange('model'); + }, 500); + } + }.observes('model').on('init') }); diff --git a/app/mixins/websocket-live-stream-mixin.js b/app/mixins/websocket-live-stream-mixin.js new file mode 100644 index 0000000..eaaf392 --- /dev/null +++ b/app/mixins/websocket-live-stream-mixin.js @@ -0,0 +1,77 @@ +import Ember from 'ember'; +import ENV from '../config/environment'; + +export default Ember.Mixin.create({ + host: 'ws://' + ENV.APP.LIVE_HOST, + namespace: '', + + init() { + this._super(...arguments); + + // create socket + var socket = new WebSocket(this.host + this.namespace); + socket.binaryType = 'arraybuffer'; + + // register event callbacks + var self = this; + socket.onopen = function(event) { self.onopen.apply(self, [event]); }; + socket.onclose = function(event) { self.onclose.apply(self, [event]); }; + socket.onmessage = function(event) { self.onmessage.apply(self, [event]); }; + socket.onerror = function(event) { self.onerror.apply(self, [event]); }; + }, + + onopen(event) { + Ember.debug('websocket opened'); + }, + + onclose(event) { + Ember.debug('websocket closed: ' + event.code); + }, + + onmessage(event) { + // read the message into JSON + var message = this._messageToJSON(event.data); + + var simulationData = this.store.peekRecord('simulation-data', message.simulator); + if (simulationData != null) { + simulationData.set('sequence', message.sequence); + simulationData.set('values', message.values); + } else { + this.store.createRecord('simulation-data', { + sequence: message.sequence, + values: message.values, + id: message.simulator + }); + } + }, + + onerror(event) { + Ember.debug('websocket error'); + }, + + _messageToJSON(blob) { + var data = new DataView(blob); + + let OFFSET_ENDIAN = 1; + let OFFSET_TYPE = 2; + let OFFSET_VERSION = 4; + + var bits = data.getUint8(0); + var simulator = data.getUint8(0x01); + var endian = (bits >> OFFSET_ENDIAN) & 0x1 ? 0 : 1; + var length = data.getUint16(0x02, endian); + + var values = new Float32Array(data.buffer, data.byteOffset + 0x10, length); + + return { + endian: endian, + version: (bits >> OFFSET_VERSION) & 0xF, + type: (bits >> OFFSET_TYPE) & 0x3, + length: length, + sequence: data.getUint32(0x04, endian), + timestamp: data.getUint32(0x08, endian) * 1e3 + data.getUint32(0x0C, endian) * 1e-6, + values: values, + simulator: simulator + }; + } +}); diff --git a/app/models/simulation-data.js b/app/models/simulation-data.js index d7af5bc..b5cffe8 100644 --- a/app/models/simulation-data.js +++ b/app/models/simulation-data.js @@ -7,12 +7,26 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ +import Ember from 'ember'; import Model from 'ember-data/model'; import attr from 'ember-data/attr'; // import { belongsTo, hasMany } from 'ember-data/relationships'; export default Model.extend({ - simulator: attr('number'), + simulator: Ember.computed.alias('id'), sequence: attr('number'), - values: attr('array') + values: attr('array'), + + historyValues() { + return this._history; + }, + + _history: [], + + _updateHistory: function() { + this._history.unshift(this.get('values')); + while (this._history.length > 500) { + this._history.shift(); + } + }.observes('values') }); diff --git a/app/routes/index.js b/app/routes/index.js index e4d4e02..ab4ab0a 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -9,6 +9,7 @@ import Ember from 'ember'; import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; +import WebsocketLiveStreamMixin from '../mixins/websocket-live-stream-mixin'; -export default Ember.Route.extend(AuthenticatedRouteMixin, { +export default Ember.Route.extend(AuthenticatedRouteMixin, WebsocketLiveStreamMixin, { }); diff --git a/app/routes/simulation-model/edit.js b/app/routes/simulation-model/edit.js index f2d770f..992b1b1 100644 --- a/app/routes/simulation-model/edit.js +++ b/app/routes/simulation-model/edit.js @@ -1,7 +1,7 @@ import Ember from 'ember'; export default Ember.Route.extend({ - /*model() { - return this.store.findRecord('simulation-data', 0); - }*/ + model() { + return this.store.peekRecord('simulation-data', 1); + } }); diff --git a/app/serializers/simulation-data.js b/app/serializers/simulation-data.js deleted file mode 100644 index 919e22c..0000000 --- a/app/serializers/simulation-data.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * File: simulation-data.js - * Author: Markus Grigull - * Date: 20.07.2016 - * Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ - -import Ember from 'ember'; -import DS from 'ember-data'; - -export default DS.Serializer.extend({ - normalizeResponse(store, primaryModelClass, payload, id, requestType) { - console.log('normalizeResponse'); - return {}; - }, - - serialize(record, options) { - console.log('serialize'); - return null; - } -}); diff --git a/app/templates/simulation-model/edit.hbs b/app/templates/simulation-model/edit.hbs index 8b13789..5db3453 100644 --- a/app/templates/simulation-model/edit.hbs +++ b/app/templates/simulation-model/edit.hbs @@ -1 +1,8 @@ +{{sequence}} +
+ +{{#each values as |value|}} + {{value}} +
+{{/each}} diff --git a/tests/unit/adapters/simulation-data-test.js b/tests/unit/adapters/simulation-data-test.js deleted file mode 100644 index 7a55f5e..0000000 --- a/tests/unit/adapters/simulation-data-test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { moduleFor, test } from 'ember-qunit'; - -moduleFor('adapter:simulation-data', 'Unit | Adapter | simulation data', { - // Specify the other units that are required for this test. - // needs: ['serializer:foo'] -}); - -// Replace this with your real tests. -test('it exists', function(assert) { - let adapter = this.subject(); - assert.ok(adapter); -}); diff --git a/tests/unit/mixins/websocket-live-stream-mixin-test.js b/tests/unit/mixins/websocket-live-stream-mixin-test.js new file mode 100644 index 0000000..7cc9580 --- /dev/null +++ b/tests/unit/mixins/websocket-live-stream-mixin-test.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; +import WebsocketLiveStreamMixinMixin from 'villasweb-frontend/mixins/websocket-live-stream-mixin'; +import { module, test } from 'qunit'; + +module('Unit | Mixin | websocket live stream mixin'); + +// Replace this with your real tests. +test('it works', function(assert) { + let WebsocketLiveStreamMixinObject = Ember.Object.extend(WebsocketLiveStreamMixinMixin); + let subject = WebsocketLiveStreamMixinObject.create(); + assert.ok(subject); +}); diff --git a/tests/unit/serializers/simulation-data-test.js b/tests/unit/serializers/simulation-data-test.js deleted file mode 100644 index 607b2cb..0000000 --- a/tests/unit/serializers/simulation-data-test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { moduleForModel, test } from 'ember-qunit'; - -moduleForModel('simulation-data', 'Unit | Serializer | simulation data', { - // Specify the other units that are required for this test. - needs: ['serializer:simulation-data'] -}); - -// Replace this with your real tests. -test('it serializes records', function(assert) { - let record = this.subject(); - - let serializedRecord = record.serialize(); - - assert.ok(serializedRecord); -});