fetching + broadcasting dynamic data from RotClient-s
This commit is contained in:
@@ -395,6 +395,7 @@
|
||||
this.state = new RotatorState();
|
||||
this.ui = new RotatorUI(this.state);
|
||||
this.renderer = new RotatorRenderer('MainCanvas', this.state);
|
||||
this.websocket = null;
|
||||
|
||||
this.bindEvents();
|
||||
}
|
||||
@@ -415,22 +416,10 @@
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
// Sequential fetch to protect embedded web servers from connection exhaustion
|
||||
const endpoints = [
|
||||
{ key: 'azShift', url: 'readStart', isNum: true },
|
||||
{ key: 'azRange', url: 'readMax', isNum: true },
|
||||
{ key: 'antRadiationAngle', url: 'readAnt', isNum: true },
|
||||
{ key: 'antName', url: 'readAntName', isNum: false },
|
||||
{ key: 'mapUrl', url: 'readMapUrl', isNum: false },
|
||||
{ key: 'mac', url: 'readMAC', isNum: false },
|
||||
{ key: 'elevation', url: 'readElevation', isNum: true }
|
||||
];
|
||||
const initData = await this.startWs();
|
||||
|
||||
for (let conf of endpoints) {
|
||||
const val = await RotatorAPI.fetchText(conf.url);
|
||||
if (val !== null) {
|
||||
this.state[conf.key] = conf.isNum ? Number(val) : val;
|
||||
}
|
||||
for (const [key, value] of Object.entries(initData)) {
|
||||
this.state[key] = value;
|
||||
}
|
||||
|
||||
this.ui.updateStatic();
|
||||
@@ -438,59 +427,53 @@
|
||||
|
||||
// Start timers
|
||||
// this.startLoops();
|
||||
this.startWs();
|
||||
|
||||
}
|
||||
|
||||
startWs() {
|
||||
const websocket = new WebSocket(document.location.href.replace(/\/?$/, '/') + "ws");
|
||||
websocket.addEventListener("message", (e) => {
|
||||
if (!e || !e.data)
|
||||
return;
|
||||
const data = JSON.parse(e.data);
|
||||
if (!data)
|
||||
return;
|
||||
async startWs() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.websocket = new WebSocket(document.location.href.replace(/\/?$/, '/') + "ws");
|
||||
this.websocket.addEventListener("message", (e) => {
|
||||
if (!e || !e.data)
|
||||
return;
|
||||
|
||||
console.log(`RECEIVED: `, data);
|
||||
const parsed = JSON.parse(e.data);
|
||||
if (!parsed)
|
||||
return;
|
||||
|
||||
const data = parsed.data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
const rotData = data['rot14'];
|
||||
if (rotData.initData) {
|
||||
resolve(rotData.initData); // super ugly
|
||||
}
|
||||
|
||||
if (rotData.dynamic) {
|
||||
const numAz = rotData.dynamic.azimuth;
|
||||
const numStat = rotData.dynamic.status;
|
||||
|
||||
let needsRender = false;
|
||||
if (this.state.azimuth !== numAz || this.state.status !== numStat) {
|
||||
needsRender = true;
|
||||
}
|
||||
|
||||
this.state.adc = rotData.dynamic.adc;
|
||||
this.state.azimuth = numAz;
|
||||
this.state.status = numStat;
|
||||
this.state.lastSeen = Date.now();
|
||||
|
||||
if (needsRender) this.renderer.render();
|
||||
}
|
||||
|
||||
console.log(`RECEIVED: `, data);
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
this.websocket.send(JSON.stringify({ ping: 1 }));
|
||||
}, 2000);
|
||||
});
|
||||
setInterval(() => {
|
||||
websocket.send(JSON.stringify({ ping: 1 }));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
async pollData() {
|
||||
const adc = await RotatorAPI.fetchText('readADC');
|
||||
const az = await RotatorAPI.fetchText('readAZ');
|
||||
const stat = await RotatorAPI.fetchText('readStat');
|
||||
|
||||
if (adc !== null && az !== null && stat !== null) {
|
||||
const numAz = Number(az);
|
||||
const numStat = Number(stat);
|
||||
|
||||
let needsRender = false;
|
||||
if (this.state.azimuth !== numAz || this.state.status !== numStat) {
|
||||
needsRender = true;
|
||||
}
|
||||
|
||||
this.state.adc = Number(adc);
|
||||
this.state.azimuth = numAz;
|
||||
this.state.status = numStat;
|
||||
this.state.lastSeen = Date.now();
|
||||
|
||||
if (needsRender) this.renderer.render();
|
||||
}
|
||||
this.ui.updateDynamic();
|
||||
}
|
||||
|
||||
startLoops() {
|
||||
// Data polling
|
||||
setInterval(() => this.pollData(), 500);
|
||||
// Force UI status check (offline state handling)
|
||||
setInterval(() => this.ui.updateDynamic(), 2000);
|
||||
// Map refresh
|
||||
setInterval(() => this.renderer.updateMap(this.state.mapUrl), 600000);
|
||||
|
||||
// Trigger first poll instantly
|
||||
this.pollData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user