1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

Detect close and restart of simulators

Simulator state is requested every 5 seconds if simulator is offline
This commit is contained in:
Markus Grigull 2017-03-18 14:53:27 +01:00
parent fcd80a1680
commit 69f8648303
5 changed files with 140 additions and 43 deletions

View file

@ -21,6 +21,7 @@ import Header from '../components/header';
import Footer from '../components/footer';
import SidebarMenu from '../components/menu-sidebar';
import Home from './home';
import '../styles/app.css';
class App extends Component {
@ -28,11 +29,44 @@ class App extends Component {
return [ SimulationStore, SimulatorStore, UserStore ];
}
static calculateState() {
static calculateState(prevState) {
// get list of running simulators
var simulators = SimulatorStore.getState().filter(simulator => {
return simulator.running;
});
// check if running simulators changed
if (prevState != null) {
var equal = true;
// compare each element with its old one
if (prevState.runningSimulators.length === simulators.length) {
equal = prevState.runningSimulators.every(oldSimulator => {
const simulator = simulators.find(element => {
return element._id === oldSimulator._id;
});
if (simulator == null) {
return false;
}
return simulator.running === oldSimulator.running;
});
} else {
equal = false;
}
// replace with old array to prevent change trigger
if (equal) {
simulators = prevState.runningSimulators;
}
}
return {
simulators: SimulatorStore.getState(),
simulations: SimulationStore.getState(),
currentUser: UserStore.getState().currentUser
currentUser: UserStore.getState().currentUser,
runningSimulators: simulators
};
}
@ -60,44 +94,51 @@ class App extends Component {
});
}
componentDidUpdate() {
if (this.state.simulators && this.state.simulations && this.state.simulations.length > 0) {
// get list of used simulators
var simulators = [];
componentWillUpdate(nextProps, nextState) {
// open connection to each required simulator
const requiredSimulators = this.requiredSimulatorsBySimulations();
this.state.simulations.forEach((simulation) => {
// open connection to each simulator running a simulation model
simulation.models.forEach((simulationModel) => {
// add simulator to list if not already part of
const index = simulators.findIndex((element) => {
return element.simulator === simulationModel.simulator;
});
requiredSimulators.forEach(simulator => {
this.connectSimulator(simulator);
});
}
if (index === -1) {
simulators.push({ simulator: simulationModel.simulator, signals: simulationModel.length });
} else {
if (simulators[index].length < simulationModel.length) {
simulators[index].length = simulationModel.length;
}
}
});
});
requiredSimulatorsBySimulations() {
var simulators = [];
// open connection to each simulator
this.state.simulators.forEach((simulator) => {
this.state.simulations.forEach((simulation) => {
simulation.models.forEach((simulationModel) => {
// add simulator to list if not already part of
const index = simulators.findIndex((element) => {
return element.simulator === simulator._id;
return element.simulator === simulationModel.simulator;
});
if (index !== -1) {
AppDispatcher.dispatch({
type: 'simulatorData/open',
identifier: simulator._id,
endpoint: simulator.endpoint,
signals: simulators[index].signals
});
if (index === -1) {
simulators.push({ simulator: simulationModel.simulator, signals: simulationModel.length });
} else {
if (simulators[index].length < simulationModel.length) {
simulators[index].length = simulationModel.length;
}
}
});
});
return simulators;
}
connectSimulator(data) {
// get simulator object
const simulator = this.state.runningSimulators.find(element => {
return element._id === data.simulator;
});
if (simulator != null) {
AppDispatcher.dispatch({
type: 'simulatorData/open',
identifier: simulator._id,
endpoint: simulator.endpoint,
signals: data.signals
});
}
}

View file

@ -42,6 +42,10 @@ class SimulatorDataDataManager {
type: 'simulatorData/closed',
identifier: identifier
});
// remove from list
delete this._sockets[identifier];
this._sockets[identifier] = null;
}
onMessage(event, identifier) {

View file

@ -14,6 +14,8 @@ import AppDispatcher from '../app-dispatcher';
class SimulatorsDataManager extends RestDataManager {
constructor() {
super('simulator', '/simulators');
this._timers = [];
}
isRunning(simulator) {
@ -26,24 +28,59 @@ class SimulatorsDataManager extends RestDataManager {
// send request
RestAPI.get('http://' + path).then(response => {
// check if simulator is running
var running = false;
simulator.running = false;
response.forEach(sim => {
if (sim.name === name) {
running = true;
// save properties
simulator.running = true;
//simulator.defaultTypes = sim.units;
//simulator.defaultLabels = sim.series;
}
});
// report simulator running state
simulator.running = running;
AppDispatcher.dispatch({
type: 'simulators/running',
simulator: simulator,
running: running
running: simulator.running
});
// remove timer if needed
if (simulator.running) {
const index = this._timers.findIndex(timer => {
return timer.simulator === simulator._id;
});
if (index !== -1) {
this._timers.splice(index, 1);
}
}
}).catch(error => {
//console.log(error);
simulator.running = false;
AppDispatcher.dispatch({
type: 'simulators/running',
simulator: simulator,
running: simulator.running
});
// check for existing timer
const timer = this._timers.find(element => {
return element.simulator === simulator._id;
});
if (timer == null) {
// add timer
var self = this;
const timerID = setInterval(function() {
self.isRunning(simulator);
}, 5000);
this._timers.push({ id: timerID, simulator: simulator._id });
}
});
}
}

View file

@ -70,10 +70,11 @@ class SimulationDataStore extends ReduceStore {
case 'simulatorData/closed':
// close and delete socket
if (state[action.identifier] != null) {
state[action.identifier].close();
state[action.identifier] = null;
// delete data
//delete state[action.identifier];
//state[action.identifier] = null;
this.__emitChange();
//this.__emitChange();
}
return state;

View file

@ -18,6 +18,7 @@ class SimulatorStore extends ArrayStore {
reduce(state, action) {
switch (action.type) {
case 'simulators/loaded':
case 'simulators/is-running':
// get simulator running state
if (Array.isArray(action.data)) {
action.data.forEach((simulator) => {
@ -30,9 +31,22 @@ class SimulatorStore extends ArrayStore {
return super.reduce(state, action);
case 'simulators/running':
// update simulator
return this.updateElements(state, [ action.simulator ]);
case 'simulatorData/closed':
// get simulator
var simulator = state.find(element => {
return element._id === action.identifier;
});
// update running state
simulator.running = false;
// restart requesting again
SimulatorsDataManager.isRunning(simulator);
return this.updateElements(state, [ simulator ]);
default:
return super.reduce(state, action);
}