dt-common-device 3.0.9 → 3.0.11
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/config/config.d.ts +1 -2
- package/dist/config/config.js +4 -5
- package/dist/device/cloud/interface.d.ts +101 -0
- package/dist/device/cloud/interface.js +3 -0
- package/dist/device/cloud/interfaces/IDeviceConnectionService.d.ts +7 -0
- package/dist/device/cloud/interfaces/IDeviceConnectionService.js +3 -0
- package/dist/device/cloud/interfaces/IDevicesService.d.ts +9 -0
- package/dist/device/cloud/services/Device.service.d.ts +39 -0
- package/dist/device/cloud/services/Device.service.js +9 -0
- package/dist/device/cloud/services/DeviceCloudService.d.ts +42 -0
- package/dist/device/cloud/services/DeviceCloudService.js +59 -0
- package/dist/device/cloud/services/DeviceHub.service.d.ts +3 -0
- package/dist/device/cloud/services/DeviceHub.service.js +6 -0
- package/dist/device/cloud/services/Hub.service.d.ts +25 -0
- package/dist/device/cloud/services/Hub.service.js +9 -0
- package/dist/device/cloud/services/SmartThingsDeviceService.d.ts +38 -0
- package/dist/device/cloud/services/SmartThingsDeviceService.js +52 -0
- package/dist/device/index.d.ts +4 -0
- package/dist/device/index.js +20 -0
- package/dist/device/local/events/EventHandler.js +6 -6
- package/dist/device/local/events/Events.d.ts +12 -33
- package/dist/device/local/events/Events.js +12 -33
- package/dist/device/local/interface.d.ts +0 -0
- package/dist/device/local/interface.js +1 -0
- package/dist/device/local/interfaces/IDevice.d.ts +1 -0
- package/dist/device/local/repository/Schedule.repository.d.ts +0 -1
- package/dist/device/local/repository/Schedule.repository.js +6 -6
- package/dist/device/local/services/DeviceHub.service.d.ts +11 -0
- package/dist/device/local/services/DeviceHub.service.js +40 -0
- package/dist/queue/entities/HybridHttpQueue.d.ts +4 -14
- package/dist/queue/entities/HybridHttpQueue.js +31 -119
- package/dist/queue/interfaces/IHybridHttpQueue.d.ts +2 -12
- package/dist/queue/interfaces/IJobResult.d.ts +1 -8
- package/dist/queue/interfaces/index.d.ts +0 -1
- package/dist/queue/interfaces/index.js +0 -1
- package/dist/queue/services/QueueService.d.ts +2 -12
- package/dist/queue/types/queue.types.d.ts +10 -29
- package/dist/queue/utils/jobUtils.d.ts +0 -3
- package/dist/queue/utils/jobUtils.js +0 -48
- package/dist/queue/utils/queueUtils.d.ts +7 -0
- package/dist/queue/utils/queueUtils.js +113 -4
- package/package.json +6 -1
- package/.eslintrc.js +0 -44
- package/dist/audit/AuditProperties.d.ts +0 -16
- package/dist/audit/AuditUtils.d.ts +0 -2
- package/dist/audit/AuditUtils.js +0 -36
- package/src/alerts/Alert.model.ts +0 -289
- package/src/alerts/Alert.repository.ts +0 -487
- package/src/alerts/Alert.service.ts +0 -711
- package/src/alerts/AlertBuilder.example.ts +0 -126
- package/src/alerts/AlertBuilder.ts +0 -208
- package/src/alerts/AlertService.example.ts +0 -232
- package/src/alerts/alert.types.ts +0 -64
- package/src/alerts/index.ts +0 -3
- package/src/audit/AuditProperties.ts +0 -16
- package/src/audit/AuditUtils.ts +0 -38
- package/src/config/config.ts +0 -202
- package/src/config/config.types.ts +0 -21
- package/src/connection/Connection.repository.ts +0 -52
- package/src/connection/Connection.service.ts +0 -39
- package/src/connection/IConnection.ts +0 -27
- package/src/connection/index.ts +0 -3
- package/src/constants/ConnectionProviders.ts +0 -11
- package/src/constants/Event.ts +0 -89
- package/src/constants/Service.ts +0 -17
- package/src/constants/index.ts +0 -3
- package/src/db/db.ts +0 -24
- package/src/db/index.ts +0 -2
- package/src/db/redis.ts +0 -20
- package/src/device/cloud/entities/CloudDevice.ts +0 -40
- package/src/device/cloud/entities/CloudDeviceService.ts +0 -8
- package/src/device/cloud/entities/DeviceFactory.ts +0 -27
- package/src/device/cloud/entities/index.ts +0 -3
- package/src/device/cloud/interfaces/ICloudDevice.ts +0 -14
- package/src/device/cloud/interfaces/ICloudDeviceService.ts +0 -6
- package/src/device/cloud/interfaces/IDeviceFactory.ts +0 -5
- package/src/device/cloud/interfaces/IRawDataTransformer.ts +0 -5
- package/src/device/cloud/interfaces/IRawDevice.ts +0 -19
- package/src/device/cloud/interfaces/index.ts +0 -5
- package/src/device/local/interfaces/IDevice.ts +0 -61
- package/src/device/local/interfaces/IDtDevice.ts +0 -16
- package/src/device/local/interfaces/ISchedule.ts +0 -40
- package/src/device/local/interfaces/index.ts +0 -3
- package/src/device/local/repository/Device.repository.ts +0 -368
- package/src/device/local/repository/Hub.repository.ts +0 -107
- package/src/device/local/repository/Schedule.repository.ts +0 -72
- package/src/device/local/services/Device.service.ts +0 -436
- package/src/device/local/services/Hub.service.ts +0 -57
- package/src/device/local/services/Schedule.service.ts +0 -26
- package/src/device/local/services/index.ts +0 -3
- package/src/docs/Alert.model.md +0 -319
- package/src/docs/Alerts&IssuesModel.md +0 -312
- package/src/docs/Issue.model.md +0 -386
- package/src/docs/SECURITY.md +0 -67
- package/src/docs/TROUBLESHOOTING.md +0 -184
- package/src/events/BaseEventHandler.ts +0 -145
- package/src/events/BaseEventTransformer.ts +0 -97
- package/src/events/DeviceEventHandler.ts +0 -213
- package/src/events/DeviceEventTransformerFactory.ts +0 -77
- package/src/events/EventHandler.ts +0 -124
- package/src/events/EventHandlerOrchestrator.ts +0 -119
- package/src/events/EventProcessingService.ts +0 -248
- package/src/events/InternalEventSubscription.ts +0 -194
- package/src/events/index.ts +0 -9
- package/src/events/interfaces/DeviceEvent.ts +0 -56
- package/src/events/interfaces/IEventHandler.ts +0 -28
- package/src/events/interfaces/IEventTransformer.ts +0 -8
- package/src/events/interfaces/IInternalEvent.ts +0 -33
- package/src/events/interfaces/index.ts +0 -4
- package/src/index.ts +0 -43
- package/src/issues/Issue.model.ts +0 -350
- package/src/issues/Issue.repository.ts +0 -517
- package/src/issues/Issue.service.ts +0 -932
- package/src/issues/IssueBuilder.example.ts +0 -210
- package/src/issues/IssueBuilder.ts +0 -263
- package/src/issues/IssueService.example.ts +0 -310
- package/src/issues/index.ts +0 -2
- package/src/issues/issue.types.ts +0 -98
- package/src/property/IProperty.ts +0 -30
- package/src/property/Property.repository.ts +0 -53
- package/src/property/Property.service.ts +0 -38
- package/src/property/index.ts +0 -2
- package/src/queue/entities/HybridHttpQueue.ts +0 -274
- package/src/queue/entities/index.ts +0 -1
- package/src/queue/index.ts +0 -6
- package/src/queue/interfaces/IHttpRequestJob.ts +0 -10
- package/src/queue/interfaces/IHybridHttpQueue.ts +0 -25
- package/src/queue/interfaces/IJobResult.ts +0 -15
- package/src/queue/interfaces/IRateLimitConfig.ts +0 -5
- package/src/queue/interfaces/index.ts +0 -4
- package/src/queue/services/QueueService.ts +0 -40
- package/src/queue/services/index.ts +0 -1
- package/src/queue/types/http.types.ts +0 -23
- package/src/queue/types/index.ts +0 -2
- package/src/queue/types/queue.types.ts +0 -21
- package/src/queue/utils/index.ts +0 -3
- package/src/queue/utils/jobUtils.ts +0 -79
- package/src/queue/utils/queueUtils.ts +0 -84
- package/src/queue/utils/rateLimit.utils.ts +0 -131
- package/src/utils/http.utils.ts +0 -143
- package/src/utils/index.ts +0 -2
- package/src/utils/redis.utils.ts +0 -74
- package/tsconfig.json +0 -20
- /package/dist/{audit/AuditProperties.js → device/cloud/interfaces/IDevicesService.js} +0 -0
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
import { IDevice, IStatus } from "../interfaces";
|
|
2
|
-
import { EventHandler } from "../../../events/EventHandler";
|
|
3
|
-
import { isEqual } from "lodash";
|
|
4
|
-
import { DeviceRepository } from "../repository/Device.repository";
|
|
5
|
-
import Container from "typedi";
|
|
6
|
-
import { AlertService } from "../../../alerts/Alert.service";
|
|
7
|
-
import { IssueService } from "../../../issues/Issue.service";
|
|
8
|
-
import { Source } from "../../../constants/Service";
|
|
9
|
-
import { getConfig } from "../../../config/config";
|
|
10
|
-
|
|
11
|
-
export class LocalDeviceService {
|
|
12
|
-
private readonly eventHandler: EventHandler;
|
|
13
|
-
private readonly deviceRepository: DeviceRepository;
|
|
14
|
-
private readonly alertService: AlertService;
|
|
15
|
-
private readonly issueService: IssueService;
|
|
16
|
-
private readonly logger;
|
|
17
|
-
|
|
18
|
-
constructor() {
|
|
19
|
-
this.eventHandler = new EventHandler();
|
|
20
|
-
this.deviceRepository = Container.get(DeviceRepository);
|
|
21
|
-
this.alertService = Container.get(AlertService);
|
|
22
|
-
this.issueService = Container.get(IssueService);
|
|
23
|
-
this.logger = getConfig().LOGGER;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async createDevice(body: IDevice): Promise<IDevice> {
|
|
27
|
-
const device = await this.deviceRepository.createDevice(body);
|
|
28
|
-
await this.eventHandler.onDeviceCreate(device);
|
|
29
|
-
return device;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async getDevice(
|
|
33
|
-
deviceId: string,
|
|
34
|
-
withHubDetails: boolean = false
|
|
35
|
-
): Promise<IDevice> {
|
|
36
|
-
if (!deviceId) {
|
|
37
|
-
throw new Error("Device ID is required");
|
|
38
|
-
}
|
|
39
|
-
return await this.deviceRepository.getDevice(deviceId, withHubDetails);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async getDevices(
|
|
43
|
-
deviceIds: string[],
|
|
44
|
-
withHubDetails: boolean = false
|
|
45
|
-
): Promise<IDevice[]> {
|
|
46
|
-
if (!deviceIds.length) {
|
|
47
|
-
throw new Error("At least one device ID is required");
|
|
48
|
-
}
|
|
49
|
-
return await this.deviceRepository.getDevices(deviceIds, withHubDetails);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async getPropertyDevices(
|
|
53
|
-
propertyId: string,
|
|
54
|
-
selectDeviceId: boolean = false,
|
|
55
|
-
type?: string,
|
|
56
|
-
withHubDetails: boolean = false
|
|
57
|
-
): Promise<IDevice[]> {
|
|
58
|
-
if (!propertyId) {
|
|
59
|
-
throw new Error("Property ID is required");
|
|
60
|
-
}
|
|
61
|
-
return await this.deviceRepository.getPropertyDevices(
|
|
62
|
-
propertyId,
|
|
63
|
-
selectDeviceId,
|
|
64
|
-
type,
|
|
65
|
-
withHubDetails
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async getPropertyDeviceIds(
|
|
70
|
-
propertyId: string,
|
|
71
|
-
selectDeviceId: boolean = false,
|
|
72
|
-
type: string
|
|
73
|
-
) {
|
|
74
|
-
if (!propertyId) {
|
|
75
|
-
throw new Error("Property ID is required");
|
|
76
|
-
}
|
|
77
|
-
return await this.deviceRepository.getPropertyDeviceIds(
|
|
78
|
-
propertyId,
|
|
79
|
-
selectDeviceId,
|
|
80
|
-
type
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async updateDevice(deviceId: string, body: any): Promise<any> {
|
|
85
|
-
if (!deviceId) {
|
|
86
|
-
throw new Error("Device ID is required");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
await this.deviceRepository.updateDevice(deviceId, body);
|
|
90
|
-
return await this.eventHandler.onDeviceUpdate(deviceId, body);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async deleteDevice(deviceId: string): Promise<any> {
|
|
94
|
-
if (!deviceId) {
|
|
95
|
-
throw new Error("Device ID is required");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
await this.deviceRepository.deleteDevice(deviceId);
|
|
99
|
-
return await this.eventHandler.onDeviceDelete(deviceId);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async getState(deviceId: string) {
|
|
103
|
-
if (!deviceId) {
|
|
104
|
-
throw new Error("Device ID is required");
|
|
105
|
-
}
|
|
106
|
-
return await this.deviceRepository.getState(deviceId);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async setState(deviceId: string, newState: any) {
|
|
110
|
-
if (!deviceId || !newState) {
|
|
111
|
-
throw new Error("Device ID and new state are required");
|
|
112
|
-
}
|
|
113
|
-
// If old state and new state are different
|
|
114
|
-
const oldState = (await this.getState(deviceId))?.data?.state ?? {};
|
|
115
|
-
const changedKeys = Object.keys(newState).filter(
|
|
116
|
-
(key) => !isEqual(oldState[key], newState[key])
|
|
117
|
-
);
|
|
118
|
-
if (changedKeys.length > 0) {
|
|
119
|
-
await this.deviceRepository.setState(deviceId, newState);
|
|
120
|
-
return await this.eventHandler.onStateChange(deviceId, newState);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async getStatus(deviceId: string) {
|
|
125
|
-
if (!deviceId) {
|
|
126
|
-
throw new Error("Device ID is required");
|
|
127
|
-
}
|
|
128
|
-
return await this.deviceRepository.getStatus(deviceId);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async setStatus(
|
|
132
|
-
deviceId: string,
|
|
133
|
-
newStatus: IStatus,
|
|
134
|
-
source: Source,
|
|
135
|
-
reason?: string
|
|
136
|
-
) {
|
|
137
|
-
if (!deviceId || !newStatus) {
|
|
138
|
-
throw new Error("Device ID and new status are required");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const device = await this.getDevice(deviceId);
|
|
142
|
-
const oldStatus = device.status;
|
|
143
|
-
const currentTime = new Date().toISOString();
|
|
144
|
-
|
|
145
|
-
// Determine if the new status is ONLINE or OFFLINE
|
|
146
|
-
const isNewStatusOnline = newStatus.liveStatus === "ONLINE";
|
|
147
|
-
const isNewStatusOffline = newStatus.liveStatus === "OFFLINE";
|
|
148
|
-
|
|
149
|
-
if (isNewStatusOffline) {
|
|
150
|
-
// New Status = OFFLINE
|
|
151
|
-
await this.handleOfflineStatus(
|
|
152
|
-
deviceId,
|
|
153
|
-
device,
|
|
154
|
-
oldStatus,
|
|
155
|
-
newStatus,
|
|
156
|
-
source,
|
|
157
|
-
reason,
|
|
158
|
-
currentTime
|
|
159
|
-
);
|
|
160
|
-
} else if (isNewStatusOnline) {
|
|
161
|
-
// New Status = ONLINE
|
|
162
|
-
await this.handleOnlineStatus(
|
|
163
|
-
deviceId,
|
|
164
|
-
device,
|
|
165
|
-
oldStatus,
|
|
166
|
-
newStatus,
|
|
167
|
-
source,
|
|
168
|
-
reason,
|
|
169
|
-
currentTime
|
|
170
|
-
);
|
|
171
|
-
} else {
|
|
172
|
-
// For any other status, just update normally
|
|
173
|
-
await this.deviceRepository.setStatus(deviceId, newStatus);
|
|
174
|
-
await this.eventHandler.onStatusChange(deviceId, newStatus);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private async handleOfflineStatus(
|
|
179
|
-
deviceId: string,
|
|
180
|
-
device: IDevice,
|
|
181
|
-
oldStatus: any,
|
|
182
|
-
newStatus: IStatus,
|
|
183
|
-
source: Source,
|
|
184
|
-
reason?: string,
|
|
185
|
-
currentTime?: string
|
|
186
|
-
) {
|
|
187
|
-
const isExistingStatusOnline = oldStatus?.online === true;
|
|
188
|
-
const isExistingStatusOffline = oldStatus?.online === false;
|
|
189
|
-
|
|
190
|
-
if (isExistingStatusOnline) {
|
|
191
|
-
// Existing status is Online
|
|
192
|
-
newStatus.online = true;
|
|
193
|
-
newStatus.liveStatus = "OFFLINE";
|
|
194
|
-
newStatus.lastUpdated = currentTime;
|
|
195
|
-
newStatus.error = {
|
|
196
|
-
type: "offline",
|
|
197
|
-
message: reason || "Device went offline",
|
|
198
|
-
default: {},
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
await this.deviceRepository.setStatus(deviceId, newStatus);
|
|
202
|
-
await this.eventHandler.onStatusChange(deviceId, newStatus);
|
|
203
|
-
} else if (isExistingStatusOffline) {
|
|
204
|
-
// Existing status is Offline
|
|
205
|
-
const timeLapsed = oldStatus?.lastUpdated
|
|
206
|
-
? Date.now() - new Date(oldStatus.lastUpdated).getTime()
|
|
207
|
-
: 0;
|
|
208
|
-
|
|
209
|
-
const baselineTime = await this.getDeviceBaseline(deviceId);
|
|
210
|
-
|
|
211
|
-
if (timeLapsed > baselineTime) {
|
|
212
|
-
// When the time lapsed is higher than the baseline time
|
|
213
|
-
newStatus.online = false;
|
|
214
|
-
newStatus.liveStatus = "OFFLINE";
|
|
215
|
-
newStatus.lastUpdated = currentTime;
|
|
216
|
-
newStatus.error = {
|
|
217
|
-
type: "offline",
|
|
218
|
-
message: reason || "Device has been offline for longer than baseline",
|
|
219
|
-
default: {},
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
await this.deviceRepository.setStatus(deviceId, newStatus);
|
|
223
|
-
await this.eventHandler.onStatusChange(deviceId, newStatus);
|
|
224
|
-
|
|
225
|
-
// Raise alert
|
|
226
|
-
await this.alertService.raiseDeviceOfflineAlert(device, source, reason);
|
|
227
|
-
|
|
228
|
-
// Raise issue when the device goes offline if longer than the baseline
|
|
229
|
-
await this.issueService.createDeviceOfflineIssue(
|
|
230
|
-
device,
|
|
231
|
-
source,
|
|
232
|
-
reason
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
private async handleOnlineStatus(
|
|
239
|
-
deviceId: string,
|
|
240
|
-
device: IDevice,
|
|
241
|
-
oldStatus: any,
|
|
242
|
-
newStatus: IStatus,
|
|
243
|
-
source: Source,
|
|
244
|
-
reason?: string,
|
|
245
|
-
currentTime?: string
|
|
246
|
-
) {
|
|
247
|
-
const isExistingStatusOnline = oldStatus?.online === true;
|
|
248
|
-
const isExistingStatusOffline = oldStatus?.online === false;
|
|
249
|
-
|
|
250
|
-
if (isExistingStatusOnline) {
|
|
251
|
-
// Existing status is Online
|
|
252
|
-
if (oldStatus?.liveStatus === "ONLINE") {
|
|
253
|
-
// liveStatus = Online → Do nothing
|
|
254
|
-
return;
|
|
255
|
-
} else if (oldStatus?.liveStatus === "OFFLINE") {
|
|
256
|
-
// liveStatus = Offline → Follow the step #2 (same as existing status is Offline)
|
|
257
|
-
newStatus.online = true;
|
|
258
|
-
newStatus.liveStatus = "ONLINE";
|
|
259
|
-
newStatus.lastUpdated = currentTime;
|
|
260
|
-
newStatus.error = {}; // Clear the error
|
|
261
|
-
|
|
262
|
-
await this.deviceRepository.setStatus(deviceId, newStatus);
|
|
263
|
-
await this.eventHandler.onStatusChange(deviceId, newStatus);
|
|
264
|
-
|
|
265
|
-
//TODO: ALERT NEEDED?
|
|
266
|
-
// Raise alert
|
|
267
|
-
await this.alertService.raiseDeviceOnlineAlert(device, source, reason);
|
|
268
|
-
}
|
|
269
|
-
} else if (isExistingStatusOffline) {
|
|
270
|
-
// Existing status is Offline
|
|
271
|
-
newStatus.online = true;
|
|
272
|
-
newStatus.liveStatus = "ONLINE";
|
|
273
|
-
newStatus.lastUpdated = currentTime;
|
|
274
|
-
newStatus.error = undefined; // Clear the error
|
|
275
|
-
|
|
276
|
-
await this.deviceRepository.setStatus(deviceId, newStatus);
|
|
277
|
-
await this.eventHandler.onStatusChange(deviceId, newStatus);
|
|
278
|
-
|
|
279
|
-
//TODO: ALERT NEEDED?
|
|
280
|
-
// Raise alert
|
|
281
|
-
await this.alertService.raiseDeviceOnlineAlert(device, source, reason);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
private async getDeviceBaseline(deviceId: string): Promise<number> {
|
|
286
|
-
// TODO: Implement device baseline retrieval
|
|
287
|
-
// This should return the baseline time in milliseconds for the specific device
|
|
288
|
-
// For now, returning a default value of 5 minutes (300000ms)
|
|
289
|
-
// In a real implementation, this would fetch from device configuration or settings
|
|
290
|
-
return 3600000; // 1 hour in milliseconds
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async getBatteryLevel(deviceId: string) {
|
|
294
|
-
if (!deviceId) {
|
|
295
|
-
throw new Error("Device ID is required");
|
|
296
|
-
}
|
|
297
|
-
return await this.deviceRepository.getBatteryLevel(deviceId);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async setBatteryLevel(
|
|
301
|
-
deviceId: string,
|
|
302
|
-
batteryLevel: number,
|
|
303
|
-
source: Source
|
|
304
|
-
) {
|
|
305
|
-
if (!deviceId || batteryLevel === undefined || batteryLevel === null) {
|
|
306
|
-
throw new Error("Device ID and battery level are required");
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Get device information
|
|
310
|
-
const device = await this.getDevice(deviceId);
|
|
311
|
-
|
|
312
|
-
// Fetch the old battery level state
|
|
313
|
-
const oldBatteryLevel = device.state?.batteryPercentage;
|
|
314
|
-
|
|
315
|
-
// Check if battery level has changed
|
|
316
|
-
const isDifferent = !isEqual(oldBatteryLevel?.value, batteryLevel);
|
|
317
|
-
|
|
318
|
-
if (isDifferent) {
|
|
319
|
-
// Check if current time is greater than or equal to last updated time (8-hour logic)
|
|
320
|
-
const shouldUpdate = this.shouldUpdateBatteryLevel(
|
|
321
|
-
oldBatteryLevel?.lastUpdated
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
if (shouldUpdate) {
|
|
325
|
-
// Save the battery level in the device
|
|
326
|
-
await this.deviceRepository.setBatteryLevel(deviceId, batteryLevel);
|
|
327
|
-
await this.eventHandler.onBatteryLevelChange(deviceId, batteryLevel);
|
|
328
|
-
|
|
329
|
-
// Get property threshold
|
|
330
|
-
const propertyThreshold = await this.getPropertyBatteryThreshold(
|
|
331
|
-
device.propertyId
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
// Check if battery level is below threshold
|
|
335
|
-
if (batteryLevel < propertyThreshold) {
|
|
336
|
-
// Raise alert
|
|
337
|
-
await this.alertService.raiseDeviceBatteryAlert(
|
|
338
|
-
device,
|
|
339
|
-
batteryLevel,
|
|
340
|
-
propertyThreshold,
|
|
341
|
-
source
|
|
342
|
-
);
|
|
343
|
-
|
|
344
|
-
// Raise issue when the level is below threshold
|
|
345
|
-
await this.issueService.createDeviceBatteryIssue(
|
|
346
|
-
device,
|
|
347
|
-
batteryLevel,
|
|
348
|
-
propertyThreshold,
|
|
349
|
-
source
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
private shouldUpdateBatteryLevel(lastUpdated?: string): boolean {
|
|
357
|
-
if (!lastUpdated) {
|
|
358
|
-
return true; // No previous update, so we should update
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const lastUpdateTime = new Date(lastUpdated).getTime();
|
|
362
|
-
const currentTime = Date.now();
|
|
363
|
-
const eightHoursInMs = 8 * 60 * 60 * 1000; // 8 hours in milliseconds
|
|
364
|
-
|
|
365
|
-
// Return true if current time is greater than or equal to last updated time + 8 hours
|
|
366
|
-
return currentTime >= lastUpdateTime + eightHoursInMs;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
private async getPropertyBatteryThreshold(
|
|
370
|
-
propertyId: string
|
|
371
|
-
): Promise<number> {
|
|
372
|
-
// TODO: Implement property battery threshold retrieval
|
|
373
|
-
// This should return the battery threshold for the specific property
|
|
374
|
-
// For now, returning a default value of 20%
|
|
375
|
-
// In a real implementation, this would fetch from property configuration or settings
|
|
376
|
-
return 20; // 20% default threshold
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async getMetaData(deviceId: string) {
|
|
380
|
-
if (!deviceId) {
|
|
381
|
-
throw new Error("Device ID is required");
|
|
382
|
-
}
|
|
383
|
-
return await this.deviceRepository.getMetaData(deviceId);
|
|
384
|
-
}
|
|
385
|
-
async setMetaData(deviceId: string, metaData: Record<string, any>) {
|
|
386
|
-
if (!deviceId || !metaData) {
|
|
387
|
-
throw new Error("Device ID and meta data are required");
|
|
388
|
-
}
|
|
389
|
-
await this.eventHandler.onDeviceMetaChange(deviceId, metaData);
|
|
390
|
-
return await this.deviceRepository.setMetaData(deviceId, metaData);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
async getDevicesByZone(zoneId: string) {
|
|
394
|
-
if (!zoneId) {
|
|
395
|
-
throw new Error("Zone ID is required");
|
|
396
|
-
}
|
|
397
|
-
return await this.deviceRepository.getDevicesByZone(zoneId);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
async getDevicesByAccessGroup(accessGroupId: string) {
|
|
401
|
-
if (!accessGroupId) {
|
|
402
|
-
throw new Error("Access Group ID is required");
|
|
403
|
-
}
|
|
404
|
-
return await this.deviceRepository.getDevicesByAccessGroup(accessGroupId);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
async querySelect(query: any, fields: string[]) {
|
|
408
|
-
if (!query || Object.keys(query).length === 0) {
|
|
409
|
-
throw new Error("Query is required");
|
|
410
|
-
}
|
|
411
|
-
return await this.deviceRepository.querySelect(query, fields);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
async queryCount(query: any): Promise<number> {
|
|
415
|
-
if (!query || Object.keys(query).length === 0) {
|
|
416
|
-
throw new Error("Query is required");
|
|
417
|
-
}
|
|
418
|
-
const count = await this.deviceRepository.queryCount(query);
|
|
419
|
-
return count;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
async deleteDevices(query: any) {
|
|
423
|
-
if (!query || Object.keys(query).length === 0) {
|
|
424
|
-
throw new Error("Query is required");
|
|
425
|
-
}
|
|
426
|
-
return await this.deviceRepository.deleteDevices(query);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
async queryDevices(query: any) {
|
|
430
|
-
if (!query || Object.keys(query).length === 0) {
|
|
431
|
-
throw new Error("Query is required");
|
|
432
|
-
}
|
|
433
|
-
const res = await this.deviceRepository.queryDevices(query);
|
|
434
|
-
return res;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { IDevice } from "../interfaces";
|
|
2
|
-
import { HubRepository } from "../repository/Hub.repository";
|
|
3
|
-
import Container from "typedi";
|
|
4
|
-
|
|
5
|
-
export class LocalHubService {
|
|
6
|
-
private readonly hubRepository: HubRepository;
|
|
7
|
-
constructor() {
|
|
8
|
-
this.hubRepository = Container.get(HubRepository);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async addHub(body: Partial<IDevice>): Promise<IDevice> {
|
|
12
|
-
return await this.hubRepository.addHub(body);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async getHubs(hubIds: string[]): Promise<IDevice[]> {
|
|
16
|
-
if (!hubIds.length) {
|
|
17
|
-
throw new Error("At least one hub ID is required");
|
|
18
|
-
}
|
|
19
|
-
return await this.hubRepository.getHubs(hubIds);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async getHub(hubId: string): Promise<IDevice> {
|
|
23
|
-
if (!hubId) {
|
|
24
|
-
throw new Error("Hub ID is required");
|
|
25
|
-
}
|
|
26
|
-
return await this.hubRepository.getHub(hubId);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async updateHub(hubId: string, body: Partial<IDevice>): Promise<IDevice> {
|
|
30
|
-
if (!hubId) {
|
|
31
|
-
throw new Error("Hub ID is required");
|
|
32
|
-
}
|
|
33
|
-
return await this.hubRepository.updateHub(hubId, body);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async getStatus(hubId: string): Promise<any> {
|
|
37
|
-
if (!hubId) {
|
|
38
|
-
throw new Error("Hub ID is required");
|
|
39
|
-
}
|
|
40
|
-
return await this.hubRepository.getStatus(hubId);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async deleteHub(hubId: string): Promise<any> {
|
|
44
|
-
if (!hubId) {
|
|
45
|
-
throw new Error("Hub ID is required");
|
|
46
|
-
}
|
|
47
|
-
return await this.hubRepository.deleteHub(hubId);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
async deleteAllHubs(hubIds: string[]): Promise<any> {
|
|
52
|
-
if (!hubIds.length) {
|
|
53
|
-
throw new Error("At least one hub ID is required");
|
|
54
|
-
}
|
|
55
|
-
return await this.hubRepository.deleteAllHubs(hubIds);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import Container from "typedi";
|
|
2
|
-
import { ScheduleRepository } from "../repository/Schedule.repository";
|
|
3
|
-
import { ISchedule } from "../interfaces/ISchedule";
|
|
4
|
-
|
|
5
|
-
export class LocalScheduleService {
|
|
6
|
-
private readonly scheduleRepository: ScheduleRepository;
|
|
7
|
-
constructor() {
|
|
8
|
-
this.scheduleRepository = Container.get(ScheduleRepository);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async getSchedule(scheduleId: string) {
|
|
12
|
-
return await this.scheduleRepository.getSchedule(scheduleId);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async setSchedule(scheduleId: string, schedule: ISchedule) {
|
|
16
|
-
return await this.scheduleRepository.setSchedule(scheduleId, schedule);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async getScheduleByZone(zoneId: string) {
|
|
20
|
-
return await this.scheduleRepository.getScheduleByZone(zoneId);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async deleteSchedule(scheduleId: string) {
|
|
24
|
-
return await this.scheduleRepository.deleteSchedule(scheduleId);
|
|
25
|
-
}
|
|
26
|
-
}
|