Mu2_Deploy/ui/general/spirilink.js
2024-10-20 17:18:42 -03:00

250 lines
11 KiB
JavaScript

const scriptLocation = "/usr/local/echopilot/";
const confLocation = "/etc/wifibroadcast.cfg";
const encryptionFileLocation = "/etc/drone.key"; // Destination for encryption key
// Elements
const version = document.getElementById("version");
const file_location = document.getElementById("file_location");
const wifiChannel = document.getElementById("wifiChannel");
const wifiRegion = document.getElementById("wifiRegion");
const wifiTxPower = document.getElementById("wifiTxPower");
const tempInterval = document.getElementById("tempInterval");
const tempWarning = document.getElementById("tempWarning");
const droneMavlinkFwmark = document.getElementById("droneMavlinkFwmark");
const droneMavlinkType = document.getElementById("droneMavlinkType");
const droneMavlinkIP = document.getElementById("droneMavlinkIP");
const droneMavlinkPort = document.getElementById("droneMavlinkPort");
const droneVideoFwmark = document.getElementById("droneVideoFwmark");
const droneVideoType = document.getElementById("droneVideoType");
const droneVideoIP = document.getElementById("droneVideoIP");
const droneVideoPort = document.getElementById("droneVideoPort");
const injectRssi = document.getElementById("injectRssi");
const mavlinkSysId = document.getElementById("mavlinkSysId");
const mavlinkCompId = document.getElementById("mavlinkCompId");
const mavlinkTcpPort = document.getElementById("mavlinkTcpPort");
// Load initial settings
document.onload = InitPage();
// Save file button
document.getElementById("save").addEventListener("click", SaveSettings);
// Apply encryption file button
document.getElementById("applyEncryptionFile").addEventListener("click", ApplyEncryptionFile);
// Function to initialize the page
function InitPage() {
cockpit.script(scriptLocation + "cockpitScript.sh -v")
file_location.innerHTML = confLocation;
cockpit.file(confLocation)
.read()
.then((content) => {
console.log("Configuration file content:", content);
SuccessReadFile(content);
})
.catch(error => {
console.error("Failed to read configuration file:", error);
FailureReadFile(error);
});
}
// Load configuration values from the configuration file
function SuccessReadFile(content) {
try {
// WiFi Configuration
wifiChannel.value = getValueByKey(content, "common", "wifi_channel");
console.log("wifi_channel:", wifiChannel.value);
// Remove surrounding quotes from wifi_region value if present
wifiRegion.value = getValueByKey(content, "common", "wifi_region").replace(/^['"]|['"]$/g, "");
console.log("wifi_region:", wifiRegion.value);
// Handle "None" value for wifi_txpower
const txPowerValue = getValueByKey(content, "common", "wifi_txpower");
wifiTxPower.value = txPowerValue === "None" ? "" : txPowerValue;
console.log("wifi_txpower:", wifiTxPower.value);
tempInterval.value = getValueByKey(content, "common", "temp_measurement_interval");
console.log("temp_measurement_interval:", tempInterval.value);
tempWarning.value = getValueByKey(content, "common", "temp_overheat_warning");
console.log("temp_overheat_warning:", tempWarning.value);
// Drone MAVLink Configuration
droneMavlinkFwmark.value = getValueByKey(content, "drone_mavlink", "fwmark");
console.log("drone_mavlink_fwmark:", droneMavlinkFwmark.value);
const droneMavlinkPeer = getValueByKey(content, "drone_mavlink", "peer");
console.log("drone_mavlink_peer:", droneMavlinkPeer);
if (droneMavlinkPeer) {
parsePeer(droneMavlinkPeer, droneMavlinkType, droneMavlinkIP, droneMavlinkPort);
}
// Drone Video Configuration
droneVideoFwmark.value = getValueByKey(content, "drone_video", "fwmark");
console.log("drone_video_fwmark:", droneVideoFwmark.value);
const droneVideoPeer = getValueByKey(content, "drone_video", "peer");
console.log("drone_video_peer:", droneVideoPeer);
if (droneVideoPeer) {
parsePeer(droneVideoPeer, droneVideoType, droneVideoIP, droneVideoPort);
}
// MAVLink Configuration
injectRssi.checked = getValueByKey(content, "mavlink", "inject_rssi") === "True";
console.log("inject_rssi:", injectRssi.checked);
mavlinkSysId.value = getValueByKey(content, "mavlink", "mavlink_sys_id");
console.log("mavlink_sys_id:", mavlinkSysId.value);
mavlinkCompId.value = getValueByKey(content, "mavlink", "mavlink_comp_id");
console.log("mavlink_comp_id:", mavlinkCompId.value);
const tcpPortValue = getValueByKey(content, "mavlink", "mavlink_tcp_port");
mavlinkTcpPort.value = tcpPortValue === "None" ? "" : tcpPortValue;
console.log("mavlink_tcp_port:", mavlinkTcpPort.value);
} catch (e) {
console.error("Error parsing configuration file:", e);
FailureReadFile(e);
}
}
// Save configuration values to the configuration file
function SaveSettings() {
try {
cockpit.file(confLocation)
.read()
.then((content) => {
// WiFi Configuration
content = setValueByKey(content, "[common]", "wifi_channel", wifiChannel.value);
content = setValueByKey(content, "[common]", "wifi_region", wifiRegion.value);
content = setValueByKey(content, "[common]", "wifi_txpower", wifiTxPower.value === "" ? "None" : wifiTxPower.value);
content = setValueByKey(content, "[common]", "temp_measurement_interval", tempInterval.value);
content = setValueByKey(content, "[common]", "temp_overheat_warning", tempWarning.value);
// Drone MAVLink Configuration
const droneMavlinkPeer = `${droneMavlinkType.value}://${droneMavlinkIP.value}:${droneMavlinkPort.value}`;
content = setValueByKey(content, "[drone_mavlink]", "fwmark", droneMavlinkFwmark.value);
content = setValueByKey(content, "[drone_mavlink]", "peer", droneMavlinkPeer);
// Drone Video Configuration
const droneVideoPeer = `${droneVideoType.value}://${droneVideoIP.value}:${droneVideoPort.value}`;
content = setValueByKey(content, "[drone_video]", "fwmark", droneVideoFwmark.value);
content = setValueByKey(content, "[drone_video]", "peer", droneVideoPeer);
// MAVLink Configuration
content = setValueByKey(content, "[mavlink]", "inject_rssi", injectRssi.checked ? "True" : "False");
content = setValueByKey(content, "[mavlink]", "mavlink_sys_id", mavlinkSysId.value);
content = setValueByKey(content, "[mavlink]", "mavlink_comp_id", mavlinkCompId.value);
content = setValueByKey(content, "[mavlink]", "mavlink_tcp_port", mavlinkTcpPort.value === "" ? "None" : mavlinkTcpPort.value);
cockpit.file(confLocation, { superuser: "try" }).replace(content)
.then(() => {
console.log("Configuration saved successfully.");
RestartWifibroadcastService();
Success();
})
.catch((error) => {
console.error("Failed to save configuration:", error);
Fail(error);
});
})
.catch(error => {
console.error("Failed to read configuration file:", error);
FailureReadFile(error);
});
} catch (e) {
console.error("Error during save operation:", e);
FailureReadFile(e);
}
}
// Apply encryption file from base station
function ApplyEncryptionFile() {
const command = `
/usr/bin/sshpass -p 'spirifriend' scp -o StrictHostKeyChecking=no spiri@spiri-base.local:/home/spiri/drone.key /tmp/drone.key &&
/usr/bin/sudo /bin/mv /tmp/drone.key ${encryptionFileLocation} &&
/usr/bin/sudo /bin/systemctl restart wifibroadcast@drone
`;
cockpit.spawn(["bash", "-c", command], { superuser: "require" })
.then(() => {
console.log("Encryption key applied and wifibroadcast service restarted.");
Success();
})
.catch((error) => {
console.error("Failed to apply encryption key or restart service:", error);
Fail(error);
});
}
// Restart wifibroadcast service
function RestartWifibroadcastService() {
cockpit.spawn(["systemctl", "restart", "wifibroadcast@drone"], { superuser: "require" })
.then(() => {
console.log("wifibroadcast@drone service restarted.");
})
.catch((error) => {
console.error("Failed to restart wifibroadcast@drone service:", error);
});
}
// Success handler
function Success() {
result.style.color = "green";
result.innerHTML = "Success, settings saved.";
setTimeout(() => result.innerHTML = "", 5000);
}
// Failure handler
function Fail(error) {
result.style.color = "red";
result.innerHTML = error.message;
}
// Parse Peer configuration (type, IP, port)
function parsePeer(peer, typeElement, ipElement, portElement) {
if (!peer) {
console.warn("Peer value is empty or undefined.");
return; // Skip if peer is empty
}
const regex = /(listen|connect):\/\/([\d.]+):(\d+)/;
const match = peer.match(regex);
if (match) {
typeElement.value = match[1];
ipElement.value = match[2];
portElement.value = match[3];
} else {
console.error("Failed to parse peer:", peer);
}
}
// Get value by key from configuration content
function getValueByKey(content, section, key) {
const sectionRegex = new RegExp(`\\[${section}\\][\\s\\S]*?^${key}\\s*=\\s*(.*)`, "m");
const match = content.match(sectionRegex);
if (match) {
let value = match[1].trim();
console.log(`Found key [${key}] in section [${section}]:`, value);
return value;
} else {
console.warn(`Key [${key}] not found in section [${section}]`);
return "";
}
}
// Set value by key in configuration content
function setValueByKey(content, section, key, value) {
const regex = new RegExp(`(${section}[\\s\\S]*?)(${key}\\s*=\\s*)(.*)`, "m");
if (content.match(regex)) {
return content.replace(regex, `$1$2${value}`);
} else {
// Add key if not found
const sectionRegex = new RegExp(`(${section}[\\s\\S]*?)\\n`, "m");
return content.match(sectionRegex)
? content.replace(sectionRegex, `$1\n${key} = ${value}\n`)
: `${content}\n${section}\n${key} = ${value}\n`;
}
}