From 3c23f0e20e4c97ee7997be1f4a909b9b1dc7e2c1 Mon Sep 17 00:00:00 2001 From: Khavin Shankar Date: Fri, 28 Jul 2023 12:19:34 +0530 Subject: [PATCH 1/2] group device status by minutes (#78) --- src/controller/ObservationController.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/controller/ObservationController.js b/src/controller/ObservationController.js index f585a86..5b573d4 100644 --- a/src/controller/ObservationController.js +++ b/src/controller/ObservationController.js @@ -373,13 +373,13 @@ const updateObservationsToCare = async () => { const filterStatusData = () => { const MIN_IN_MS = 60000; statusData = statusData.filter( - (status) => new Date() - status.time <= 30 * MIN_IN_MS + (status) => new Date() - new Date(status.time) <= 30 * MIN_IN_MS ); }; const parseDataAsStatus = (data) => { return { - time: new Date(), + time: new Date(new Date().setSeconds(0, 0)).toISOString(), status: data.reduce((acc, device_observations) => { device_observations.forEach((observation) => { @@ -396,7 +396,24 @@ const parseDataAsStatus = (data) => { const addStatusData = (data) => { filterStatusData(); - statusData.push(parseDataAsStatus(data)); + const newStatus = parseDataAsStatus(data); + + const index = statusData.findIndex( + (status) => status.time === newStatus.time + ); + + if (index === -1) { + statusData.push(newStatus); + return; + } + + statusData[index] = { + time: newStatus.time, + status: { + ...statusData[index].status, + ...newStatus.status, + }, + }; }; export class ObservationController { From 9f9926df459701696330fe21167e1595b68eba18 Mon Sep 17 00:00:00 2001 From: Khavin Shankar Date: Fri, 28 Jul 2023 12:20:14 +0530 Subject: [PATCH 2/2] added a route a get all camera statuses (#79) --- src/Validators/cameraValidators.js | 24 +++++++++++ src/controller/CameraController.js | 67 ++++++++++++++++++++++++++++++ src/router/cameraRouter.js | 7 ++++ 3 files changed, 98 insertions(+) diff --git a/src/Validators/cameraValidators.js b/src/Validators/cameraValidators.js index 9934158..28ecfdf 100644 --- a/src/Validators/cameraValidators.js +++ b/src/Validators/cameraValidators.js @@ -46,6 +46,30 @@ export const baseGetCameraParamsValidators = [ .withMessage("port must be integer."), ]; +export const camerasStatusBodyValidators = [ + body().isArray().withMessage("body must be a valid array."), + body("*.hostname") + .exists({ checkFalsy: true }) + .withMessage("hostname is required.") + .isString() + .withMessage("hostname must be string."), + body("*.username") + .exists({ checkFalsy: true }) + .withMessage("username is required.") + .isString() + .withMessage("username must be string."), + body("*.password") + .exists({ checkFalsy: true }) + .withMessage("password is required.") + .isString() + .withMessage("password must be string."), + body("*.port") + .exists({ checkFalsy: true }) + .withMessage("port is required.") + .isInt() + .withMessage("port must be integer."), +]; + export const gotoPresetValidator = [ ...baseCameraParamsValidators, body("preset") diff --git a/src/controller/CameraController.js b/src/controller/CameraController.js index d97ad98..517ce84 100644 --- a/src/controller/CameraController.js +++ b/src/controller/CameraController.js @@ -140,6 +140,73 @@ export class CameraController { res.send(status); }); + /** + * @swagger + * /cameras/status: + * post: + * summary: "Get status of cameras" + * tags: + * - status + * requestBody: + * content: + * application/json: + * schema: + * type: array + * items: + * type: object + * properties: + * hostname: + * type: string + * description: Device Id or device IP address + * port: + * type: number + * enum: [80, 443] + * username: + * type: string + * password: + * type: string + * responses: + * "200": + * description: Return camera statuses + * content: + * application/json: + * schema: + * type: object + * properties: + * time: + * type: string + * format: date-time + * status: + * type: object + * properties: + * device_id: + * type: string + * enum: [up, down] + */ + static getCameraStatuses = catchAsync(async (req, res) => { + const cameras = req.body; + + const cameraStatuses = await Promise.all( + cameras.map(async (camera) => { + const camParams = this._getCamParams(camera); + const status = await CameraUtils.getStatus({ camParams }); + + return { + deviceId: camera.hostname, + status: status?.error === "NO error" ? "up" : "down", + }; + }) + ); + + return res.json({ + time: new Date().toISOString(), + status: cameraStatuses.reduce( + (acc, curr) => (acc[curr.deviceId] = curr.status), + {} + ), + }); + }); + /** * @swagger * /absoluteMove: diff --git a/src/router/cameraRouter.js b/src/router/cameraRouter.js index 3ed6b01..4147edd 100644 --- a/src/router/cameraRouter.js +++ b/src/router/cameraRouter.js @@ -5,6 +5,7 @@ import { CameraController } from "../controller/CameraController.js"; import { validate } from "../middleware/validate.js"; import { baseCameraParamsValidators, + camerasStatusBodyValidators, setPresetValidators, baseGetCameraParamsValidators, camMoveValidator, @@ -31,6 +32,12 @@ router.get( CameraController.getStatus ); +router.post( + "cameras/status", + validate(camerasStatusBodyValidators), + CameraController.getCameraStatuses +); + router.post( "/gotoPreset", validate(gotoPresetValidator),