Added basic control panel

This commit is contained in:
2026-03-11 16:46:06 +01:00
parent 7df210aaf2
commit c4eedfff1e
105 changed files with 21923 additions and 958 deletions

View File

@@ -1,6 +1,7 @@
import { RawData, WebSocket } from 'ws';
import { Main } from '../Main';
import { delay, ServiceState } from '../Utils';
import { State, StatusType } from '../Status';
const PREFIX = '[Unity]';
export class UnityWebSocket {
@@ -29,6 +30,8 @@ export class UnityWebSocket {
constructor(Main: Main) {
this._Main = Main;
this.updateStatus();
}
handle(command: string, ...args: any[]) {
@@ -74,7 +77,7 @@ export class UnityWebSocket {
this.socket.send(
JSON.stringify({
type: 'quit_application',
})
}),
);
}
@@ -87,7 +90,7 @@ export class UnityWebSocket {
type: 'set_slider_value',
sliderIndex,
sliderValue,
})
}),
);
if (this.parameters.sliders[sliderIndex] == undefined) return;
@@ -104,7 +107,7 @@ export class UnityWebSocket {
type: 'set_advanced_slider_value',
sliderIndex,
sliderValue,
})
}),
);
if (this.parameters.advancedSliders[sliderIndex] == undefined) return;
@@ -120,7 +123,7 @@ export class UnityWebSocket {
JSON.stringify({
type: 'set_out_of_service',
showOutOfService: state,
})
}),
);
this.parameters.outOfService = true;
@@ -130,14 +133,40 @@ export class UnityWebSocket {
broadcastState() {
this._Main.WebServer.socket.emit(
'unityWebSocketState',
this.getState()
this.getState(),
);
}
updateStatus() {
if (this.state != 'CONNECTED') {
this._Main.Status.update(
StatusType.CameraUnityStream,
CameraUnityStateColors[this.state],
this.message,
{
reboot: this.state === 'FAILED',
},
);
} else {
const status = !this.parameters.zedReady
? 'Waiting for ZED stream'
: this.message;
this._Main.Status.update(
StatusType.CameraUnityStream,
this.parameters.zedReady ? State.Green : State.Yellow,
status,
{
reboot: this.parameters.zedReady,
},
);
}
}
setInfo(message: string, error: string, state: ServiceState = 'FAILED') {
this.message = message;
this.error = error;
this.state = state;
this.updateStatus();
this.broadcastState();
if (error != null) this._Main.Twilio.sendError('UnityWebSocket', error);
@@ -185,7 +214,7 @@ export class UnityWebSocket {
? 2
: null,
};
}
},
);
this.parameters.advancedSliders =
message.heartbeat.dataAdvancedSliders.map((slider) => {
@@ -199,12 +228,13 @@ export class UnityWebSocket {
};
});
this.updateStatus();
this.broadcastState();
break;
case 'response_camera_frame':
this._Main.WebServer.Calibration.writeCalibrationImage(
message.imageBase64
message.imageBase64,
);
break;
}
@@ -261,7 +291,7 @@ export class UnityWebSocket {
await delay(1000);
this.socket = new WebSocket(
`ws://${this._Main.Config.unity.webSocket.ip}:${this._Main.Config.unity.webSocket.port}`
`ws://${this._Main.Config.unity.webSocket.ip}:${this._Main.Config.unity.webSocket.port}`,
);
this.socket.on('error', (error) => {
@@ -269,7 +299,7 @@ export class UnityWebSocket {
this.setInfo(
'Connection error',
`Could not connect: ${error.message}`,
'FAILED'
'FAILED',
);
this.reconnect();
});
@@ -288,7 +318,7 @@ export class UnityWebSocket {
this.setInfo(
'Disconnected',
'Unity was disconnected unexpectedly',
'FAILED'
'FAILED',
);
this.reconnect();
});
@@ -300,7 +330,10 @@ export class UnityWebSocket {
private calibrationImageClock: NodeJS.Timeout;
startFetchClocks() {
this.socket.send(
JSON.stringify({ type: 'set_heartbeat_auto_send', autoSend: false })
JSON.stringify({
type: 'set_heartbeat_auto_send',
autoSend: false,
}),
);
this.heartbeatClock = setInterval(() => {
if (
@@ -409,6 +442,13 @@ interface UnitySocketMessageHeartbeat extends UnitySocketMessageBase {
showOutOfService?: boolean;
};
}
export const CameraUnityStateColors: Record<ServiceState, State> = {
CONNECTED: State.Green,
DISCONNECTED: State.Gray,
CONNECTING: State.Yellow,
FAILED: State.Red,
};
interface UnitySocketMessageCameraFrame extends UnitySocketMessageBase {
type: 'response_camera_frame';
imageBase64: string;