@victronenergy/mfd-modules 11.1.3 → 11.1.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.
|
@@ -311,7 +311,7 @@ export class MqttStore {
|
|
|
311
311
|
this.urgentTopicPrefixes = [
|
|
312
312
|
`N/${portalId}/switch/`,
|
|
313
313
|
`N/${portalId}/system/0/SwitchableOutput`,
|
|
314
|
-
`N/${portalId}/
|
|
314
|
+
`N/${portalId}/settings/0/Settings/Gui2/Switchpane/Preset/`,
|
|
315
315
|
];
|
|
316
316
|
}
|
|
317
317
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.store.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"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","sourcesContent":["import { comparer, makeAutoObservable, runInAction } from \"mobx\"\nimport { computedFn } from \"mobx-utils\"\nimport * as mqtt from \"mqtt\"\nimport { IClientPublishOptions, MqttClient } from \"mqtt\"\nimport { MqttMessage, MqttMessages, PortalId, STATUS, Topics } from \"../Mqtt\"\nimport Logger from \"../../utils/logger\"\nimport { getMessageJson } from \"../../utils/util\"\nimport { useMemo } from \"react\"\nimport { assign } from \"lodash-es\"\n\nlet store: MqttStore\n\nexport class MqttStore {\n client?: MqttClient | null\n error?: object | null | boolean\n status: string = STATUS.CONNECTING\n messages: MqttMessages = {}\n messageQueue: MqttMessages = {}\n topicsSubscribed: Set<string> = new Set<string>()\n portalId: PortalId\n uniqueId: string = Math.random().toString(16).substr(2, 8)\n keepAliveHandlerRef: ReturnType<typeof setInterval> | undefined\n queueWorker: ReturnType<typeof setTimeout> | undefined\n meanQueueWorkerPassDuration: number = 0\n urgentTopicPrefixes: string[] = []\n initialLoadComplete: boolean = false\n\n /**\n * Returns the current cached message for a given MQTT topic.\n *\n * React Components using this method will re-render when their specific\n * topic's message changes.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for the given topic. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topic - The MQTT topic to retrieve the message for\n * @returns The message object for the topic, or undefined if topic is not provided or not found\n */\n messageFromTopic = computedFn(\n (topic?: string) => {\n // Logger.log(`DEBUG: messageFromTopic: ${JSON.stringify(topic)}`)\n // trace()\n return topic ? this.messages[topic] : undefined\n },\n { name: \"Mqtt.store.messageFromTopic\", equals: comparer.identity }\n )\n\n /**\n * Returns the current cached messages for a given set of MQTT topics.\n *\n * This is a memoized computed function - each set of topics has its own cached value.\n *\n * React Components using this method will re-render when\n * any of the messages for specified topics change.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the specified topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topics - The MQTT topics to retrieve the messages for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByTopics = computedFn(\n (topics?: Topics) => {\n // Logger.log(`DEBUG: messagesByTopics: ${JSON.stringify(topics)}`)\n // trace()\n if (!topics) {\n return {}\n }\n\n const result: { [key: string]: MqttMessage | MqttMessage[] } = {}\n\n Object.entries(topics).forEach(([label, topic]) => {\n if (Array.isArray(topic)) {\n result[label] = topic.map((t) => this.messageFromTopic(t))\n } else if (topic === undefined) {\n result[label] = undefined\n } else {\n result[label] = this.messageFromTopic(topic)\n }\n })\n\n return result\n },\n { name: \"Mqtt.store.messagesByTopics\", equals: comparer.identity }\n )\n\n /**\n * Returns the current cached messages for MQTT topics specified via regex.\n *\n * React Components using this method will re-render when\n * values of any of the matched topics change. The components also re-render\n * when new MQTT topics are received and match needs to be checked.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the matched topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param wildcard - The MQTT wildcard to retrieve the message for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByWildcard = computedFn(\n (wildcard?: string) => {\n // Logger.log(`DEBUG: messagesByWildcard: ${JSON.stringify(wildcard)}`)\n // trace()\n if (wildcard === undefined || wildcard === \"\" || wildcard === null) return {}\n\n const topicRegex = new RegExp(wildcard.replace(/\\+/g, \"\\\\w*\")) // + in mqtt is anything -> .*\n\n return Object.fromEntries(\n Object.keys(this.messages)\n .filter((topic) => topic.match(topicRegex))\n .map((topic) => [topic, this.messages[topic]])\n // Filter out empty results\n .filter(\n ([_key, message]) =>\n message !== undefined &&\n message !== null &&\n (!Array.isArray(message) ||\n (message.length !== 0 && !message.every((v) => v === undefined || v === null)))\n )\n )\n },\n { name: \"Mqtt.store.messagesByWildcard\", equals: comparer.identity }\n )\n\n constructor() {\n makeAutoObservable(this, {\n messageQueue: false,\n urgentTopicPrefixes: false,\n initialLoadComplete: false,\n completeInitialLoad: false,\n setupKeepaliveTimer: false,\n clearKeepaliveTimer: false,\n sendFullKeepalive: false,\n sendSuppressedKeepalive: false,\n setupQueueWorker: false,\n removeQueueWorker: false,\n scheduleNextQueueWorkerPass: false,\n subscribeToTopic: false,\n subscribeToAllTopics: false,\n clearSubscribedTopics: false,\n })\n }\n\n get isConnected() {\n return this.status === STATUS.CONNECTED\n }\n\n subscribeToTopic = (topic?: string) => {\n if (!topic) return\n if (topic.includes(\"undefined\")) return\n\n if (!this.topicsSubscribed.has(topic)) {\n Logger.log(`Subscribing to ${topic}`)\n this.client?.subscribe(topic, (err, granted) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n if (granted !== undefined && granted[0]) {\n Logger.log(`Subscribed to ${granted[0].topic} with Qos ${granted[0].qos}`)\n } else {\n Logger.log(`Subscribed to ${topic} with Qos unknown`)\n }\n })\n\n this.topicsSubscribed.add(topic)\n }\n }\n\n clearSubscribedTopics() {\n this.topicsSubscribed.clear()\n this.urgentTopicPrefixes = []\n this.initialLoadComplete = false\n runInAction(() => {\n this.portalId = undefined\n })\n }\n\n addMessage = (topic: string, message: { value: string | undefined }) => {\n // Logger.log(`DEBUG: addMessage: topic: ${topic}, urgentPrefixes: ${JSON.stringify(this.urgentTopicPrefixes)}`)\n if (this.initialLoadComplete && this.urgentTopicPrefixes.some((prefix) => topic.startsWith(prefix))) {\n // NOTE: If topic starts with one of the urgent prefixes, deliver it immediately\n this.messages[topic] = message.value\n } else {\n // NOTE: Otherwise store message to the queue, and move messages from the queue\n // NOTE: to the React components that are MobX observers periodically and in batches\n this.messageQueue[topic] = message.value\n }\n }\n\n completeInitialLoad = () => {\n this.addMessagesFromQueue()\n this.initialLoadComplete = true\n }\n\n addMessagesFromQueue = () => {\n // keys() avoids materializing all values just to check emptiness\n if (Object.keys(this.messageQueue).length > 0) {\n // Logger.log(`DEBUG: addMessagesFromQueue: in queue: ${JSON.stringify(Object.values(this.messageQueue).length)}`)\n assign(this.messages, this.messageQueue)\n // Logger.log(`DEBUG: addMessagesFromQueue: to process: ${JSON.stringify(Object.values(this.messages).length)}`)\n this.messageQueue = {}\n }\n }\n\n scheduleNextQueueWorkerPass = (timeout: number) => {\n this.queueWorker = setTimeout(() => {\n const started = performance.now()\n this.addMessagesFromQueue()\n const ended = performance.now()\n this.meanQueueWorkerPassDuration = addToMean(this.meanQueueWorkerPassDuration, 10, ended - started)\n // Schedule next update after 1 - 3 seconds\n // depending on how fast we were able to process the incoming messages\n const newTimeout = Math.max(1000, Math.min(this.meanQueueWorkerPassDuration * 50, 3000))\n this.scheduleNextQueueWorkerPass(newTimeout)\n }, timeout)\n }\n\n setupQueueWorker = () => {\n this.removeQueueWorker()\n\n this.meanQueueWorkerPassDuration = 20 // ms\n this.scheduleNextQueueWorkerPass(1000) // ms\n }\n\n removeQueueWorker = () => {\n if (this.queueWorker) {\n clearTimeout(this.queueWorker)\n }\n this.queueWorker = undefined\n }\n\n setPortalId = (portalId: string) => {\n this.portalId = portalId\n this.urgentTopicPrefixes = [\n `N/${portalId}/switch/`,\n `N/${portalId}/system/0/SwitchableOutput`,\n `N/${portalId}/system/0/GenericInput`,\n ]\n }\n\n setStatus(status: string) {\n this.status = status\n }\n\n setError(error: object | null | boolean) {\n this.error = error\n }\n\n boot = (\n protocol: string,\n host: string = \"localhost\",\n port: number | null,\n path: string = \"websocket-mqtt\",\n remote: boolean = false,\n portalId?: string\n ) => {\n Logger.log(\"MQTT booting\")\n\n let client = this.client\n\n if (client) {\n client.end(true)\n this.client = undefined\n this.portalId = undefined\n this.topicsSubscribed.clear()\n this.urgentTopicPrefixes = []\n this.initialLoadComplete = false\n }\n\n let url\n if (remote) {\n if (!host) {\n return\n }\n // remote connection to VRM broker always uses MQTTS over 443\n url = `mqtts://${host}:443`\n } else {\n // local connection derives websocket protocol from web app protocol\n const wsproto = protocol === \"https:\" ? \"wss:\" : \"ws:\"\n if (port) {\n url = `${wsproto}//${host}:${port}/${path}`\n } else {\n url = `${wsproto}//${host}/${path}`\n }\n }\n\n Logger.log(`MQTT connecting to ${url}`)\n client = mqtt.connect(url, { resubscribe: false })\n\n this.client = client\n this.portalId = portalId\n\n client.on(\"error\", (error) => {\n Logger.log(\"MQTT error\")\n runInAction(() => {\n this.setError(error)\n this.setStatus(STATUS.DISCONNECTED)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"offline\", () => {\n Logger.log(\"MQTT offline\")\n runInAction(() => {\n this.setError(true)\n this.setStatus(STATUS.OFFLINE)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"connect\", () => {\n Logger.log(\"MQTT connected\")\n runInAction(() => {\n this.setError(null)\n this.setStatus(STATUS.CONNECTED)\n // Never use wildcard when connecting remotely\n this.subscribeToTopic(`N/${remote ? portalId : \"+\"}/system/0/Serial`)\n this.setupKeepaliveTimer()\n })\n })\n\n client.on(\"message\", (topic, message) => {\n // Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)\n\n const str = message.toString()\n if (str === \"\") return\n\n const parsed = getMessageJson(str)\n\n if (topic.endsWith(\"/system/0/Serial\") && !this.portalId) {\n if (this.portalId !== parsed.value && parsed.value !== undefined) {\n this.setPortalId(parsed.value)\n }\n\n runInAction(() => this.subscribeToAllTopics())\n }\n if (!this.initialLoadComplete && topic.endsWith(\"full_publish_completed\")) {\n const uniqueId = (parsed[\"full-publish-completed-echo\"] as string) || \"\"\n Logger.log(\n `Received full_publish_completed for ${this.portalId} with full-publish-completed-echo: '${uniqueId}'`\n )\n if (uniqueId === this.uniqueId) {\n this.completeInitialLoad()\n this.setupQueueWorker()\n }\n }\n\n this.addMessage(topic, parsed)\n })\n\n Logger.log(\"MQTT booted\")\n }\n\n subscribeToAllTopics = () => {\n const topics = [\n `N/${this.portalId}/settings/#`,\n `N/${this.portalId}/system/#`,\n `N/${this.portalId}/vebus/#`,\n `N/${this.portalId}/alternator/#`,\n `N/${this.portalId}/battery/#`,\n `N/${this.portalId}/charger/#`,\n `N/${this.portalId}/dcsource/#`,\n `N/${this.portalId}/generator/#`,\n `N/${this.portalId}/genset/#`,\n `N/${this.portalId}/dcgenset/#`,\n `N/${this.portalId}/inverter/#`,\n `N/${this.portalId}/tank/#`,\n `N/${this.portalId}/temperature/#`,\n `N/${this.portalId}/switch/#`,\n `N/${this.portalId}/full_publish_completed`,\n ]\n\n this.client?.subscribe(topics, (err) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n // When we received all topics we send a full keepalive.\n this.sendFullKeepalive()\n })\n }\n\n sendSuppressedKeepalive = () => {\n if (this.portalId) {\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending keepalive for ${this.portalId} with ${SUPPRESSED_KEEPALIVE_OPTIONS}`)\n this.client?.publish(topic, SUPPRESSED_KEEPALIVE_OPTIONS)\n }\n }\n\n sendFullKeepalive = () => {\n if (this.portalId) {\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending first keepalive for ${this.portalId} with full-publish-completed-echo: '${this.uniqueId}'`)\n this.client?.publish(topic, `{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"${this.uniqueId}\" } ] }`)\n }\n }\n\n setupKeepaliveTimer = () => {\n this.clearKeepaliveTimer()\n\n this.keepAliveHandlerRef = setInterval(this.sendSuppressedKeepalive, 30000)\n\n this.sendFullKeepalive()\n }\n\n clearKeepaliveTimer = () => {\n const ref = this.keepAliveHandlerRef\n if (ref) {\n clearInterval(ref)\n }\n this.keepAliveHandlerRef = undefined\n }\n\n publish = (topic: string, data: string | number | { raw: string }, options?: IClientPublishOptions) => {\n if (this.status !== STATUS.CONNECTED || !this.client) {\n Logger.log(\"Could not publish value, not connected to MQTT broker\")\n return\n }\n const message =\n typeof data === \"object\" && data !== null && \"raw\" in data ? data.raw : JSON.stringify({ value: data })\n\n Logger.log(`Publishing to ${topic}: ${message}`)\n\n this.client?.publish(topic, message, options ?? {})\n }\n}\n\nconst SUPPRESSED_KEEPALIVE_OPTIONS = JSON.stringify({ \"keepalive-options\": [\"suppress-republish\"] })\n\n/**\n * Compute mean by providing existing mean, number of samples, and new sample.\n *\n * @param {number} mean current mean\n * @param {number} n number of sampled values\n * @param {number} newValue the sample\n * @returns {number} the new mean\n *\n * @example\n * addToMean(14, 5, 53); // => 20.5\n */\nfunction addToMean(mean: number, n: number, newValue: number): number {\n return mean + (newValue - mean) / (n + 1)\n}\n\nfunction initializeStore() {\n const _store = store ?? new MqttStore()\n // For SSG and SSR always create a new store\n if (typeof window === \"undefined\") return _store\n // Create the store once in the client\n if (!store) store = _store\n\n return _store\n}\n\nexport function useMqtt() {\n return useMemo(() => initializeStore(), [])\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Mqtt.store.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"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","sourcesContent":["import { comparer, makeAutoObservable, runInAction } from \"mobx\"\nimport { computedFn } from \"mobx-utils\"\nimport * as mqtt from \"mqtt\"\nimport { IClientPublishOptions, MqttClient } from \"mqtt\"\nimport { MqttMessage, MqttMessages, PortalId, STATUS, Topics } from \"../Mqtt\"\nimport Logger from \"../../utils/logger\"\nimport { getMessageJson } from \"../../utils/util\"\nimport { useMemo } from \"react\"\nimport { assign } from \"lodash-es\"\n\nlet store: MqttStore\n\nexport class MqttStore {\n client?: MqttClient | null\n error?: object | null | boolean\n status: string = STATUS.CONNECTING\n messages: MqttMessages = {}\n messageQueue: MqttMessages = {}\n topicsSubscribed: Set<string> = new Set<string>()\n portalId: PortalId\n uniqueId: string = Math.random().toString(16).substr(2, 8)\n keepAliveHandlerRef: ReturnType<typeof setInterval> | undefined\n queueWorker: ReturnType<typeof setTimeout> | undefined\n meanQueueWorkerPassDuration: number = 0\n urgentTopicPrefixes: string[] = []\n initialLoadComplete: boolean = false\n\n /**\n * Returns the current cached message for a given MQTT topic.\n *\n * React Components using this method will re-render when their specific\n * topic's message changes.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for the given topic. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topic - The MQTT topic to retrieve the message for\n * @returns The message object for the topic, or undefined if topic is not provided or not found\n */\n messageFromTopic = computedFn(\n (topic?: string) => {\n // Logger.log(`DEBUG: messageFromTopic: ${JSON.stringify(topic)}`)\n // trace()\n return topic ? this.messages[topic] : undefined\n },\n { name: \"Mqtt.store.messageFromTopic\", equals: comparer.identity }\n )\n\n /**\n * Returns the current cached messages for a given set of MQTT topics.\n *\n * This is a memoized computed function - each set of topics has its own cached value.\n *\n * React Components using this method will re-render when\n * any of the messages for specified topics change.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the specified topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topics - The MQTT topics to retrieve the messages for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByTopics = computedFn(\n (topics?: Topics) => {\n // Logger.log(`DEBUG: messagesByTopics: ${JSON.stringify(topics)}`)\n // trace()\n if (!topics) {\n return {}\n }\n\n const result: { [key: string]: MqttMessage | MqttMessage[] } = {}\n\n Object.entries(topics).forEach(([label, topic]) => {\n if (Array.isArray(topic)) {\n result[label] = topic.map((t) => this.messageFromTopic(t))\n } else if (topic === undefined) {\n result[label] = undefined\n } else {\n result[label] = this.messageFromTopic(topic)\n }\n })\n\n return result\n },\n { name: \"Mqtt.store.messagesByTopics\", equals: comparer.identity }\n )\n\n /**\n * Returns the current cached messages for MQTT topics specified via regex.\n *\n * React Components using this method will re-render when\n * values of any of the matched topics change. The components also re-render\n * when new MQTT topics are received and match needs to be checked.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the matched topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param wildcard - The MQTT wildcard to retrieve the message for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByWildcard = computedFn(\n (wildcard?: string) => {\n // Logger.log(`DEBUG: messagesByWildcard: ${JSON.stringify(wildcard)}`)\n // trace()\n if (wildcard === undefined || wildcard === \"\" || wildcard === null) return {}\n\n const topicRegex = new RegExp(wildcard.replace(/\\+/g, \"\\\\w*\")) // + in mqtt is anything -> .*\n\n return Object.fromEntries(\n Object.keys(this.messages)\n .filter((topic) => topic.match(topicRegex))\n .map((topic) => [topic, this.messages[topic]])\n // Filter out empty results\n .filter(\n ([_key, message]) =>\n message !== undefined &&\n message !== null &&\n (!Array.isArray(message) ||\n (message.length !== 0 && !message.every((v) => v === undefined || v === null)))\n )\n )\n },\n { name: \"Mqtt.store.messagesByWildcard\", equals: comparer.identity }\n )\n\n constructor() {\n makeAutoObservable(this, {\n messageQueue: false,\n urgentTopicPrefixes: false,\n initialLoadComplete: false,\n completeInitialLoad: false,\n setupKeepaliveTimer: false,\n clearKeepaliveTimer: false,\n sendFullKeepalive: false,\n sendSuppressedKeepalive: false,\n setupQueueWorker: false,\n removeQueueWorker: false,\n scheduleNextQueueWorkerPass: false,\n subscribeToTopic: false,\n subscribeToAllTopics: false,\n clearSubscribedTopics: false,\n })\n }\n\n get isConnected() {\n return this.status === STATUS.CONNECTED\n }\n\n subscribeToTopic = (topic?: string) => {\n if (!topic) return\n if (topic.includes(\"undefined\")) return\n\n if (!this.topicsSubscribed.has(topic)) {\n Logger.log(`Subscribing to ${topic}`)\n this.client?.subscribe(topic, (err, granted) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n if (granted !== undefined && granted[0]) {\n Logger.log(`Subscribed to ${granted[0].topic} with Qos ${granted[0].qos}`)\n } else {\n Logger.log(`Subscribed to ${topic} with Qos unknown`)\n }\n })\n\n this.topicsSubscribed.add(topic)\n }\n }\n\n clearSubscribedTopics() {\n this.topicsSubscribed.clear()\n this.urgentTopicPrefixes = []\n this.initialLoadComplete = false\n runInAction(() => {\n this.portalId = undefined\n })\n }\n\n addMessage = (topic: string, message: { value: string | undefined }) => {\n // Logger.log(`DEBUG: addMessage: topic: ${topic}, urgentPrefixes: ${JSON.stringify(this.urgentTopicPrefixes)}`)\n if (this.initialLoadComplete && this.urgentTopicPrefixes.some((prefix) => topic.startsWith(prefix))) {\n // NOTE: If topic starts with one of the urgent prefixes, deliver it immediately\n this.messages[topic] = message.value\n } else {\n // NOTE: Otherwise store message to the queue, and move messages from the queue\n // NOTE: to the React components that are MobX observers periodically and in batches\n this.messageQueue[topic] = message.value\n }\n }\n\n completeInitialLoad = () => {\n this.addMessagesFromQueue()\n this.initialLoadComplete = true\n }\n\n addMessagesFromQueue = () => {\n // keys() avoids materializing all values just to check emptiness\n if (Object.keys(this.messageQueue).length > 0) {\n // Logger.log(`DEBUG: addMessagesFromQueue: in queue: ${JSON.stringify(Object.values(this.messageQueue).length)}`)\n assign(this.messages, this.messageQueue)\n // Logger.log(`DEBUG: addMessagesFromQueue: to process: ${JSON.stringify(Object.values(this.messages).length)}`)\n this.messageQueue = {}\n }\n }\n\n scheduleNextQueueWorkerPass = (timeout: number) => {\n this.queueWorker = setTimeout(() => {\n const started = performance.now()\n this.addMessagesFromQueue()\n const ended = performance.now()\n this.meanQueueWorkerPassDuration = addToMean(this.meanQueueWorkerPassDuration, 10, ended - started)\n // Schedule next update after 1 - 3 seconds\n // depending on how fast we were able to process the incoming messages\n const newTimeout = Math.max(1000, Math.min(this.meanQueueWorkerPassDuration * 50, 3000))\n this.scheduleNextQueueWorkerPass(newTimeout)\n }, timeout)\n }\n\n setupQueueWorker = () => {\n this.removeQueueWorker()\n\n this.meanQueueWorkerPassDuration = 20 // ms\n this.scheduleNextQueueWorkerPass(1000) // ms\n }\n\n removeQueueWorker = () => {\n if (this.queueWorker) {\n clearTimeout(this.queueWorker)\n }\n this.queueWorker = undefined\n }\n\n setPortalId = (portalId: string) => {\n this.portalId = portalId\n this.urgentTopicPrefixes = [\n `N/${portalId}/switch/`,\n `N/${portalId}/system/0/SwitchableOutput`,\n `N/${portalId}/settings/0/Settings/Gui2/Switchpane/Preset/`,\n ]\n }\n\n setStatus(status: string) {\n this.status = status\n }\n\n setError(error: object | null | boolean) {\n this.error = error\n }\n\n boot = (\n protocol: string,\n host: string = \"localhost\",\n port: number | null,\n path: string = \"websocket-mqtt\",\n remote: boolean = false,\n portalId?: string\n ) => {\n Logger.log(\"MQTT booting\")\n\n let client = this.client\n\n if (client) {\n client.end(true)\n this.client = undefined\n this.portalId = undefined\n this.topicsSubscribed.clear()\n this.urgentTopicPrefixes = []\n this.initialLoadComplete = false\n }\n\n let url\n if (remote) {\n if (!host) {\n return\n }\n // remote connection to VRM broker always uses MQTTS over 443\n url = `mqtts://${host}:443`\n } else {\n // local connection derives websocket protocol from web app protocol\n const wsproto = protocol === \"https:\" ? \"wss:\" : \"ws:\"\n if (port) {\n url = `${wsproto}//${host}:${port}/${path}`\n } else {\n url = `${wsproto}//${host}/${path}`\n }\n }\n\n Logger.log(`MQTT connecting to ${url}`)\n client = mqtt.connect(url, { resubscribe: false })\n\n this.client = client\n this.portalId = portalId\n\n client.on(\"error\", (error) => {\n Logger.log(\"MQTT error\")\n runInAction(() => {\n this.setError(error)\n this.setStatus(STATUS.DISCONNECTED)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"offline\", () => {\n Logger.log(\"MQTT offline\")\n runInAction(() => {\n this.setError(true)\n this.setStatus(STATUS.OFFLINE)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"connect\", () => {\n Logger.log(\"MQTT connected\")\n runInAction(() => {\n this.setError(null)\n this.setStatus(STATUS.CONNECTED)\n // Never use wildcard when connecting remotely\n this.subscribeToTopic(`N/${remote ? portalId : \"+\"}/system/0/Serial`)\n this.setupKeepaliveTimer()\n })\n })\n\n client.on(\"message\", (topic, message) => {\n // Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)\n\n const str = message.toString()\n if (str === \"\") return\n\n const parsed = getMessageJson(str)\n\n if (topic.endsWith(\"/system/0/Serial\") && !this.portalId) {\n if (this.portalId !== parsed.value && parsed.value !== undefined) {\n this.setPortalId(parsed.value)\n }\n\n runInAction(() => this.subscribeToAllTopics())\n }\n if (!this.initialLoadComplete && topic.endsWith(\"full_publish_completed\")) {\n const uniqueId = (parsed[\"full-publish-completed-echo\"] as string) || \"\"\n Logger.log(\n `Received full_publish_completed for ${this.portalId} with full-publish-completed-echo: '${uniqueId}'`\n )\n if (uniqueId === this.uniqueId) {\n this.completeInitialLoad()\n this.setupQueueWorker()\n }\n }\n\n this.addMessage(topic, parsed)\n })\n\n Logger.log(\"MQTT booted\")\n }\n\n subscribeToAllTopics = () => {\n const topics = [\n `N/${this.portalId}/settings/#`,\n `N/${this.portalId}/system/#`,\n `N/${this.portalId}/vebus/#`,\n `N/${this.portalId}/alternator/#`,\n `N/${this.portalId}/battery/#`,\n `N/${this.portalId}/charger/#`,\n `N/${this.portalId}/dcsource/#`,\n `N/${this.portalId}/generator/#`,\n `N/${this.portalId}/genset/#`,\n `N/${this.portalId}/dcgenset/#`,\n `N/${this.portalId}/inverter/#`,\n `N/${this.portalId}/tank/#`,\n `N/${this.portalId}/temperature/#`,\n `N/${this.portalId}/switch/#`,\n `N/${this.portalId}/full_publish_completed`,\n ]\n\n this.client?.subscribe(topics, (err) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n // When we received all topics we send a full keepalive.\n this.sendFullKeepalive()\n })\n }\n\n sendSuppressedKeepalive = () => {\n if (this.portalId) {\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending keepalive for ${this.portalId} with ${SUPPRESSED_KEEPALIVE_OPTIONS}`)\n this.client?.publish(topic, SUPPRESSED_KEEPALIVE_OPTIONS)\n }\n }\n\n sendFullKeepalive = () => {\n if (this.portalId) {\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending first keepalive for ${this.portalId} with full-publish-completed-echo: '${this.uniqueId}'`)\n this.client?.publish(topic, `{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"${this.uniqueId}\" } ] }`)\n }\n }\n\n setupKeepaliveTimer = () => {\n this.clearKeepaliveTimer()\n\n this.keepAliveHandlerRef = setInterval(this.sendSuppressedKeepalive, 30000)\n\n this.sendFullKeepalive()\n }\n\n clearKeepaliveTimer = () => {\n const ref = this.keepAliveHandlerRef\n if (ref) {\n clearInterval(ref)\n }\n this.keepAliveHandlerRef = undefined\n }\n\n publish = (topic: string, data: string | number | { raw: string }, options?: IClientPublishOptions) => {\n if (this.status !== STATUS.CONNECTED || !this.client) {\n Logger.log(\"Could not publish value, not connected to MQTT broker\")\n return\n }\n const message =\n typeof data === \"object\" && data !== null && \"raw\" in data ? data.raw : JSON.stringify({ value: data })\n\n Logger.log(`Publishing to ${topic}: ${message}`)\n\n this.client?.publish(topic, message, options ?? {})\n }\n}\n\nconst SUPPRESSED_KEEPALIVE_OPTIONS = JSON.stringify({ \"keepalive-options\": [\"suppress-republish\"] })\n\n/**\n * Compute mean by providing existing mean, number of samples, and new sample.\n *\n * @param {number} mean current mean\n * @param {number} n number of sampled values\n * @param {number} newValue the sample\n * @returns {number} the new mean\n *\n * @example\n * addToMean(14, 5, 53); // => 20.5\n */\nfunction addToMean(mean: number, n: number, newValue: number): number {\n return mean + (newValue - mean) / (n + 1)\n}\n\nfunction initializeStore() {\n const _store = store ?? new MqttStore()\n // For SSG and SSR always create a new store\n if (typeof window === \"undefined\") return _store\n // Create the store once in the client\n if (!store) store = _store\n\n return _store\n}\n\nexport function useMqtt() {\n return useMemo(() => initializeStore(), [])\n}\n"]}
|