From b0b85ff3e784a3b6d4d561eb450308af7933ce5f Mon Sep 17 00:00:00 2001
From: Markus Tacker
Date: Tue, 28 May 2024 21:45:03 +0200
Subject: [PATCH] feat: improve handling of lwm2m objects
---
pages/device.page.tsx | 25 +++----
src/chart/toChartData.ts | 2 +-
src/components/BME680.tsx | 4 +-
src/components/DeviceHeader.tsx | 15 ++--
src/components/SignalQuality.tsx | 6 +-
src/components/deviceInfo/NetworkInfo.tsx | 6 +-
src/components/deviceInfo/NetworkModeInfo.tsx | 6 +-
src/components/deviceInfo/SoftwareInfo.tsx | 5 +-
.../PCA20035-solar/SolarThingyBattery.tsx | 4 +-
.../model/PCA20035-solar/SolarThingyChart.tsx | 32 +++++++--
src/context/Device.tsx | 69 +++++++++++++++----
src/context/DeviceLocation.tsx | 12 ++--
src/context/DeviceState.tsx | 66 ------------------
src/context/{LwM2MHistory.tsx => History.tsx} | 46 +++++--------
src/map/CellularLocation.tsx | 7 +-
src/map/GNSSLocation.tsx | 8 +--
src/map/Map.tsx | 9 ++-
17 files changed, 155 insertions(+), 167 deletions(-)
delete mode 100644 src/context/DeviceState.tsx
rename src/context/{LwM2MHistory.tsx => History.tsx} (55%)
diff --git a/pages/device.page.tsx b/pages/device.page.tsx
index 030c8f45..32e2252d 100644
--- a/pages/device.page.tsx
+++ b/pages/device.page.tsx
@@ -3,10 +3,9 @@ import { Navbar } from '#components/Navbar.js'
import { Provider as ModelsProvider } from '#context/Models.js'
import { Provider as DeviceProvider } from '#context/Device.js'
import { Provider as DeviceLocationProvider } from '#context/DeviceLocation.js'
-import { Provider as DeviceStateProvider } from '#context/DeviceState.js'
import { Provider as FingerprintProvider } from '#context/Fingerprint.js'
import { Provider as ParametersProvider } from '#context/Parameters.js'
-import { Provider as LwM2MHistoryProvider } from '#context/LwM2MHistory.js'
+import { Provider as HistoryProvider } from '#context/History.js'
import { Device } from '#page/Device.js'
import type { IndexPageProps } from './index.page.server.js'
import { WebsocketDisconnectNotifier } from '#components/WebsocketDisconnectNotifier.js'
@@ -17,18 +16,16 @@ export const Page = ({ models }: IndexPageProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/chart/toChartData.ts b/src/chart/toChartData.ts
index e5376581..a634991c 100644
--- a/src/chart/toChartData.ts
+++ b/src/chart/toChartData.ts
@@ -5,7 +5,7 @@ import {
type BatteryReading,
type BatteryReadings,
type GainReadings,
-} from '#context/LwM2MHistory.js'
+} from '#context/History.js'
import { xAxisForType } from '#chart/xAxisForType.js'
export const toChartData = ({
diff --git a/src/components/BME680.tsx b/src/components/BME680.tsx
index 4244139d..20ddec36 100644
--- a/src/components/BME680.tsx
+++ b/src/components/BME680.tsx
@@ -1,5 +1,5 @@
import { LoadingIndicator } from '#components/ValueLoading.js'
-import { useLwM2MHistory } from '#context/LwM2MHistory.js'
+import { useHistory } from '#context/History.js'
import {
AngryIcon,
AnnoyedIcon,
@@ -43,7 +43,7 @@ export const BME680 = () => (
)
export const EnvironmentReadings = () => {
- const { environment } = useLwM2MHistory()
+ const { environment } = useHistory()
const { p, mbar, IAQ: iaq, c, ts: updateTime } = environment[0] ?? {}
diff --git a/src/components/DeviceHeader.tsx b/src/components/DeviceHeader.tsx
index d38876eb..f08c91b8 100644
--- a/src/components/DeviceHeader.tsx
+++ b/src/components/DeviceHeader.tsx
@@ -1,7 +1,6 @@
import { DeviceModeSelector } from '#components/DeviceModeSelector.js'
import { useDevice, type Device } from '#context/Device.js'
-import { useDeviceState } from '#context/DeviceState.js'
-import { useLwM2MHistory } from '#context/LwM2MHistory.js'
+import { useHistory } from '#context/History.js'
import { identifyIssuer } from 'e118-iin-list'
import {
ActivitySquareIcon,
@@ -101,7 +100,7 @@ export const DeviceHeader = ({ device }: { device: Device }) => {
}
const SignalQualityInfo = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const { eest, ts } =
state.filter(isConnectionInformation).map(toConnectionInformation)[0] ?? {}
@@ -136,7 +135,7 @@ const SignalQualityInfo = () => {
}
const EnvironmentInfo = () => {
- const { environment } = useLwM2MHistory()
+ const { environment } = useHistory()
const { IAQ: iaq, c, ts: updateTime } = environment[0] ?? {}
return (
@@ -169,7 +168,7 @@ const EnvironmentInfo = () => {
}
const NetworkModeInfo = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const { networkMode, currentBand, ts } =
state.filter(isConnectionInformation).map(toConnectionInformation)[0] ?? {}
@@ -214,7 +213,7 @@ const NetworkModeInfo = () => {
}
const BatteryInfo = () => {
- const { battery } = useLwM2MHistory()
+ const { battery } = useHistory()
const batteryReading = battery[0]
return (
@@ -244,7 +243,7 @@ const BatteryInfo = () => {
}
const Interact = () => {
- const { button } = useLwM2MHistory()
+ const { button } = useHistory()
const buttonPress = button[0]
return (
@@ -309,7 +308,7 @@ const PublicationInterval = ({ onConfigure }: { onConfigure?: () => void }) => {
}
const SIMInfo = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const { iccid, ts } =
state.filter(isDeviceInformation).map(toDeviceInformation)[0] ?? {}
diff --git a/src/components/SignalQuality.tsx b/src/components/SignalQuality.tsx
index fe0cc14c..b450622a 100644
--- a/src/components/SignalQuality.tsx
+++ b/src/components/SignalQuality.tsx
@@ -1,4 +1,3 @@
-import { useDeviceState } from '#context/DeviceState.js'
import {
Signal,
SignalHigh,
@@ -14,6 +13,7 @@ import {
isConnectionInformation,
toConnectionInformation,
} from '#proto/lwm2m.js'
+import { useDevice } from '#context/Device.js'
/**
* The %CONEVAL AT command returns amongst other data the energy estimate: Relative estimated energy consumption of data transmission compared to nominal consumption. A higher value means smaller energy consumption. 5: Difficulties in setting up connections. Maximum number of repetitions might be needed for data.
@@ -86,7 +86,7 @@ export const EnergyEstimateLabel = new Map([
])
export const SignalQuality = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const eest = state
.filter(isConnectionInformation)
@@ -108,7 +108,7 @@ export const SignalQuality = () => {
}
export const SignalQualityIcon = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const eest = state
.filter(isConnectionInformation)
.map(toConnectionInformation)[0]?.eest
diff --git a/src/components/deviceInfo/NetworkInfo.tsx b/src/components/deviceInfo/NetworkInfo.tsx
index 4b82be44..1914bc7f 100644
--- a/src/components/deviceInfo/NetworkInfo.tsx
+++ b/src/components/deviceInfo/NetworkInfo.tsx
@@ -1,5 +1,4 @@
import { LoadingIndicator } from '#components/ValueLoading.js'
-import { useDeviceState } from '#context/DeviceState.js'
import { identifyIssuer } from 'e118-iin-list'
import { CpuIcon } from 'lucide-preact'
import { SignalQuality } from '#components/SignalQuality.js'
@@ -11,9 +10,12 @@ import {
toConnectionInformation,
toDeviceInformation,
} from '#proto/lwm2m.js'
+import { useDevice } from '#context/Device.js'
export const NetworkInfo = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
+
+ console.log(state)
const networkMode = state
.filter(isConnectionInformation)
diff --git a/src/components/deviceInfo/NetworkModeInfo.tsx b/src/components/deviceInfo/NetworkModeInfo.tsx
index 083d842b..95974a12 100644
--- a/src/components/deviceInfo/NetworkModeInfo.tsx
+++ b/src/components/deviceInfo/NetworkModeInfo.tsx
@@ -1,14 +1,14 @@
import { LoadingIndicator } from '#components/ValueLoading.js'
-import { useDeviceState } from '#context/DeviceState.js'
import {
isConnectionInformation,
toConnectionInformation,
} from '#proto/lwm2m.js'
import { LTEm } from '#components/icons/LTE-m.js'
import { NBIot } from '#components/icons/NBIot.js'
+import { useDevice } from '#context/Device.js'
export const NetworkModeInfo = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const networkMode = state
.filter(isConnectionInformation)
.map(toConnectionInformation)[0]?.networkMode
@@ -38,7 +38,7 @@ export const NetworkModeInfo = () => {
}
export const NetworkModeIcon = () => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const networkInfo = state
.filter(isConnectionInformation)
.map(toConnectionInformation)[0]
diff --git a/src/components/deviceInfo/SoftwareInfo.tsx b/src/components/deviceInfo/SoftwareInfo.tsx
index 334f59cf..e0c2d58c 100644
--- a/src/components/deviceInfo/SoftwareInfo.tsx
+++ b/src/components/deviceInfo/SoftwareInfo.tsx
@@ -1,5 +1,4 @@
-import { type Device } from '#context/Device.js'
-import { useDeviceState } from '#context/DeviceState.js'
+import { useDevice, type Device } from '#context/Device.js'
import { parseModemFirmwareVersion } from '#utils/parseModemFirmwareVersion.js'
import { AlertTriangle, CheckCircle2 } from 'lucide-preact'
import { ValueLoading } from '#components/ValueLoading.js'
@@ -7,7 +6,7 @@ import { isOutdated } from '#components/deviceInfo/isOutdated.js'
import { isDeviceInformation, toDeviceInformation } from '#proto/lwm2m.js'
export const SoftwareInfo = ({ device }: { device: Device }) => {
- const { state } = useDeviceState()
+ const { reported: state } = useDevice()
const type = device.model
const deviceInfo = state
diff --git a/src/components/model/PCA20035-solar/SolarThingyBattery.tsx b/src/components/model/PCA20035-solar/SolarThingyBattery.tsx
index 9e1286d0..8a346b08 100644
--- a/src/components/model/PCA20035-solar/SolarThingyBattery.tsx
+++ b/src/components/model/PCA20035-solar/SolarThingyBattery.tsx
@@ -1,6 +1,6 @@
import { Ago } from '#components/Ago.js'
import { LoadingIndicator } from '#components/ValueLoading.js'
-import { useLwM2MHistory } from '#context/LwM2MHistory.js'
+import { useHistory } from '#context/History.js'
import {
Battery,
BatteryFull,
@@ -25,7 +25,7 @@ export const SolarThingyBattery = () => (
)
const BatteryInfo = () => {
- const { battery } = useLwM2MHistory()
+ const { battery } = useHistory()
const batteryReading = battery[0]
if (batteryReading?.['%'] === undefined)
return
diff --git a/src/components/model/PCA20035-solar/SolarThingyChart.tsx b/src/components/model/PCA20035-solar/SolarThingyChart.tsx
index d6a3ff8d..825ed951 100644
--- a/src/components/model/PCA20035-solar/SolarThingyChart.tsx
+++ b/src/components/model/PCA20035-solar/SolarThingyChart.tsx
@@ -3,18 +3,42 @@ import { Ago } from '#components/Ago.js'
import { LoadingIndicator } from '#components/ValueLoading.js'
import { formatFloat } from '#utils/formatFloat.js'
import { BatteryCharging, Sun } from 'lucide-preact'
-import { isNotHistory, useLwM2MHistory } from '#context/LwM2MHistory.js'
import { toChartData } from '#chart/toChartData.js'
import { DateRangeButton } from '#chart/DateRangeButton.js'
import { WithResize } from '#components/ResizeObserver.js'
import { WaitingForData } from '#components/WaitingForData.js'
import { timeSpans } from '#chart/timeSpans.js'
+import { useHistory } from '#context/History.js'
+import { useDevice } from '#context/Device.js'
+import {
+ isBatteryAndPower,
+ isSolarCharge,
+ toBattery,
+ toSolarCharge,
+} from '#proto/lwm2m.js'
+import {
+ timestampResources,
+ type LwM2MObjectInstance,
+} from '@hello.nrfcloud.com/proto-map/lwm2m'
+
+const byTimestamp = (i1: LwM2MObjectInstance, i2: LwM2MObjectInstance) => {
+ const ts1 = i1.Resources[timestampResources[i1.ObjectID] as number] as number
+ const ts2 = i2.Resources[timestampResources[i2.ObjectID] as number] as number
+ return ts2 - ts1
+}
export const SolarThingyChart = () => {
- const { battery, gain, timeSpan, setTimeSpan } = useLwM2MHistory()
+ const { battery, gain, timeSpan, setTimeSpan } = useHistory()
+ const { reported } = useDevice()
- const currentBattery = battery.filter(isNotHistory)[0]
- const currentGain = gain.filter(isNotHistory)[0]
+ const currentBattery = reported
+ .filter(isBatteryAndPower)
+ .sort(byTimestamp)
+ .map(toBattery)[0]
+ const currentGain = reported
+ .filter(isSolarCharge)
+ .sort(byTimestamp)
+ .map(toSolarCharge)[0]
const hasChartData = gain.length + battery.length > 0
diff --git a/src/context/Device.tsx b/src/context/Device.tsx
index ce970042..9c14b072 100644
--- a/src/context/Device.tsx
+++ b/src/context/Device.tsx
@@ -40,9 +40,14 @@ export const DeviceContext = createContext<{
connected: boolean
connectionFailed: boolean
disconnected: boolean
- addMessageListener: (listener: MessageListenerFn) => {
+ onReported: (listener: ListenerFn) => {
remove: () => void
}
+ reported: LwM2MObjectInstance[]
+ onDesired: (listener: ListenerFn) => {
+ remove: () => void
+ }
+ desired: LwM2MObjectInstance[]
send?: (message: LwM2MObjectInstance) => void
configuration: {
desired: Configuration
@@ -54,9 +59,14 @@ export const DeviceContext = createContext<{
}>({
connected: false,
disconnected: false,
- addMessageListener: () => ({
+ onReported: () => ({
+ remove: () => undefined,
+ }),
+ reported: [],
+ onDesired: () => ({
remove: () => undefined,
}),
+ desired: [],
connectionFailed: false,
configuration: {
desired: DefaultConfiguration,
@@ -65,13 +75,13 @@ export const DeviceContext = createContext<{
configure: async () => Promise.reject(new Error('Not implemented')),
})
-export type MessageListenerFn = (message: LwM2MObjectInstance) => unknown
+export type ListenerFn = (instance: LwM2MObjectInstance) => unknown
export const Provider = ({ children }: { children: ComponentChildren }) => {
const [device, setDevice] = useState(undefined)
const [lastSeen, setLastSeen] = useState(undefined)
const [connectionFailed, setConnectionFailed] = useState(false)
- const [messages, setMessages] = useState([])
+
const { fingerprint } = useFingerprint()
const { onParameters } = useParameters()
const { models } = useModels()
@@ -83,7 +93,10 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
const [reportedConfig] = useState(DefaultConfiguration)
const connected = ws !== undefined
- const listeners = useRef([])
+ const [reported, setReported] = useState([])
+ const reportedListeners = useRef([])
+ const [desired, setDesired] = useState([])
+ const desiredListeners = useRef([])
// Set up websocket connection
useEffect(() => {
@@ -141,12 +154,25 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
setLastSeen(new Date(maybeValid.lastSeen))
}
} else if (isShadow(maybeValid)) {
- const instances = maybeValid.reported
- setMessages((m) => [...m, ...instances])
- listeners.current.forEach((listener) => instances.map(listener))
+ const reported = maybeValid.reported
+ if (reported.length > 0) {
+ setReported((r) => [...reported, ...r])
+ reportedListeners.current.forEach((listener) =>
+ reported.map(listener),
+ )
+ }
+ const desired = maybeValid.desired
+ if (desired.length > 0) {
+ setDesired((d) => [...desired, ...d])
+ desiredListeners.current.forEach((listener) =>
+ desired.map(listener),
+ )
+ }
} else if (isUpdate(maybeValid)) {
- setMessages((m) => [...m, maybeValid])
- listeners.current.forEach((listener) => listener(maybeValid))
+ setReported((r) => [...r, ...reported])
+ reportedListeners.current.forEach((listener) =>
+ reported.map(listener),
+ )
setLastSeen((l) => {
const ts = maybeValid.Resources[99] as number
if (ts === undefined) return l
@@ -198,15 +224,30 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
device,
lastSeen,
connected,
- addMessageListener: (fn) => {
- listeners.current.push(fn)
- messages.map(fn)
+ onReported: (fn) => {
+ reportedListeners.current.push(fn)
+ reported.map(fn)
+ return {
+ remove: () => {
+ reportedListeners.current = reportedListeners.current.filter(
+ (f) => f !== fn,
+ )
+ },
+ }
+ },
+ reported,
+ onDesired: (fn) => {
+ desiredListeners.current.push(fn)
+ desired.map(fn)
return {
remove: () => {
- listeners.current = listeners.current.filter((f) => f !== fn)
+ desiredListeners.current = desiredListeners.current.filter(
+ (f) => f !== fn,
+ )
},
}
},
+ desired,
connectionFailed,
send,
disconnected,
diff --git a/src/context/DeviceLocation.tsx b/src/context/DeviceLocation.tsx
index d2bdabcc..315a4e2e 100644
--- a/src/context/DeviceLocation.tsx
+++ b/src/context/DeviceLocation.tsx
@@ -1,7 +1,7 @@
import type { LocationSource } from '#map/LocationSourceLabels.js'
import { createContext, type ComponentChildren } from 'preact'
import { useContext, useEffect, useState } from 'preact/hooks'
-import { useDevice, type MessageListenerFn } from '#context/Device.js'
+import { useDevice, type ListenerFn } from '#context/Device.js'
import { isGeolocation, toGeoLocation, type GeoLocation } from '#proto/lwm2m.js'
import { TimeSpan } from '#api/api.js'
@@ -27,7 +27,7 @@ export const DeviceLocationContext = createContext<{
* FIXME: Fetch location history via REST
*/
export const Provider = ({ children }: { children: ComponentChildren }) => {
- const { addMessageListener, device } = useDevice()
+ const { onReported, device } = useDevice()
const [timeSpan, setTimeSpan] = useState(TimeSpan.lastHour)
const [locations, setLocations] = useState({})
@@ -35,14 +35,14 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
useEffect(() => {
if (device === undefined) return
- const listener: MessageListenerFn = (message) => {
- if (isGeolocation(message))
+ const listener: ListenerFn = (instance) => {
+ if (isGeolocation(instance))
setLocations((l) => ({
...l,
- [message.Resources[6]]: toGeoLocation(message),
+ [instance.Resources[6]]: toGeoLocation(instance),
}))
}
- const { remove } = addMessageListener(listener)
+ const { remove } = onReported(listener)
return () => {
remove()
diff --git a/src/context/DeviceState.tsx b/src/context/DeviceState.tsx
deleted file mode 100644
index 757c6a66..00000000
--- a/src/context/DeviceState.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import type { Shadow } from '@hello.nrfcloud.com/proto/hello'
-import { Context } from '@hello.nrfcloud.com/proto/hello'
-import { type Static } from '@sinclair/typebox'
-import { createContext, type ComponentChildren } from 'preact'
-import { useContext, useEffect, useState } from 'preact/hooks'
-import { useDevice, type MessageListenerFn } from '#context/Device.js'
-import { isObject } from 'lodash-es'
-import type { LwM2MObjectInstance } from '@hello.nrfcloud.com/proto-map/lwm2m'
-
-export const DeviceStateContext = createContext<{
- state: Array
- desiredConfig: Array
- updateConfig: (update: Array) => void
-}>({
- state: [],
- desiredConfig: [],
- updateConfig: () => undefined,
-})
-
-export const Provider = ({ children }: { children: ComponentChildren }) => {
- const { addMessageListener, device } = useDevice()
- const [state] = useState>([])
- const [desiredConfig, setDesiredConfig] = useState<
- Array
- >([])
-
- useEffect(() => {
- if (device === undefined) return
- const listener: MessageListenerFn = (message) => {
- if (isShadow(message)) {
- // FIXME: parse shadow
- }
- }
- const { remove } = addMessageListener(listener)
-
- return () => {
- remove()
- }
- }, [device])
-
- return (
- {
- setDesiredConfig((cfg) => ({ ...cfg, ...update }))
- },
- }}
- >
- {children}
-
- )
-}
-
-export const Consumer = DeviceStateContext.Consumer
-
-export const useDeviceState = () => useContext(DeviceStateContext)
-
-const isShadow = (message: unknown): message is Static =>
- isObject(message) &&
- '@context' in message &&
- message['@context'] === Context.shadow
-
-// FIXME: Implement
-export const gnssEnabled = (): boolean => false
diff --git a/src/context/LwM2MHistory.tsx b/src/context/History.tsx
similarity index 55%
rename from src/context/LwM2MHistory.tsx
rename to src/context/History.tsx
index e96ed9d0..7ef3c436 100644
--- a/src/context/LwM2MHistory.tsx
+++ b/src/context/History.tsx
@@ -15,18 +15,15 @@ import {
} from '#proto/lwm2m.js'
import { createContext, type ComponentChildren } from 'preact'
import { useContext, useEffect, useState } from 'preact/hooks'
-import { useDevice, type MessageListenerFn } from '#context/Device.js'
+import { useDevice, type ListenerFn } from '#context/Device.js'
import { byTs } from '#context/byTs.js'
-type FromHistory = {
- fromHistory?: boolean
-}
-export type BatteryReading = Battery & FromHistory
+export type BatteryReading = Battery
export type BatteryReadings = BatteryReading[]
-export type GainReading = SolarCharge & FromHistory
+export type GainReading = SolarCharge
export type GainReadings = GainReading[]
-export const LwM2MHistoryContext = createContext<{
+export const HistoryContext = createContext<{
battery: BatteryReadings
gain: GainReadings
environment: Environment[]
@@ -44,7 +41,7 @@ export const LwM2MHistoryContext = createContext<{
// FIXME: Add Gain and Battery history
export const Provider = ({ children }: { children: ComponentChildren }) => {
- const { addMessageListener } = useDevice()
+ const { onReported } = useDevice()
const [timeSpan, setTimeSpan] = useState(TimeSpan.lastHour)
const [battery, setBattery] = useState([])
@@ -52,23 +49,23 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
const [environment, setEnvironment] = useState>([])
const [button, setButton] = useState>([])
- const onMessage: MessageListenerFn = (message) => {
- if (isBatteryAndPower(message)) {
- setBattery((b) => [toBattery(message), ...b].sort(byTs))
+ const listener: ListenerFn = (instance) => {
+ if (isBatteryAndPower(instance)) {
+ setBattery((b) => [toBattery(instance), ...b].sort(byTs))
}
- if (isSolarCharge(message)) {
- setGain((b) => [toSolarCharge(message), ...b].sort(byTs))
+ if (isSolarCharge(instance)) {
+ setGain((b) => [toSolarCharge(instance), ...b].sort(byTs))
}
- if (isEnvironment(message)) {
- setEnvironment((m) => [toEnvironment(message), ...m].sort(byTs))
+ if (isEnvironment(instance)) {
+ setEnvironment((m) => [toEnvironment(instance), ...m].sort(byTs))
}
- if (isButtonPress(message)) {
- setButton((m) => [toButton(message), ...m].sort(byTs))
+ if (isButtonPress(instance)) {
+ setButton((m) => [toButton(instance), ...m].sort(byTs))
}
}
useEffect(() => {
- const { remove } = addMessageListener(onMessage)
+ const { remove } = onReported(listener)
return () => {
remove()
@@ -76,7 +73,7 @@ export const Provider = ({ children }: { children: ComponentChildren }) => {
}, [])
return (
- {
}}
>
{children}
-
+
)
}
-export const Consumer = LwM2MHistoryContext.Consumer
-
-export const useLwM2MHistory = () => useContext(LwM2MHistoryContext)
-
-export const isNotHistory = ({ fromHistory }: FromHistory) =>
- fromHistory !== true
+export const Consumer = HistoryContext.Consumer
-export const isHistory = ({ fromHistory }: FromHistory) => fromHistory === true
+export const useHistory = () => useContext(HistoryContext)
diff --git a/src/map/CellularLocation.tsx b/src/map/CellularLocation.tsx
index f65a2167..23ac1506 100644
--- a/src/map/CellularLocation.tsx
+++ b/src/map/CellularLocation.tsx
@@ -1,7 +1,5 @@
import { LoadingIndicator } from '#components/ValueLoading.js'
import { NRFCloudLogo } from '#components/icons/NRFCloudLogo.js'
-import { useDeviceLocation } from '#context/DeviceLocation.js'
-import { gnssEnabled } from '#context/DeviceState.js'
import { Located } from '#map/Map.js'
import { compareLocations } from '#map/compareLocations.js'
import type { GeoLocation } from '#proto/lwm2m.js'
@@ -9,9 +7,12 @@ import {
LocationSource,
LocationSourceLabels,
} from '#map/LocationSourceLabels.js'
+import { useDeviceLocation } from '#context/DeviceLocation.js'
+import { useDevice } from '#context/Device.js'
export const CellularLocation = () => {
const { locations } = useDeviceLocation()
+ const { configuration } = useDevice()
const scellLocation = locations[LocationSource.SCELL]
const mcellLocation = locations[LocationSource.MCELL]
const cellularLocations: GeoLocation[] = []
@@ -46,7 +47,7 @@ export const CellularLocation = () => {
Multi-cell (MCELL) is using multiple cell towers to triangulate the
device location. Up to 17 cell towers can be used at once.
- {gnssEnabled() && (
+ {configuration.reported.gnssEnabled && (
{
const { locations } = useDeviceLocation()
+ const { configuration } = useDevice()
const gnssLocation = locations[LocationSource.GNSS]
return (
@@ -23,7 +23,7 @@ export const GNSSLocation = ({ device }: { device: Device }) => {
Depending on your use-case scenario you can control whether to enable
GNSS on this device:
- {gnssEnabled() && (
+ {configuration.reported.gnssEnabled && (
<>
{gnssLocation !== undefined && }
{gnssLocation === undefined && (
diff --git a/src/map/Map.tsx b/src/map/Map.tsx
index 3b05ad44..f4e2c7e9 100644
--- a/src/map/Map.tsx
+++ b/src/map/Map.tsx
@@ -13,9 +13,7 @@ import { timeSpans } from '#chart/timeSpans.js'
import { CountryFlag } from '#components/CountryFlag.js'
import { LoadingIndicator } from '#components/ValueLoading.js'
import { mccmnc2country } from '#components/mccmnc2country.js'
-import { type Device } from '#context/Device.js'
-import { useDeviceLocation, type Locations } from '#context/DeviceLocation.js'
-import { useDeviceState } from '#context/DeviceState.js'
+import { useDevice, type Device } from '#context/Device.js'
import { useParameters } from '#context/Parameters.js'
import { CellularLocation } from '#map/CellularLocation.js'
import { GNSSLocation } from '#map/GNSSLocation.js'
@@ -39,6 +37,7 @@ import {
toConnectionInformation,
type GeoLocation,
} from '#proto/lwm2m.js'
+import { useDeviceLocation, type Locations } from '#context/DeviceLocation.js'
const trailColor = '#e169a5'
const defaultColor = '#C7C7C7'
@@ -428,8 +427,8 @@ export const Map = ({ device }: { device: Device }) => {
}
const NetworkLocation = () => {
- const { state } = useDeviceState()
- const mccmnc = state
+ const { reported } = useDevice()
+ const mccmnc = reported
.filter(isConnectionInformation)
.map(toConnectionInformation)[0]?.mccmnc
const country =