From 4a9563f603a44ee0af53415c6627d55b1ecc4cb3 Mon Sep 17 00:00:00 2001 From: Markus Grigull Date: Thu, 21 Jul 2016 08:57:04 +0200 Subject: [PATCH] Add websocket data receiving Very buggy early tests --- app/adapters/simulation-data.js | 108 ++++++++++++++++++ app/models/simulation-data.js | 18 +++ app/routes/simulation-model/edit.js | 3 + app/routes/simulation-model/index.js | 17 ++- app/serializers/simulation-data.js | 23 ++++ app/templates/simulation-model/edit.hbs | 2 +- app/templates/simulation-model/index.hbs | 10 +- app/transforms/array.js | 20 ++++ config/environment.js | 3 +- tests/unit/adapters/simulation-data-test.js | 12 ++ tests/unit/models/simulation-data-test.js | 12 ++ .../unit/serializers/simulation-data-test.js | 15 +++ tests/unit/transforms/array-test.js | 12 ++ 13 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 app/adapters/simulation-data.js create mode 100644 app/models/simulation-data.js create mode 100644 app/serializers/simulation-data.js create mode 100644 app/transforms/array.js create mode 100644 tests/unit/adapters/simulation-data-test.js create mode 100644 tests/unit/models/simulation-data-test.js create mode 100644 tests/unit/serializers/simulation-data-test.js create mode 100644 tests/unit/transforms/array-test.js diff --git a/app/adapters/simulation-data.js b/app/adapters/simulation-data.js new file mode 100644 index 0000000..7fba6e0 --- /dev/null +++ b/app/adapters/simulation-data.js @@ -0,0 +1,108 @@ +/** + * 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/models/simulation-data.js b/app/models/simulation-data.js new file mode 100644 index 0000000..d7af5bc --- /dev/null +++ b/app/models/simulation-data.js @@ -0,0 +1,18 @@ +/** + * 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 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'), + sequence: attr('number'), + values: attr('array') +}); diff --git a/app/routes/simulation-model/edit.js b/app/routes/simulation-model/edit.js index 26d9f31..f2d770f 100644 --- a/app/routes/simulation-model/edit.js +++ b/app/routes/simulation-model/edit.js @@ -1,4 +1,7 @@ import Ember from 'ember'; export default Ember.Route.extend({ + /*model() { + return this.store.findRecord('simulation-data', 0); + }*/ }); diff --git a/app/routes/simulation-model/index.js b/app/routes/simulation-model/index.js index 26d9f31..d520ee0 100644 --- a/app/routes/simulation-model/index.js +++ b/app/routes/simulation-model/index.js @@ -1,4 +1,17 @@ -import Ember from 'ember'; +/** + * File: index.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. + **********************************************************************************/ -export default Ember.Route.extend({ +import Ember from 'ember'; +import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; + +export default Ember.Route.extend(AuthenticatedRouteMixin, { + model(params) { + return this.store.findRecord('simulation-model', params.modelid); + } }); diff --git a/app/serializers/simulation-data.js b/app/serializers/simulation-data.js new file mode 100644 index 0000000..919e22c --- /dev/null +++ b/app/serializers/simulation-data.js @@ -0,0 +1,23 @@ +/** + * 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 c24cd68..8b13789 100644 --- a/app/templates/simulation-model/edit.hbs +++ b/app/templates/simulation-model/edit.hbs @@ -1 +1 @@ -{{outlet}} + diff --git a/app/templates/simulation-model/index.hbs b/app/templates/simulation-model/index.hbs index c24cd68..2c69e6f 100644 --- a/app/templates/simulation-model/index.hbs +++ b/app/templates/simulation-model/index.hbs @@ -1 +1,9 @@ -{{outlet}} +

{{model.name}}

+ +

+ Running: {{#if model.running}} + true + {{else}} + false + {{/if}} +

diff --git a/app/transforms/array.js b/app/transforms/array.js new file mode 100644 index 0000000..7e1093f --- /dev/null +++ b/app/transforms/array.js @@ -0,0 +1,20 @@ +import Ember from 'ember'; +import Transform from 'ember-data/transform'; + +export default Transform.extend({ + deserialize(serialized) { + if (Ember.isArray(serialized)) { + return serialized; + } else { + return []; + } + }, + + serialize(deserialized) { + if (Ember.isArray(deserialized)) { + return deserialized; + } else { + return []; + } + } +}); diff --git a/config/environment.js b/config/environment.js index f359e20..b440274 100644 --- a/config/environment.js +++ b/config/environment.js @@ -14,7 +14,8 @@ module.exports = function(environment) { }, APP: { - API_HOST: 'localhost:3000' + API_HOST: 'localhost:3000', + LIVE_HOST: 'localhost:4000' } }; diff --git a/tests/unit/adapters/simulation-data-test.js b/tests/unit/adapters/simulation-data-test.js new file mode 100644 index 0000000..7a55f5e --- /dev/null +++ b/tests/unit/adapters/simulation-data-test.js @@ -0,0 +1,12 @@ +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/models/simulation-data-test.js b/tests/unit/models/simulation-data-test.js new file mode 100644 index 0000000..8faab14 --- /dev/null +++ b/tests/unit/models/simulation-data-test.js @@ -0,0 +1,12 @@ +import { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('simulation-data', 'Unit | Model | simulation data', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('it exists', function(assert) { + let model = this.subject(); + // let store = this.store(); + assert.ok(!!model); +}); diff --git a/tests/unit/serializers/simulation-data-test.js b/tests/unit/serializers/simulation-data-test.js new file mode 100644 index 0000000..607b2cb --- /dev/null +++ b/tests/unit/serializers/simulation-data-test.js @@ -0,0 +1,15 @@ +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); +}); diff --git a/tests/unit/transforms/array-test.js b/tests/unit/transforms/array-test.js new file mode 100644 index 0000000..372f9af --- /dev/null +++ b/tests/unit/transforms/array-test.js @@ -0,0 +1,12 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('transform:array', 'Unit | Transform | array', { + // 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 transform = this.subject(); + assert.ok(transform); +});