rhombus-node-mcp 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/api/camera-tool-api.js +108 -0
- package/dist/api/clips-tool-api.js +36 -0
- package/dist/api/create-camera-policy-tool-api.js +9 -0
- package/dist/api/create-tool-api.js +53 -0
- package/dist/api/entity-lookup-tool-api.js +37 -0
- package/dist/api/events-tool-api.js +320 -0
- package/dist/api/faces-tool-api.js +110 -0
- package/dist/api/get-entity-tool-api.js +176 -0
- package/dist/api/get-org-information-tool-api.js +9 -0
- package/dist/api/location-tool-api.js +9 -0
- package/dist/api/lpr-tool-api.js +68 -0
- package/dist/api/policy-alerts-tool-api.js +42 -0
- package/dist/api/reboot-cameras-tool-api.js +34 -0
- package/dist/api/report-tool-api.js +426 -0
- package/dist/api/time-tool-api.js +90 -0
- package/dist/api/update-tool-api.js +148 -0
- package/dist/createServer.js +7 -1
- package/dist/disabled-tools/endpoint-to-keys-tool.js +84 -0
- package/dist/disabled-tools/semantic-search-tool.js +90 -0
- package/dist/index.js +3 -5
- package/dist/logger.js +4 -3
- package/dist/network.js +42 -15
- package/dist/resources/routes.json.js +1 -1
- package/dist/services/embedding-service.js +153 -0
- package/dist/services/faiss-search-service.js +261 -0
- package/dist/tools/camera-tool.js +100 -0
- package/dist/tools/clips-tool.js +23 -37
- package/dist/tools/count-tool.js +25 -0
- package/dist/tools/create-camera-policy-tool.js +214 -0
- package/dist/tools/create-tool.js +25 -74
- package/dist/tools/entity-lookup-tool.js +35 -0
- package/dist/tools/events-tool.js +188 -92
- package/dist/tools/faces-tool.js +59 -132
- package/dist/tools/get-entity-tool.js +78 -0
- package/dist/tools/get-org-information-tool.js +18 -0
- package/dist/tools/location-tool.js +24 -31
- package/dist/tools/lpr-tool.js +71 -0
- package/dist/tools/policy-alerts-tool.js +32 -42
- package/dist/tools/reboot-cameras-tool.js +34 -0
- package/dist/tools/report-tool.js +190 -0
- package/dist/tools/time-conversion-tool.js +43 -0
- package/dist/tools/time-tool.js +17 -57
- package/dist/tools/update-tool.js +262 -0
- package/dist/transports/streamable-http.js +160 -57
- package/dist/{tools/devices/camera-tool/types.js → types/camera-tool-types.js} +13 -0
- package/dist/types/clips-tool-types.js +41 -0
- package/dist/types/create-camera-policy-tool-types.js +44 -0
- package/dist/types/create-tool-types.js +8 -0
- package/dist/types/deviceType.js +1 -0
- package/dist/types/endpoint-to-keys-tool-types.js +7 -0
- package/dist/types/entity-lookup-tool-types.js +70 -0
- package/dist/types/events-tools-types.js +257 -0
- package/dist/types/faces-tools-types.js +143 -0
- package/dist/types/get-entity-tool-types.js +25 -0
- package/dist/types/get-org-information-tool-types.js +3 -0
- package/dist/types/location-tool-types.js +11 -0
- package/dist/types/lpr-tool-types.js +97 -0
- package/dist/types/policy-alerts-tool-types.js +74 -0
- package/dist/types/reboot-cameras-tool-types.js +8 -0
- package/dist/types/report-tool-types.js +268 -0
- package/dist/types/schema-components.js +7093 -0
- package/dist/types/schema.js +1 -0
- package/dist/types/semantic-search-tool-types.js +5 -0
- package/dist/types/time-conversion-tool-types.js +8 -0
- package/dist/types/time-tool-types.js +11 -0
- package/dist/types/update-tool-types.js +186 -0
- package/dist/types/zod-schemas.js +21315 -0
- package/dist/types.js +17 -7
- package/dist/util.js +94 -2
- package/dist/utils/confirmation.js +1 -1
- package/dist/utils/reduce-output.js +35 -0
- package/dist/utils/remove-nulls.js +28 -0
- package/dist/utils/temp.js +8 -0
- package/dist/utils/timestampInput.js +12 -0
- package/package.json +23 -3
- package/dist/tools/devices/camera-tool/camera-tool.js +0 -218
- package/dist/tools/devices/get-entity-tool.js +0 -118
- package/dist/tools/get-org-information.js +0 -17
- package/dist/tools/reboot-cameras.js +0 -62
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { postApi } from "../network.js";
|
|
2
|
+
import { formatTimestamp } from "../util.js";
|
|
3
|
+
import { removeNulls } from "../utils/remove-nulls.js";
|
|
4
|
+
export async function getFaceEvents(args, timeZone, requestModifiers, sessionId) {
|
|
5
|
+
let allFaceEvents = [];
|
|
6
|
+
let currentArgs = { ...args };
|
|
7
|
+
let hasMore = true;
|
|
8
|
+
let lastResponse = null;
|
|
9
|
+
while (hasMore) {
|
|
10
|
+
// Filter out empty/undefined fields from currentArgs
|
|
11
|
+
// OptionalNullable so that we can remove some fields before returning them to the MCP client
|
|
12
|
+
let filteredArgs = { ...currentArgs };
|
|
13
|
+
if (filteredArgs.pageRequest) {
|
|
14
|
+
if (filteredArgs.pageRequest.lastEvaluatedKey === "") {
|
|
15
|
+
delete filteredArgs.pageRequest.lastEvaluatedKey;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (filteredArgs.searchFilter) {
|
|
19
|
+
// Remove empty arrays
|
|
20
|
+
// if (
|
|
21
|
+
// filteredArgs.searchFilter.deviceUuids &&
|
|
22
|
+
// filteredArgs.searchFilter.deviceUuids.length === 0
|
|
23
|
+
// ) {
|
|
24
|
+
// // @ts-expect-error - we can break typing
|
|
25
|
+
// delete filteredArgs.searchFilter.deviceUuids;
|
|
26
|
+
// }
|
|
27
|
+
if (filteredArgs.searchFilter.faceNames && filteredArgs.searchFilter.faceNames.length === 0) {
|
|
28
|
+
// @ts-expect-error - we can break typing
|
|
29
|
+
delete filteredArgs.searchFilter.faceNames;
|
|
30
|
+
}
|
|
31
|
+
if (filteredArgs.searchFilter.labels && filteredArgs.searchFilter.labels.length === 0) {
|
|
32
|
+
// @ts-expect-error - we can break typing
|
|
33
|
+
delete filteredArgs.searchFilter.labels;
|
|
34
|
+
}
|
|
35
|
+
// Remove empty strings
|
|
36
|
+
// if (filteredArgs.searchFilter.faceNameContains === "") {
|
|
37
|
+
// delete filteredArgs.searchFilter.faceNameContains;
|
|
38
|
+
// }
|
|
39
|
+
// Remove false booleans
|
|
40
|
+
if (filteredArgs.searchFilter.hasEmbedding === false) {
|
|
41
|
+
delete filteredArgs.searchFilter.hasEmbedding;
|
|
42
|
+
}
|
|
43
|
+
if (filteredArgs.searchFilter.hasName === false) {
|
|
44
|
+
delete filteredArgs.searchFilter.hasName;
|
|
45
|
+
}
|
|
46
|
+
// if there is no timestampFilter, we can remove it
|
|
47
|
+
// rangeEnd and rangeStart are ISO 8601 strings
|
|
48
|
+
if (filteredArgs.searchFilter.timestampFilter) {
|
|
49
|
+
if (filteredArgs.searchFilter.timestampFilter.rangeEnd === null) {
|
|
50
|
+
delete filteredArgs.searchFilter.timestampFilter.rangeEnd;
|
|
51
|
+
}
|
|
52
|
+
if (filteredArgs.searchFilter.timestampFilter.rangeStart === null) {
|
|
53
|
+
delete filteredArgs.searchFilter.timestampFilter.rangeStart;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// one last sweep of null values
|
|
58
|
+
console.log("filteredArgs", filteredArgs);
|
|
59
|
+
filteredArgs = removeNulls(filteredArgs);
|
|
60
|
+
const response = await postApi({
|
|
61
|
+
route: "/faceRecognition/faceEvent/findFaceEventsByOrg",
|
|
62
|
+
body: filteredArgs,
|
|
63
|
+
modifiers: requestModifiers,
|
|
64
|
+
sessionId,
|
|
65
|
+
});
|
|
66
|
+
lastResponse = response;
|
|
67
|
+
// Filter the faceEvents to only include the specified fields
|
|
68
|
+
if (response && response.faceEvents) {
|
|
69
|
+
const filteredEvents = response.faceEvents.map((event) => ({
|
|
70
|
+
deviceUuid: event.deviceUuid,
|
|
71
|
+
eventTimestampMs: event.eventTimestamp,
|
|
72
|
+
eventTimestamp: formatTimestamp(event.eventTimestamp, timeZone),
|
|
73
|
+
faceName: event.faceName,
|
|
74
|
+
locationUuid: event.locationUuid,
|
|
75
|
+
personUuid: event.personUuid,
|
|
76
|
+
// selectedPersonMatch: event.selectedPersonMatch,
|
|
77
|
+
thumbnailS3Key: event.thumbnailS3Key,
|
|
78
|
+
// topPersonMatches: event.topPersonMatches,
|
|
79
|
+
uuid: event.uuid,
|
|
80
|
+
}));
|
|
81
|
+
allFaceEvents.push(...filteredEvents);
|
|
82
|
+
// Check if we should continue pagination
|
|
83
|
+
if (response.faceEvents.length === 100 && response.lastEvaluatedKey) {
|
|
84
|
+
// Update the pageRequest for the next iteration
|
|
85
|
+
currentArgs = {
|
|
86
|
+
...currentArgs,
|
|
87
|
+
pageRequest: {
|
|
88
|
+
maxPageSize: currentArgs.pageRequest?.maxPageSize || 100,
|
|
89
|
+
lastEvaluatedKey: response.lastEvaluatedKey,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
hasMore = false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
hasMore = false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return allFaceEvents;
|
|
102
|
+
}
|
|
103
|
+
export async function getRegisteredFaces(_args, requestModifiers, sessionId) {
|
|
104
|
+
return await postApi({
|
|
105
|
+
route: "/faceRecognition/person/findPeopleByOrg",
|
|
106
|
+
body: {},
|
|
107
|
+
modifiers: requestModifiers,
|
|
108
|
+
sessionId,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { logger } from "../logger.js";
|
|
2
|
+
import { postApi } from "../network.js";
|
|
3
|
+
import { formatTimestamp } from "../util.js";
|
|
4
|
+
import { tempFunc } from "../utils/temp.js";
|
|
5
|
+
export async function getCameraList(requestModifiers, sessionId) {
|
|
6
|
+
return {
|
|
7
|
+
cameras: (await postApi({
|
|
8
|
+
route: "/camera/getMinimalCameraStateList",
|
|
9
|
+
body: {},
|
|
10
|
+
modifiers: requestModifiers,
|
|
11
|
+
sessionId,
|
|
12
|
+
})).cameraStates.filter((camera) => !!camera.locationUuid),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export async function getDoorbellCameras(requestModifiers, sessionId) {
|
|
16
|
+
return {
|
|
17
|
+
doorbellCameras: (await postApi({
|
|
18
|
+
route: "/doorbellcamera/getMinimalStateList",
|
|
19
|
+
body: {},
|
|
20
|
+
modifiers: requestModifiers,
|
|
21
|
+
sessionId,
|
|
22
|
+
})).minimalStates.filter((doorbellCamera) => !!doorbellCamera.locationUuid),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export async function getBadgeReaders(requestModifiers, sessionId) {
|
|
26
|
+
return await postApi({
|
|
27
|
+
route: "/badgereader/getMinimalStateList",
|
|
28
|
+
body: {},
|
|
29
|
+
modifiers: requestModifiers,
|
|
30
|
+
sessionId,
|
|
31
|
+
}).then(response => {
|
|
32
|
+
return {
|
|
33
|
+
badgeReaders: response.minimalStates.filter((badgeReader) => !!badgeReader.locationUuid),
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function getAccessControlledDoors(requestModifiers, sessionId) {
|
|
38
|
+
return await postApi({
|
|
39
|
+
route: "/component/findAccessControlledDoors",
|
|
40
|
+
body: {},
|
|
41
|
+
modifiers: requestModifiers,
|
|
42
|
+
sessionId,
|
|
43
|
+
}).then(response => {
|
|
44
|
+
return {
|
|
45
|
+
accessControlledDoors: (response.accessControlledDoors || []).map((door) => {
|
|
46
|
+
return {
|
|
47
|
+
geofenceEnabled: door.geofenceEnabled,
|
|
48
|
+
locationUuid: door.locationUuid,
|
|
49
|
+
policyUuid: door.policyUuid,
|
|
50
|
+
name: door.name,
|
|
51
|
+
uuid: door.uuid,
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export async function getAudioGateways(timeZone, requestModifiers, sessionId) {
|
|
58
|
+
return await postApi({
|
|
59
|
+
route: "/audiogateway/getMinimalAudioGatewayStateList",
|
|
60
|
+
body: {},
|
|
61
|
+
modifiers: requestModifiers,
|
|
62
|
+
sessionId,
|
|
63
|
+
}).then(response => {
|
|
64
|
+
return {
|
|
65
|
+
audioGateways: response.audioGatewayStates
|
|
66
|
+
.filter((camera) => !!camera.locationUuid)
|
|
67
|
+
.map((gateway) => ({
|
|
68
|
+
...gateway,
|
|
69
|
+
createdAtString: gateway.createdAtMillis
|
|
70
|
+
? formatTimestamp(gateway.createdAtMillis, timeZone)
|
|
71
|
+
: undefined,
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export async function getDoorSensors(requestModifiers, sessionId) {
|
|
77
|
+
return await postApi({
|
|
78
|
+
route: "/door/getMinimalDoorStateList",
|
|
79
|
+
body: {},
|
|
80
|
+
modifiers: requestModifiers,
|
|
81
|
+
sessionId,
|
|
82
|
+
}).then(response => {
|
|
83
|
+
return {
|
|
84
|
+
doorStates: response.doorStates.filter((door) => !!door.locationUuid),
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export async function getEnvironmentalSensors(timeZone, tempUnit, requestModifiers, sessionId) {
|
|
89
|
+
return await postApi({
|
|
90
|
+
route: "/climate/getMinimalClimateStateList",
|
|
91
|
+
body: {},
|
|
92
|
+
modifiers: requestModifiers,
|
|
93
|
+
sessionId,
|
|
94
|
+
}).then(response => {
|
|
95
|
+
logger.info("Using tempUnit: ", tempUnit);
|
|
96
|
+
return {
|
|
97
|
+
climateStates: response.climateStates
|
|
98
|
+
.filter((sensor) => !!sensor.locationUuid)
|
|
99
|
+
.map((_sensor) => {
|
|
100
|
+
const { temperatureCelcius, ...sensor } = _sensor;
|
|
101
|
+
return {
|
|
102
|
+
...sensor,
|
|
103
|
+
temperature: tempFunc(temperatureCelcius ?? 0, tempUnit),
|
|
104
|
+
createdAtString: sensor.createdAtMillis
|
|
105
|
+
? formatTimestamp(sensor.createdAtMillis, timeZone)
|
|
106
|
+
: undefined,
|
|
107
|
+
};
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export async function getMotionSensors(requestModifiers, sessionId) {
|
|
113
|
+
return await postApi({
|
|
114
|
+
route: "/occupancy/getMinimalOccupancySensorStateList",
|
|
115
|
+
body: {},
|
|
116
|
+
modifiers: requestModifiers,
|
|
117
|
+
sessionId,
|
|
118
|
+
}).then(response => {
|
|
119
|
+
return {
|
|
120
|
+
occupancySensorStates: response.occupancySensorStates.filter((occupancySensor) => !!occupancySensor.locationUuid),
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
export async function getButtons(timeZone, requestModifiers, sessionId) {
|
|
125
|
+
return await postApi({
|
|
126
|
+
route: "/button/getMinimalButtonStateList",
|
|
127
|
+
body: {},
|
|
128
|
+
modifiers: requestModifiers,
|
|
129
|
+
sessionId,
|
|
130
|
+
}).then(response => {
|
|
131
|
+
return {
|
|
132
|
+
buttonStates: response.states
|
|
133
|
+
.filter((button) => !!button.locationUuid)
|
|
134
|
+
.map((button) => ({
|
|
135
|
+
...button,
|
|
136
|
+
createdAtString: button.createdAtMillis
|
|
137
|
+
? formatTimestamp(button.createdAtMillis, timeZone)
|
|
138
|
+
: undefined,
|
|
139
|
+
})),
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
export async function getKeypads(requestModifiers, sessionId) {
|
|
144
|
+
return await postApi({
|
|
145
|
+
route: "/keypad/getKeypadsForOrg",
|
|
146
|
+
body: {},
|
|
147
|
+
modifiers: requestModifiers,
|
|
148
|
+
sessionId,
|
|
149
|
+
}).then(response => {
|
|
150
|
+
return {
|
|
151
|
+
keypadStates: response.keypads.filter((keypad) => !!keypad.locationUuid),
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
export async function getEnvironmentalGateways(timeZone, requestModifiers, sessionId) {
|
|
156
|
+
return await postApi({
|
|
157
|
+
route: "/climate/getMinimalEnvironmentalGatewayStates",
|
|
158
|
+
body: {},
|
|
159
|
+
modifiers: requestModifiers,
|
|
160
|
+
sessionId,
|
|
161
|
+
}).then(response => {
|
|
162
|
+
return {
|
|
163
|
+
minimalEnvironmentalGatewayStates: response.minimalEnvironmentalGatewayStates
|
|
164
|
+
.filter((gateway) => !!gateway.locationUuid)
|
|
165
|
+
.map((gateway) => ({
|
|
166
|
+
...gateway,
|
|
167
|
+
createdAtString: gateway.createdAtMillis
|
|
168
|
+
? formatTimestamp(gateway.createdAtMillis, timeZone)
|
|
169
|
+
: undefined,
|
|
170
|
+
timestampString: gateway.timestampMs
|
|
171
|
+
? formatTimestamp(gateway.timestampMs, timeZone)
|
|
172
|
+
: undefined,
|
|
173
|
+
})),
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { postApi } from "../network.js";
|
|
2
|
+
import { formatTimestamp } from "../util.js";
|
|
3
|
+
export async function getVehicleEvents(args, timeZone, requestModifiers, sessionId) {
|
|
4
|
+
const requestArgs = {
|
|
5
|
+
deviceUuidFilter: args.deviceUuidFilter,
|
|
6
|
+
locationUuidFilter: args.locationUuidFilter,
|
|
7
|
+
vehicleLabelQuery: args.vehicleLabelQuery,
|
|
8
|
+
licensePlateFuzzyQuery: args.licensePlateFuzzyQuery,
|
|
9
|
+
startTimeMs: args.startTime ? new Date(args.startTime).getTime() : undefined,
|
|
10
|
+
endTimeMs: args.endTime ? new Date(args.endTime).getTime() : undefined,
|
|
11
|
+
};
|
|
12
|
+
const res = await postApi({
|
|
13
|
+
route: "/vehicle/getVehicleEvents",
|
|
14
|
+
body: requestArgs,
|
|
15
|
+
modifiers: requestModifiers,
|
|
16
|
+
sessionId,
|
|
17
|
+
});
|
|
18
|
+
if (res.error) {
|
|
19
|
+
throw new Error(JSON.stringify(res));
|
|
20
|
+
}
|
|
21
|
+
return (res.events?.map(event => ({
|
|
22
|
+
uuid: event.uuid ?? "",
|
|
23
|
+
deviceUuid: event.deviceUuid ?? undefined,
|
|
24
|
+
eventTimestamp: formatTimestamp(event.eventTimestamp ?? Date.now(), timeZone),
|
|
25
|
+
imageS3Key: event.imageS3Key ?? undefined,
|
|
26
|
+
thumbnailS3Key: event.thumbnailS3Key ?? undefined,
|
|
27
|
+
locationUuid: event.locationUuid ?? undefined,
|
|
28
|
+
vehicleLicensePlate: event.vehicleLicensePlate ?? "No License Plate",
|
|
29
|
+
})) ?? []);
|
|
30
|
+
}
|
|
31
|
+
export async function getSavedVehicles(timeZone, requestModifiers, sessionId) {
|
|
32
|
+
const res = await postApi({
|
|
33
|
+
route: "/vehicle/getVehicles",
|
|
34
|
+
body: {},
|
|
35
|
+
modifiers: requestModifiers,
|
|
36
|
+
sessionId,
|
|
37
|
+
});
|
|
38
|
+
if (res.error) {
|
|
39
|
+
throw new Error(JSON.stringify(res));
|
|
40
|
+
}
|
|
41
|
+
return (res.vehicles?.map(vehicle => ({
|
|
42
|
+
createdTimestamp: formatTimestamp(vehicle.createdAtMillis ?? Date.now(), timeZone),
|
|
43
|
+
name: vehicle.name ?? "No Name",
|
|
44
|
+
description: vehicle.description ?? "No Description",
|
|
45
|
+
licensePlate: vehicle.licensePlate ?? "No License Plate",
|
|
46
|
+
orgUuid: vehicle.orgUuid ?? "",
|
|
47
|
+
})) ?? []);
|
|
48
|
+
}
|
|
49
|
+
export async function getVehicleLabels(requestModifiers, sessionId) {
|
|
50
|
+
const res = await postApi({
|
|
51
|
+
route: "/vehicle/getVehicleLabelsForOrg",
|
|
52
|
+
body: {},
|
|
53
|
+
modifiers: requestModifiers,
|
|
54
|
+
sessionId,
|
|
55
|
+
});
|
|
56
|
+
if (res.error) {
|
|
57
|
+
throw new Error(JSON.stringify(res));
|
|
58
|
+
}
|
|
59
|
+
const processedVehicleLabels = {};
|
|
60
|
+
for (const [licensePlate, labels] of Object.entries(res.vehicleLabels ?? {})) {
|
|
61
|
+
const filteredLabels = labels?.filter(label => label !== null) ?? [];
|
|
62
|
+
if (!filteredLabels || filteredLabels.length === 0) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
processedVehicleLabels[licensePlate] = filteredLabels;
|
|
66
|
+
}
|
|
67
|
+
return processedVehicleLabels;
|
|
68
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { postApi } from "../network.js";
|
|
2
|
+
import { formatTimestamp } from "../util.js";
|
|
3
|
+
export async function getPolicyAlerts(args, requestModifiers, sessionId) {
|
|
4
|
+
return await postApi({
|
|
5
|
+
route: "/event/getPolicyAlerts",
|
|
6
|
+
body: args,
|
|
7
|
+
modifiers: requestModifiers,
|
|
8
|
+
sessionId,
|
|
9
|
+
}).then(response => {
|
|
10
|
+
return {
|
|
11
|
+
...response,
|
|
12
|
+
policyAlerts: (response.policyAlerts || []).map((alert) => ({
|
|
13
|
+
...alert,
|
|
14
|
+
labels: [
|
|
15
|
+
...(alert.alertingEventFaces || []),
|
|
16
|
+
...(alert.alertingEventVehicles || []),
|
|
17
|
+
].flatMap(alert => alert.labels),
|
|
18
|
+
createdOnString: alert.timestampMs
|
|
19
|
+
? formatTimestamp(alert.timestampMs, args.timeZone)
|
|
20
|
+
: undefined,
|
|
21
|
+
})),
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export async function getExpiringPolicyAlerts(args, requestModifiers, sessionId) {
|
|
26
|
+
return await postApi({
|
|
27
|
+
route: "/event/getExpiringPolicyAlerts",
|
|
28
|
+
body: args,
|
|
29
|
+
modifiers: requestModifiers,
|
|
30
|
+
sessionId,
|
|
31
|
+
}).then(response => {
|
|
32
|
+
return {
|
|
33
|
+
...response,
|
|
34
|
+
policyAlerts: (response.policyAlerts || []).map((alert) => ({
|
|
35
|
+
...alert,
|
|
36
|
+
createdOnString: alert.timestampMs
|
|
37
|
+
? formatTimestamp(alert.timestampMs)
|
|
38
|
+
: undefined,
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { postApi } from "../network.js";
|
|
2
|
+
export async function rebootCameras(cameraUuids, requestModifiers, sessionId) {
|
|
3
|
+
let successCount = 0;
|
|
4
|
+
let errorCount = 0;
|
|
5
|
+
for (const cameraUuid of cameraUuids) {
|
|
6
|
+
try {
|
|
7
|
+
const body = { cameraUuid };
|
|
8
|
+
const response = await postApi({
|
|
9
|
+
route: "/camera/reboot",
|
|
10
|
+
body,
|
|
11
|
+
modifiers: requestModifiers,
|
|
12
|
+
sessionId,
|
|
13
|
+
});
|
|
14
|
+
if (response.error) {
|
|
15
|
+
errorCount++;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
successCount++;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const ret = `Error rebooting cameras: ${error}`;
|
|
23
|
+
return { error: true, status: ret };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
let status;
|
|
27
|
+
if (successCount === cameraUuids.length)
|
|
28
|
+
status = "SUCCESS";
|
|
29
|
+
else if (successCount > 0 && successCount < cameraUuids.length)
|
|
30
|
+
status = "PARTIAL_SUCCESS";
|
|
31
|
+
else
|
|
32
|
+
status = "ERROR";
|
|
33
|
+
return { status, successCount, errorCount };
|
|
34
|
+
}
|