diff --git a/app/controllers/cwmp_controller.ts b/app/controllers/cwmp_controller.ts index 3faf291..bd3f78d 100644 --- a/app/controllers/cwmp_controller.ts +++ b/app/controllers/cwmp_controller.ts @@ -172,6 +172,12 @@ export default class CwmpController { logger.info({ events }, 'CWMP Inform events extracted') + // Track last periodic inform timestamp + const isPeriodic = events.some((e) => String(e).toUpperCase().includes('PERIODIC') || String(e) === '2') + if (isPeriodic) { + await DeviceModel.updateOne({ identifier: hashId }, { $set: { lastPeriodicInformAt: new Date() } }).catch(() => {}) + } + // Start state machine await manager.startStateMachine(device, session, { events }) manager.bindRemoteToDevice(remoteKey, device.deviceId) diff --git a/app/controllers/devices_controller.ts b/app/controllers/devices_controller.ts index 84a75e1..a64c2f0 100644 --- a/app/controllers/devices_controller.ts +++ b/app/controllers/devices_controller.ts @@ -8,7 +8,7 @@ export default class DevicesController { private deviceService = new DeviceService() async criteriaValues({ response }: HttpContext) { - const values = await DeviceModel.distinctCriteriaValues() + const values = await (DeviceModel as any).distinctCriteriaValues() return response.json(values) } diff --git a/app/domain/device/device_record.ts b/app/domain/device/device_record.ts index f0eceb6..bdf9336 100644 --- a/app/domain/device/device_record.ts +++ b/app/domain/device/device_record.ts @@ -14,6 +14,7 @@ export interface DeviceRecord { compliance?: DeviceComplianceInfo provisioningCode?: string references?: DeviceReference[] + lastPeriodicInformAt?: Date updatedAt?: Date createdAt?: Date } diff --git a/inertia/pages/DeviceDetail.vue b/inertia/pages/DeviceDetail.vue index 8deaee5..b1206c4 100644 --- a/inertia/pages/DeviceDetail.vue +++ b/inertia/pages/DeviceDetail.vue @@ -126,6 +126,18 @@ function submitGetModel() { }) } +// Estimated next connection = lastPeriodicInformAt + PeriodicInformInterval +const estimatedNextConnection = (() => { + const lastPeriodic = device.lastPeriodicInformAt + if (!lastPeriodic) return null + const allParams = [...(device.properties || []), ...(device.parameters || [])] + const intervalParam = allParams.find((p: any) => p.name?.includes('PeriodicInformInterval')) + const intervalSeconds = intervalParam?.value ? parseInt(intervalParam.value, 10) : 0 + if (!intervalSeconds || intervalSeconds <= 0) return null + const next = new Date(new Date(lastPeriodic).getTime() + intervalSeconds * 1000) + return next.toLocaleString() +})() + // Check if the device has a ConnectionRequestURL (needed for immediate mode / Refresh) const hasConnectionRequestUrl = (() => { const allParams = [...(device.properties || []), ...(device.parameters || [])] @@ -333,6 +345,23 @@ async function resolveAllProviders() { + +