diverter-device-emulator/src/routes.js
2026-09-22 22:26:58 +01:00

145 lines
4.2 KiB
JavaScript

const express = require("express");
const deviceManager = require("./deviceManager");
const thingsboard = require("./thingsboard");
const config = require("./config");
const router = express.Router();
function asyncHandler(fn) {
return (req, res, next) => {
try {
Promise.resolve(fn(req, res, next)).catch(next);
} catch (error) {
next(error);
}
};
}
function idsFromBody(body) {
const ids = body?.ids;
if (!Array.isArray(ids) || ids.length === 0) {
const error = new Error("ids[] is required");
error.status = 400;
throw error;
}
return ids.map(String);
}
router.get("/health", asyncHandler(async (_req, res) => {
const tb = await thingsboard.ping();
res.json({
ok: true,
mqttUrl: config.tbMqttUrl,
thingsboard: tb,
});
}));
router.get("/telemetry-schema", (_req, res) => {
res.json(deviceManager.telemetrySchema());
});
router.get("/device-profiles", asyncHandler(async (_req, res) => {
const profiles = await thingsboard.listDeviceProfiles();
const preferred = profiles.find((profile) => profile.preferred);
res.json({
profiles,
defaultProfileId: preferred?.id || config.tbDeviceProfileId || null,
});
}));
router.get("/devices", (_req, res) => {
res.json({ devices: deviceManager.list() });
});
router.post("/devices", asyncHandler(async (req, res) => {
const device = await deviceManager.create({
name: req.body?.name,
label: req.body?.label,
type: req.body?.type,
deviceProfileId: req.body?.deviceProfileId,
accessToken: req.body?.accessToken,
id: req.body?.id,
});
res.status(201).json({ device });
}));
router.post("/devices/adopt", asyncHandler(async (req, res) => {
const device = await deviceManager.adopt({
name: req.body?.name,
label: req.body?.label,
type: req.body?.type,
});
res.status(201).json({ device });
}));
router.delete("/devices/:id", asyncHandler(async (req, res) => {
const result = await deviceManager.remove(req.params.id);
res.json(result);
}));
router.post("/devices/delete", asyncHandler(async (req, res) => {
const results = await deviceManager.removeMany(idsFromBody(req.body));
res.json({ results });
}));
router.patch("/devices/:id/published-keys", asyncHandler(async (req, res) => {
const device = deviceManager.setPublishedKeys(req.params.id, req.body?.keys);
res.json({ device });
}));
router.patch("/devices/:id/telemetry", asyncHandler(async (req, res) => {
const device = deviceManager.updateTelemetry(req.params.id, req.body || {});
res.json({ device });
}));
router.post("/devices/:id/telemetry/start", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.startTelemetry(req.params.id) });
}));
router.post("/devices/:id/telemetry/stop", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.stopTelemetry(req.params.id) });
}));
router.post("/devices/:id/telemetry/publish", asyncHandler(async (req, res) => {
const device = deviceManager.updateTelemetry(req.params.id, req.body || {});
res.json({ device });
}));
router.post("/devices/:id/interval", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.setIntervalMs(req.params.id, req.body?.intervalMs) });
}));
router.patch("/devices/:id/plant", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.setPlant(req.params.id, req.body || {}) });
}));
router.post("/devices/:id/disable", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.disable(req.params.id) });
}));
router.post("/devices/:id/enable", asyncHandler(async (req, res) => {
res.json({ device: deviceManager.enable(req.params.id) });
}));
router.post("/devices/disable", asyncHandler(async (req, res) => {
res.json({ results: deviceManager.applyMany(idsFromBody(req.body), deviceManager.disable) });
}));
router.post("/devices/enable", asyncHandler(async (req, res) => {
res.json({ results: deviceManager.applyMany(idsFromBody(req.body), deviceManager.enable) });
}));
router.use((_req, res) => {
res.status(404).json({ error: "Not found" });
});
router.use((error, _req, res, _next) => {
const status = error.status || 500;
res.status(status).json({
error: error.message || "Unexpected error",
timedOut: Boolean(error.timedOut),
});
});
module.exports = router;