@7365admin1/core 3.32.2-staging.74 → 3.32.2-staging.75
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/dist/index.js +68 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
- package/test/camera-alert.util.test.mjs +109 -0
package/dist/index.js
CHANGED
|
@@ -24737,6 +24737,47 @@ var loggerDahua = winston.createLogger({
|
|
|
24737
24737
|
]
|
|
24738
24738
|
});
|
|
24739
24739
|
|
|
24740
|
+
// src/utils/camera-alert.util.ts
|
|
24741
|
+
var DIRECTION_WORDS = {
|
|
24742
|
+
entry: "entry",
|
|
24743
|
+
exit: "exit",
|
|
24744
|
+
both: "entry and exit",
|
|
24745
|
+
visitors: "visitor",
|
|
24746
|
+
residents: "resident"
|
|
24747
|
+
};
|
|
24748
|
+
function describeCamera(camera) {
|
|
24749
|
+
const site = String(camera?.siteName ?? "").trim();
|
|
24750
|
+
const name = String(camera?.name ?? "").trim();
|
|
24751
|
+
const at = site ? ` at ${site}` : "";
|
|
24752
|
+
if (name)
|
|
24753
|
+
return `Camera "${name}"${at}`;
|
|
24754
|
+
const words = DIRECTION_WORDS[String(camera?.direction ?? "").trim().toLowerCase()];
|
|
24755
|
+
return words ? `The ${words} ANPR camera${at}` : `The ANPR camera${at}`;
|
|
24756
|
+
}
|
|
24757
|
+
function cameraUnreachableMessage(camera) {
|
|
24758
|
+
return `${describeCamera(camera)} is not responding. Plate reads and automatic barrier opening are stopped while it is down. The server keeps trying to reconnect on its own. If it does not come back, ask your site technician or the security-system installer to check the camera's power and network.`;
|
|
24759
|
+
}
|
|
24760
|
+
function cameraRecoveredMessage(camera) {
|
|
24761
|
+
return `${describeCamera(camera)} is responding again. Plate reads have resumed.`;
|
|
24762
|
+
}
|
|
24763
|
+
function cameraCredentialsMessage(camera) {
|
|
24764
|
+
return `${describeCamera(camera)} refused the login, so it cannot read plates. The username or password saved for it is wrong. An administrator can correct them in Site Settings > Cameras; if they are already correct, the camera's own account needs checking by your site technician.`;
|
|
24765
|
+
}
|
|
24766
|
+
function cameraNotAuthorisedMessage(camera) {
|
|
24767
|
+
return `${describeCamera(camera)} rejected our connection, so it cannot read plates. This usually means its account is not allowed to use the plate-reading feed. Please ask your site technician or the security-system installer to check the camera's account permissions.`;
|
|
24768
|
+
}
|
|
24769
|
+
var CAMERA_ALERT_AT_ATTEMPT = [1, 6, 30, 90];
|
|
24770
|
+
var CAMERA_ALERT_EVERY_AFTER = 90;
|
|
24771
|
+
function shouldAlertOnFailure(consecutiveFailures) {
|
|
24772
|
+
if (!Number.isInteger(consecutiveFailures) || consecutiveFailures < 1)
|
|
24773
|
+
return false;
|
|
24774
|
+
if (CAMERA_ALERT_AT_ATTEMPT.includes(consecutiveFailures))
|
|
24775
|
+
return true;
|
|
24776
|
+
if (consecutiveFailures < CAMERA_ALERT_EVERY_AFTER)
|
|
24777
|
+
return false;
|
|
24778
|
+
return (consecutiveFailures - CAMERA_ALERT_EVERY_AFTER) % CAMERA_ALERT_EVERY_AFTER === 0;
|
|
24779
|
+
}
|
|
24780
|
+
|
|
24740
24781
|
// src/services/dahua.service.ts
|
|
24741
24782
|
var cameraRegistry = /* @__PURE__ */ new Map();
|
|
24742
24783
|
var _savedOnDetected;
|
|
@@ -25230,6 +25271,8 @@ function useDahuaService() {
|
|
|
25230
25271
|
async function getTrafficJunction(camera, signal, onDetected) {
|
|
25231
25272
|
console.log(`getTrafficJunction camera object`, camera);
|
|
25232
25273
|
let authFailureCount = 0;
|
|
25274
|
+
let connectionFailureCount = 0;
|
|
25275
|
+
let alertedFailureCount = 0;
|
|
25233
25276
|
const MAX_AUTH_RETRIES = 10;
|
|
25234
25277
|
while (!signal.aborted) {
|
|
25235
25278
|
let bufferQueue = null;
|
|
@@ -25257,19 +25300,33 @@ function useDahuaService() {
|
|
|
25257
25300
|
onDetected({
|
|
25258
25301
|
site: camera?.site,
|
|
25259
25302
|
direction: camera?.direction,
|
|
25260
|
-
messagePermanent:
|
|
25303
|
+
messagePermanent: cameraCredentialsMessage(camera)
|
|
25261
25304
|
});
|
|
25262
25305
|
}
|
|
25263
25306
|
return;
|
|
25264
25307
|
} else if ([400, 500].includes(statusCode)) {
|
|
25265
25308
|
loggerDahua.error(`[${camera?.siteName}-${camera?.direction}] Connection error: ${statusCode}`);
|
|
25266
25309
|
if (onDetected) {
|
|
25267
|
-
onDetected({ site: camera?.site, messagePermanent:
|
|
25310
|
+
onDetected({ site: camera?.site, messagePermanent: cameraNotAuthorisedMessage(camera) });
|
|
25268
25311
|
}
|
|
25269
25312
|
return;
|
|
25270
25313
|
}
|
|
25271
25314
|
authFailureCount = 0;
|
|
25272
25315
|
isAuthFailure = false;
|
|
25316
|
+
if (alertedFailureCount > 0 && onDetected) {
|
|
25317
|
+
onDetected({
|
|
25318
|
+
site: camera?.site,
|
|
25319
|
+
direction: camera?.direction,
|
|
25320
|
+
// `event` and `camera` let a client group or clear an alert per
|
|
25321
|
+
// camera instead of matching on the message text. Older clients
|
|
25322
|
+
// ignore them and just render `message`, as they always have.
|
|
25323
|
+
event: "camera-recovered",
|
|
25324
|
+
camera: camera?._id?.toString(),
|
|
25325
|
+
message: cameraRecoveredMessage(camera)
|
|
25326
|
+
});
|
|
25327
|
+
}
|
|
25328
|
+
connectionFailureCount = 0;
|
|
25329
|
+
alertedFailureCount = 0;
|
|
25273
25330
|
loggerDahua.info(`[${camera?.siteName}-${camera?.direction}] Successfully connected to ANPR.`);
|
|
25274
25331
|
const contentType = response.res.headers["content-type"];
|
|
25275
25332
|
const boundaryMatch = contentType?.match(/boundary=(.*)$/i);
|
|
@@ -25323,7 +25380,7 @@ function useDahuaService() {
|
|
|
25323
25380
|
onDetected({
|
|
25324
25381
|
site: camera?.site,
|
|
25325
25382
|
direction: camera?.direction,
|
|
25326
|
-
messagePermanent:
|
|
25383
|
+
messagePermanent: cameraCredentialsMessage(camera)
|
|
25327
25384
|
});
|
|
25328
25385
|
}
|
|
25329
25386
|
return;
|
|
@@ -25343,7 +25400,7 @@ function useDahuaService() {
|
|
|
25343
25400
|
onDetected({
|
|
25344
25401
|
site: camera?.site,
|
|
25345
25402
|
direction: camera?.direction,
|
|
25346
|
-
messagePermanent:
|
|
25403
|
+
messagePermanent: cameraCredentialsMessage(camera)
|
|
25347
25404
|
});
|
|
25348
25405
|
}
|
|
25349
25406
|
return;
|
|
@@ -25351,14 +25408,18 @@ function useDahuaService() {
|
|
|
25351
25408
|
} else {
|
|
25352
25409
|
authFailureCount = 0;
|
|
25353
25410
|
isAuthFailure = false;
|
|
25411
|
+
connectionFailureCount++;
|
|
25354
25412
|
loggerDahua.error(
|
|
25355
|
-
`[${camera?.siteName}-${camera?.direction}] Connection lost or error: ${error.message || error}. Retrying in 10 seconds
|
|
25413
|
+
`[${camera?.siteName}-${camera?.direction}] Connection lost or error: ${error.message || error}. Retrying in 10 seconds... (failure ${connectionFailureCount})`
|
|
25356
25414
|
);
|
|
25357
|
-
if (onDetected) {
|
|
25415
|
+
if (onDetected && shouldAlertOnFailure(connectionFailureCount)) {
|
|
25416
|
+
alertedFailureCount = connectionFailureCount;
|
|
25358
25417
|
onDetected({
|
|
25359
25418
|
site: camera?.site,
|
|
25360
25419
|
direction: camera?.direction,
|
|
25361
|
-
|
|
25420
|
+
event: "camera-fault",
|
|
25421
|
+
camera: camera?._id?.toString(),
|
|
25422
|
+
message: cameraUnreachableMessage(camera)
|
|
25362
25423
|
});
|
|
25363
25424
|
}
|
|
25364
25425
|
}
|