diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java index 1f156d103c6..f384cac0406 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java @@ -33,6 +33,7 @@ import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChanne import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.thing.type.AutoUpdatePolicy; import org.openhab.core.types.Command; import org.openhab.core.types.State; @@ -63,6 +64,7 @@ public class Climate extends AbstractComponent { public static final String TEMPERATURE_LOW_CH_ID = "temperature-low"; public static final String TEMPERATURE_LOW_CH_ID_DEPRECATED = "temperatureLow"; public static final String POWER_CH_ID = "power"; + public static final String JSON_ATTRIBUTES_CHANNEL_ID = "json-attributes"; public enum TemperatureUnit { @SerializedName("C") @@ -149,7 +151,7 @@ public class Climate extends AbstractComponent { // hold modes. @SerializedName("json_attributes_template") - protected @Nullable String jsonAttributesTemplate; // Attributes are not supported yet + protected @Nullable String jsonAttributesTemplate; @SerializedName("json_attributes_topic") protected @Nullable String jsonAttributesTopic; @@ -295,6 +297,13 @@ public class Climate extends AbstractComponent { buildOptionalChannel(POWER_CH_ID, ComponentChannelType.SWITCH, new OnOffValue(), updateListener, null, channelConfiguration.powerCommandTopic, null, null, null); + + if (channelConfiguration.jsonAttributesTopic != null) { + buildChannel(JSON_ATTRIBUTES_CHANNEL_ID, ComponentChannelType.STRING, new TextValue(), "JSON Attributes", + componentConfiguration.getUpdateListener()) + .stateTopic(channelConfiguration.jsonAttributesTopic, channelConfiguration.jsonAttributesTemplate) + .withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build(); + } finalizeChannels(); } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java index 3ea6c61914d..d5e6bb7d490 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java @@ -70,7 +70,7 @@ public class ClimateTests extends AbstractComponentTests { "unique_id": "0x847127fffe11dd6a_climate_zigbee2mqtt"}\ """); - assertThat(component.channels.size(), is(6)); + assertThat(component.channels.size(), is(7)); assertThat(component.getName(), is("th1")); assertChannel(component, Climate.ACTION_CH_ID, "zigbee2mqtt/th1", "", "th1", TextValue.class); @@ -84,6 +84,8 @@ public class ClimateTests extends AbstractComponentTests { TextValue.class); assertChannel(component, Climate.TEMPERATURE_CH_ID, "zigbee2mqtt/th1", "zigbee2mqtt/th1/set/current_heating_setpoint", "th1", NumberValue.class); + assertChannel(component, Climate.JSON_ATTRIBUTES_CHANNEL_ID, "zigbee2mqtt/th1", "", "JSON Attributes", + TextValue.class); publishMessage("zigbee2mqtt/th1", """ {"running_state": "idle", "away_mode": "ON", \ @@ -140,7 +142,7 @@ public class ClimateTests extends AbstractComponentTests { "unique_id": "0x847127fffe11dd6a_climate_zigbee2mqtt", "send_if_off": "false"}\ """); - assertThat(component.channels.size(), is(7)); + assertThat(component.channels.size(), is(8)); assertThat(component.getName(), is("th1")); assertChannel(component, Climate.ACTION_CH_ID, "zigbee2mqtt/th1", "", "th1", TextValue.class); @@ -154,6 +156,8 @@ public class ClimateTests extends AbstractComponentTests { TextValue.class); assertChannel(component, Climate.TEMPERATURE_CH_ID, "zigbee2mqtt/th1", "zigbee2mqtt/th1/set/current_heating_setpoint", "th1", NumberValue.class); + assertChannel(component, Climate.JSON_ATTRIBUTES_CHANNEL_ID, "zigbee2mqtt/th1", "", "JSON Attributes", + TextValue.class); publishMessage("zigbee2mqtt/th1", """ {"running_state": "idle", "away_mode": "ON", \ @@ -244,7 +248,7 @@ public class ClimateTests extends AbstractComponentTests { "temp_step": "1", "precision": "0.5", "send_if_off": "false" }\ """); - assertThat(component.channels.size(), is(12)); + assertThat(component.channels.size(), is(13)); assertThat(component.getName(), is("MQTT HVAC")); assertChannel(component, Climate.ACTION_CH_ID, "zigbee2mqtt/th1", "", "MQTT HVAC", TextValue.class); @@ -269,6 +273,8 @@ public class ClimateTests extends AbstractComponentTests { assertChannel(component, Climate.TEMPERATURE_LOW_CH_ID_DEPRECATED, "zigbee2mqtt/th1", "zigbee2mqtt/th1/temperature_low", "MQTT HVAC", NumberValue.class); assertChannel(component, Climate.POWER_CH_ID, "", "zigbee2mqtt/th1/power", "MQTT HVAC", OnOffValue.class); + assertChannel(component, Climate.JSON_ATTRIBUTES_CHANNEL_ID, "zigbee2mqtt/th1", "", "JSON Attributes", + TextValue.class); publishMessage("zigbee2mqtt/th1", """ { "action": "fan", "aux": "ON", "away_mode": "OFF", \ diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java index 26932da0396..ef52a2a588c 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java @@ -119,8 +119,8 @@ public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests { verify(thingHandler, times(1)).componentDiscovered(eq(new HaID(configTopic)), any(Climate.class)); thingHandler.delayedProcessing.forceProcessNow(); - assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(6)); - verify(stateDescriptionProvider, times(6)).setDescription(any(), any(StateDescription.class)); + assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(7)); + verify(stateDescriptionProvider, times(7)).setDescription(any(), any(StateDescription.class)); verify(channelTypeProvider, times(1)).putChannelGroupType(any()); configTopic = "homeassistant/switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt/config"; @@ -130,8 +130,8 @@ public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests { verify(thingHandler, times(1)).componentDiscovered(eq(new HaID(configTopic)), any(Switch.class)); thingHandler.delayedProcessing.forceProcessNow(); - assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(7)); - verify(stateDescriptionProvider, atLeast(7)).setDescription(any(), any(StateDescription.class)); + assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(8)); + verify(stateDescriptionProvider, atLeast(8)).setDescription(any(), any(StateDescription.class)); verify(channelTypeProvider, times(3)).putChannelGroupType(any()); } @@ -253,7 +253,7 @@ public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests { "homeassistant/switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt/config", getResourceAsByteArray("component/configTS0601AutoLock.json")); thingHandler.delayedProcessing.forceProcessNow(); - assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(7)); + assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(8)); verify(stateDescriptionProvider, atLeast(7)).setDescription(any(), any(StateDescription.class)); // When dispose @@ -281,13 +281,13 @@ public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests { "homeassistant/switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt/config", getResourceAsByteArray("component/configTS0601AutoLock.json")); thingHandler.delayedProcessing.forceProcessNow(); - assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(7)); + assertThat(nonSpyThingHandler.getThing().getChannels().size(), is(8)); // When dispose nonSpyThingHandler.handleRemoval(); - // Expect channel descriptions removed, 6 for climate and 1 for switch - verify(stateDescriptionProvider, times(7)).remove(any()); + // Expect channel descriptions removed, 7 for climate and 1 for switch + verify(stateDescriptionProvider, times(8)).remove(any()); // Expect channel group types removed, 1 for each component verify(channelTypeProvider, times(2)).removeChannelGroupType(any()); }