mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-30 00:00:13 +01:00
Add live data flow from visualization to plots
Fix live-data mixin
This commit is contained in:
parent
f2d494a1b0
commit
59c9438ce1
10 changed files with 140 additions and 90 deletions
|
@ -19,8 +19,9 @@ export default Ember.Component.extend(Resizable, Draggable, {
|
|||
plot: null,
|
||||
editing: false,
|
||||
grid: false,
|
||||
data: null,
|
||||
|
||||
simulator: 0,
|
||||
simulator: 0
|
||||
|
||||
disabled_resize: false,
|
||||
autoHide_resize: false,
|
||||
|
|
|
@ -17,6 +17,7 @@ export default Ember.Component.extend({
|
|||
plots: null,
|
||||
editing: false,
|
||||
grid: true,
|
||||
data: null,
|
||||
|
||||
style: function() {
|
||||
var height = this._calculateHeight();
|
||||
|
@ -27,6 +28,10 @@ export default Ember.Component.extend({
|
|||
return Ember.String.htmlSafe('height: ' + height + 'px;');
|
||||
}.property('plots.@each.height', 'plots.@each.y'),
|
||||
|
||||
_value: function() {
|
||||
console.log(this.get('data'));
|
||||
}.property('data.2.values.@each'),
|
||||
|
||||
_calculateHeight() {
|
||||
var maxHeight = 0;
|
||||
var plots = this.get('plots');
|
||||
|
|
|
@ -13,5 +13,21 @@ export default PlotAbstract.extend({
|
|||
classNames: [ 'plotValue' ],
|
||||
|
||||
minWidth_resize: 50,
|
||||
minHeight_resize: 20
|
||||
minHeight_resize: 20,
|
||||
|
||||
simulator: 2,
|
||||
signal: 1,
|
||||
|
||||
value: function() {
|
||||
// get all values for the choosen simulator
|
||||
let values = this.get('data.' + this.get('simulator') + '.values');
|
||||
if (values) {
|
||||
return values[this.get('signal')];
|
||||
}
|
||||
|
||||
// values is null, try to reload later
|
||||
Ember.run.later(this, function() {
|
||||
this.notifyPropertyChange('data.' + this.get('simulator') + '.values');
|
||||
}, 1000);
|
||||
}.property('data.2.values')
|
||||
});
|
||||
|
|
|
@ -10,4 +10,65 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
data: {},
|
||||
|
||||
/*values: function() {
|
||||
console.log('update');
|
||||
return this.get('data');
|
||||
}.property('data.2.values'),*/
|
||||
|
||||
_getData: function() {
|
||||
// check if simulation is running
|
||||
let self = this;
|
||||
|
||||
this.get('model.project').then((project) => {
|
||||
project.get('simulation').then((simulation) => {
|
||||
if (simulation.get('running')) {
|
||||
// get all models to access data
|
||||
simulation.get('models').then((simulationModels) => {
|
||||
simulationModels.forEach(function(simulationModel) {
|
||||
// get simulator
|
||||
simulationModel.get('simulator').then((simulator) => {
|
||||
let simulatorID = simulator.get('simulatorid');
|
||||
if (simulatorID) {
|
||||
// add simulation data to list
|
||||
self._loadDataForSimulator(simulatorID);
|
||||
} else {
|
||||
Ember.debug('undefined simulator id');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// clear simulation data
|
||||
this.set('data', {});
|
||||
|
||||
//Ember.debug('Simulation not running');
|
||||
|
||||
// check again if simulation is running
|
||||
Ember.run.later(this, function() {
|
||||
// trigger _getData observer
|
||||
this.notifyPropertyChange('model');
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}.observes('model'),
|
||||
|
||||
_loadDataForSimulator(simulatorID) {
|
||||
// get data by simulator id
|
||||
let simulationData = this.store.peekRecord('simulation-data', simulatorID);
|
||||
if (simulationData) {
|
||||
// add data to list
|
||||
this.get('data')[simulatorID] = simulationData;
|
||||
|
||||
// notify object for property changes
|
||||
this.notifyPropertyChange('data.' + simulatorID + '.values');
|
||||
} else {
|
||||
// try to load data later
|
||||
Ember.run.later(this, function() {
|
||||
this._loadDataForSimulator(simulatorID);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@ export default Ember.Mixin.create({
|
|||
|
||||
INTERVAL: 5000,
|
||||
|
||||
_sockets: [],
|
||||
_sockets: {},
|
||||
|
||||
init: function() {
|
||||
this._super();
|
||||
|
@ -36,79 +36,79 @@ export default Ember.Mixin.create({
|
|||
_fetchRunningSimulations: function() {
|
||||
// check if the user is logged in
|
||||
if (this.get('sessionUser.user') != null) {
|
||||
// load simulators
|
||||
// get all simulations to find all running ones
|
||||
var self = this;
|
||||
|
||||
this.get('store').findAll('simulator').then(function() {
|
||||
// get all simulations to find all running ones
|
||||
self.get('store').findAll('simulation').then(function(simulations) {
|
||||
simulations.forEach(function(simulation) {
|
||||
// check if the simulation is running
|
||||
if (simulation.get('running')) {
|
||||
// get all models
|
||||
simulation.get('models').forEach(function(model) {
|
||||
self.get('store').findRecord('simulation-model', model.get('id')).then(function(m) {
|
||||
self._addSocket(m);
|
||||
});
|
||||
this.get('store').findAll('simulation').then(function(simulations) {
|
||||
simulations.forEach(function(simulation) {
|
||||
// check if the simulation is running
|
||||
if (simulation.get('running')) {
|
||||
// get all models for this simulation
|
||||
simulation.get('models').then((models) => {
|
||||
models.forEach(function(simulationModel) {
|
||||
self._addSocket(simulationModel);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_addSocket(simulationModel) {
|
||||
// search for existing socket
|
||||
var length = this.get('_sockets').length;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (this.get('_sockets')[i].id === simulationModel.get('id')) {
|
||||
// dont do anything
|
||||
return;
|
||||
}
|
||||
// check if socket is already open
|
||||
let id = simulationModel.get('id');
|
||||
if (this.get('_sockets')[id] !== undefined) {
|
||||
//Ember.debug('skip ' + simulationModel.get('name'));
|
||||
return;
|
||||
}
|
||||
|
||||
// add new socket
|
||||
var socket = new WebSocket('ws://' + simulationModel.get('simulator.endpoint'));
|
||||
socket.binaryType = 'arraybuffer';
|
||||
// get simulator endpoint
|
||||
simulationModel.get('simulator').then((simulator) => {
|
||||
// get simulator endpoint
|
||||
let endpoint = simulator.get('endpoint');
|
||||
if (endpoint) {
|
||||
// add new socket
|
||||
let socket = new WebSocket('ws://' + endpoint);
|
||||
socket.binaryType = 'arraybuffer';
|
||||
|
||||
// register callbacks
|
||||
var self = this;
|
||||
// register callbacks
|
||||
let self = this;
|
||||
|
||||
socket.onopen = function(event) { self._onSocketOpen.apply(self, [event]); };
|
||||
socket.onclose = function(event) { self._onSocketClose.apply(self, [event]); };
|
||||
socket.onmessage = function(event) { self._onSocketMessage.apply(self, [event]); };
|
||||
socket.onerror = function(event) { self._onSocketError.apply(self, [event]); };
|
||||
socket.onopen = function(event) { self._onSocketOpen.apply(self, [event]); };
|
||||
socket.onclose = function(event) { self._onSocketClose.apply(self, [event]); };
|
||||
socket.onmessage = function(event) { self._onSocketMessage.apply(self, [event]); };
|
||||
socket.onerror = function(event) { self._onSocketError.apply(self, [event]); };
|
||||
|
||||
this.get('_sockets').pushObject({ id: simulationModel.get('id'), socket: socket });
|
||||
// add socket to list of known sockets
|
||||
this.get('_sockets')[id] = socket;
|
||||
|
||||
console.log('Socket created for ' + simulationModel.get('name') + ': ws://' + simulationModel.get('simulator.endpoint'));
|
||||
//Ember.debug('Socket created for ' + simulationModel.get('name') + ': ws://' + endpoint);
|
||||
} else {
|
||||
Ember.debug('Undefined endpoint for ' + simulationModel.get('name'));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_removeSocket(socket) {
|
||||
var length = this.get('_sockets').length;
|
||||
var i = 0;
|
||||
// search through all sockets
|
||||
let sockets = this.get('_sockets');
|
||||
|
||||
while (i < length) {
|
||||
if (this.get('_sockets')[i].socket === socket) {
|
||||
// remove object from array
|
||||
this.get('_sockets').slice(i, 1);
|
||||
console.log('socket removed');
|
||||
} else {
|
||||
// increase index if no object was removed
|
||||
i++;
|
||||
for (let id in sockets) {
|
||||
if (sockets[id] === socket) {
|
||||
// remove socket from list
|
||||
delete sockets[id];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onSocketOpen(/* event */) {
|
||||
Ember.debug('websocket opened');
|
||||
//Ember.debug('websocket opened');
|
||||
},
|
||||
|
||||
_onSocketClose(event) {
|
||||
if (event.wasClean) {
|
||||
|
||||
Ember.debug('websocket closed');
|
||||
} else {
|
||||
Ember.debug('websocket closed: ' + event.code);
|
||||
}
|
||||
|
@ -139,6 +139,7 @@ export default Ember.Mixin.create({
|
|||
},
|
||||
|
||||
_messageToJSON(blob) {
|
||||
// parse incoming message into usable data
|
||||
var data = new DataView(blob);
|
||||
|
||||
let OFFSET_ENDIAN = 1;
|
||||
|
|
|
@ -12,9 +12,6 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout
|
|||
|
||||
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||
model(params) {
|
||||
return Ember.RSVP.hash({
|
||||
/*simulation: this.store.findRecord('simulation', params.simulationid),*/
|
||||
visualization: this.store.findRecord('visualization', params.visualizationid)
|
||||
});
|
||||
return this.store.findRecord('visualization', params.visualizationid);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{{#each plots as |plot|}}
|
||||
{{component plot.type plot=plot editing=editing grid=grid}}
|
||||
{{component plot.type plot=plot editing=editing grid=grid data=data}}
|
||||
{{/each}}
|
||||
|
|
|
@ -1,31 +1 @@
|
|||
Value
|
||||
|
||||
<div class="popover-content hidden">
|
||||
<div class="plot-edit-container">
|
||||
<form class="plot-edit-form" {{action 'savePlot' on='submit'}}>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="simulator">Simulator</label>
|
||||
</td>
|
||||
<td>
|
||||
{{input id='simulator' type='number' value=plot.simulator min=1 max=255 width='60px'}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="signal">Signal</label>
|
||||
</td>
|
||||
<td>
|
||||
{{input id='signal' value=plot.signal}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<button type="submit">Save</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
Value: {{value}}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{{#link-to 'project.index' project.id}}Back to {{model.project.name}}{{/link-to}}
|
||||
{{#link-to 'project.index' model.project.id}}Back to {{model.project.name}}{{/link-to}}
|
||||
|
||||
<h1>{{model.visualization.name}}</h1>
|
||||
<h1>{{model.name}}</h1>
|
||||
|
||||
{{plot-container plots=model.visualization.plots}}
|
||||
{{plot-container plots=model.plots data=data}}
|
||||
|
||||
<p>
|
||||
{{#link-to "visualization.edit" model.visualization.id}}Edit layout{{/link-to}}
|
||||
{{#link-to "visualization.edit" model.id}}Edit layout{{/link-to}}
|
||||
</p>
|
||||
|
|
|
@ -14,8 +14,7 @@ module.exports = function(environment) {
|
|||
},
|
||||
|
||||
APP: {
|
||||
API_HOST: 'localhost:3000',
|
||||
LIVE_HOST: 'localhost:4000'
|
||||
API_HOST: 'localhost:3000'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue