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.
@@ -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; } });
@@ -41,7 +41,9 @@ export declare const DT_EVENT_TYPES: {
41
41
  UNKNOWN: string;
42
42
  };
43
43
  BATTERY: {
44
- REPLACED: string;
44
+ STATE: {
45
+ REPLACE: string;
46
+ };
45
47
  LEVEL: {
46
48
  UNKNOWN: string;
47
49
  NORMAL: string;
@@ -44,7 +44,9 @@ exports.DT_EVENT_TYPES = {
44
44
  UNKNOWN: "device.status.unknown",
45
45
  },
46
46
  BATTERY: {
47
- REPLACED: "device.battery.replaced",
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.REPLACED,
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(device, source, reason) {
249
- const zone = await typedi_1.default.get(Admin_service_1.AdminService).getZone(device.zoneId);
250
- return await this.createDeviceIssue({
251
- entityId: device.deviceId,
252
- entityType: issue_types_1.EntityType.DEVICE,
253
- entitySubType: device.deviceType.type,
254
- propertyId: device.propertyId,
255
- zoneId: device.zoneId,
256
- title: "Door Left Open - Requires Attention",
257
- description: `${zone?.name} has a door left open, for more than 10 minutes. ${reason ? `Reason: ${reason}.` : ""}`,
258
- createdBy: source,
259
- category: issue_types_1.IssuesCategory.SECURITY,
260
- priority: issue_types_1.IssuePriority.HIGH,
261
- type: issue_types_1.IssueType.DOOR_LEFT_OPEN,
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 = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dt-common-device",
3
- "version": "7.2.1",
3
+ "version": "7.2.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [