dt-common-device 7.2.1 → 7.2.4
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/alerts/Alert.model.js +5 -0
- package/dist/alerts/Alert.repository.js +10 -0
- package/dist/alerts/Alert.service.js +6 -0
- package/dist/alerts/alert.types.d.ts +15 -0
- package/dist/alerts/alert.types.js +13 -1
- package/dist/constants/Event.d.ts +3 -1
- package/dist/constants/Event.js +3 -1
- package/dist/entities/device/local/services/Device.service.d.ts +1 -0
- package/dist/entities/device/local/services/Device.service.js +19 -0
- package/dist/events/DeviceEventHandler.js +1 -1
- package/dist/events/EventHandler.d.ts +1 -0
- package/dist/events/EventHandler.js +10 -0
- package/dist/issues/Issue.repository.js +12 -0
- package/dist/issues/Issue.service.d.ts +0 -1
- package/dist/issues/Issue.service.js +30 -16
- package/dist/issues/issue.types.d.ts +3 -10
- package/dist/issues/issue.types.js +0 -9
- package/package.json +1 -1
|
@@ -79,6 +79,11 @@ const AlertSchema = new mongoose_1.Schema({
|
|
|
79
79
|
enum: Object.values(alert_types_1.AlertSeverity),
|
|
80
80
|
default: alert_types_1.AlertSeverity.LOW,
|
|
81
81
|
},
|
|
82
|
+
type: {
|
|
83
|
+
type: String,
|
|
84
|
+
enum: Object.values(alert_types_1.AlertType),
|
|
85
|
+
required: true,
|
|
86
|
+
},
|
|
82
87
|
isRead: {
|
|
83
88
|
type: Boolean,
|
|
84
89
|
default: false,
|
|
@@ -68,6 +68,16 @@ let AlertRepository = (() => {
|
|
|
68
68
|
query.isRead = filters.isRead;
|
|
69
69
|
if (!filters.includeDeleted)
|
|
70
70
|
query.isDeleted = false;
|
|
71
|
+
if (filters.type)
|
|
72
|
+
query.type = filters.type;
|
|
73
|
+
// Date filtering
|
|
74
|
+
if (filters.startDate || filters.endDate) {
|
|
75
|
+
query.createdAt = {};
|
|
76
|
+
if (filters.startDate)
|
|
77
|
+
query.createdAt.$gte = filters.startDate;
|
|
78
|
+
if (filters.endDate)
|
|
79
|
+
query.createdAt.$lte = filters.endDate;
|
|
80
|
+
}
|
|
71
81
|
return query;
|
|
72
82
|
}
|
|
73
83
|
/**
|
|
@@ -544,6 +544,12 @@ let AlertService = (() => {
|
|
|
544
544
|
if (filters.skip && filters.skip < 0) {
|
|
545
545
|
throw new Error("Skip must be non-negative");
|
|
546
546
|
}
|
|
547
|
+
// Validate date filters
|
|
548
|
+
if (filters.startDate &&
|
|
549
|
+
filters.endDate &&
|
|
550
|
+
filters.startDate > filters.endDate) {
|
|
551
|
+
throw new Error("Start date must be before or equal to end date");
|
|
552
|
+
}
|
|
547
553
|
}
|
|
548
554
|
validateUpdateData(data) {
|
|
549
555
|
if (data.title && data.title.trim().length < 3) {
|
|
@@ -11,11 +11,23 @@ export declare enum AlertSeverity {
|
|
|
11
11
|
HIGH = "HIGH",
|
|
12
12
|
CRITICAL = "CRITICAL"
|
|
13
13
|
}
|
|
14
|
+
export declare enum AlertType {
|
|
15
|
+
ACCOUNT_NEW_DEVICE = "ACCOUNT_NEW_DEVICE",
|
|
16
|
+
DEVICE_TAMPER_ATTEMPT = "DEVICE_TAMPER_ATTEMPT",
|
|
17
|
+
DOOR_LEFT_OPEN = "DOOR_LEFT_OPEN",
|
|
18
|
+
DOOR_OPEN_FREQUENT = "DOOR_OPEN_FREQUENT",
|
|
19
|
+
DOOR_OPEN_OUTSIDE_BIZ_HOURS = "DOOR_OPEN_OUTSIDE_BIZ_HOURS",
|
|
20
|
+
LOCK_ACCESS_EMERGENCY_CODE = "LOCK_ACCESS_EMERGENCY_CODE",
|
|
21
|
+
LOCK_ACCESS_MASTER_CODE = "LOCK_ACCESS_MASTER_CODE",
|
|
22
|
+
SPECIFIC_DOOR_ACCESS = "SPECIFIC_DOOR_ACCESS",
|
|
23
|
+
GUEST_LOCK_FIRST_ACCESS = "GUEST_LOCK_FIRST_ACCESS"
|
|
24
|
+
}
|
|
14
25
|
export interface AlertDocument {
|
|
15
26
|
_id: string;
|
|
16
27
|
category: AlertCategory;
|
|
17
28
|
propertyId: string;
|
|
18
29
|
zoneId: string;
|
|
30
|
+
type: AlertType;
|
|
19
31
|
title: string;
|
|
20
32
|
description: string;
|
|
21
33
|
entityId?: string;
|
|
@@ -61,9 +73,12 @@ export interface IAlertQuery {
|
|
|
61
73
|
severity?: AlertSeverity;
|
|
62
74
|
entityType?: EntityType;
|
|
63
75
|
entityId?: string;
|
|
76
|
+
type?: AlertType;
|
|
64
77
|
isActive?: boolean;
|
|
65
78
|
isRead?: boolean;
|
|
66
79
|
includeDeleted?: boolean;
|
|
80
|
+
startDate?: Date;
|
|
81
|
+
endDate?: Date;
|
|
67
82
|
sort?: {
|
|
68
83
|
[key: string]: 1 | -1;
|
|
69
84
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntityType = exports.AlertSeverity = exports.AlertCategory = void 0;
|
|
3
|
+
exports.EntityType = exports.AlertType = exports.AlertSeverity = exports.AlertCategory = void 0;
|
|
4
4
|
var AlertCategory;
|
|
5
5
|
(function (AlertCategory) {
|
|
6
6
|
AlertCategory["OPERATIONS"] = "OPERATIONS";
|
|
@@ -15,6 +15,18 @@ var AlertSeverity;
|
|
|
15
15
|
AlertSeverity["HIGH"] = "HIGH";
|
|
16
16
|
AlertSeverity["CRITICAL"] = "CRITICAL";
|
|
17
17
|
})(AlertSeverity || (exports.AlertSeverity = AlertSeverity = {}));
|
|
18
|
+
var AlertType;
|
|
19
|
+
(function (AlertType) {
|
|
20
|
+
AlertType["ACCOUNT_NEW_DEVICE"] = "ACCOUNT_NEW_DEVICE";
|
|
21
|
+
AlertType["DEVICE_TAMPER_ATTEMPT"] = "DEVICE_TAMPER_ATTEMPT";
|
|
22
|
+
AlertType["DOOR_LEFT_OPEN"] = "DOOR_LEFT_OPEN";
|
|
23
|
+
AlertType["DOOR_OPEN_FREQUENT"] = "DOOR_OPEN_FREQUENT";
|
|
24
|
+
AlertType["DOOR_OPEN_OUTSIDE_BIZ_HOURS"] = "DOOR_OPEN_OUTSIDE_BIZ_HOURS";
|
|
25
|
+
AlertType["LOCK_ACCESS_EMERGENCY_CODE"] = "LOCK_ACCESS_EMERGENCY_CODE";
|
|
26
|
+
AlertType["LOCK_ACCESS_MASTER_CODE"] = "LOCK_ACCESS_MASTER_CODE";
|
|
27
|
+
AlertType["SPECIFIC_DOOR_ACCESS"] = "SPECIFIC_DOOR_ACCESS";
|
|
28
|
+
AlertType["GUEST_LOCK_FIRST_ACCESS"] = "GUEST_LOCK_FIRST_ACCESS";
|
|
29
|
+
})(AlertType || (exports.AlertType = AlertType = {}));
|
|
18
30
|
// Re-export EntityType from issue.types.ts to avoid duplication
|
|
19
31
|
var issue_types_1 = require("../issues/issue.types");
|
|
20
32
|
Object.defineProperty(exports, "EntityType", { enumerable: true, get: function () { return issue_types_1.EntityType; } });
|
package/dist/constants/Event.js
CHANGED
|
@@ -44,7 +44,9 @@ exports.DT_EVENT_TYPES = {
|
|
|
44
44
|
UNKNOWN: "device.status.unknown",
|
|
45
45
|
},
|
|
46
46
|
BATTERY: {
|
|
47
|
-
|
|
47
|
+
STATE: {
|
|
48
|
+
REPLACE: "device.battery.state.replace",
|
|
49
|
+
},
|
|
48
50
|
LEVEL: {
|
|
49
51
|
UNKNOWN: "device.battery.level.unknown",
|
|
50
52
|
NORMAL: "device.battery.level.normal",
|
|
@@ -26,6 +26,7 @@ export declare class LocalDeviceService {
|
|
|
26
26
|
getBatteryLevel(deviceId: string): Promise<Record<string, any>>;
|
|
27
27
|
setBatteryLevel(deviceId: string, batteryLevel: number, source: Source, auditBody: IAuditProperties): Promise<void>;
|
|
28
28
|
private shouldUpdateBatteryLevel;
|
|
29
|
+
updateBatteryState(deviceId: string, batteryState: any): Promise<void>;
|
|
29
30
|
private getPropertyBatteryThreshold;
|
|
30
31
|
private checkForDeviceMalfunctions;
|
|
31
32
|
getMetaData(deviceId: string): Promise<any>;
|
|
@@ -355,6 +355,17 @@ let LocalDeviceService = (() => {
|
|
|
355
355
|
// Save the battery level in the device
|
|
356
356
|
await this.deviceRepository.setBatteryLevel(deviceId, batteryLevel);
|
|
357
357
|
await this.eventHandler.onBatteryLevelChange(deviceId, batteryLevel, auditBody);
|
|
358
|
+
// Additional condition: if battery level is less than 50, update battery state to "replace"
|
|
359
|
+
if (batteryLevel < 50) {
|
|
360
|
+
const batteryState = {
|
|
361
|
+
batteryState: {
|
|
362
|
+
value: "replace",
|
|
363
|
+
lastUpdated: new Date().toISOString(),
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
await this.updateBatteryState(deviceId, batteryState);
|
|
367
|
+
await this.eventHandler.onBatteryStateChange(deviceId, batteryState, auditBody);
|
|
368
|
+
}
|
|
358
369
|
// Get property threshold
|
|
359
370
|
const propertyThreshold = await this.getPropertyBatteryThreshold(device.propertyId);
|
|
360
371
|
// Check if battery level is below threshold
|
|
@@ -377,6 +388,14 @@ let LocalDeviceService = (() => {
|
|
|
377
388
|
// Return true if current time is greater than or equal to last updated time + 8 hours
|
|
378
389
|
return currentTime >= lastUpdateTime + eightHoursInMs;
|
|
379
390
|
}
|
|
391
|
+
async updateBatteryState(deviceId, batteryState) {
|
|
392
|
+
try {
|
|
393
|
+
await this.deviceRepository.updateDevice(deviceId, batteryState);
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
console.error("Error updating battery state:", error);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
380
399
|
async getPropertyBatteryThreshold(propertyId) {
|
|
381
400
|
// TODO: Implement property battery threshold retrieval
|
|
382
401
|
// This should return the battery threshold for the specific property
|
|
@@ -90,7 +90,7 @@ let DeviceEventHandler = (() => {
|
|
|
90
90
|
Event_1.DT_EVENT_TYPES.DEVICE.STATUS.ONLINE,
|
|
91
91
|
Event_1.DT_EVENT_TYPES.DEVICE.STATUS.OFFLINE,
|
|
92
92
|
Event_1.DT_EVENT_TYPES.DEVICE.STATUS.UNKNOWN,
|
|
93
|
-
Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.
|
|
93
|
+
Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.STATE.REPLACE,
|
|
94
94
|
Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.LEVEL.UNKNOWN,
|
|
95
95
|
Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.LEVEL.LOW,
|
|
96
96
|
Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.LEVEL.CRITICAL,
|
|
@@ -9,5 +9,6 @@ export declare class EventHandler {
|
|
|
9
9
|
onStatusChange(deviceId: string, status: any, auditProperties: IAuditProperties, eventType: any): Promise<void>;
|
|
10
10
|
onStatusChangeMany(query: IStatusQuery, status: IStatus, auditProperties: IAuditProperties, eventType: any): Promise<void>;
|
|
11
11
|
onBatteryLevelChange(deviceId: string, batteryLevel: number, auditProperties: IAuditProperties): Promise<void>;
|
|
12
|
+
onBatteryStateChange(deviceId: string, batteryState: any, auditProperties: IAuditProperties): Promise<void>;
|
|
12
13
|
onDeviceMetaChange(deviceId: string, metaData: Record<string, any>, auditProperties: IAuditProperties): Promise<void>;
|
|
13
14
|
}
|
|
@@ -125,6 +125,16 @@ let EventHandler = (() => {
|
|
|
125
125
|
},
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
+
async onBatteryStateChange(deviceId, batteryState, auditProperties) {
|
|
129
|
+
await (0, audit_1.pushAudit)({
|
|
130
|
+
auditType: Event_1.DT_EVENT_TYPES.DEVICE.BATTERY.STATE.REPLACE,
|
|
131
|
+
auditData: {
|
|
132
|
+
deviceId,
|
|
133
|
+
batteryState,
|
|
134
|
+
...auditProperties,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
128
138
|
async onDeviceMetaChange(deviceId, metaData, auditProperties) {
|
|
129
139
|
await (0, audit_1.pushAudit)({
|
|
130
140
|
auditType: Event_1.DT_EVENT_TYPES.DEVICE.METADATA.UPDATED,
|
|
@@ -64,10 +64,22 @@ let IssueRepository = (() => {
|
|
|
64
64
|
query.category = filters.category;
|
|
65
65
|
if (filters.entityType)
|
|
66
66
|
query.entityType = filters.entityType;
|
|
67
|
+
if (filters.entitySubType)
|
|
68
|
+
query.entitySubType = filters.entitySubType;
|
|
67
69
|
if (filters.entityId)
|
|
68
70
|
query.entityId = filters.entityId;
|
|
71
|
+
if (filters.type)
|
|
72
|
+
query.type = filters.type;
|
|
69
73
|
if (!filters.includeDeleted)
|
|
70
74
|
query.isDeleted = false;
|
|
75
|
+
// Date filtering
|
|
76
|
+
if (filters.startDate || filters.endDate) {
|
|
77
|
+
query.createdAt = {};
|
|
78
|
+
if (filters.startDate)
|
|
79
|
+
query.createdAt.$gte = filters.startDate;
|
|
80
|
+
if (filters.endDate)
|
|
81
|
+
query.createdAt.$lte = filters.endDate;
|
|
82
|
+
}
|
|
71
83
|
if (filters.sort)
|
|
72
84
|
query.sort = filters.sort;
|
|
73
85
|
if (filters.limit)
|
|
@@ -43,7 +43,6 @@ export declare class IssueService {
|
|
|
43
43
|
* Create issue for device going offline longer than baseline
|
|
44
44
|
*/
|
|
45
45
|
createDeviceOfflineIssue(device: IDevice, source: Source, reason?: string): Promise<IIssueDocument | null>;
|
|
46
|
-
createDoorLeftOpenIssue(device: IDevice, source: Source, reason?: string): Promise<IIssueDocument | null>;
|
|
47
46
|
/**
|
|
48
47
|
* Create issue for device battery level below threshold (READINESS + OPERATIONAL + ENERGY)
|
|
49
48
|
*/
|
|
@@ -245,22 +245,30 @@ let IssueService = (() => {
|
|
|
245
245
|
type: issue_types_1.IssueType.DEVICE_OFFLINE,
|
|
246
246
|
});
|
|
247
247
|
}
|
|
248
|
-
async createDoorLeftOpenIssue(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
248
|
+
// async createDoorLeftOpenIssue(
|
|
249
|
+
// device: IDevice,
|
|
250
|
+
// source: Source,
|
|
251
|
+
// reason?: string
|
|
252
|
+
// ): Promise<IIssueDocument | null> {
|
|
253
|
+
// const zone = await Container.get(AdminService).getZone(device.zoneId);
|
|
254
|
+
// return await this.createDeviceIssue({
|
|
255
|
+
// entityId: device.deviceId,
|
|
256
|
+
// entityType: EntityType.DEVICE,
|
|
257
|
+
// entitySubType: device.deviceType.type as EntitySubType,
|
|
258
|
+
// propertyId: device.propertyId,
|
|
259
|
+
// zoneId: device.zoneId,
|
|
260
|
+
// title: "Door Left Open - Requires Attention",
|
|
261
|
+
// description: `${
|
|
262
|
+
// zone?.name
|
|
263
|
+
// } has a door left open, for more than 10 minutes. ${
|
|
264
|
+
// reason ? `Reason: ${reason}.` : ""
|
|
265
|
+
// }`,
|
|
266
|
+
// createdBy: source,
|
|
267
|
+
// category: IssuesCategory.SECURITY,
|
|
268
|
+
// priority: IssuePriority.HIGH,
|
|
269
|
+
// type: IssueType.DOOR_LEFT_OPEN,
|
|
270
|
+
// });
|
|
271
|
+
// }
|
|
264
272
|
/**
|
|
265
273
|
* Create issue for device battery level below threshold (READINESS + OPERATIONAL + ENERGY)
|
|
266
274
|
*/
|
|
@@ -836,6 +844,12 @@ let IssueService = (() => {
|
|
|
836
844
|
if (filters.skip && filters.skip < 0) {
|
|
837
845
|
throw new Error("Skip must be non-negative");
|
|
838
846
|
}
|
|
847
|
+
// Validate date filters
|
|
848
|
+
if (filters.startDate &&
|
|
849
|
+
filters.endDate &&
|
|
850
|
+
filters.startDate > filters.endDate) {
|
|
851
|
+
throw new Error("Start date must be before or equal to end date");
|
|
852
|
+
}
|
|
839
853
|
}
|
|
840
854
|
validateUpdateData(data) {
|
|
841
855
|
if (data.title && data.title.trim().length < 5) {
|
|
@@ -52,18 +52,9 @@ export declare enum IssueType {
|
|
|
52
52
|
DEVICE_OFFLINE = "DEVICE_OFFLINE",
|
|
53
53
|
HUB_OFFLINE = "HUB_OFFLINE",
|
|
54
54
|
ACCOUNT_UNAUTHORIZED = "ACCOUNT_UNAUTHORIZED",
|
|
55
|
-
ACCOUNT_NEW_DEVICE = "ACCOUNT_NEW_DEVICE",
|
|
56
55
|
ACCOUNT_MISSING_DEVICE = "ACCOUNT_MISSING_DEVICE",
|
|
57
|
-
DEVICE_TAMPER_ATTEMPT = "DEVICE_TAMPER_ATTEMPT",
|
|
58
56
|
LOCK_JAMMED = "LOCK_JAMMED",
|
|
59
|
-
DEVICE_MALFUNCTION = "DEVICE_MALFUNCTION"
|
|
60
|
-
DOOR_LEFT_OPEN = "DOOR_LEFT_OPEN",
|
|
61
|
-
DOOR_OPEN_FREQUENT = "DOOR_OPEN_FREQUENT",
|
|
62
|
-
DOOR_OPEN_OUTSIDE_BIZ_HOURS = "DOOR_OPEN_OUTSIDE_BIZ_HOURS",
|
|
63
|
-
LOCK_ACCESS_EMERGENCY_CODE = "LOCK_ACCESS_EMERGENCY_CODE",
|
|
64
|
-
LOCK_ACCESS_MASTER_CODE = "LOCK_ACCESS_MASTER_CODE",
|
|
65
|
-
SPECIFIC_DOOR_ACCESS = "SPECIFIC_DOOR_ACCESS",
|
|
66
|
-
GUEST_LOCK_FIRST_ACCESS = "GUEST_LOCK_FIRST_ACCESS"
|
|
57
|
+
DEVICE_MALFUNCTION = "DEVICE_MALFUNCTION"
|
|
67
58
|
}
|
|
68
59
|
export interface IssueDocument {
|
|
69
60
|
_id: string;
|
|
@@ -139,6 +130,8 @@ export interface IIssueQuery {
|
|
|
139
130
|
entitySubType?: EntitySubType;
|
|
140
131
|
entityId?: string;
|
|
141
132
|
includeDeleted?: boolean;
|
|
133
|
+
startDate?: Date;
|
|
134
|
+
endDate?: Date;
|
|
142
135
|
limit?: number;
|
|
143
136
|
skip?: number;
|
|
144
137
|
sort?: {
|
|
@@ -54,16 +54,7 @@ var IssueType;
|
|
|
54
54
|
IssueType["DEVICE_OFFLINE"] = "DEVICE_OFFLINE";
|
|
55
55
|
IssueType["HUB_OFFLINE"] = "HUB_OFFLINE";
|
|
56
56
|
IssueType["ACCOUNT_UNAUTHORIZED"] = "ACCOUNT_UNAUTHORIZED";
|
|
57
|
-
IssueType["ACCOUNT_NEW_DEVICE"] = "ACCOUNT_NEW_DEVICE";
|
|
58
57
|
IssueType["ACCOUNT_MISSING_DEVICE"] = "ACCOUNT_MISSING_DEVICE";
|
|
59
|
-
IssueType["DEVICE_TAMPER_ATTEMPT"] = "DEVICE_TAMPER_ATTEMPT";
|
|
60
58
|
IssueType["LOCK_JAMMED"] = "LOCK_JAMMED";
|
|
61
59
|
IssueType["DEVICE_MALFUNCTION"] = "DEVICE_MALFUNCTION";
|
|
62
|
-
IssueType["DOOR_LEFT_OPEN"] = "DOOR_LEFT_OPEN";
|
|
63
|
-
IssueType["DOOR_OPEN_FREQUENT"] = "DOOR_OPEN_FREQUENT";
|
|
64
|
-
IssueType["DOOR_OPEN_OUTSIDE_BIZ_HOURS"] = "DOOR_OPEN_OUTSIDE_BIZ_HOURS";
|
|
65
|
-
IssueType["LOCK_ACCESS_EMERGENCY_CODE"] = "LOCK_ACCESS_EMERGENCY_CODE";
|
|
66
|
-
IssueType["LOCK_ACCESS_MASTER_CODE"] = "LOCK_ACCESS_MASTER_CODE";
|
|
67
|
-
IssueType["SPECIFIC_DOOR_ACCESS"] = "SPECIFIC_DOOR_ACCESS";
|
|
68
|
-
IssueType["GUEST_LOCK_FIRST_ACCESS"] = "GUEST_LOCK_FIRST_ACCESS";
|
|
69
60
|
})(IssueType || (exports.IssueType = IssueType = {}));
|