From 573959ee59c275b9e05d416672837b6347d2e7d0 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 Signed-off-by: Ciprian Pascu --- .../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); }