rhombus-node-mcp
Version:
MCP server for Rhombus API
113 lines (112 loc) • 4.33 kB
JavaScript
import { postApi } from "../network/network.js";
function computeUptimeStats(cameraUuid, cameraName, locationUuid, windows, startTimeSec, endTimeSec) {
const totalPeriodSeconds = endTimeSec - startTimeSec;
let totalUptimeSeconds = 0;
const sortedWindows = windows
.filter(w => w.startSeconds != null && w.durationSeconds != null)
.sort((a, b) => (a.startSeconds ?? 0) - (b.startSeconds ?? 0));
for (const w of sortedWindows) {
const wStart = Math.max(w.startSeconds, startTimeSec);
const wEnd = Math.min(w.startSeconds + w.durationSeconds, endTimeSec);
if (wEnd > wStart) {
totalUptimeSeconds += wEnd - wStart;
}
}
let outageCount = 0;
let longestOutageSeconds = 0;
let lastEnd = startTimeSec;
for (const w of sortedWindows) {
const wStart = Math.max(w.startSeconds, startTimeSec);
if (wStart > lastEnd) {
outageCount++;
longestOutageSeconds = Math.max(longestOutageSeconds, wStart - lastEnd);
}
const wEnd = Math.min(w.startSeconds + w.durationSeconds, endTimeSec);
lastEnd = Math.max(lastEnd, wEnd);
}
if (lastEnd < endTimeSec) {
outageCount++;
longestOutageSeconds = Math.max(longestOutageSeconds, endTimeSec - lastEnd);
}
const uptimePercentage = totalPeriodSeconds > 0
? Math.round((totalUptimeSeconds / totalPeriodSeconds) * 10000) / 100
: 0;
return {
cameraUuid,
cameraName,
locationUuid,
totalUptimeSeconds,
totalPeriodSeconds,
uptimePercentage,
outageCount,
longestOutageSeconds,
};
}
export async function getCameraUptime(cameraUuid, startTimeSec, endTimeSec, requestModifiers, sessionId) {
const res = await postApi({
route: "/camera/getUptimeWindows",
body: {
cameraUuid,
startTime: startTimeSec,
endTime: endTimeSec,
},
modifiers: requestModifiers,
sessionId,
});
if (res.error) {
throw new Error(res.errorMsg ?? "Failed to get camera uptime windows");
}
return computeUptimeStats(cameraUuid, undefined, undefined, (res.uptimeWindows ?? []), startTimeSec, endTimeSec);
}
export async function getFleetUptime(startTimeSec, endTimeSec, requestModifiers, sessionId) {
const cameraListRes = await postApi({
route: "/camera/getMinimalCameraStateList",
body: {},
modifiers: requestModifiers,
sessionId,
});
const cameras = (cameraListRes.cameraStates ?? [])
.filter((c) => c.locationUuid)
.map((c) => ({
uuid: c.uuid,
name: c.name ?? c.uuid,
locationUuid: c.locationUuid,
}));
const uptimeResults = [];
const batchSize = 10;
for (let i = 0; i < cameras.length; i += batchSize) {
const batch = cameras.slice(i, i + batchSize);
const batchResults = await Promise.all(batch.map(async (cam) => {
try {
const res = await postApi({
route: "/camera/getUptimeWindows",
body: {
cameraUuid: cam.uuid,
startTime: startTimeSec,
endTime: endTimeSec,
},
modifiers: requestModifiers,
sessionId,
});
return computeUptimeStats(cam.uuid, cam.name, cam.locationUuid, (res.uptimeWindows ?? []), startTimeSec, endTimeSec);
}
catch {
return computeUptimeStats(cam.uuid, cam.name, cam.locationUuid, [], startTimeSec, endTimeSec);
}
}));
uptimeResults.push(...batchResults);
}
uptimeResults.sort((a, b) => a.uptimePercentage - b.uptimePercentage);
const avgUptime = uptimeResults.length > 0
? Math.round((uptimeResults.reduce((sum, r) => sum + r.uptimePercentage, 0) / uptimeResults.length) * 100) / 100
: 0;
return {
cameras: uptimeResults,
summary: {
totalCameras: uptimeResults.length,
averageUptimePercentage: avgUptime,
worstCamera: uptimeResults[0]?.cameraName,
worstUptimePercentage: uptimeResults[0]?.uptimePercentage,
},
};
}