From c6f2fca499754e80f6d7a8f2449490e25cbaa53c Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Fri, 13 Dec 2024 02:26:58 -0700 Subject: [PATCH] [mqtt.homeassistant] fix unbounded growth of config for device_trigger (#17894) Because of how it shares a channel, whenever openHAB was rebooted and it would first restore the device trigger components from the channel configuration, and then from the MQTT message, it didn't identify it as the same component as before, and so would merge into another instance of itself. My Things.json is normally 13MB, and had grown to 545MB, and my openHAB was constantly having memory issues! So now just make sure we only keep unique information, which will automatically clean up anyone in a bad state. Signed-off-by: Cody Cutrer --- .../internal/component/DeviceTrigger.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java index d3e1ebcc047f5..68723b765a9d5 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java @@ -111,17 +111,22 @@ public boolean merge(DeviceTrigger other) { newConfiguration.put("nodeid", currentConfiguration.get("nodeid")); Object objectIdObject = currentConfiguration.get("objectid"); if (objectIdObject instanceof String objectIdString) { - newConfiguration.put("objectid", List.of(objectIdString, other.getHaID().objectID)); + if (!objectIdString.equals(other.getHaID().objectID)) { + newConfiguration.put("objectid", List.of(objectIdString, other.getHaID().objectID)); + } } else if (objectIdObject instanceof List objectIdList) { - newConfiguration.put("objectid", - Stream.concat(objectIdList.stream(), Stream.of(other.getHaID().objectID)).toList()); + newConfiguration.put("objectid", Stream.concat(objectIdList.stream(), Stream.of(other.getHaID().objectID)) + .sorted().distinct().toList()); } Object configObject = currentConfiguration.get("config"); if (configObject instanceof String configString) { - newConfiguration.put("config", List.of(configString, other.getChannelConfigurationJson())); + if (!configString.equals(other.getChannelConfigurationJson())) { + newConfiguration.put("config", List.of(configString, other.getChannelConfigurationJson())); + } } else if (configObject instanceof List configList) { newConfiguration.put("config", - Stream.concat(configList.stream(), Stream.of(other.getChannelConfigurationJson())).toList()); + Stream.concat(configList.stream(), Stream.of(other.getChannelConfigurationJson())).sorted() + .distinct().toList()); } // Append payload to allowed values @@ -130,7 +135,8 @@ public boolean merge(DeviceTrigger other) { // Need to accept anything value = new TextValue(); } else { - String[] newValues = Stream.concat(payloads.stream(), Stream.of(otherPayload)).toArray(String[]::new); + String[] newValues = Stream.concat(payloads.stream(), Stream.of(otherPayload)).distinct() + .toArray(String[]::new); value = new TextValue(newValues); }