diff --git a/packages/modules/web_themes/colors/source/src/assets/js/processMessages.ts b/packages/modules/web_themes/colors/source/src/assets/js/processMessages.ts index a47a9635a3..654557d392 100755 --- a/packages/modules/web_themes/colors/source/src/assets/js/processMessages.ts +++ b/packages/modules/web_themes/colors/source/src/assets/js/processMessages.ts @@ -24,7 +24,10 @@ import { processVehicleTemplateMessages, } from '@/components/chargePointList/processMessages' import { processSmarthomeMessages } from '@/components/smartHome/processMessages' -import { processConsumerMessages } from '@/components/consumerList/processMessages' +import { + processConsumerMessages, + registerConsumerFromHierarchy, +} from '@/components/consumerList/processMessages' import { addCounter, counters, @@ -33,7 +36,7 @@ import { import { mqttClientId } from './mqttClient' import { add } from '@/components/mqttViewer/model' import { globalConfig } from './themeConfig' -import { addConsumer, consumers } from '@/components/consumerList/model' +import { consumers } from '@/components/consumerList/model' const topicsToSubscribe = [ 'openWB/counter/#', @@ -183,7 +186,7 @@ function processHierarchy(hierarchy: Hierarchy) { addPvSystem(hierarchy.id) break case 'consumer': - addConsumer(hierarchy.id) + registerConsumerFromHierarchy(hierarchy.id) break default: // console.warn('Ignored Hierarchy type: ' + hierarchy.type) diff --git a/packages/modules/web_themes/colors/source/src/components/consumerList/processMessages.ts b/packages/modules/web_themes/colors/source/src/components/consumerList/processMessages.ts index e8f6a391e0..903ecaddf5 100644 --- a/packages/modules/web_themes/colors/source/src/components/consumerList/processMessages.ts +++ b/packages/modules/web_themes/colors/source/src/components/consumerList/processMessages.ts @@ -11,6 +11,24 @@ export function processConsumerMessages(topic: string, message: string) { } } +// device messages for a consumer id not yet created by the hierarchy are buffered here and +// replayed once registerConsumerFromHierarchy creates it, instead of being dropped or creating +// a consumer that may not actually be in the current hierarchy (eg. a stale retained topic) +const pendingMessages = new Map() + +// called from hierarchy processing - the only place a consumer may be created, so its color +// (assigned from consumers.size at creation) stays consistent with the hierarchy order +export function registerConsumerFromHierarchy(index: number, showInList = true) { + addConsumer(index, showInList) + const pending = pendingMessages.get(index) + if (pending) { + pendingMessages.delete(index) + pending.forEach(({ topic, message }) => + processConsumerDeviceMessages(topic, message), + ) + } +} + // Consumers device messages function processConsumerDeviceMessages(topic: string, message: string) { const index = getIndex(topic) @@ -19,7 +37,10 @@ function processConsumerDeviceMessages(topic: string, message: string) { return } if (!consumers.has(index)) { - console.warn('Invalid consumer id received: ' + index) + const pending = pendingMessages.get(index) ?? [] + pending.push({ topic, message }) + pendingMessages.set(index, pending) + return } const dev = consumers.get(index)! if (topic.match(/^openWB\/consumer\/[0-9]+\/get\/power$/i)) {