diff --git a/lambda/onMessage.ts b/lambda/onMessage.ts index 9fb4f15..9a6c109 100644 --- a/lambda/onMessage.ts +++ b/lambda/onMessage.ts @@ -123,7 +123,7 @@ export const handler = async ( if (message.data === 'LWM2M-shadows') { // Publish LwM2M shadows - const shadows = await fetchLwM2M() + const shadows = await fetchLwM2M(1) console.log( JSON.stringify({ diff --git a/lambda/publishLwM2MShadowsToJSON.ts b/lambda/publishLwM2MShadowsToJSON.ts index 82cf3cc..6e899ec 100644 --- a/lambda/publishLwM2MShadowsToJSON.ts +++ b/lambda/publishLwM2MShadowsToJSON.ts @@ -17,7 +17,7 @@ export const handler = async (): Promise => { CacheControl: 'public, max-age=60', Body: JSON.stringify({ '@context': 'https://github.com/hello-nrfcloud/proto/map/devices', - devices: (await fetchShadows()).map(({ deviceId, objects }) => ({ + devices: (await fetchShadows(30)).map(({ deviceId, objects }) => ({ '@context': 'https://github.com/hello-nrfcloud/proto/map/device', id: deviceId, model: 'world.thingy.rocks', diff --git a/lwm2m/fetchLwM2MShadows.ts b/lwm2m/fetchLwM2MShadows.ts index fce5c60..433e954 100644 --- a/lwm2m/fetchLwM2MShadows.ts +++ b/lwm2m/fetchLwM2MShadows.ts @@ -2,6 +2,7 @@ import { IoTClient, SearchIndexCommand } from '@aws-sdk/client-iot' import type { LwM2MObjectInstance } from '@hello.nrfcloud.com/proto-lwm2m' import { shadowToObjects } from './shadowToObjects.js' import { getDeviceInfo } from '../lambda/withDeviceAlias.js' +import { instanceTs } from './instanceTs.js' type LwM2MShadow = { deviceId: string @@ -11,9 +12,9 @@ type LwM2MShadow = { export const fetchLwM2MShadows = ( iot: IoTClient, -): (() => Promise) => { +): ((notOlderThanDays?: number) => Promise) => { const deviceInfo = getDeviceInfo(iot) - return async () => { + return async (notOlderThanDays = 30) => { const { things } = await iot.send( new SearchIndexCommand({ // Find all things which have an LwM2M shadow @@ -36,7 +37,13 @@ export const fetchLwM2MShadows = ( return { deviceId: thingName as string, alias, - objects: shadowToObjects(reported), + objects: shadowToObjects(reported).filter((instance) => { + const updateTs = instanceTs(instance) + return ( + Date.now() - updateTs.getTime() < + notOlderThanDays * 24 * 60 * 60 * 1000 + ) + }), } } catch (err) { console.error(`Failed to convert shadow for thing ${thingName}`) diff --git a/lwm2m/instanceTs.spec.ts b/lwm2m/instanceTs.spec.ts new file mode 100644 index 0000000..e61073e --- /dev/null +++ b/lwm2m/instanceTs.spec.ts @@ -0,0 +1,19 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert/strict' +import { instanceTs } from './instanceTs.js' + +void describe('instanceTs()', () => { + void it('should return the timestamp of the instance', () => + assert.equal( + instanceTs({ + ObjectID: 14210, + ObjectVersion: '1.0', + Resources: { + '0': 3.5399999618530273, + '1': 4.168000221252441, + '99': '2024-02-23T10:18:20.474Z', + }, + }).getTime(), + new Date('2024-02-23T10:18:20.474Z').getTime(), + )) +}) diff --git a/lwm2m/instanceTs.ts b/lwm2m/instanceTs.ts new file mode 100644 index 0000000..eea05d4 --- /dev/null +++ b/lwm2m/instanceTs.ts @@ -0,0 +1,18 @@ +import { + type LwM2MObjectInstance, + definitions, + LwM2MObjectID, + timestampResources, +} from '@hello.nrfcloud.com/proto-lwm2m' + +export const instanceTs = (instance: LwM2MObjectInstance): Date => { + const definition = definitions[instance.ObjectID as LwM2MObjectID] + const tsResourceId = timestampResources[definition.ObjectID] as number + const ts = instance.Resources[tsResourceId] as string + return new Date(ts) +} + +export const newestInstanceFirst = ( + i1: LwM2MObjectInstance, + i2: LwM2MObjectInstance, +): number => instanceTs(i2).getTime() - instanceTs(i1).getTime()