openclaw / src /cli /nodes-cli /register.location.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
f778c12 verified
Raw
History Blame Contribute Delete
3.62 kB
// Node location commands: invokes location.get on a paired node and formats the location payload.
import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce";
import type { Command } from "commander";
import { defaultRuntime } from "../../runtime.js";
import { runNodesCommand } from "./cli-utils.js";
import {
buildNodeInvokeParams,
callNodesGatewayCli,
nodesCallOpts,
parseOptionalNodeNonNegativeInteger,
parseOptionalNodePositiveInteger,
resolveCliNodeId,
} from "./rpc.js";
import type { NodesRpcOpts } from "./types.js";
/** Register node location lookup commands. */
export function registerNodesLocationCommands(nodes: Command) {
const location = nodes.command("location").description("Fetch location from a paired node");
nodesCallOpts(
location
.command("get")
.description("Fetch the current location from a node")
.requiredOption("--node <idOrNameOrIp>", "Node id, name, or IP")
.option("--max-age <ms>", "Use cached location newer than this (ms)")
.option(
"--accuracy <coarse|balanced|precise>",
"Desired accuracy (default: balanced/precise depending on node setting)",
)
.option("--location-timeout <ms>", "Location fix timeout (ms)", "10000")
.option("--invoke-timeout <ms>", "Node invoke timeout in ms (default 20000)", "20000")
.action(async (opts: NodesRpcOpts) => {
await runNodesCommand("location get", async () => {
const desiredAccuracyRaw = normalizeOptionalLowercaseString(opts.accuracy);
const desiredAccuracy =
desiredAccuracyRaw === "coarse" ||
desiredAccuracyRaw === "balanced" ||
desiredAccuracyRaw === "precise"
? desiredAccuracyRaw
: undefined;
if (opts.accuracy !== undefined && desiredAccuracy === undefined) {
throw new Error("invalid --accuracy (use coarse|balanced|precise)");
}
const maxAgeMs = parseOptionalNodeNonNegativeInteger(opts.maxAge, "--max-age");
const timeoutMs = parseOptionalNodePositiveInteger(
opts.locationTimeout,
"--location-timeout",
);
const invokeTimeoutMs = parseOptionalNodePositiveInteger(
opts.invokeTimeout,
"--invoke-timeout",
);
const nodeId = await resolveCliNodeId(opts, opts.node ?? "");
const invokeParams = buildNodeInvokeParams({
nodeId,
command: "location.get",
params: {
maxAgeMs,
desiredAccuracy,
timeoutMs,
},
timeoutMs: invokeTimeoutMs,
});
const raw = await callNodesGatewayCli("node.invoke", opts, invokeParams);
const res = typeof raw === "object" && raw !== null ? (raw as { payload?: unknown }) : {};
const payload =
res.payload && typeof res.payload === "object"
? (res.payload as Record<string, unknown>)
: {};
if (opts.json) {
defaultRuntime.writeJson(payload);
return;
}
const lat = payload.lat;
const lon = payload.lon;
const acc = payload.accuracyMeters;
if (typeof lat === "number" && typeof lon === "number") {
const accText = typeof acc === "number" ? ` ±${acc.toFixed(1)}m` : "";
defaultRuntime.log(`${lat},${lon}${accText}`);
return;
}
defaultRuntime.writeJson(payload, 0);
});
}),
{ timeoutMs: 30_000 },
);
}