initialize generic rms-software repository
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.
This commit is contained in:
93
plugins/rms.rotor.hamlib/index.js
Normal file
93
plugins/rms.rotor.hamlib/index.js
Normal file
@@ -0,0 +1,93 @@
|
||||
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
|
||||
};
|
||||
Reference in New Issue
Block a user