swimtracker-app/data_processing/SwimTrackerWebsocketConnect...

156 lines
4.6 KiB
JavaScript
Raw Normal View History

import ReconnectingWebSocket from 'reconnecting-websocket';
import * as msgpack from 'msgpack-lite';
const OpCodes = {
// from swim tracker device to frontend
ERROR: 1,
INITIAL_INFO: 2,
SESSION_STARTED: 3,
SESSION_STOPPED: 4,
SESSION_NEW_DATA: 5,
ANSWER_USER_LIST: 6,
ANSWER_SESSION_LIST: 7,
WIFI_STATE_RESPONSE: 8,
WIFI_SCAN_RESPONSE: 9,
// from frontend to device
START_SESSION: 128,
STOP_SESSION: 129,
TARE: 130,
QUERY_USER_LIST: 131,
QUERY_SESSION_LIST: 132,
WIFI_STATE_SET: 133,
WIFI_STATE_GET: 134,
WIFI_TRIGGER_SCAN: 135,
};
export default class SwimTrackerWebsocketConnection {
2021-06-13 12:43:50 +02:00
constructor(swimTrackerHost, onData, onStarted, onStopped, onWifiStateInfo, onConnect, onDisconnect) {
this.swimTrackerHost = swimTrackerHost;
this.onData = onData;
this.onStarted = onStarted;
this.onStopped = onStopped;
2021-06-13 12:43:50 +02:00
this.onWifiStateInfo = onWifiStateInfo;
this.onConnect = onConnect;
this.onDisconnect = onDisconnect;
const wsOptions = {
maxReconnectionDelay: 4000
};
this.ws = new ReconnectingWebSocket(`ws://${swimTrackerHost}:81`, [], wsOptions);
this.ws.onmessage = this._onMessage;
this.ws.onopen = this.onConnect;
this.ws.onclose = this.onDisconnect;
this.ws.onerror = this._onError;
this.ws.binaryType = 'arraybuffer';
this.msgpackCodec = msgpack.createCodec();
this.msgpackCodec.addExtUnpacker(205, function (byteArr) {
const buffer = byteArr.buffer.slice(byteArr.byteOffset, byteArr.byteLength + byteArr.byteOffset);
const result = new Int16Array(buffer);
return result;
});
2021-06-13 12:43:50 +02:00
this._wifiScanPromises = [];
}
sendStartCommand() {
2021-06-13 12:43:50 +02:00
this._sendMsg(OpCodes.START_SESSION);
}
sendStopCommand() {
2021-06-13 12:43:50 +02:00
this._sendMsg(OpCodes.STOP_SESSION);
}
sendTareCommand() {
2021-06-13 12:43:50 +02:00
this._sendMsg(OpCodes.TARE);
}
scanWifiNetworks() {
2021-06-13 12:43:50 +02:00
console.log("Trigger wifi scan");
this._sendMsg(OpCodes.WIFI_TRIGGER_SCAN);
2021-06-13 12:43:50 +02:00
let conn = this;
return new Promise((resolve, reject) => {
conn._wifiScanPromises.push({ resolve: resolve, reject: reject });
});
}
wifiResetToProvisioning() {
this._sendMsg(OpCodes.WIFI_STATE_SET, {
"reset_to_provisioning": true,
});
}
2021-06-13 12:43:50 +02:00
wifiSetModeAP(password) {
this._sendMsg(OpCodes.WIFI_STATE_SET, {
"ap_password": password,
});
}
wifiSetModeSTA(ssid, password) {
this._sendMsg(OpCodes.WIFI_STATE_SET, {
"sta_ssid": ssid,
"sta_password": password,
});
}
_sendMsg(code, data) {
let msg = undefined;
if (data) {
const serializedData = msgpack.encode(data);
msg = new Uint8Array([code, ...serializedData]);
} else {
msg = new Uint8Array(1);
msg[0] = OpCodes.WIFI_TRIGGER_SCAN;
}
2021-06-13 12:43:50 +02:00
this.ws.send(msg);
}
_onMessage = (e) => {
const dv = new DataView(e.data);
const opCode = dv.getInt8(0);
2021-06-13 12:43:50 +02:00
const payload = new Uint8Array(e.data).slice(1);
if (opCode === OpCodes.INITIAL_INFO) {
const headerSize = 6;
const running = Boolean(dv.getInt8(1));
const sessionId = dv.getUint32(2);
if (running && e.data.byteLength > headerSize) {
const data = new Uint16Array(e.data.slice(headerSize));
this.onStarted(sessionId);
this.onData(data);
} else
this.onStopped();
} else if (opCode === OpCodes.SESSION_STARTED) {
const sessionId = dv.getUint32(1);
this.onStarted(sessionId);
} else if (opCode === OpCodes.SESSION_STOPPED) {
this.onStopped();
} else if (opCode === OpCodes.SESSION_NEW_DATA) {
const data = new Uint16Array(e.data.slice(1));
this.onData(data);
} else if (opCode === OpCodes.WIFI_SCAN_RESPONSE) {
2021-06-13 12:43:50 +02:00
const scanResult = msgpack.decode(payload, { codec: this.msgpackCodec });
for (let i = 0; i < this._wifiScanPromises.length; ++i) {
this._wifiScanPromises[i].resolve(scanResult);
}
2021-06-13 12:43:50 +02:00
this._wifiScanPromises.length = 0;
} else if (opCode === OpCodes.WIFI_STATE_RESPONSE) {
const wifiInfo = msgpack.decode(payload, { codec: this.msgpackCodec });
this.onWifiStateInfo(wifiInfo);
}
}
_onError = (ev) => {
console.log("Websocket error", ev);
}
};