2024-01-27 16:44:18 +00:00
|
|
|
/*
|
2023-11-09 14:48:10 +00:00
|
|
|
import {
|
|
|
|
newMessageReceived,
|
|
|
|
newBeaconReceived,
|
|
|
|
updateTransmissionStatus,
|
|
|
|
setStateSuccess,
|
|
|
|
setStateFailed,
|
|
|
|
} from "./chatHandler";
|
2024-01-27 16:44:18 +00:00
|
|
|
*/
|
2023-11-09 14:48:10 +00:00
|
|
|
import { displayToast } from "./popupHandler";
|
2024-02-03 12:55:30 +00:00
|
|
|
import {
|
|
|
|
getFreedataMessages,
|
|
|
|
getConfig,
|
|
|
|
getAudioDevices,
|
|
|
|
getSerialDevices,
|
|
|
|
getModemState,
|
|
|
|
} from "./api";
|
|
|
|
import { processFreedataMessages } from "./messagesHandler.ts";
|
2024-02-20 09:05:13 +00:00
|
|
|
import { processRadioStatus } from "./radioHandler.ts";
|
2023-11-09 14:48:10 +00:00
|
|
|
|
|
|
|
// ----------------- init pinia stores -------------
|
|
|
|
import { setActivePinia } from "pinia";
|
|
|
|
import pinia from "../store/index";
|
|
|
|
setActivePinia(pinia);
|
|
|
|
import { useStateStore } from "../store/stateStore.js";
|
|
|
|
const stateStore = useStateStore(pinia);
|
|
|
|
|
2024-02-10 12:57:33 +00:00
|
|
|
import {
|
|
|
|
settingsStore as settings,
|
|
|
|
getRemote,
|
|
|
|
} from "../store/settingsStore.js";
|
2023-11-09 14:48:10 +00:00
|
|
|
|
2023-11-13 06:21:13 +00:00
|
|
|
export function connectionFailed(endpoint, event) {
|
|
|
|
stateStore.modem_connection = "disconnected";
|
2023-11-13 06:20:06 +00:00
|
|
|
}
|
2023-11-11 19:46:49 +00:00
|
|
|
export function stateDispatcher(data) {
|
2023-11-13 16:28:00 +00:00
|
|
|
data = JSON.parse(data);
|
2024-02-04 15:43:06 +00:00
|
|
|
//Leave commented when not needed, otherwise can lead to heap overflows due to the amount of data logged
|
|
|
|
//console.debug(data);
|
2024-01-04 20:14:16 +00:00
|
|
|
if (data["type"] == "state-change" || data["type"] == "state") {
|
2024-01-09 09:19:55 +00:00
|
|
|
stateStore.modem_connection = "connected";
|
|
|
|
|
2024-01-28 20:29:56 +00:00
|
|
|
stateStore.busy_state = data["is_modem_busy"];
|
|
|
|
|
2023-11-12 18:56:15 +00:00
|
|
|
stateStore.channel_busy = data["channel_busy"];
|
|
|
|
stateStore.is_codec2_traffic = data["is_codec2_traffic"];
|
|
|
|
stateStore.is_modem_running = data["is_modem_running"];
|
2023-11-28 22:46:55 +00:00
|
|
|
stateStore.dbfs_level = Math.round(data["audio_dbfs"]);
|
|
|
|
stateStore.dbfs_level_percent = Math.round(
|
|
|
|
Math.pow(10, data["audio_dbfs"] / 20) * 100,
|
|
|
|
);
|
2024-01-12 19:34:07 +00:00
|
|
|
|
|
|
|
stateStore.s_meter_strength_raw = Math.round(data["s_meter_strength"]);
|
|
|
|
stateStore.s_meter_strength_percent = Math.round(
|
|
|
|
Math.pow(10, data["s_meter_strength"] / 20) * 100,
|
|
|
|
);
|
|
|
|
|
2023-11-13 21:35:54 +00:00
|
|
|
stateStore.channel_busy_slot = data["channel_busy_slot"];
|
|
|
|
stateStore.beacon_state = data["is_beacon_running"];
|
2023-11-18 22:50:40 +00:00
|
|
|
stateStore.radio_status = data["radio_status"];
|
|
|
|
stateStore.frequency = data["radio_frequency"];
|
2023-11-26 18:54:28 +00:00
|
|
|
stateStore.mode = data["radio_mode"];
|
2023-12-05 03:24:30 +00:00
|
|
|
//Reverse entries so most recent is first
|
2023-12-03 16:49:56 +00:00
|
|
|
stateStore.activities = Object.entries(data["activities"]).reverse();
|
2023-12-05 03:24:30 +00:00
|
|
|
build_HSL();
|
2023-11-11 19:47:05 +00:00
|
|
|
}
|
2023-11-11 19:46:49 +00:00
|
|
|
}
|
2024-01-04 14:46:58 +00:00
|
|
|
|
2023-11-11 19:46:49 +00:00
|
|
|
export function eventDispatcher(data) {
|
|
|
|
data = JSON.parse(data);
|
2024-01-14 07:09:38 +00:00
|
|
|
console.debug(data);
|
2024-01-04 19:55:33 +00:00
|
|
|
|
2023-12-01 02:12:04 +00:00
|
|
|
if (data["scatter"] !== undefined) {
|
|
|
|
stateStore.scatter = JSON.parse(data["scatter"]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-02-03 12:55:30 +00:00
|
|
|
switch (data["message-db"]) {
|
2024-01-27 16:44:18 +00:00
|
|
|
case "changed":
|
2024-02-03 12:55:30 +00:00
|
|
|
console.log("fetching new messages...");
|
|
|
|
var messages = getFreedataMessages();
|
|
|
|
processFreedataMessages(messages);
|
2024-01-27 16:44:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-30 21:49:43 +00:00
|
|
|
switch (data["ptt"]) {
|
|
|
|
case true:
|
2023-12-01 02:12:04 +00:00
|
|
|
case false:
|
2023-11-30 21:49:43 +00:00
|
|
|
// get ptt state as a first test
|
2023-12-01 02:12:04 +00:00
|
|
|
//console.warn("PTT state true")
|
2023-11-30 21:49:43 +00:00
|
|
|
stateStore.ptt_state = data.ptt;
|
|
|
|
return;
|
|
|
|
}
|
2023-12-01 03:08:42 +00:00
|
|
|
|
2024-01-05 14:52:59 +00:00
|
|
|
switch (data["modem"]) {
|
|
|
|
case "started":
|
|
|
|
displayToast("success", "bi-arrow-left-right", "Modem started", 5000);
|
2024-02-03 10:40:07 +00:00
|
|
|
getModemState();
|
|
|
|
getConfig();
|
|
|
|
getAudioDevices();
|
|
|
|
getSerialDevices();
|
|
|
|
getFreedataMessages();
|
2024-02-20 09:05:13 +00:00
|
|
|
processRadioStatus();
|
2024-01-05 14:52:59 +00:00
|
|
|
return;
|
2024-01-05 14:52:29 +00:00
|
|
|
|
2024-01-05 14:52:59 +00:00
|
|
|
case "stopped":
|
2024-02-03 10:40:07 +00:00
|
|
|
displayToast("warning", "bi-arrow-left-right", "Modem stopped", 5000);
|
2024-01-05 14:52:59 +00:00
|
|
|
return;
|
2024-01-05 14:52:29 +00:00
|
|
|
|
2024-01-05 14:52:59 +00:00
|
|
|
case "restarted":
|
|
|
|
displayToast("secondary", "bi-bootstrap-reboot", "Modem restarted", 5000);
|
2024-02-03 10:40:07 +00:00
|
|
|
getModemState();
|
|
|
|
getConfig();
|
|
|
|
getAudioDevices();
|
|
|
|
getSerialDevices();
|
|
|
|
getFreedataMessages();
|
2024-02-20 09:05:13 +00:00
|
|
|
processRadioStatus();
|
2024-01-05 14:52:59 +00:00
|
|
|
return;
|
2024-01-05 14:52:29 +00:00
|
|
|
|
2024-01-05 14:52:59 +00:00
|
|
|
case "failed":
|
|
|
|
displayToast(
|
|
|
|
"danger",
|
|
|
|
"bi-bootstrap-reboot",
|
|
|
|
"Modem startup failed | bad config?",
|
|
|
|
5000,
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
2024-01-05 14:52:29 +00:00
|
|
|
|
2024-01-04 20:14:16 +00:00
|
|
|
var message = "";
|
2024-01-04 19:55:33 +00:00
|
|
|
|
2024-01-04 14:46:58 +00:00
|
|
|
switch (data["type"]) {
|
|
|
|
case "hello-client":
|
2024-01-04 20:14:16 +00:00
|
|
|
message = "Connected to server";
|
|
|
|
displayToast("success", "bi-ethernet", message, 5000);
|
|
|
|
stateStore.modem_connection = "connected";
|
2024-02-10 12:57:18 +00:00
|
|
|
|
|
|
|
getRemote().then(() => {
|
2024-02-10 12:57:33 +00:00
|
|
|
//initConnections();
|
|
|
|
getModemState();
|
2024-02-10 12:57:18 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
//getConfig();
|
2024-02-03 10:40:07 +00:00
|
|
|
getModemState();
|
2024-02-08 12:39:18 +00:00
|
|
|
getOverallHealth();
|
2024-02-03 10:40:07 +00:00
|
|
|
getAudioDevices();
|
|
|
|
getSerialDevices();
|
|
|
|
getFreedataMessages();
|
|
|
|
processFreedataMessages();
|
2024-02-20 09:05:13 +00:00
|
|
|
processRadioStatus();
|
2024-02-03 11:09:57 +00:00
|
|
|
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
2024-01-04 19:55:33 +00:00
|
|
|
|
2024-02-08 09:14:40 +00:00
|
|
|
switch (data["received"]) {
|
|
|
|
case "PING":
|
|
|
|
message = `Ping request from: ${data.dxcallsign}, SNR: ${data.snr}`;
|
|
|
|
displayToast("success", "bi-check-circle", message, 5000);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case "PING_ACK":
|
|
|
|
message = `Ping acknowledged from: ${data.dxcallsign}, SNR: ${data.snr}`;
|
|
|
|
displayToast("success", "bi-check-circle", message, 5000);
|
|
|
|
return;
|
|
|
|
}
|
2024-02-08 09:12:49 +00:00
|
|
|
|
2024-01-04 19:55:33 +00:00
|
|
|
case "arq":
|
2024-01-04 20:14:16 +00:00
|
|
|
if (data["arq-transfer-outbound"]) {
|
|
|
|
switch (data["arq-transfer-outbound"].state) {
|
|
|
|
case "NEW":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-outbound"].session_id}, DXCall: ${data["arq-transfer-outbound"].dxcall}, Total Bytes: ${data["arq-transfer-outbound"].total_bytes}, State: ${data["arq-transfer-outbound"].state}`;
|
|
|
|
displayToast("success", "bi-check-circle", message, 5000);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.dxcallsign = data["arq-transfer-outbound"].dxcall;
|
2024-01-14 07:09:38 +00:00
|
|
|
stateStore.arq_transmission_percent = 0;
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_total_bytes = 0;
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
case "OPEN_SENT":
|
2024-01-14 07:09:38 +00:00
|
|
|
console.info("state OPEN_SENT needs to be implemented");
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "INFO_SENT":
|
2024-01-14 07:09:38 +00:00
|
|
|
console.info("state INFO_SENT needs to be implemented");
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "BURST_SENT":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-outbound"].session_id}, DXCall: ${data["arq-transfer-outbound"].dxcall}, Received Bytes: ${data["arq-transfer-outbound"].received_bytes}/${data["arq-transfer-outbound"].total_bytes}, State: ${data["arq-transfer-outbound"].state}`;
|
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent =
|
|
|
|
(data["arq-transfer-outbound"].received_bytes /
|
|
|
|
data["arq-transfer-outbound"].total_bytes) *
|
|
|
|
100;
|
|
|
|
stateStore.arq_total_bytes =
|
|
|
|
data["arq-transfer-outbound"].received_bytes;
|
2024-02-24 21:01:15 +00:00
|
|
|
stateStore.arq_speed_list_timestamp = data["arq-transfer-outbound"].statistics.time_histogram
|
|
|
|
stateStore.arq_speed_list_bpm = data["arq-transfer-outbound"].statistics.bpm_histogram
|
|
|
|
stateStore.arq_speed_list_snr = data["arq-transfer-outbound"].statistics.snr_histogram
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "ABORTING":
|
2024-01-14 07:09:38 +00:00
|
|
|
console.info("state ABORTING needs to be implemented");
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "ABORTED":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${
|
|
|
|
data["arq-transfer-outbound"].session_id
|
|
|
|
}, DXCall: ${data["arq-transfer-outbound"].dxcall}, Total Bytes: ${
|
|
|
|
data["arq-transfer-outbound"].total_bytes
|
|
|
|
}, Success: ${
|
|
|
|
data["arq-transfer-outbound"].success ? "Yes" : "No"
|
|
|
|
}, State: ${data["arq-transfer-outbound"].state}, Data: ${
|
|
|
|
data["arq-transfer-outbound"].data ? "Available" : "Not Available"
|
|
|
|
}`;
|
|
|
|
displayToast("warning", "bi-exclamation-triangle", message, 5000);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case "FAILED":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${
|
|
|
|
data["arq-transfer-outbound"].session_id
|
|
|
|
}, DXCall: ${data["arq-transfer-outbound"].dxcall}, Total Bytes: ${
|
|
|
|
data["arq-transfer-outbound"].total_bytes
|
|
|
|
}, Success: ${
|
|
|
|
data["arq-transfer-outbound"].success ? "Yes" : "No"
|
|
|
|
}, State: ${data["arq-transfer-outbound"].state}, Data: ${
|
|
|
|
data["arq-transfer-outbound"].data ? "Available" : "Not Available"
|
|
|
|
}`;
|
|
|
|
displayToast("danger", "bi-x-octagon", message, 5000);
|
|
|
|
return;
|
2023-11-09 14:48:10 +00:00
|
|
|
}
|
2024-01-04 20:14:16 +00:00
|
|
|
}
|
2023-11-09 14:48:51 +00:00
|
|
|
|
2024-01-04 20:14:16 +00:00
|
|
|
if (data["arq-transfer-inbound"]) {
|
|
|
|
switch (data["arq-transfer-inbound"].state) {
|
|
|
|
case "NEW":
|
2024-01-05 15:52:16 +00:00
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-inbound"].session_id}, DXCall: ${data["arq-transfer-inbound"].dxcall}, State: ${data["arq-transfer-inbound"].state}`;
|
2024-01-04 20:14:16 +00:00
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
2024-01-14 07:09:38 +00:00
|
|
|
stateStore.dxcallsign = data["arq-transfer-inbound"].dxcall;
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent = 0;
|
2024-01-14 07:09:38 +00:00
|
|
|
stateStore.arq_total_bytes = 0;
|
2024-02-24 21:01:15 +00:00
|
|
|
stateStore.arq_speed_list_timestamp = data["arq-transfer-inbound"].statistics.time_histogram
|
|
|
|
stateStore.arq_speed_list_bpm = data["arq-transfer-inbound"].statistics.bpm_histogram
|
|
|
|
stateStore.arq_speed_list_snr = data["arq-transfer-inbound"].statistics.snr_histogram
|
|
|
|
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "OPEN_ACK_SENT":
|
|
|
|
message = `Session ID: ${data["arq-transfer-inbound"].session_id}, DXCall: ${data["arq-transfer-inbound"].dxcall}, Total Bytes: ${data["arq-transfer-inbound"].total_bytes}, State: ${data["arq-transfer-inbound"].state}`;
|
|
|
|
displayToast("info", "bi-arrow-left-right", message, 5000);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent =
|
|
|
|
(data["arq-transfer-inbound"].received_bytes /
|
|
|
|
data["arq-transfer-inbound"].total_bytes) *
|
|
|
|
100;
|
|
|
|
stateStore.arq_total_bytes =
|
|
|
|
data["arq-transfer-inbound"].received_bytes;
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "INFO_ACK_SENT":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-inbound"].session_id}, DXCall: ${data["arq-transfer-inbound"].dxcall}, Received Bytes: ${data["arq-transfer-inbound"].received_bytes}/${data["arq-transfer-inbound"].total_bytes}, State: ${data["arq-transfer-inbound"].state}`;
|
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent =
|
|
|
|
(data["arq-transfer-inbound"].received_bytes /
|
|
|
|
data["arq-transfer-inbound"].total_bytes) *
|
|
|
|
100;
|
|
|
|
stateStore.arq_total_bytes =
|
|
|
|
data["arq-transfer-inbound"].received_bytes;
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "BURST_REPLY_SENT":
|
2024-01-05 15:52:16 +00:00
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-inbound"].session_id}, DXCall: ${data["arq-transfer-inbound"].dxcall}, Received Bytes: ${data["arq-transfer-inbound"].received_bytes}/${data["arq-transfer-inbound"].total_bytes}, State: ${data["arq-transfer-inbound"].state}`;
|
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent =
|
|
|
|
(data["arq-transfer-inbound"].received_bytes /
|
|
|
|
data["arq-transfer-inbound"].total_bytes) *
|
|
|
|
100;
|
|
|
|
stateStore.arq_total_bytes =
|
|
|
|
data["arq-transfer-inbound"].received_bytes;
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "ENDED":
|
2024-01-05 15:52:16 +00:00
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-inbound"].session_id}, DXCall: ${data["arq-transfer-inbound"].dxcall}, Received Bytes: ${data["arq-transfer-inbound"].received_bytes}/${data["arq-transfer-inbound"].total_bytes}, State: ${data["arq-transfer-inbound"].state}`;
|
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
|
|
|
// Forward data to chat module
|
2024-01-05 15:52:38 +00:00
|
|
|
newMessageReceived(
|
|
|
|
data["arq-transfer-inbound"].data,
|
|
|
|
data["arq-transfer-inbound"],
|
|
|
|
);
|
2024-01-14 07:10:30 +00:00
|
|
|
stateStore.arq_transmission_percent =
|
|
|
|
(data["arq-transfer-inbound"].received_bytes /
|
|
|
|
data["arq-transfer-inbound"].total_bytes) *
|
|
|
|
100;
|
|
|
|
stateStore.arq_total_bytes =
|
|
|
|
data["arq-transfer-inbound"].received_bytes;
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "ABORTED":
|
2024-01-14 07:09:38 +00:00
|
|
|
console.info("state ABORTED needs to be implemented");
|
2024-01-04 20:14:16 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case "FAILED":
|
|
|
|
message = `Type: ${data.type}, Session ID: ${data["arq-transfer-outbound"].session_id}, DXCall: ${data["arq-transfer-outbound"].dxcall}, Received Bytes: ${data["arq-transfer-outbound"].received_bytes}/${data["arq-transfer-outbound"].total_bytes}, State: ${data["arq-transfer-outbound"].state}`;
|
|
|
|
displayToast("info", "bi-info-circle", message, 5000);
|
|
|
|
return;
|
2024-01-04 19:55:33 +00:00
|
|
|
}
|
2024-01-04 20:14:16 +00:00
|
|
|
}
|
|
|
|
return;
|
2023-11-09 14:48:51 +00:00
|
|
|
}
|
2023-11-09 14:48:10 +00:00
|
|
|
}
|
2024-01-04 14:46:58 +00:00
|
|
|
|
|
|
|
function build_HSL() {
|
|
|
|
//Use data from activities to build HSL list
|
|
|
|
for (let i = 0; i < stateStore.activities.length; i++) {
|
|
|
|
if (
|
|
|
|
stateStore.activities[i][1].direction != "received" ||
|
|
|
|
stateStore.activities[i][1].origin == undefined
|
|
|
|
) {
|
|
|
|
//Ignore stations without origin and not received type
|
|
|
|
//console.warn("HSL: Ignoring " + stateStore.activities[i][0]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let found = false;
|
|
|
|
for (let ii = 0; ii < stateStore.heard_stations.length; ii++) {
|
|
|
|
if (
|
|
|
|
stateStore.heard_stations[ii].origin ==
|
|
|
|
stateStore.activities[i][1].origin
|
|
|
|
) {
|
|
|
|
//Station already in HSL, check if newer than one in HSL
|
|
|
|
found = true;
|
|
|
|
if (
|
|
|
|
stateStore.heard_stations[ii].timestamp <
|
|
|
|
stateStore.activities[i][1].timestamp
|
|
|
|
) {
|
|
|
|
//Update existing entry in HSL
|
|
|
|
stateStore.heard_stations[ii] = stateStore.activities[i][1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found == false) {
|
|
|
|
//Station not in HSL, let us add it
|
|
|
|
stateStore.heard_stations.push(stateStore.activities[i][1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stateStore.heard_stations.sort((a, b) => b.timestamp - a.timestamp); // b - a for reverse sort
|
2024-01-04 20:14:16 +00:00
|
|
|
}
|
2024-02-08 12:39:18 +00:00
|
|
|
|
|
|
|
export function getOverallHealth() {
|
|
|
|
//Return a number indicating health for icon bg color; lower the number the healthier
|
|
|
|
let health = 0;
|
|
|
|
if (stateStore.modem_connection !== "connected") {
|
|
|
|
health += 5;
|
|
|
|
stateStore.is_modem_running = false;
|
|
|
|
stateStore.radio_status = false;
|
|
|
|
}
|
|
|
|
if (!stateStore.is_modem_running) health += 3;
|
|
|
|
if (stateStore.radio_status === false) health += 2;
|
|
|
|
if (process.env.FDUpdateAvail === "1") health += 1;
|
|
|
|
return health;
|
2024-02-08 12:39:36 +00:00
|
|
|
}
|