Add the reusable RMS core application (server, web UI, plugins, tests, tools) with generic defaults, GPL licensing, and maintainer context documentation so deployments can consume this repo as software source independent of station-specific overlays.
94 lines
2.7 KiB
JavaScript
94 lines
2.7 KiB
JavaScript
async function createPlugin(ctx) {
|
|
let lastAzimuth = Number(ctx.getSetting("defaultAzimuth", ctx.env.ROTOR_DEFAULT_AZIMUTH || 0));
|
|
const simulate = typeof ctx.simulateHardware === "boolean"
|
|
? ctx.simulateHardware
|
|
: (process.platform !== "linux" && String(ctx.env.ALLOW_NON_LINUX_CMDS || "false") !== "true");
|
|
|
|
return {
|
|
async execute(action, input) {
|
|
if (action === "getAzimuth") {
|
|
return getRotorStatus(ctx, simulate, () => lastAzimuth, (value) => {
|
|
lastAzimuth = value;
|
|
});
|
|
}
|
|
if (action !== "setAzimuth") {
|
|
throw new Error(`Unknown action: ${action}`);
|
|
}
|
|
const target = Number(input && input.target);
|
|
if (!Number.isFinite(target) || target < 0 || target > 360) {
|
|
throw new Error("target muss zwischen 0 und 360 sein");
|
|
}
|
|
|
|
const template = String(ctx.getSetting("setTemplate", ctx.env.ROTOR_SET_CMD_TEMPLATE || "")).trim();
|
|
if (template) {
|
|
if (simulate) {
|
|
lastAzimuth = target;
|
|
return {
|
|
ok: true,
|
|
skipped: true,
|
|
message: `Rotor auf ${target} Grad simuliert (${ctx.execMode || "dev"})`
|
|
};
|
|
}
|
|
const command = template.replace(/\{az\}/g, String(target));
|
|
const result = await ctx.commandRunner(command, {
|
|
timeoutMs: Number(ctx.env.ROTOR_SET_TIMEOUT_MS || 20000)
|
|
});
|
|
if (!result.ok) {
|
|
throw new Error(result.stderr || result.error || "Rotor set failed");
|
|
}
|
|
}
|
|
|
|
lastAzimuth = target;
|
|
ctx.emit("ui.control.state.changed", {
|
|
controlId: "rotor-main",
|
|
data: { azimuth: lastAzimuth, moving: false }
|
|
});
|
|
return {
|
|
ok: true,
|
|
message: `Rotor auf ${target} Grad gesetzt`
|
|
};
|
|
},
|
|
async getStatus() {
|
|
return getRotorStatus(ctx, simulate, () => lastAzimuth, (value) => {
|
|
lastAzimuth = value;
|
|
});
|
|
},
|
|
async health() {
|
|
return { ok: true };
|
|
}
|
|
};
|
|
}
|
|
|
|
async function getRotorStatus(ctx, simulate, getLastAzimuth, setLastAzimuth) {
|
|
const getCmd = String(ctx.getSetting("getCommand", ctx.env.ROTOR_GET_CMD || "")).trim();
|
|
if (getCmd) {
|
|
if (simulate) {
|
|
return {
|
|
azimuth: getLastAzimuth(),
|
|
moving: false,
|
|
min: 0,
|
|
max: 360
|
|
};
|
|
}
|
|
const result = await ctx.commandRunner(getCmd, {
|
|
timeoutMs: Number(ctx.env.ROTOR_GET_TIMEOUT_MS || 10000)
|
|
});
|
|
if (result.ok) {
|
|
const parsed = Number(String(result.stdout).split(/\s+/)[0]);
|
|
if (Number.isFinite(parsed)) {
|
|
setLastAzimuth(parsed < 0 ? parsed + 360 : parsed);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
azimuth: getLastAzimuth(),
|
|
moving: false,
|
|
min: 0,
|
|
max: 360
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
createPlugin
|
|
};
|