mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-31 13:34:22 +02:00
[mqtt.homeassistant] Use default strings for all commands and states (#18383)
* [mqtt.homeassistant] Use default strings for all commands Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
+51
-21
@@ -14,8 +14,9 @@ package org.openhab.binding.mqtt.generic.values;
|
|||||||
|
|
||||||
import static java.util.function.Predicate.not;
|
import static java.util.function.Predicate.not;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -38,11 +39,33 @@ import org.openhab.core.types.UnDefType;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class TextValue extends Value {
|
public class TextValue extends Value {
|
||||||
private final @Nullable Set<String> states;
|
private final @Nullable Map<String, String> states;
|
||||||
private final @Nullable Set<String> commands;
|
private final @Nullable Map<String, String> commands;
|
||||||
|
|
||||||
protected @Nullable String nullValue = null;
|
protected @Nullable String nullValue = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a string value with a limited number of allowed states and commands.
|
||||||
|
*
|
||||||
|
* @param states Allowed states. The key is the value that is received from MQTT,
|
||||||
|
* and the value is how matching values will be presented in openHAB.
|
||||||
|
* @param commands Allowed commands. The key is the value that will be received by
|
||||||
|
* openHAB, and the value is how matching commands will be sent to MQTT.
|
||||||
|
*/
|
||||||
|
public TextValue(Map<String, String> states, Map<String, String> commands) {
|
||||||
|
super(CoreItemFactory.STRING, List.of(StringType.class));
|
||||||
|
if (!states.isEmpty()) {
|
||||||
|
this.states = new LinkedHashMap(states);
|
||||||
|
} else {
|
||||||
|
this.states = null;
|
||||||
|
}
|
||||||
|
if (!commands.isEmpty()) {
|
||||||
|
this.commands = new LinkedHashMap(commands);
|
||||||
|
} else {
|
||||||
|
this.commands = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a string value with a limited number of allowed states and commands.
|
* Create a string value with a limited number of allowed states and commands.
|
||||||
*
|
*
|
||||||
@@ -53,13 +76,15 @@ public class TextValue extends Value {
|
|||||||
*/
|
*/
|
||||||
public TextValue(String[] states, String[] commands) {
|
public TextValue(String[] states, String[] commands) {
|
||||||
super(CoreItemFactory.STRING, List.of(StringType.class));
|
super(CoreItemFactory.STRING, List.of(StringType.class));
|
||||||
Set<String> s = Stream.of(states).filter(not(String::isBlank)).collect(Collectors.toSet());
|
Map<String, String> s = Stream.of(states).filter(not(String::isBlank))
|
||||||
|
.collect(Collectors.toMap(str -> str, str -> str, (a, b) -> a, LinkedHashMap::new));
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
this.states = s;
|
this.states = s;
|
||||||
} else {
|
} else {
|
||||||
this.states = null;
|
this.states = null;
|
||||||
}
|
}
|
||||||
Set<String> c = Stream.of(commands).filter(not(String::isBlank)).collect(Collectors.toSet());
|
Map<String, String> c = Stream.of(commands).filter(not(String::isBlank))
|
||||||
|
.collect(Collectors.toMap(str -> str, str -> str, (a, b) -> a, LinkedHashMap::new));
|
||||||
if (!c.isEmpty()) {
|
if (!c.isEmpty()) {
|
||||||
this.commands = c;
|
this.commands = c;
|
||||||
} else {
|
} else {
|
||||||
@@ -89,10 +114,13 @@ public class TextValue extends Value {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StringType parseCommand(Command command) throws IllegalArgumentException {
|
public StringType parseCommand(Command command) throws IllegalArgumentException {
|
||||||
final Set<String> commands = this.commands;
|
final Map<String, String> commands = this.commands;
|
||||||
String valueStr = command.toString();
|
String valueStr = command.toString();
|
||||||
if (commands != null && !commands.contains(valueStr)) {
|
if (commands != null) {
|
||||||
throw new IllegalArgumentException("Value " + valueStr + " not within range");
|
if (!commands.containsKey(valueStr)) {
|
||||||
|
throw new IllegalArgumentException("Value " + valueStr + " not within range");
|
||||||
|
}
|
||||||
|
return new StringType(commands.get(valueStr));
|
||||||
}
|
}
|
||||||
return new StringType(valueStr);
|
return new StringType(valueStr);
|
||||||
}
|
}
|
||||||
@@ -103,13 +131,17 @@ public class TextValue extends Value {
|
|||||||
return UnDefType.NULL;
|
return UnDefType.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<String> states = this.states;
|
final Map<String, String> states = this.states;
|
||||||
String valueStr = command.toString();
|
String valueStr = command.toString();
|
||||||
if (states != null && !states.contains(valueStr)) {
|
if (states != null) {
|
||||||
if (valueStr.isEmpty()) {
|
if (!states.containsKey(valueStr)) {
|
||||||
return UnDefType.NULL;
|
if (valueStr.isEmpty()) {
|
||||||
|
return UnDefType.NULL;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Value " + valueStr + " not within range");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Value " + valueStr + " not within range");
|
return new StringType(states.get(valueStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new StringType(valueStr);
|
return new StringType(valueStr);
|
||||||
@@ -118,18 +150,16 @@ public class TextValue extends Value {
|
|||||||
/**
|
/**
|
||||||
* @return valid states. Can be null.
|
* @return valid states. Can be null.
|
||||||
*/
|
*/
|
||||||
public @Nullable Set<String> getStates() {
|
public @Nullable Map<String, String> getStates() {
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StateDescriptionFragmentBuilder createStateDescription(boolean readOnly) {
|
public StateDescriptionFragmentBuilder createStateDescription(boolean readOnly) {
|
||||||
StateDescriptionFragmentBuilder builder = super.createStateDescription(readOnly);
|
StateDescriptionFragmentBuilder builder = super.createStateDescription(readOnly);
|
||||||
final Set<String> states = this.states;
|
final Map<String, String> states = this.states;
|
||||||
if (states != null) {
|
if (states != null) {
|
||||||
for (String state : states) {
|
states.forEach((ohState, mqttState) -> builder.withOption(new StateOption(ohState, ohState)));
|
||||||
builder = builder.withOption(new StateOption(state, state));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
@@ -137,10 +167,10 @@ public class TextValue extends Value {
|
|||||||
@Override
|
@Override
|
||||||
public CommandDescriptionBuilder createCommandDescription() {
|
public CommandDescriptionBuilder createCommandDescription() {
|
||||||
CommandDescriptionBuilder builder = super.createCommandDescription();
|
CommandDescriptionBuilder builder = super.createCommandDescription();
|
||||||
final Set<String> commands = this.commands;
|
final Map<String, String> commands = this.commands;
|
||||||
if (commands != null) {
|
if (commands != null) {
|
||||||
for (String command : commands) {
|
for (String command : commands.keySet()) {
|
||||||
builder = builder.withCommandOption(new CommandOption(command, command));
|
builder.withCommandOption(new CommandOption(command, command));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ Note also that just because these tables show that a channel may be read/write,
|
|||||||
|
|
||||||
### [Alarm Control Panel](https://www.home-assistant.io/integrations/alarm_control_panel.mqtt/)
|
### [Alarm Control Panel](https://www.home-assistant.io/integrations/alarm_control_panel.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
| Channel ID | Type | R/W | Description |
|
||||||
|-----------------|--------|-----|------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------|--------|-----|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| state | String | R/W | The current state of the alarm system, and the ability to change its state. Inspect the state and command descriptions for valid values. |
|
| state | String | R/W | The current state of the alarm system, and the ability to change its state. Inspect the state and command descriptions for values supported by your device. Possible values are ARM_AWAY, ARM_CUSTOM_BYPASS, ARM_HOME, ARM_NIGHT, ARM_VACATION, DISARM, TRIGGER for commands; armed_away, armed_custom_bypass, armed_home, armed_night, armed_vacation, arming, disarmed, disarming, pending, triggered for states. |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
### [Binary Sensor](https://www.home-assistant.io/integrations/binary_sensor.mqtt/)
|
### [Binary Sensor](https://www.home-assistant.io/integrations/binary_sensor.mqtt/)
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ Note also that just because these tables show that a channel may be read/write,
|
|||||||
|
|
||||||
### [Button](https://www.home-assistant.io/integrations/button.mqtt/)
|
### [Button](https://www.home-assistant.io/integrations/button.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
| Channel ID | Type | R/W | Description |
|
||||||
|-----------------|--------|-----|------------------------------------------------------------------------------|
|
|-----------------|--------|-----|-----------------------------------------------------|
|
||||||
| button | String | WO | Inspect the state description for the proper string to send (usually PRESS). |
|
| button | String | WO | Send PRESS to activate the button. |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
### [Camera](https://www.home-assistant.io/integrations/camera.mqtt/)<br>
|
### [Camera](https://www.home-assistant.io/integrations/camera.mqtt/)<br>
|
||||||
|
|
||||||
@@ -138,11 +138,11 @@ If a device has multiple device triggers for the same subtype (the particular bu
|
|||||||
|
|
||||||
### [Lock](https://www.home-assistant.io/integrations/lock.mqtt/)
|
### [Lock](https://www.home-assistant.io/integrations/lock.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
| Channel ID | Type | R/W | Description |
|
||||||
|-----------------|--------|-----|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------|--------|-----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| lock | Switch | R/W | Lock/unlocked state. |
|
| lock | Switch | R/W | Lock/unlocked state. |
|
||||||
| state | String | R/W | Additional states may be supported such as jammed, or opening the door directly. Inspect the state and command descriptions for availability. |
|
| state | String | R/W | Additional states may be supported such as jammed, or opening the door directly. Inspect the state and command descriptions for values supported by your device. Possible values are LOCK, UNLOCK, OPEN for commands; JAMMED, LOCKED, LOCKING, UNLOCKED, UNLOCKING for states. |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
### [Number](https://www.home-assistant.io/integrations/number.mqtt/)
|
### [Number](https://www.home-assistant.io/integrations/number.mqtt/)
|
||||||
|
|
||||||
@@ -153,10 +153,12 @@ If a device has multiple device triggers for the same subtype (the particular bu
|
|||||||
|
|
||||||
### [Scene](https://www.home-assistant.io/integrations/scene.mqtt/)
|
### [Scene](https://www.home-assistant.io/integrations/scene.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
If a device has multiple scenes, they will only show up as a single channel. You send the name of a given scene to activate it.
|
||||||
|-----------------|--------|-----|-----------------------------------------------------------------------------------------------------------|
|
|
||||||
| scene | String | WO | Triggers a scene on the device. Inspect the state description for the proper string to send (usually ON). |
|
| Channel ID | Type | R/W | Description |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
|-----------------|--------|-----|------------------------------------------------------------------------------------------------|
|
||||||
|
| scene | String | WO | Triggers a scene on the device. Inspect the command description for the proper string to send. |
|
||||||
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
### [Select](https://www.home-assistant.io/integrations/select.mqtt/)
|
### [Select](https://www.home-assistant.io/integrations/select.mqtt/)
|
||||||
|
|
||||||
@@ -203,21 +205,22 @@ The `json-attributes` channel for this component will always appear as part of c
|
|||||||
|
|
||||||
### [Vacuum](https://www.home-assistant.io/integrations/vacuum.mqtt/)
|
### [Vacuum](https://www.home-assistant.io/integrations/vacuum.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
| Channel ID | Type | R/W | Description |
|
||||||
|-----------------|--------|-----|--------------------------------------------------------------------------------------------------|
|
|-----------------|--------|-----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| command | String | WO | Send a command to the vacuum. Inspect the state description for allowed values. |
|
| command | String | WO | Send a command to the vacuum. Inspect the command description for values supported by your device. Possible values are clean_spot, locate, pause, return_to_base, start, and stop. |
|
||||||
| fan-speed | String | R/W | Set the fan speed. Inspect the state description fro allowed values. |
|
| fan-speed | String | R/W | Set the fan speed. Inspect the state description fro allowed values. |
|
||||||
| custom-command | String | WO | Send an arbitrary command to the vacuum. This may be a raw command, or JSON. |
|
| custom-command | String | WO | Send an arbitrary command to the vacuum. This may be a raw command, or JSON. |
|
||||||
| battery-level | Dimmer | RO | The vaccum's battery level. |
|
| battery-level | Dimmer | RO | The vaccum's battery level. |
|
||||||
| state | String | RO | The state of the vacuum. One of `cleaning`, `docked`, `paused`, `idle`, `returning`, or `error`. |
|
| state | String | RO | The state of the vacuum. One of `cleaning`, `docked`, `paused`, `idle`, `returning`, or `error`. |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
### [Valve](https://www.home-assistant.io/integrations/valve.mqtt/)
|
### [Valve](https://www.home-assistant.io/integrations/valve.mqtt/)
|
||||||
|
|
||||||
| Channel ID | Type | R/W | Description |
|
| Channel ID | Type | R/W | Description |
|
||||||
|-----------------|---------------|-----|---------------------------------------------------------------------------------------------|
|
|-----------------|---------------|-----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| valve | Switch/Dimmer | R/W | If the valve is on (open), or not. For a valve with position (a Dimmer), 100% is full open. |
|
| valve | Switch/Dimmer | R/W | If the valve is on (open), or not. For a valve with position (a Dimmer), 100% is full open. |
|
||||||
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
| state | String | RO | Additional states may be supported, such as currently processing actions, or stopping the valve where it currently is. Inspect the state and command descriptions for values supported by your device. Possible values are CLOSE, OPEN, STOP for commands; open, opening, closed, closing for states. |
|
||||||
|
| json-attributes | String | RO | Additional attributes, as a serialized JSON string. |
|
||||||
|
|
||||||
|
|
||||||
## Supported Devices
|
## Supported Devices
|
||||||
|
|||||||
+52
-37
@@ -12,8 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
@@ -46,6 +47,14 @@ public class AlarmControlPanel extends AbstractComponent<AlarmControlPanel.Chann
|
|||||||
public static final String FEATURE_ARM_CUSTOM_BYPASS = "arm_custom_bypass";
|
public static final String FEATURE_ARM_CUSTOM_BYPASS = "arm_custom_bypass";
|
||||||
public static final String FEATURE_TRIGGER = "trigger";
|
public static final String FEATURE_TRIGGER = "trigger";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_ARM_HOME = "ARM_HOME";
|
||||||
|
public static final String PAYLOAD_ARM_AWAY = "ARM_AWAY";
|
||||||
|
public static final String PAYLOAD_ARM_NIGHT = "ARM_NIGHT";
|
||||||
|
public static final String PAYLOAD_ARM_VACATION = "ARM_VACATION";
|
||||||
|
public static final String PAYLOAD_ARM_CUSTOM_BYPASS = "ARM_CUSTOM_BYPASS";
|
||||||
|
public static final String PAYLOAD_DISARM = "DISARM";
|
||||||
|
public static final String PAYLOAD_TRIGGER = "TRIGGER";
|
||||||
|
|
||||||
public static final String STATE_ARMED_AWAY = "armed_away";
|
public static final String STATE_ARMED_AWAY = "armed_away";
|
||||||
public static final String STATE_ARMED_CUSTOM_BYPASS = "armed_custom_bypass";
|
public static final String STATE_ARMED_CUSTOM_BYPASS = "armed_custom_bypass";
|
||||||
public static final String STATE_ARMED_HOME = "armed_home";
|
public static final String STATE_ARMED_HOME = "armed_home";
|
||||||
@@ -73,19 +82,19 @@ public class AlarmControlPanel extends AbstractComponent<AlarmControlPanel.Chann
|
|||||||
@SerializedName("command_topic")
|
@SerializedName("command_topic")
|
||||||
protected @Nullable String commandTopic;
|
protected @Nullable String commandTopic;
|
||||||
@SerializedName("payload_arm_away")
|
@SerializedName("payload_arm_away")
|
||||||
protected String payloadArmAway = "ARM_AWAY";
|
protected String payloadArmAway = PAYLOAD_ARM_AWAY;
|
||||||
@SerializedName("payload_arm_home")
|
@SerializedName("payload_arm_home")
|
||||||
protected String payloadArmHome = "ARM_HOME";
|
protected String payloadArmHome = PAYLOAD_ARM_HOME;
|
||||||
@SerializedName("payload_arm_night")
|
@SerializedName("payload_arm_night")
|
||||||
protected String payloadArmNight = "ARM_NIGHT";
|
protected String payloadArmNight = PAYLOAD_ARM_NIGHT;
|
||||||
@SerializedName("payload_arm_vacation")
|
@SerializedName("payload_arm_vacation")
|
||||||
protected String payloadArmVacation = "ARM_VACATION";
|
protected String payloadArmVacation = PAYLOAD_ARM_VACATION;
|
||||||
@SerializedName("payload_arm_custom_bypass")
|
@SerializedName("payload_arm_custom_bypass")
|
||||||
protected String payloadArmCustomBypass = "ARM_CUSTOM_BYPASS";
|
protected String payloadArmCustomBypass = PAYLOAD_ARM_CUSTOM_BYPASS;
|
||||||
@SerializedName("payload_disarm")
|
@SerializedName("payload_disarm")
|
||||||
protected String payloadDisarm = "DISARM";
|
protected String payloadDisarm = PAYLOAD_DISARM;
|
||||||
@SerializedName("payload_trigger")
|
@SerializedName("payload_trigger")
|
||||||
protected String payloadTrigger = "TRIGGER";
|
protected String payloadTrigger = PAYLOAD_TRIGGER;
|
||||||
|
|
||||||
@SerializedName("supported_features")
|
@SerializedName("supported_features")
|
||||||
protected List<String> supportedFeatures = List.of(FEATURE_ARM_HOME, FEATURE_ARM_AWAY, FEATURE_ARM_NIGHT,
|
protected List<String> supportedFeatures = List.of(FEATURE_ARM_HOME, FEATURE_ARM_AWAY, FEATURE_ARM_NIGHT,
|
||||||
@@ -95,37 +104,43 @@ public class AlarmControlPanel extends AbstractComponent<AlarmControlPanel.Chann
|
|||||||
public AlarmControlPanel(ComponentFactory.ComponentConfiguration componentConfiguration) {
|
public AlarmControlPanel(ComponentFactory.ComponentConfiguration componentConfiguration) {
|
||||||
super(componentConfiguration, ChannelConfiguration.class);
|
super(componentConfiguration, ChannelConfiguration.class);
|
||||||
|
|
||||||
List<String> stateEnum = new ArrayList(List.of(STATE_DISARMED, STATE_TRIGGERED, STATE_ARMING, STATE_DISARMING,
|
Map<String, String> stateEnum = new LinkedHashMap<>();
|
||||||
STATE_PENDING, STATE_TRIGGERED));
|
stateEnum.put(STATE_DISARMED, STATE_DISARMED);
|
||||||
List<String> commandEnum = new ArrayList(List.of(channelConfiguration.payloadDisarm));
|
stateEnum.put(STATE_TRIGGERED, STATE_TRIGGERED);
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_HOME)) {
|
stateEnum.put(STATE_ARMING, STATE_ARMING);
|
||||||
stateEnum.add(STATE_ARMED_HOME);
|
stateEnum.put(STATE_DISARMING, STATE_DISARMING);
|
||||||
commandEnum.add(channelConfiguration.payloadArmHome);
|
stateEnum.put(STATE_PENDING, STATE_PENDING);
|
||||||
}
|
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_AWAY)) {
|
|
||||||
stateEnum.add(STATE_ARMED_AWAY);
|
|
||||||
commandEnum.add(channelConfiguration.payloadArmAway);
|
|
||||||
}
|
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_NIGHT)) {
|
|
||||||
stateEnum.add(STATE_ARMED_NIGHT);
|
|
||||||
commandEnum.add(channelConfiguration.payloadArmNight);
|
|
||||||
}
|
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_VACATION)) {
|
|
||||||
stateEnum.add(STATE_ARMED_VACATION);
|
|
||||||
commandEnum.add(channelConfiguration.payloadArmVacation);
|
|
||||||
}
|
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_CUSTOM_BYPASS)) {
|
|
||||||
stateEnum.add(STATE_ARMED_CUSTOM_BYPASS);
|
|
||||||
commandEnum.add(channelConfiguration.payloadArmCustomBypass);
|
|
||||||
}
|
|
||||||
if (channelConfiguration.supportedFeatures.contains(FEATURE_TRIGGER)) {
|
|
||||||
commandEnum.add(channelConfiguration.payloadTrigger);
|
|
||||||
}
|
|
||||||
|
|
||||||
String commandTopic = channelConfiguration.commandTopic;
|
String commandTopic = channelConfiguration.commandTopic;
|
||||||
TextValue value = (commandTopic != null)
|
Map<String, String> commandEnum = new LinkedHashMap<>();
|
||||||
? new TextValue(stateEnum.toArray(new String[0]), commandEnum.toArray(new String[0]))
|
if (commandTopic != null) {
|
||||||
: new TextValue(stateEnum.toArray(new String[0]));
|
commandEnum.put(PAYLOAD_DISARM, channelConfiguration.payloadDisarm);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_HOME)) {
|
||||||
|
stateEnum.put(STATE_ARMED_HOME, STATE_ARMED_HOME);
|
||||||
|
commandEnum.put(PAYLOAD_ARM_HOME, channelConfiguration.payloadArmHome);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_AWAY)) {
|
||||||
|
stateEnum.put(STATE_ARMED_AWAY, STATE_ARMED_AWAY);
|
||||||
|
commandEnum.put(PAYLOAD_ARM_AWAY, channelConfiguration.payloadArmAway);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_NIGHT)) {
|
||||||
|
stateEnum.put(STATE_ARMED_NIGHT, STATE_ARMED_NIGHT);
|
||||||
|
commandEnum.put(PAYLOAD_ARM_NIGHT, channelConfiguration.payloadArmNight);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_VACATION)) {
|
||||||
|
stateEnum.put(STATE_ARMED_VACATION, STATE_ARMED_VACATION);
|
||||||
|
commandEnum.put(PAYLOAD_ARM_VACATION, channelConfiguration.payloadArmVacation);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_ARM_CUSTOM_BYPASS)) {
|
||||||
|
stateEnum.put(STATE_ARMED_CUSTOM_BYPASS, STATE_ARMED_CUSTOM_BYPASS);
|
||||||
|
commandEnum.put(PAYLOAD_ARM_CUSTOM_BYPASS, channelConfiguration.payloadArmCustomBypass);
|
||||||
|
}
|
||||||
|
if (channelConfiguration.supportedFeatures.contains(FEATURE_TRIGGER)) {
|
||||||
|
commandEnum.put(PAYLOAD_TRIGGER, channelConfiguration.payloadTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextValue value = new TextValue(stateEnum, commandEnum);
|
||||||
var builder = buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, value, getName(),
|
var builder = buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, value, getName(),
|
||||||
componentConfiguration.getUpdateListener())
|
componentConfiguration.getUpdateListener())
|
||||||
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate());
|
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate());
|
||||||
|
|||||||
+6
-2
@@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.mqtt.generic.values.TextValue;
|
import org.openhab.binding.mqtt.generic.values.TextValue;
|
||||||
@@ -30,6 +32,8 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
public class Button extends AbstractComponent<Button.ChannelConfiguration> {
|
public class Button extends AbstractComponent<Button.ChannelConfiguration> {
|
||||||
public static final String BUTTON_CHANNEL_ID = "button";
|
public static final String BUTTON_CHANNEL_ID = "button";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_PRESS = "PRESS";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration class for MQTT component
|
* Configuration class for MQTT component
|
||||||
*/
|
*/
|
||||||
@@ -44,13 +48,13 @@ public class Button extends AbstractComponent<Button.ChannelConfiguration> {
|
|||||||
protected @Nullable String commandTopic;
|
protected @Nullable String commandTopic;
|
||||||
|
|
||||||
@SerializedName("payload_press")
|
@SerializedName("payload_press")
|
||||||
protected String payloadPress = "PRESS";
|
protected String payloadPress = PAYLOAD_PRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Button(ComponentFactory.ComponentConfiguration componentConfiguration) {
|
public Button(ComponentFactory.ComponentConfiguration componentConfiguration) {
|
||||||
super(componentConfiguration, ChannelConfiguration.class);
|
super(componentConfiguration, ChannelConfiguration.class);
|
||||||
|
|
||||||
TextValue value = new TextValue(new String[] { channelConfiguration.payloadPress });
|
TextValue value = new TextValue(Map.of(), Map.of(PAYLOAD_PRESS, channelConfiguration.payloadPress));
|
||||||
|
|
||||||
buildChannel(BUTTON_CHANNEL_ID, ComponentChannelType.STRING, value, getName(),
|
buildChannel(BUTTON_CHANNEL_ID, ComponentChannelType.STRING, value, getName(),
|
||||||
componentConfiguration.getUpdateListener())
|
componentConfiguration.getUpdateListener())
|
||||||
|
|||||||
+28
-11
@@ -12,6 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.mqtt.generic.values.RollershutterValue;
|
import org.openhab.binding.mqtt.generic.values.RollershutterValue;
|
||||||
@@ -41,6 +44,16 @@ public class Cover extends AbstractComponent<Cover.ChannelConfiguration> {
|
|||||||
public static final String COVER_CHANNEL_ID = "cover";
|
public static final String COVER_CHANNEL_ID = "cover";
|
||||||
public static final String STATE_CHANNEL_ID = "state";
|
public static final String STATE_CHANNEL_ID = "state";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_OPEN = "OPEN";
|
||||||
|
public static final String PAYLOAD_CLOSE = "CLOSE";
|
||||||
|
public static final String PAYLOAD_STOP = "STOP";
|
||||||
|
|
||||||
|
public static final String STATE_CLOSED = "closed";
|
||||||
|
public static final String STATE_CLOSING = "closing";
|
||||||
|
public static final String STATE_OPEN = "open";
|
||||||
|
public static final String STATE_OPENING = "opening";
|
||||||
|
public static final String STATE_STOPPED = "stopped";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration class for MQTT component
|
* Configuration class for MQTT component
|
||||||
*/
|
*/
|
||||||
@@ -56,11 +69,11 @@ public class Cover extends AbstractComponent<Cover.ChannelConfiguration> {
|
|||||||
@SerializedName("command_topic")
|
@SerializedName("command_topic")
|
||||||
protected @Nullable String commandTopic;
|
protected @Nullable String commandTopic;
|
||||||
@SerializedName("payload_open")
|
@SerializedName("payload_open")
|
||||||
protected String payloadOpen = "OPEN";
|
protected String payloadOpen = PAYLOAD_OPEN;
|
||||||
@SerializedName("payload_close")
|
@SerializedName("payload_close")
|
||||||
protected String payloadClose = "CLOSE";
|
protected String payloadClose = PAYLOAD_CLOSE;
|
||||||
@SerializedName("payload_stop")
|
@SerializedName("payload_stop")
|
||||||
protected String payloadStop = "STOP";
|
protected String payloadStop = PAYLOAD_STOP;
|
||||||
@SerializedName("position_closed")
|
@SerializedName("position_closed")
|
||||||
protected int positionClosed = 0;
|
protected int positionClosed = 0;
|
||||||
@SerializedName("position_open")
|
@SerializedName("position_open")
|
||||||
@@ -74,15 +87,15 @@ public class Cover extends AbstractComponent<Cover.ChannelConfiguration> {
|
|||||||
@SerializedName("set_position_topic")
|
@SerializedName("set_position_topic")
|
||||||
protected @Nullable String setPositionTopic;
|
protected @Nullable String setPositionTopic;
|
||||||
@SerializedName("state_closed")
|
@SerializedName("state_closed")
|
||||||
protected String stateClosed = "closed";
|
protected String stateClosed = STATE_CLOSED;
|
||||||
@SerializedName("state_closing")
|
@SerializedName("state_closing")
|
||||||
protected String stateClosing = "closing";
|
protected String stateClosing = STATE_CLOSING;
|
||||||
@SerializedName("state_open")
|
@SerializedName("state_open")
|
||||||
protected String stateOpen = "open";
|
protected String stateOpen = STATE_OPEN;
|
||||||
@SerializedName("state_opening")
|
@SerializedName("state_opening")
|
||||||
protected String stateOpening = "opening";
|
protected String stateOpening = STATE_OPENING;
|
||||||
@SerializedName("state_stopped")
|
@SerializedName("state_stopped")
|
||||||
protected String stateStopped = "stopped";
|
protected String stateStopped = STATE_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -102,9 +115,13 @@ public class Cover extends AbstractComponent<Cover.ChannelConfiguration> {
|
|||||||
// State can indicate additional information than just
|
// State can indicate additional information than just
|
||||||
// the current position, so expose it as a separate channel
|
// the current position, so expose it as a separate channel
|
||||||
if (stateTopic != null) {
|
if (stateTopic != null) {
|
||||||
TextValue value = new TextValue(new String[] { channelConfiguration.stateClosed,
|
Map<String, String> states = new LinkedHashMap<>();
|
||||||
channelConfiguration.stateClosing, channelConfiguration.stateOpen,
|
states.put(channelConfiguration.stateClosed, STATE_CLOSED);
|
||||||
channelConfiguration.stateOpening, channelConfiguration.stateStopped });
|
states.put(channelConfiguration.stateClosing, STATE_CLOSING);
|
||||||
|
states.put(channelConfiguration.stateOpen, STATE_OPEN);
|
||||||
|
states.put(channelConfiguration.stateOpening, STATE_OPENING);
|
||||||
|
states.put(channelConfiguration.stateStopped, STATE_STOPPED);
|
||||||
|
TextValue value = new TextValue(states, Map.of());
|
||||||
buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, value, "State",
|
buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, value, "State",
|
||||||
componentConfiguration.getUpdateListener()).stateTopic(stateTopic).isAdvanced(true).build();
|
componentConfiguration.getUpdateListener()).stateTopic(stateTopic).isAdvanced(true).build();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -12,8 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
@@ -121,7 +121,7 @@ public class DeviceTrigger extends AbstractComponent<DeviceTrigger.ChannelConfig
|
|||||||
Configuration newConfiguration = mergeChannelConfiguration(channel, newTrigger);
|
Configuration newConfiguration = mergeChannelConfiguration(channel, newTrigger);
|
||||||
|
|
||||||
TextValue value = (TextValue) channel.getState().getCache();
|
TextValue value = (TextValue) channel.getState().getCache();
|
||||||
Set<String> payloads = value.getStates();
|
Map<String, String> payloads = value.getStates();
|
||||||
|
|
||||||
// Append payload to allowed values
|
// Append payload to allowed values
|
||||||
String otherPayload = newTrigger.getChannelConfiguration().payload;
|
String otherPayload = newTrigger.getChannelConfiguration().payload;
|
||||||
@@ -129,7 +129,7 @@ public class DeviceTrigger extends AbstractComponent<DeviceTrigger.ChannelConfig
|
|||||||
// Need to accept anything
|
// Need to accept anything
|
||||||
value = new TextValue();
|
value = new TextValue();
|
||||||
} else {
|
} else {
|
||||||
String[] newValues = Stream.concat(payloads.stream(), Stream.of(otherPayload)).distinct()
|
String[] newValues = Stream.concat(payloads.keySet().stream(), Stream.of(otherPayload)).distinct()
|
||||||
.toArray(String[]::new);
|
.toArray(String[]::new);
|
||||||
value = new TextValue(newValues);
|
value = new TextValue(newValues);
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-21
@@ -12,6 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
|
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
|
||||||
@@ -37,6 +40,16 @@ public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
|
|||||||
public static final String LOCK_CHANNEL_ID = "lock";
|
public static final String LOCK_CHANNEL_ID = "lock";
|
||||||
public static final String STATE_CHANNEL_ID = "state";
|
public static final String STATE_CHANNEL_ID = "state";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_LOCK = "LOCK";
|
||||||
|
public static final String PAYLOAD_UNLOCK = "UNLOCK";
|
||||||
|
public static final String PAYLOAD_OPEN = "OPEN";
|
||||||
|
|
||||||
|
public static final String STATE_JAMMED = "JAMMED";
|
||||||
|
public static final String STATE_LOCKED = "LOCKED";
|
||||||
|
public static final String STATE_LOCKING = "LOCKING";
|
||||||
|
public static final String STATE_UNLOCKED = "UNLOCKED";
|
||||||
|
public static final String STATE_UNLOCKING = "UNLOCKING";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration class for MQTT component
|
* Configuration class for MQTT component
|
||||||
*/
|
*/
|
||||||
@@ -52,21 +65,21 @@ public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
|
|||||||
@SerializedName("state_topic")
|
@SerializedName("state_topic")
|
||||||
protected String stateTopic = "";
|
protected String stateTopic = "";
|
||||||
@SerializedName("payload_lock")
|
@SerializedName("payload_lock")
|
||||||
protected String payloadLock = "LOCK";
|
protected String payloadLock = PAYLOAD_LOCK;
|
||||||
@SerializedName("payload_unlock")
|
@SerializedName("payload_unlock")
|
||||||
protected String payloadUnlock = "UNLOCK";
|
protected String payloadUnlock = PAYLOAD_UNLOCK;
|
||||||
@SerializedName("payload_open")
|
@SerializedName("payload_open")
|
||||||
protected @Nullable String payloadOpen;
|
protected @Nullable String payloadOpen;
|
||||||
@SerializedName("state_jammed")
|
@SerializedName("state_jammed")
|
||||||
protected String stateJammed = "JAMMED";
|
protected String stateJammed = STATE_JAMMED;
|
||||||
@SerializedName("state_locked")
|
@SerializedName("state_locked")
|
||||||
protected String stateLocked = "LOCKED";
|
protected String stateLocked = STATE_LOCKED;
|
||||||
@SerializedName("state_locking")
|
@SerializedName("state_locking")
|
||||||
protected String stateLocking = "LOCKING";
|
protected String stateLocking = STATE_LOCKING;
|
||||||
@SerializedName("state_unlocked")
|
@SerializedName("state_unlocked")
|
||||||
protected String stateUnlocked = "UNLOCKED";
|
protected String stateUnlocked = STATE_UNLOCKED;
|
||||||
@SerializedName("state_unlocking")
|
@SerializedName("state_unlocking")
|
||||||
protected String stateUnlocking = "UNLOCKING";
|
protected String stateUnlocking = STATE_UNLOCKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean optimistic = false;
|
private boolean optimistic = false;
|
||||||
@@ -95,16 +108,21 @@ public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
|
|||||||
return true;
|
return true;
|
||||||
}).build();
|
}).build();
|
||||||
|
|
||||||
String[] commands;
|
Map<String, String> commands = new LinkedHashMap<>();
|
||||||
if (channelConfiguration.payloadOpen == null) {
|
commands.put(PAYLOAD_LOCK, channelConfiguration.payloadLock);
|
||||||
commands = new String[] { channelConfiguration.payloadLock, channelConfiguration.payloadUnlock, };
|
commands.put(PAYLOAD_UNLOCK, channelConfiguration.payloadUnlock);
|
||||||
} else {
|
String payloadOpen = channelConfiguration.payloadOpen;
|
||||||
commands = new String[] { channelConfiguration.payloadLock, channelConfiguration.payloadUnlock,
|
if (payloadOpen != null) {
|
||||||
channelConfiguration.payloadOpen };
|
commands.put(PAYLOAD_OPEN, payloadOpen);
|
||||||
}
|
}
|
||||||
stateValue = new TextValue(new String[] { channelConfiguration.stateJammed, channelConfiguration.stateLocked,
|
Map<String, String> states = new LinkedHashMap<>();
|
||||||
channelConfiguration.stateLocking, channelConfiguration.stateUnlocked,
|
states.put(channelConfiguration.stateLocked, STATE_LOCKED);
|
||||||
channelConfiguration.stateUnlocking }, commands);
|
states.put(channelConfiguration.stateUnlocked, STATE_UNLOCKED);
|
||||||
|
states.put(channelConfiguration.stateLocking, STATE_LOCKING);
|
||||||
|
states.put(channelConfiguration.stateUnlocking, STATE_UNLOCKING);
|
||||||
|
states.put(channelConfiguration.stateJammed, STATE_JAMMED);
|
||||||
|
stateValue = new TextValue(states, commands);
|
||||||
|
|
||||||
buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, stateValue, "State",
|
buildChannel(STATE_CHANNEL_ID, ComponentChannelType.STRING, stateValue, "State",
|
||||||
componentConfiguration.getUpdateListener())
|
componentConfiguration.getUpdateListener())
|
||||||
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
|
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
|
||||||
@@ -112,10 +130,11 @@ public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
|
|||||||
channelConfiguration.getQos())
|
channelConfiguration.getQos())
|
||||||
.isAdvanced(true).withAutoUpdatePolicy(AutoUpdatePolicy.VETO).commandFilter(command -> {
|
.isAdvanced(true).withAutoUpdatePolicy(AutoUpdatePolicy.VETO).commandFilter(command -> {
|
||||||
if (command instanceof StringType stringCommand) {
|
if (command instanceof StringType stringCommand) {
|
||||||
if (stringCommand.toString().equals(channelConfiguration.payloadLock)) {
|
if (stringCommand.toString().equals(PAYLOAD_LOCK)) {
|
||||||
autoUpdate(true);
|
autoUpdate(true);
|
||||||
} else if (stringCommand.toString().equals(channelConfiguration.payloadUnlock)
|
} else if (stringCommand.toString().equals(PAYLOAD_UNLOCK)
|
||||||
|| stringCommand.toString().equals(channelConfiguration.payloadOpen)) {
|
|| (channelConfiguration.payloadOpen != null
|
||||||
|
&& stringCommand.toString().equals(PAYLOAD_OPEN))) {
|
||||||
autoUpdate(false);
|
autoUpdate(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,12 +154,12 @@ public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
|
|||||||
final ChannelStateUpdateListener updateListener = componentConfiguration.getUpdateListener();
|
final ChannelStateUpdateListener updateListener = componentConfiguration.getUpdateListener();
|
||||||
|
|
||||||
if (locking) {
|
if (locking) {
|
||||||
stateValue.update(new StringType(channelConfiguration.stateLocked));
|
stateValue.update(new StringType(STATE_LOCKED));
|
||||||
updateListener.updateChannelState(stateChannelUID, stateValue.getChannelState());
|
updateListener.updateChannelState(stateChannelUID, stateValue.getChannelState());
|
||||||
lockValue.update(OnOffType.ON);
|
lockValue.update(OnOffType.ON);
|
||||||
updateListener.updateChannelState(lockChannelUID, OnOffType.ON);
|
updateListener.updateChannelState(lockChannelUID, OnOffType.ON);
|
||||||
} else {
|
} else {
|
||||||
stateValue.update(new StringType(channelConfiguration.stateUnlocked));
|
stateValue.update(new StringType(STATE_UNLOCKED));
|
||||||
updateListener.updateChannelState(stateChannelUID, stateValue.getChannelState());
|
updateListener.updateChannelState(stateChannelUID, stateValue.getChannelState());
|
||||||
lockValue.update(OnOffType.OFF);
|
lockValue.update(OnOffType.OFF);
|
||||||
updateListener.updateChannelState(lockChannelUID, OnOffType.OFF);
|
updateListener.updateChannelState(lockChannelUID, OnOffType.OFF);
|
||||||
|
|||||||
+29
-17
@@ -13,8 +13,9 @@
|
|||||||
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
package org.openhab.binding.mqtt.homeassistant.internal.component;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
@@ -49,6 +50,13 @@ public class Vacuum extends AbstractComponent<Vacuum.ChannelConfiguration> {
|
|||||||
public static final String FEATURE_FAN_SPEED = "fan_speed";
|
public static final String FEATURE_FAN_SPEED = "fan_speed";
|
||||||
public static final String FEATURE_SEND_COMMAND = "send_command";
|
public static final String FEATURE_SEND_COMMAND = "send_command";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_CLEAN_SPOT = "clean_spot";
|
||||||
|
public static final String PAYLOAD_LOCATE = "locate";
|
||||||
|
public static final String PAYLOAD_PAUSE = "pause";
|
||||||
|
public static final String PAYLOAD_RETURN_TO_BASE = "return_to_base";
|
||||||
|
public static final String PAYLOAD_START = "start";
|
||||||
|
public static final String PAYLOAD_STOP = "stop";
|
||||||
|
|
||||||
public static final String STATE_CLEANING = "cleaning";
|
public static final String STATE_CLEANING = "cleaning";
|
||||||
public static final String STATE_DOCKED = "docked";
|
public static final String STATE_DOCKED = "docked";
|
||||||
public static final String STATE_PAUSED = "paused";
|
public static final String STATE_PAUSED = "paused";
|
||||||
@@ -87,17 +95,17 @@ public class Vacuum extends AbstractComponent<Vacuum.ChannelConfiguration> {
|
|||||||
protected @Nullable String fanSpeedTopic;
|
protected @Nullable String fanSpeedTopic;
|
||||||
|
|
||||||
@SerializedName("payload_clean_spot")
|
@SerializedName("payload_clean_spot")
|
||||||
protected String payloadCleanSpot = "clean_spot";
|
protected String payloadCleanSpot = PAYLOAD_CLEAN_SPOT;
|
||||||
@SerializedName("payload_locate")
|
@SerializedName("payload_locate")
|
||||||
protected String payloadLocate = "locate";
|
protected String payloadLocate = PAYLOAD_LOCATE;
|
||||||
@SerializedName("payload_pause")
|
@SerializedName("payload_pause")
|
||||||
protected String payloadPause = "pause";
|
protected String payloadPause = PAYLOAD_PAUSE;
|
||||||
@SerializedName("payload_return_to_base")
|
@SerializedName("payload_return_to_base")
|
||||||
protected String payloadReturnToBase = "return_to_base";
|
protected String payloadReturnToBase = PAYLOAD_RETURN_TO_BASE;
|
||||||
@SerializedName("payload_start")
|
@SerializedName("payload_start")
|
||||||
protected String payloadStart = "start";
|
protected String payloadStart = PAYLOAD_START;
|
||||||
@SerializedName("payload_stop")
|
@SerializedName("payload_stop")
|
||||||
protected String payloadStop = "stop";
|
protected String payloadStop = PAYLOAD_STOP;
|
||||||
|
|
||||||
@SerializedName("send_command_topic")
|
@SerializedName("send_command_topic")
|
||||||
protected @Nullable String sendCommandTopic;
|
protected @Nullable String sendCommandTopic;
|
||||||
@@ -124,15 +132,18 @@ public class Vacuum extends AbstractComponent<Vacuum.ChannelConfiguration> {
|
|||||||
|
|
||||||
final var supportedFeatures = channelConfiguration.supportedFeatures;
|
final var supportedFeatures = channelConfiguration.supportedFeatures;
|
||||||
|
|
||||||
final List<String> commands = new ArrayList<>();
|
final Map<String, String> commands = new LinkedHashMap<>();
|
||||||
addPayloadToList(supportedFeatures, FEATURE_CLEAN_SPOT, channelConfiguration.payloadCleanSpot, commands);
|
addPayloadToList(supportedFeatures, FEATURE_CLEAN_SPOT, PAYLOAD_CLEAN_SPOT,
|
||||||
addPayloadToList(supportedFeatures, FEATURE_LOCATE, channelConfiguration.payloadLocate, commands);
|
channelConfiguration.payloadCleanSpot, commands);
|
||||||
addPayloadToList(supportedFeatures, FEATURE_RETURN_HOME, channelConfiguration.payloadReturnToBase, commands);
|
addPayloadToList(supportedFeatures, FEATURE_LOCATE, PAYLOAD_LOCATE, channelConfiguration.payloadLocate,
|
||||||
addPayloadToList(supportedFeatures, FEATURE_START, channelConfiguration.payloadStart, commands);
|
commands);
|
||||||
addPayloadToList(supportedFeatures, FEATURE_STOP, channelConfiguration.payloadStop, commands);
|
addPayloadToList(supportedFeatures, FEATURE_RETURN_HOME, PAYLOAD_RETURN_TO_BASE,
|
||||||
addPayloadToList(supportedFeatures, FEATURE_PAUSE, channelConfiguration.payloadPause, commands);
|
channelConfiguration.payloadReturnToBase, commands);
|
||||||
|
addPayloadToList(supportedFeatures, FEATURE_START, PAYLOAD_START, channelConfiguration.payloadStart, commands);
|
||||||
|
addPayloadToList(supportedFeatures, FEATURE_STOP, PAYLOAD_STOP, channelConfiguration.payloadStop, commands);
|
||||||
|
addPayloadToList(supportedFeatures, FEATURE_PAUSE, PAYLOAD_PAUSE, channelConfiguration.payloadPause, commands);
|
||||||
|
|
||||||
buildOptionalChannel(COMMAND_CH_ID, ComponentChannelType.STRING, new TextValue(commands.toArray(new String[0])),
|
buildOptionalChannel(COMMAND_CH_ID, ComponentChannelType.STRING, new TextValue(Map.of(), commands),
|
||||||
updateListener, null, channelConfiguration.commandTopic, null, null, "Command");
|
updateListener, null, channelConfiguration.commandTopic, null, null, "Command");
|
||||||
|
|
||||||
final var fanSpeedList = channelConfiguration.fanSpeedList;
|
final var fanSpeedList = channelConfiguration.fanSpeedList;
|
||||||
@@ -188,9 +199,10 @@ public class Vacuum extends AbstractComponent<Vacuum.ChannelConfiguration> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPayloadToList(List<String> supportedFeatures, String feature, String payload, List<String> list) {
|
private void addPayloadToList(List<String> supportedFeatures, String feature, String command, String payload,
|
||||||
|
Map<String, String> commands) {
|
||||||
if (supportedFeatures.contains(feature) && !payload.isEmpty()) {
|
if (supportedFeatures.contains(feature) && !payload.isEmpty()) {
|
||||||
list.add(payload);
|
commands.put(command, payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-25
@@ -14,14 +14,11 @@ package org.openhab.binding.mqtt.homeassistant.internal.component;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
@@ -61,6 +58,15 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
private static final String POSITION_KEY = "position";
|
private static final String POSITION_KEY = "position";
|
||||||
private static final String STATE_KEY = "state";
|
private static final String STATE_KEY = "state";
|
||||||
|
|
||||||
|
public static final String PAYLOAD_OPEN = "OPEN";
|
||||||
|
public static final String PAYLOAD_CLOSE = "CLOSE";
|
||||||
|
public static final String PAYLOAD_STOP = "STOP";
|
||||||
|
|
||||||
|
public static final String STATE_OPEN = "open";
|
||||||
|
public static final String STATE_OPENING = "opening";
|
||||||
|
public static final String STATE_CLOSED = "closed";
|
||||||
|
public static final String STATE_CLOSING = "closing";
|
||||||
|
|
||||||
private static final String FORMAT_INTEGER = "%.0f";
|
private static final String FORMAT_INTEGER = "%.0f";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(Valve.class);
|
private final Logger logger = LoggerFactory.getLogger(Valve.class);
|
||||||
@@ -83,9 +89,9 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
protected String commandTopic = "";
|
protected String commandTopic = "";
|
||||||
|
|
||||||
@SerializedName("payload_close")
|
@SerializedName("payload_close")
|
||||||
protected @Nullable String payloadClose = "CLOSE";
|
protected @Nullable String payloadClose = PAYLOAD_CLOSE;
|
||||||
@SerializedName("payload_open")
|
@SerializedName("payload_open")
|
||||||
protected @Nullable String payloadOpen = "OPEN";
|
protected @Nullable String payloadOpen = PAYLOAD_OPEN;
|
||||||
@SerializedName("payload_stop")
|
@SerializedName("payload_stop")
|
||||||
protected @Nullable String payloadStop;
|
protected @Nullable String payloadStop;
|
||||||
@SerializedName("position_closed")
|
@SerializedName("position_closed")
|
||||||
@@ -95,13 +101,13 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
@SerializedName("reports_position")
|
@SerializedName("reports_position")
|
||||||
protected boolean reportsPosition = false;
|
protected boolean reportsPosition = false;
|
||||||
@SerializedName("state_closed")
|
@SerializedName("state_closed")
|
||||||
protected @Nullable String stateClosed = "closed";
|
protected @Nullable String stateClosed = STATE_CLOSED;
|
||||||
@SerializedName("state_closing")
|
@SerializedName("state_closing")
|
||||||
protected @Nullable String stateClosing = "closing";
|
protected @Nullable String stateClosing = STATE_CLOSING;
|
||||||
@SerializedName("state_open")
|
@SerializedName("state_open")
|
||||||
protected @Nullable String stateOpen = "open";
|
protected @Nullable String stateOpen = STATE_OPEN;
|
||||||
@SerializedName("state_opening")
|
@SerializedName("state_opening")
|
||||||
protected @Nullable String stateOpening = "opening";
|
protected @Nullable String stateOpening = STATE_OPENING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final OnOffValue onOffValue;
|
private final OnOffValue onOffValue;
|
||||||
@@ -137,17 +143,17 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
.withAutoUpdatePolicy(autoUpdatePolicy).build();
|
.withAutoUpdatePolicy(autoUpdatePolicy).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> commandValues = new ArrayList<>();
|
Map<String, String> commandValues = new HashMap<>();
|
||||||
addCommandValue(commandValues, channelConfiguration.payloadOpen);
|
addCommandValue(commandValues, PAYLOAD_OPEN, channelConfiguration.payloadOpen);
|
||||||
addCommandValue(commandValues, channelConfiguration.payloadClose);
|
addCommandValue(commandValues, PAYLOAD_CLOSE, channelConfiguration.payloadClose);
|
||||||
addCommandValue(commandValues, channelConfiguration.payloadStop);
|
addCommandValue(commandValues, PAYLOAD_STOP, channelConfiguration.payloadStop);
|
||||||
|
|
||||||
List<String> stateValues = new ArrayList<>();
|
Map<String, String> stateValues = new HashMap<>();
|
||||||
addCommandValue(stateValues, channelConfiguration.stateOpen);
|
addCommandValue(stateValues, channelConfiguration.stateOpen, STATE_OPEN);
|
||||||
addCommandValue(stateValues, channelConfiguration.stateOpening);
|
addCommandValue(stateValues, channelConfiguration.stateOpening, STATE_OPENING);
|
||||||
addCommandValue(stateValues, channelConfiguration.stateClosed);
|
addCommandValue(stateValues, channelConfiguration.stateClosed, STATE_CLOSED);
|
||||||
addCommandValue(stateValues, channelConfiguration.stateClosing);
|
addCommandValue(stateValues, channelConfiguration.stateClosing, STATE_CLOSING);
|
||||||
stateValue = new TextValue(stateValues.toArray(new String[0]), commandValues.toArray(new String[0]));
|
stateValue = new TextValue(stateValues, commandValues);
|
||||||
|
|
||||||
final var rawStateChannel = buildChannel(RAW_STATE_CHANNEL_ID, ComponentChannelType.STRING, new TextValue(),
|
final var rawStateChannel = buildChannel(RAW_STATE_CHANNEL_ID, ComponentChannelType.STRING, new TextValue(),
|
||||||
"State", this).stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
|
"State", this).stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
|
||||||
@@ -178,9 +184,9 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
finalizeChannels();
|
finalizeChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCommandValue(List<String> commandValues, @Nullable String command) {
|
private void addCommandValue(Map<String, String> commandValues, @Nullable String key, @Nullable String value) {
|
||||||
if (command != null) {
|
if (key != null && value != null) {
|
||||||
commandValues.add(command);
|
commandValues.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +198,7 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
// then the state gets inferred from the position if it's fully open or fully closed.
|
// then the state gets inferred from the position if it's fully open or fully closed.
|
||||||
@Override
|
@Override
|
||||||
public void updateChannelState(ChannelUID channel, State state) {
|
public void updateChannelState(ChannelUID channel, State state) {
|
||||||
Set<String> states = stateValue.getStates();
|
Map<String, String> states = stateValue.getStates();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
String statePayload = state.toString();
|
String statePayload = state.toString();
|
||||||
@@ -215,9 +221,12 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
// We have both state and position; no need to guess anything
|
// We have both state and position; no need to guess anything
|
||||||
if (channelConfiguration.reportsPosition) {
|
if (channelConfiguration.reportsPosition) {
|
||||||
if (statePayload != null) {
|
if (statePayload != null) {
|
||||||
if (states != null && !states.contains(statePayload)) {
|
if (states != null && !states.containsKey(statePayload)) {
|
||||||
logger.warn("Invalid state '{}' for {}", statePayload, getHaID().toShortTopic());
|
logger.warn("Invalid state '{}' for {}", statePayload, getHaID().toShortTopic());
|
||||||
} else {
|
} else {
|
||||||
|
if (states != null) {
|
||||||
|
statePayload = Objects.requireNonNull(states.get(statePayload));
|
||||||
|
}
|
||||||
stateValue.update(new StringType(statePayload));
|
stateValue.update(new StringType(statePayload));
|
||||||
channelStateUpdateListener.updateChannelState(buildChannelUID(STATE_CHANNEL_ID),
|
channelStateUpdateListener.updateChannelState(buildChannelUID(STATE_CHANNEL_ID),
|
||||||
stateValue.getChannelState());
|
stateValue.getChannelState());
|
||||||
@@ -241,7 +250,7 @@ public class Valve extends AbstractComponent<Valve.ChannelConfiguration> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
statePayload = Objects.requireNonNull(statePayload);
|
statePayload = Objects.requireNonNull(statePayload);
|
||||||
if (states != null && states.contains(statePayload)) {
|
if (states != null && states.containsKey(statePayload)) {
|
||||||
if (channelConfiguration.reportsPosition) {
|
if (channelConfiguration.reportsPosition) {
|
||||||
if (statePayload.equals(channelConfiguration.stateClosed)) {
|
if (statePayload.equals(channelConfiguration.stateClosed)) {
|
||||||
positionValue.update(PercentType.ZERO);
|
positionValue.update(PercentType.ZERO);
|
||||||
|
|||||||
+3
-3
@@ -78,11 +78,11 @@ public class AlarmControlPanelTests extends AbstractComponentTests {
|
|||||||
publishMessage("zigbee2mqtt/alarm/state", "armed_away");
|
publishMessage("zigbee2mqtt/alarm/state", "armed_away");
|
||||||
assertState(component, AlarmControlPanel.STATE_CHANNEL_ID, new StringType("armed_away"));
|
assertState(component, AlarmControlPanel.STATE_CHANNEL_ID, new StringType("armed_away"));
|
||||||
|
|
||||||
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("DISARM_"));
|
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("DISARM"));
|
||||||
assertPublished("zigbee2mqtt/alarm/set/state", "DISARM_");
|
assertPublished("zigbee2mqtt/alarm/set/state", "DISARM_");
|
||||||
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("ARM_AWAY_"));
|
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("ARM_AWAY"));
|
||||||
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_AWAY_");
|
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_AWAY_");
|
||||||
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("ARM_HOME_"));
|
component.getChannel(AlarmControlPanel.STATE_CHANNEL_ID).getState().publishValue(new StringType("ARM_HOME"));
|
||||||
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_HOME_");
|
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_HOME_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+38
@@ -71,6 +71,44 @@ public class ButtonTests extends AbstractComponentTests {
|
|||||||
assertPublished("esphome/single-car-gdo/button/restart/command", "PRESS");
|
assertPublished("esphome/single-car-gdo/button/restart/command", "PRESS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("null")
|
||||||
|
@Test
|
||||||
|
public void testButtonWithCustomPayload() {
|
||||||
|
var component = discoverComponent(configTopicToMqtt(CONFIG_TOPIC), """
|
||||||
|
{
|
||||||
|
"dev_cla":"restart",
|
||||||
|
"name":"Restart",
|
||||||
|
"entity_category":"config",
|
||||||
|
"cmd_t":"esphome/single-car-gdo/button/restart/command",
|
||||||
|
"avty_t":"esphome/single-car-gdo/status",
|
||||||
|
"uniq_id":"78e36d645710-button-ba0e8e32",
|
||||||
|
"payload_press": "restart",
|
||||||
|
"dev":{
|
||||||
|
"ids":"78e36d645710",
|
||||||
|
"name":"Single Car Garage Door Opener",
|
||||||
|
"sw":"esphome v2023.10.4 Nov 1 2023, 09:27:02",
|
||||||
|
"mdl":"esp32dev",
|
||||||
|
"mf":"espressif"}
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
assertThat(component.channels.size(), is(1));
|
||||||
|
assertThat(component.getName(), is("Restart"));
|
||||||
|
|
||||||
|
assertChannel(component, Button.BUTTON_CHANNEL_ID, "", "esphome/single-car-gdo/button/restart/command",
|
||||||
|
"Restart", TextValue.class);
|
||||||
|
assertThat(Objects.requireNonNull(component.getChannel(Button.BUTTON_CHANNEL_ID)).getChannel()
|
||||||
|
.getAutoUpdatePolicy(), is(AutoUpdatePolicy.VETO));
|
||||||
|
|
||||||
|
linkAllChannels(component);
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException.class,
|
||||||
|
() -> component.getChannel(Button.BUTTON_CHANNEL_ID).getState().publishValue(new StringType("ON")));
|
||||||
|
assertNothingPublished("esphome/single-car-gdo/button/restart/command");
|
||||||
|
component.getChannel(Button.BUTTON_CHANNEL_ID).getState().publishValue(new StringType("PRESS"));
|
||||||
|
assertPublished("esphome/single-car-gdo/button/restart/command", "restart");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<String> getConfigTopics() {
|
protected Set<String> getConfigTopics() {
|
||||||
return Set.of(CONFIG_TOPIC);
|
return Set.of(CONFIG_TOPIC);
|
||||||
|
|||||||
+4
-3
@@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -119,11 +120,11 @@ public class DeviceTriggerTests extends AbstractComponentTests {
|
|||||||
|
|
||||||
ComponentChannel channel = Objects.requireNonNull(component1.getChannel("turn_on"));
|
ComponentChannel channel = Objects.requireNonNull(component1.getChannel("turn_on"));
|
||||||
TextValue value = (TextValue) channel.getState().getCache();
|
TextValue value = (TextValue) channel.getState().getCache();
|
||||||
Set<String> payloads = value.getStates();
|
Map<String, String> payloads = value.getStates();
|
||||||
assertNotNull(payloads);
|
assertNotNull(payloads);
|
||||||
assertThat(payloads.size(), is(2));
|
assertThat(payloads.size(), is(2));
|
||||||
assertThat(payloads.contains("press"), is(true));
|
assertThat(payloads.containsKey("press"), is(true));
|
||||||
assertThat(payloads.contains("release"), is(true));
|
assertThat(payloads.containsKey("release"), is(true));
|
||||||
Configuration channelConfig = channel.getChannel().getConfiguration();
|
Configuration channelConfig = channel.getChannel().getConfiguration();
|
||||||
Object config = channelConfig.get("config");
|
Object config = channelConfig.get("config");
|
||||||
assertNotNull(config);
|
assertNotNull(config);
|
||||||
|
|||||||
+11
-11
@@ -75,10 +75,10 @@ public class LockTests extends AbstractComponentTests {
|
|||||||
linkAllChannels(component);
|
linkAllChannels(component);
|
||||||
|
|
||||||
publishMessage("zigbee2mqtt/lock/state", "LOCKED_");
|
publishMessage("zigbee2mqtt/lock/state", "LOCKED_");
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
||||||
publishMessage("zigbee2mqtt/lock/state", "UNLOCKED_");
|
publishMessage("zigbee2mqtt/lock/state", "UNLOCKED_");
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
||||||
publishMessage("zigbee2mqtt/lock/state", "JAMMED");
|
publishMessage("zigbee2mqtt/lock/state", "JAMMED");
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("JAMMED"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("JAMMED"));
|
||||||
@@ -88,26 +88,26 @@ public class LockTests extends AbstractComponentTests {
|
|||||||
|
|
||||||
component.getChannel(Lock.LOCK_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
|
component.getChannel(Lock.LOCK_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
|
||||||
assertPublished("zigbee2mqtt/lock/set/state", "UNLOCK_");
|
assertPublished("zigbee2mqtt/lock/set/state", "UNLOCK_");
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
||||||
component.getChannel(Lock.LOCK_CHANNEL_ID).getState().publishValue(OnOffType.ON);
|
component.getChannel(Lock.LOCK_CHANNEL_ID).getState().publishValue(OnOffType.ON);
|
||||||
assertPublished("zigbee2mqtt/lock/set/state", "LOCK_");
|
assertPublished("zigbee2mqtt/lock/set/state", "LOCK_");
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
||||||
component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("UNLOCK_"));
|
component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("UNLOCK"));
|
||||||
assertPublished("zigbee2mqtt/lock/set/state", "UNLOCK_", 2);
|
assertPublished("zigbee2mqtt/lock/set/state", "UNLOCK_", 2);
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("UNLOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.OFF);
|
||||||
component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("LOCK_"));
|
component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("LOCK"));
|
||||||
assertPublished("zigbee2mqtt/lock/set/state", "LOCK_", 2);
|
assertPublished("zigbee2mqtt/lock/set/state", "LOCK_", 2);
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
||||||
|
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("LOCK")));
|
() -> component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("LOCK_")));
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("OPEN")));
|
() -> component.getChannel(Lock.STATE_CHANNEL_ID).getState().publishValue(new StringType("OPEN_")));
|
||||||
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED_"));
|
assertState(component, Lock.STATE_CHANNEL_ID, new StringType("LOCKED"));
|
||||||
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
assertState(component, Lock.LOCK_CHANNEL_ID, OnOffType.ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user