175 lines
6.0 KiB
JavaScript
175 lines
6.0 KiB
JavaScript
import SwimTrackerWebsocketConnection from "../data_processing/SwimTrackerWebsocketConnection";
|
|
import DataAnalysis from "../data_processing/DataAnalysis";
|
|
import { List } from "immutable";
|
|
|
|
export const ConnState = {
|
|
DISCONNECTED: 'disconnected',
|
|
CONNECTED_STOPPED: 'connected_stopped',
|
|
CONNECTED_RUNNING: 'connected_running',
|
|
CONNECTED_STARTING: 'connected_starting', // start message sent, but device hasn't ack'ed it yet
|
|
CONNECTED_STOPPING: 'connected_stopping' // stop message sent..
|
|
}
|
|
|
|
export const WifiState = {
|
|
UNKNOWN: 'unknown',
|
|
STA: 'sta', // connected to regular wifi
|
|
AP_PROVISIONING: 'ap_provisioning', // acting as access point for provisioning
|
|
AP_SECURE: 'ap_secure', // acting as access point, password has been set
|
|
}
|
|
|
|
// -------------------------------------------- Actions ---------------------------------------------
|
|
|
|
export const DEVICE_DISCONNECT = "DEVICE_DISCONNECT";
|
|
export const DEVICE_CONNECT = "DEVICE_CONNECT";
|
|
export const SESSION_STARTED = "SESSION_STARTED";
|
|
export const SESSION_STOPPED = "SESSION_STOPPED";
|
|
export const SESSION_NEW_DATA = "SESSION_NEW_DATA";
|
|
|
|
export const START_SESSION = "START_SESSION";
|
|
export const STOP_SESSION = "STOP_SESSION";
|
|
|
|
export const WIFI_SET_STATE = "WIFI_SET_STATE";
|
|
|
|
export const reportNewWifiState = (newStateStr, newHostname) => ({
|
|
type: WIFI_SET_STATE,
|
|
newStateStr: newStateStr,
|
|
newHostname: newHostname,
|
|
});
|
|
|
|
export const reportSessionStarted = (sessionId) => ({
|
|
type: SESSION_STARTED,
|
|
sessionId: sessionId
|
|
});
|
|
|
|
export const reportSessionStopped = () => ({
|
|
type: SESSION_STOPPED
|
|
});
|
|
|
|
export const reportNewSessionData = (allMeasurements, analysis) => ({
|
|
type: SESSION_NEW_DATA,
|
|
data: allMeasurements,
|
|
analysis: analysis
|
|
});
|
|
|
|
export const reportDeviceConnect = () => ({
|
|
type: DEVICE_CONNECT
|
|
});
|
|
|
|
export const reportDeviceDisconnect = () => ({
|
|
type: DEVICE_DISCONNECT
|
|
});
|
|
|
|
export const startSession = () => ({
|
|
type: START_SESSION
|
|
});
|
|
|
|
export const stopSession = () => ({
|
|
type: STOP_SESSION
|
|
});
|
|
|
|
// -------------------------------------------- Device coupling -------------------------------------
|
|
|
|
export class DeviceReduxCoupling {
|
|
constructor(reduxStore) {
|
|
this.reduxStore = reduxStore;
|
|
this.analysis = new DataAnalysis();
|
|
|
|
this.conn = null;
|
|
|
|
this.reduxStore.subscribe(this._onStateChange);
|
|
this._onStateChange();
|
|
}
|
|
|
|
_onStateChange = () => {
|
|
const state = this.reduxStore.getState();
|
|
|
|
if (this.conn === null || (state.settings.swimTrackerHost != this.conn.swimTrackerHost)) {
|
|
if( this.conn !== null) {
|
|
this.conn.close();
|
|
}
|
|
|
|
this.conn = new SwimTrackerWebsocketConnection(state.settings.swimTrackerHost,
|
|
this._onNewData,
|
|
(sessionId) => this.reduxStore.dispatch(reportSessionStarted(sessionId)),
|
|
() => this.reduxStore.dispatch(reportSessionStopped()),
|
|
(response) => this.reduxStore.dispatch(reportNewWifiState(response["state"], response["hostname"])),
|
|
() => this.reduxStore.dispatch(reportDeviceConnect()),
|
|
() => this.reduxStore.dispatch(reportDeviceDisconnect())
|
|
);
|
|
}
|
|
if (state.deviceState.connState === ConnState.CONNECTED_STARTING) {
|
|
console.log("sending start command to connection");
|
|
this.conn.sendStartCommand();
|
|
}
|
|
else if (state.deviceState.connState === ConnState.CONNECTED_STOPPING)
|
|
this.conn.sendStopCommand();
|
|
}
|
|
|
|
_onNewData = (newData) => {
|
|
const state = this.reduxStore.getState();
|
|
const allMeasurements = state.deviceState.measurements.concat(List(newData));
|
|
const analysisResult = this.analysis.analyze(state.settings.analysis, state.deviceState.sessionId, allMeasurements);
|
|
this.reduxStore.dispatch(reportNewSessionData(allMeasurements, analysisResult));
|
|
}
|
|
};
|
|
|
|
// -------------------------------------------- Reducer -----------------------------------------------
|
|
|
|
const INITIAL_ANALYSIS = {
|
|
'peaks': List(),
|
|
'totalTime': null,
|
|
'totalMomentum': null,
|
|
'peakMax': null,
|
|
'momentumWindow': null,
|
|
'peakMaxWindow': null,
|
|
};
|
|
|
|
const INITIAL_DEVICE_STATE = {
|
|
connState: ConnState.DISCONNECTED,
|
|
wifiState: WifiState.UNKNOWN,
|
|
sessionId: 0,
|
|
measurements: List(),
|
|
analysis: INITIAL_ANALYSIS,
|
|
deviceReportedHostname: "",
|
|
};
|
|
|
|
export const deviceStateReducer = (state = INITIAL_DEVICE_STATE, action) => {
|
|
switch (action.type) {
|
|
case SESSION_NEW_DATA:
|
|
const res = {
|
|
...state,
|
|
measurements: action.data,
|
|
analysis: { ...state.analysis, ...action.analysis }
|
|
};
|
|
return res;
|
|
case DEVICE_CONNECT:
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.CONNECTED_STOPPED };
|
|
case DEVICE_DISCONNECT:
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.DISCONNECTED };
|
|
case SESSION_STARTED:
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.CONNECTED_RUNNING, sessionId: action.sessionId };
|
|
case SESSION_STOPPED:
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.CONNECTED_STOPPED };
|
|
case START_SESSION:
|
|
if (state.connState === ConnState.SESSION_STARTED)
|
|
return state;
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.CONNECTED_STARTING };
|
|
case STOP_SESSION:
|
|
if (state.connState === ConnState.SESSION_STOPPED)
|
|
return state;
|
|
return { ...INITIAL_DEVICE_STATE, wifiState: state.wifiState, connState: ConnState.CONNECTED_STOPPING };
|
|
case WIFI_SET_STATE:
|
|
let wifiState = WifiState.UNKNOWN;
|
|
if (action.newStateStr === "STATION_MODE") { wifiState = WifiState.STA; }
|
|
else if (action.newStateStr === "AP_PROVISIONING") { wifiState = WifiState.AP_PROVISIONING; }
|
|
else if (action.newStateStr === "AP_SECURE") { wifiState = WifiState.AP_SECURE; }
|
|
return { ...state, wifiState: wifiState, deviceReportedHostname: action.newHostname };
|
|
default:
|
|
//console.log("Unhandled state in deviceStateReducer", action, action.type, "state", state);
|
|
return state;
|
|
}
|
|
};
|
|
|
|
|
|
|