Skip to content

Commit

Permalink
[mqtt.homeassistant] JSON Attributes can exist on Climate (#17610)
Browse files Browse the repository at this point in the history
Signed-off-by: Cody Cutrer <cody@cutrer.us>
  • Loading branch information
ccutrer authored Oct 22, 2024
1 parent b94ed45 commit ecb1e96
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;

Expand Down Expand Up @@ -63,6 +64,7 @@ public class Climate extends AbstractComponent<Climate.ChannelConfiguration> {
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")
Expand Down Expand Up @@ -149,7 +151,7 @@ static class ChannelConfiguration extends AbstractChannelConfiguration {
// 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;

Expand Down Expand Up @@ -295,6 +297,13 @@ ComponentChannelType.SWITCH, new OnOffValue(), updateListener, null,

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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void testTS0601Climate() {
"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);
Expand All @@ -84,6 +84,8 @@ public void testTS0601Climate() {
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", \
Expand Down Expand Up @@ -140,7 +142,7 @@ public void testTS0601ClimateNotSendIfOff() {
"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);
Expand All @@ -154,6 +156,8 @@ public void testTS0601ClimateNotSendIfOff() {
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", \
Expand Down Expand Up @@ -244,7 +248,7 @@ public void testClimate() {
"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);
Expand All @@ -269,6 +273,8 @@ public void testClimate() {
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", \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public void testInitialize() {
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";
Expand All @@ -130,8 +130,8 @@ public void testInitialize() {
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());
}

Expand Down Expand Up @@ -253,7 +253,7 @@ public void testDispose() {
"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
Expand Down Expand Up @@ -281,13 +281,13 @@ public void testRemoveThing() {
"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());
}
Expand Down

0 comments on commit ecb1e96

Please sign in to comment.