[mqtt.homeassistant] implement effect channel for light (#15914)
Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
dcf4255b98
commit
44e32d3fbb
|
@ -98,8 +98,9 @@ public class DefaultSchemaLight extends Light {
|
|||
.build();
|
||||
}
|
||||
|
||||
if (channelConfiguration.effectStateTopic != null || channelConfiguration.effectCommandTopic != null) {
|
||||
buildChannel(EFFECT_CHANNEL_ID, effectValue, "Lighting effect", this)
|
||||
if (effectValue != null
|
||||
&& (channelConfiguration.effectStateTopic != null || channelConfiguration.effectCommandTopic != null)) {
|
||||
buildChannel(EFFECT_CHANNEL_ID, Objects.requireNonNull(effectValue), "Lighting Effect", this)
|
||||
.stateTopic(channelConfiguration.effectStateTopic, channelConfiguration.effectValueTemplate)
|
||||
.commandTopic(channelConfiguration.effectCommandTopic, channelConfiguration.isRetain(),
|
||||
channelConfiguration.getQos())
|
||||
|
|
|
@ -114,6 +114,22 @@ public class JSONSchemaLight extends AbstractRawSchemaLight {
|
|||
onOffChannel = buildChannel(ON_OFF_CHANNEL_ID, onOffValue, "On/Off State", this)
|
||||
.commandTopic(DUMMY_TOPIC, true, 1).commandFilter(this::handleCommand).build();
|
||||
}
|
||||
|
||||
if (effectValue != null) {
|
||||
buildChannel(EFFECT_CHANNEL_ID, Objects.requireNonNull(effectValue), "Lighting Effect", this)
|
||||
.commandTopic(DUMMY_TOPIC, true, 1).commandFilter(command -> handleEffectCommand(command)).build();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleEffectCommand(Command command) {
|
||||
if (command instanceof StringType) {
|
||||
JSONState json = new JSONState();
|
||||
json.state = "ON";
|
||||
json.effect = command.toString();
|
||||
publishState(json);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,6 +167,10 @@ public class JSONSchemaLight extends AbstractRawSchemaLight {
|
|||
}
|
||||
}
|
||||
|
||||
publishState(json);
|
||||
}
|
||||
|
||||
private void publishState(JSONState json) {
|
||||
String command = getGson().toJson(json);
|
||||
logger.debug("Publishing new state '{}' of light {} to MQTT.", command, getName());
|
||||
rawChannel.getState().publishValue(new StringType(command));
|
||||
|
@ -224,6 +244,15 @@ public class JSONSchemaLight extends AbstractRawSchemaLight {
|
|||
return;
|
||||
}
|
||||
|
||||
if (effectValue != null) {
|
||||
if (jsonState.effect != null) {
|
||||
effectValue.update(new StringType(jsonState.effect));
|
||||
listener.updateChannelState(buildChannelUID(EFFECT_CHANNEL_ID), effectValue.getChannelState());
|
||||
} else {
|
||||
listener.updateChannelState(buildChannelUID(EFFECT_CHANNEL_ID), UnDefType.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonState.state != null) {
|
||||
onOffValue.update(onOffValue.parseCommand(new StringType(jsonState.state)));
|
||||
if (brightnessValue.getChannelState() instanceof UnDefType) {
|
||||
|
|
|
@ -47,7 +47,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
* three different schemas.
|
||||
*
|
||||
* As of now, only on/off, brightness, and RGB are fully implemented and tested.
|
||||
* HS and XY are implemented, but not tested. Color temp and effect are only
|
||||
* HS and XY are implemented, but not tested. Color temp is only
|
||||
* implemented (but not tested) for the default schema.
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
|
@ -246,7 +246,7 @@ public abstract class Light extends AbstractComponent<Light.ChannelConfiguration
|
|||
protected OnOffValue onOffValue;
|
||||
protected PercentageValue brightnessValue;
|
||||
protected final NumberValue colorTempValue;
|
||||
protected final TextValue effectValue = new TextValue();
|
||||
protected final @Nullable TextValue effectValue;
|
||||
protected final ColorValue colorValue = new ColorValue(ColorMode.HSB, null, null, 100);
|
||||
|
||||
protected final List<ComponentChannel> hiddenChannels = new ArrayList<>();
|
||||
|
@ -281,6 +281,13 @@ public abstract class Light extends AbstractComponent<Light.ChannelConfiguration
|
|||
brightnessValue = new PercentageValue(null, new BigDecimal(channelConfiguration.brightnessScale), null, null,
|
||||
null);
|
||||
@Nullable
|
||||
List<String> effectList = channelConfiguration.effectList;
|
||||
if (effectList != null) {
|
||||
effectValue = new TextValue(effectList.toArray(new String[0]));
|
||||
} else {
|
||||
effectValue = null;
|
||||
}
|
||||
@Nullable
|
||||
BigDecimal min = null, max = null;
|
||||
if (channelConfiguration.minMireds != null) {
|
||||
min = new BigDecimal(channelConfiguration.minMireds);
|
||||
|
|
|
@ -27,11 +27,13 @@ import org.junit.jupiter.api.Test;
|
|||
import org.openhab.binding.mqtt.generic.values.ColorValue;
|
||||
import org.openhab.binding.mqtt.generic.values.OnOffValue;
|
||||
import org.openhab.binding.mqtt.generic.values.PercentageValue;
|
||||
import org.openhab.binding.mqtt.generic.values.TextValue;
|
||||
import org.openhab.binding.mqtt.homeassistant.internal.ComponentChannel;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
|
||||
/**
|
||||
* Tests for {@link Light} confirming to the default schema
|
||||
|
@ -285,6 +287,40 @@ public class DefaultSchemaLightTests extends AbstractComponentTests {
|
|||
assertPublished("zigbee2mqtt/light/set/state", "OFF_");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnOffWithEffect() throws InterruptedException {
|
||||
// @formatter:off
|
||||
var component = (Light) discoverComponent(configTopicToMqtt(CONFIG_TOPIC),
|
||||
"{ " +
|
||||
" \"name\": \"light\", " +
|
||||
" \"state_topic\": \"zigbee2mqtt/light/state\", " +
|
||||
" \"command_topic\": \"zigbee2mqtt/light/set/state\", " +
|
||||
" \"effect_command_topic\": \"zigbee2mqtt/light/set/effect\", " +
|
||||
" \"state_value_template\": \"{{ value_json.power }}\", " +
|
||||
" \"effect_list\": [\"party\", \"rainbow\"]," +
|
||||
" \"effect_state_topic\": \"zigbee2mqtt/light/effect\"" +
|
||||
"}");
|
||||
// @formatter:on
|
||||
|
||||
assertThat(component.channels.size(), is(2));
|
||||
assertThat(component.getName(), is("light"));
|
||||
|
||||
assertChannel(component, Light.ON_OFF_CHANNEL_ID, "zigbee2mqtt/light/state", "zigbee2mqtt/light/set/state",
|
||||
"On/Off State", OnOffValue.class);
|
||||
assertChannel(component, Light.EFFECT_CHANNEL_ID, "zigbee2mqtt/light/effect", "zigbee2mqtt/light/set/effect",
|
||||
"Lighting Effect", TextValue.class);
|
||||
|
||||
publishMessage("zigbee2mqtt/light/state", "{\"power\": \"ON\"}");
|
||||
assertState(component, Light.ON_OFF_CHANNEL_ID, OnOffType.ON);
|
||||
publishMessage("zigbee2mqtt/light/effect", "party");
|
||||
assertState(component, Light.EFFECT_CHANNEL_ID, new StringType("party"));
|
||||
publishMessage("zigbee2mqtt/light/state", "{\"power\": \"OFF\"}");
|
||||
assertState(component, Light.ON_OFF_CHANNEL_ID, OnOffType.OFF);
|
||||
|
||||
sendCommand(component, Light.EFFECT_CHANNEL_ID, new StringType("rainbow"));
|
||||
assertPublished("zigbee2mqtt/light/set/effect", "rainbow");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getConfigTopics() {
|
||||
return Set.of(CONFIG_TOPIC);
|
||||
|
|
Loading…
Reference in New Issue