.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())
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
}
}
+ 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));
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) {
* 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
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<>();
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);
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
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);