private final String label;
private final ChannelStateUpdateListener channelStateUpdateListener;
- private @Nullable String state_topic;
- private @Nullable String command_topic;
+ private @Nullable String stateTopic;
+ private @Nullable String commandTopic;
private boolean retain;
private boolean trigger;
private @Nullable Integer qos;
this.channelStateUpdateListener = channelStateUpdateListener;
}
- public Builder stateTopic(@Nullable String state_topic) {
- this.state_topic = state_topic;
+ public Builder stateTopic(@Nullable String stateTopic) {
+ this.stateTopic = stateTopic;
return this;
}
- public Builder stateTopic(@Nullable String state_topic, @Nullable String... templates) {
- this.state_topic = state_topic;
- if (state_topic != null && !state_topic.isBlank()) {
+ public Builder stateTopic(@Nullable String stateTopic, @Nullable String... templates) {
+ this.stateTopic = stateTopic;
+ if (stateTopic != null && !stateTopic.isBlank()) {
for (String template : templates) {
if (template != null && !template.isBlank()) {
this.templateIn = template;
/**
* @deprecated use commandTopic(String, boolean, int)
- * @param command_topic topic
+ * @param commandTopic topic
* @param retain retain
* @return this
*/
@Deprecated
- public Builder commandTopic(@Nullable String command_topic, boolean retain) {
- this.command_topic = command_topic;
+ public Builder commandTopic(@Nullable String commandTopic, boolean retain) {
+ this.commandTopic = commandTopic;
this.retain = retain;
return this;
}
- public Builder commandTopic(@Nullable String command_topic, boolean retain, int qos) {
- return commandTopic(command_topic, retain, qos, null);
+ public Builder commandTopic(@Nullable String commandTopic, boolean retain, int qos) {
+ return commandTopic(commandTopic, retain, qos, null);
}
- public Builder commandTopic(@Nullable String command_topic, boolean retain, int qos,
- @Nullable String template) {
- this.command_topic = command_topic;
+ public Builder commandTopic(@Nullable String commandTopic, boolean retain, int qos, @Nullable String template) {
+ this.commandTopic = commandTopic;
this.retain = retain;
this.qos = qos;
- if (command_topic != null && !command_topic.isBlank()) {
+ if (commandTopic != null && !commandTopic.isBlank()) {
this.templateOut = template;
}
return this;
channelTypeUID = new ChannelTypeUID(MqttBindingConstants.BINDING_ID,
channelUID.getGroupId() + "_" + channelID);
channelState = new HomeAssistantChannelState(
- ChannelConfigBuilder.create().withRetain(retain).withQos(qos).withStateTopic(state_topic)
- .withCommandTopic(command_topic).makeTrigger(trigger).build(),
+ ChannelConfigBuilder.create().withRetain(retain).withQos(qos).withStateTopic(stateTopic)
+ .withCommandTopic(commandTopic).makeTrigger(trigger).build(),
channelUID, valueState, channelStateUpdateListener, commandFilter);
- String localStateTopic = state_topic;
+ String localStateTopic = stateTopic;
if (localStateTopic == null || localStateTopic.isBlank() || this.trigger) {
type = ChannelTypeBuilder.trigger(channelTypeUID, label)
.withConfigDescriptionURI(URI.create(MqttBindingConstants.CONFIG_HA_CHANNEL)).build();
} else {
- StateDescriptionFragment description = valueState.createStateDescription(command_topic == null).build();
+ StateDescriptionFragment description = valueState.createStateDescription(commandTopic == null).build();
type = ChannelTypeBuilder.state(channelTypeUID, label, channelState.getItemType())
.withConfigDescriptionURI(URI.create(MqttBindingConstants.CONFIG_HA_CHANNEL))
.withStateDescriptionFragment(description).build();
if (!nodeID.equals(other.nodeID)) {
return false;
}
- if (!objectID.equals(other.objectID)) {
- return false;
- }
- return true;
+ return objectID.equals(other.objectID);
}
@Override
this.configSeen = false;
- String availability_topic = this.channelConfiguration.getAvailabilityTopic();
- if (availability_topic != null) {
- componentConfiguration.getTracker().addAvailabilityTopic(availability_topic,
+ String availabilityTopic = this.channelConfiguration.getAvailabilityTopic();
+ if (availabilityTopic != null) {
+ componentConfiguration.getTracker().addAvailabilityTopic(availabilityTopic,
this.channelConfiguration.getPayloadAvailable(),
this.channelConfiguration.getPayloadNotAvailable());
}
/**
* Return a components channel. A HomeAssistant MQTT component consists of multiple functions
* and those are mapped to one or more channels. The channel IDs are constants within the
- * derived Component, like the {@link Switch#switchChannelID}.
+ * derived Component, like the {@link Switch#SWITCH_CHANNEL_ID}.
*
* @param channelID The channel ID
* @return A components channel
import org.openhab.binding.mqtt.generic.values.TextValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT alarm control panel, following the https://www.home-assistant.io/components/alarm_control_panel.mqtt/
* specification.
*/
@NonNullByDefault
public class AlarmControlPanel extends AbstractComponent<AlarmControlPanel.ChannelConfiguration> {
- public static final String stateChannelID = "alarm"; // Randomly chosen channel "ID"
- public static final String switchDisarmChannelID = "disarm"; // Randomly chosen channel "ID"
- public static final String switchArmHomeChannelID = "armhome"; // Randomly chosen channel "ID"
- public static final String switchArmAwayChannelID = "armaway"; // Randomly chosen channel "ID"
+ public static final String STATE_CHANNEL_ID = "alarm"; // Randomly chosen channel "ID"
+ public static final String SWITCH_DISARM_CHANNEL_ID = "disarm"; // Randomly chosen channel "ID"
+ public static final String SWITCH_ARM_HOME_CHANNEL_ID = "armhome"; // Randomly chosen channel "ID"
+ public static final String SWITCH_ARM_AWAY_CHANNEL_ID = "armaway"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
protected @Nullable String code;
- protected String state_topic = "";
- protected String state_disarmed = "disarmed";
- protected String state_armed_home = "armed_home";
- protected String state_armed_away = "armed_away";
- protected String state_pending = "pending";
- protected String state_triggered = "triggered";
+ @SerializedName("state_topic")
+ protected String stateTopic = "";
+ @SerializedName("state_disarmed")
+ protected String stateDisarmed = "disarmed";
+ @SerializedName("state_armed_home")
+ protected String stateArmedHome = "armed_home";
+ @SerializedName("state_armed_away")
+ protected String stateArmedAway = "armed_away";
+ @SerializedName("state_pending")
+ protected String statePending = "pending";
+ @SerializedName("state_triggered")
+ protected String stateTriggered = "triggered";
- protected @Nullable String command_topic;
- protected String payload_disarm = "DISARM";
- protected String payload_arm_home = "ARM_HOME";
- protected String payload_arm_away = "ARM_AWAY";
+ @SerializedName("command_topic")
+ protected @Nullable String commandTopic;
+ @SerializedName("payload_disarm")
+ protected String payloadDisarm = "DISARM";
+ @SerializedName("payload_arm_home")
+ protected String payloadArmHome = "ARM_HOME";
+ @SerializedName("payload_arm_away")
+ protected String payloadArmAway = "ARM_AWAY";
}
public AlarmControlPanel(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
- final String[] state_enum = { channelConfiguration.state_disarmed, channelConfiguration.state_armed_home,
- channelConfiguration.state_armed_away, channelConfiguration.state_pending,
- channelConfiguration.state_triggered };
- buildChannel(stateChannelID, new TextValue(state_enum), channelConfiguration.getName(),
+ final String[] stateEnum = { channelConfiguration.stateDisarmed, channelConfiguration.stateArmedHome,
+ channelConfiguration.stateArmedAway, channelConfiguration.statePending,
+ channelConfiguration.stateTriggered };
+ buildChannel(STATE_CHANNEL_ID, new TextValue(stateEnum), channelConfiguration.getName(),
componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())//
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())//
.build();
- String command_topic = channelConfiguration.command_topic;
- if (command_topic != null) {
- buildChannel(switchDisarmChannelID, new TextValue(new String[] { channelConfiguration.payload_disarm }),
+ String commandTopic = channelConfiguration.commandTopic;
+ if (commandTopic != null) {
+ buildChannel(SWITCH_DISARM_CHANNEL_ID, new TextValue(new String[] { channelConfiguration.payloadDisarm }),
channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .commandTopic(command_topic, channelConfiguration.isRetain(), channelConfiguration.getQos())
+ .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos())
.build();
- buildChannel(switchArmHomeChannelID, new TextValue(new String[] { channelConfiguration.payload_arm_home }),
- channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .commandTopic(command_topic, channelConfiguration.isRetain(), channelConfiguration.getQos())
+ buildChannel(SWITCH_ARM_HOME_CHANNEL_ID,
+ new TextValue(new String[] { channelConfiguration.payloadArmHome }), channelConfiguration.getName(),
+ componentConfiguration.getUpdateListener())
+ .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos())
.build();
- buildChannel(switchArmAwayChannelID, new TextValue(new String[] { channelConfiguration.payload_arm_away }),
- channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .commandTopic(command_topic, channelConfiguration.isRetain(), channelConfiguration.getQos())
+ buildChannel(SWITCH_ARM_AWAY_CHANNEL_ID,
+ new TextValue(new String[] { channelConfiguration.payloadArmAway }), channelConfiguration.getName(),
+ componentConfiguration.getUpdateListener())
+ .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos())
.build();
}
}
import org.openhab.binding.mqtt.homeassistant.internal.listener.ExpireUpdateStateListener;
import org.openhab.binding.mqtt.homeassistant.internal.listener.OffDelayUpdateStateListener;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT BinarySensor, following the https://www.home-assistant.io/components/binary_sensor.mqtt/ specification.
*
*/
@NonNullByDefault
public class BinarySensor extends AbstractComponent<BinarySensor.ChannelConfiguration> {
- public static final String sensorChannelID = "sensor"; // Randomly chosen channel "ID"
+ public static final String SENSOR_CHANNEL_ID = "sensor"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
super("MQTT Binary Sensor");
}
- protected @Nullable String device_class;
- protected boolean force_update = false;
- protected @Nullable Integer expire_after;
- protected @Nullable Integer off_delay;
+ @SerializedName("device_class")
+ protected @Nullable String deviceClass;
+ @SerializedName("force_update")
+ protected boolean forceUpdate = false;
+ @SerializedName("expire_after")
+ protected @Nullable Integer expireAfter;
+ @SerializedName("off_delay")
+ protected @Nullable Integer offDelay;
- protected String state_topic = "";
- protected String payload_on = "ON";
- protected String payload_off = "OFF";
+ @SerializedName("state_topic")
+ protected String stateTopic = "";
+ @SerializedName("payload_on")
+ protected String payloadOn = "ON";
+ @SerializedName("payload_off")
+ protected String payloadOff = "OFF";
- protected @Nullable String json_attributes_topic;
- protected @Nullable String json_attributes_template;
- protected @Nullable List<String> json_attributes;
+ @SerializedName("json_attributes_topic")
+ protected @Nullable String jsonAttributesTopic;
+ @SerializedName("json_attributes_template")
+ protected @Nullable String jsonAttributesTemplate;
+ @SerializedName("json_attributes")
+ protected @Nullable List<String> jsonAttributes;
}
public BinarySensor(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
- OnOffValue value = new OnOffValue(channelConfiguration.payload_on, channelConfiguration.payload_off);
+ OnOffValue value = new OnOffValue(channelConfiguration.payloadOn, channelConfiguration.payloadOff);
- buildChannel(sensorChannelID, value, "value", getListener(componentConfiguration, value))
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate()).build();
+ buildChannel(SENSOR_CHANNEL_ID, value, "value", getListener(componentConfiguration, value))
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()).build();
}
private ChannelStateUpdateListener getListener(ComponentFactory.ComponentConfiguration componentConfiguration,
Value value) {
ChannelStateUpdateListener updateListener = componentConfiguration.getUpdateListener();
- if (channelConfiguration.expire_after != null) {
- updateListener = new ExpireUpdateStateListener(updateListener, channelConfiguration.expire_after, value,
+ if (channelConfiguration.expireAfter != null) {
+ updateListener = new ExpireUpdateStateListener(updateListener, channelConfiguration.expireAfter, value,
componentConfiguration.getTracker(), componentConfiguration.getScheduler());
}
- if (channelConfiguration.off_delay != null) {
- updateListener = new OffDelayUpdateStateListener(updateListener, channelConfiguration.off_delay, value,
+ if (channelConfiguration.offDelay != null) {
+ updateListener = new OffDelayUpdateStateListener(updateListener, channelConfiguration.offDelay, value,
componentConfiguration.getScheduler());
}
*/
@NonNullByDefault
public class Camera extends AbstractComponent<Camera.ChannelConfiguration> {
- public static final String cameraChannelID = "camera"; // Randomly chosen channel "ID"
+ public static final String CAMERA_CHANNEL_ID = "camera"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
ImageValue value = new ImageValue();
- buildChannel(cameraChannelID, value, channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.topic).build();
+ buildChannel(CAMERA_CHANNEL_ID, value, channelConfiguration.getName(),
+ componentConfiguration.getUpdateListener()).stateTopic(channelConfiguration.topic).build();
}
}
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT climate component, following the https://www.home-assistant.io/components/climate.mqtt/ specification.
*
super("MQTT HVAC");
}
- protected @Nullable String action_template;
- protected @Nullable String action_topic;
-
- protected @Nullable String aux_command_topic;
- protected @Nullable String aux_state_template;
- protected @Nullable String aux_state_topic;
-
- protected @Nullable String away_mode_command_topic;
- protected @Nullable String away_mode_state_template;
- protected @Nullable String away_mode_state_topic;
-
- protected @Nullable String current_temperature_template;
- protected @Nullable String current_temperature_topic;
-
- protected @Nullable String fan_mode_command_template;
- protected @Nullable String fan_mode_command_topic;
- protected @Nullable String fan_mode_state_template;
- protected @Nullable String fan_mode_state_topic;
- protected List<String> fan_modes = Arrays.asList("auto", "low", "medium", "high");
-
- protected @Nullable String hold_command_template;
- protected @Nullable String hold_command_topic;
- protected @Nullable String hold_state_template;
- protected @Nullable String hold_state_topic;
- protected @Nullable List<String> hold_modes; // Are there default modes? Now the channel will be ignored without
- // hold modes.
-
- protected @Nullable String json_attributes_template; // Attributes are not supported yet
- protected @Nullable String json_attributes_topic;
-
- protected @Nullable String mode_command_template;
- protected @Nullable String mode_command_topic;
- protected @Nullable String mode_state_template;
- protected @Nullable String mode_state_topic;
+ @SerializedName("action_template")
+ protected @Nullable String actionTemplate;
+ @SerializedName("action_topic")
+ protected @Nullable String actionTopic;
+
+ @SerializedName("aux_command_topic")
+ protected @Nullable String auxCommandTopic;
+ @SerializedName("aux_state_template")
+ protected @Nullable String auxStateTemplate;
+ @SerializedName("aux_state_topic")
+ protected @Nullable String auxStateTopic;
+
+ @SerializedName("away_mode_command_topic")
+ protected @Nullable String awayModeCommandTopic;
+ @SerializedName("away_mode_state_template")
+ protected @Nullable String awayModeStateTemplate;
+ @SerializedName("away_mode_state_topic")
+ protected @Nullable String awayModeStateTopic;
+
+ @SerializedName("current_temperature_template")
+ protected @Nullable String currentTemperatureTemplate;
+ @SerializedName("current_temperature_topic")
+ protected @Nullable String currentTemperatureTopic;
+
+ @SerializedName("fan_mode_command_template")
+ protected @Nullable String fanModeCommandTemplate;
+ @SerializedName("fan_mode_command_topic")
+ protected @Nullable String fanModeCommandTopic;
+ @SerializedName("fan_mode_state_template")
+ protected @Nullable String fanModeStateTemplate;
+ @SerializedName("fan_mode_state_topic")
+ protected @Nullable String fanModeStateTopic;
+ @SerializedName("fan_modes")
+ protected List<String> fanModes = Arrays.asList("auto", "low", "medium", "high");
+
+ @SerializedName("hold_command_template")
+ protected @Nullable String holdCommandTemplate;
+ @SerializedName("hold_command_topic")
+ protected @Nullable String holdCommandTopic;
+ @SerializedName("hold_state_template")
+ protected @Nullable String holdStateTemplate;
+ @SerializedName("hold_state_topic")
+ protected @Nullable String holdStateTopic;
+ @SerializedName("hold_modes")
+ protected @Nullable List<String> holdModes; // Are there default modes? Now the channel will be ignored without
+ // hold modes.
+
+ @SerializedName("json_attributes_template")
+ protected @Nullable String jsonAttributesTemplate; // Attributes are not supported yet
+ @SerializedName("json_attributes_topic")
+ protected @Nullable String jsonAttributesTopic;
+
+ @SerializedName("mode_command_template")
+ protected @Nullable String modeCommandTemplate;
+ @SerializedName("mode_command_topic")
+ protected @Nullable String modeCommandTopic;
+ @SerializedName("mode_state_template")
+ protected @Nullable String modeStateTemplate;
+ @SerializedName("mode_state_topic")
+ protected @Nullable String modeStateTopic;
protected List<String> modes = Arrays.asList("auto", "off", "cool", "heat", "dry", "fan_only");
- protected @Nullable String swing_command_template;
- protected @Nullable String swing_command_topic;
- protected @Nullable String swing_state_template;
- protected @Nullable String swing_state_topic;
- protected List<String> swing_modes = Arrays.asList("on", "off");
-
- protected @Nullable String temperature_command_template;
- protected @Nullable String temperature_command_topic;
- protected @Nullable String temperature_state_template;
- protected @Nullable String temperature_state_topic;
-
- protected @Nullable String temperature_high_command_template;
- protected @Nullable String temperature_high_command_topic;
- protected @Nullable String temperature_high_state_template;
- protected @Nullable String temperature_high_state_topic;
-
- protected @Nullable String temperature_low_command_template;
- protected @Nullable String temperature_low_command_topic;
- protected @Nullable String temperature_low_state_template;
- protected @Nullable String temperature_low_state_topic;
-
- protected @Nullable String power_command_topic;
+ @SerializedName("swing_command_template")
+ protected @Nullable String swingCommandTemplate;
+ @SerializedName("swing_command_topic")
+ protected @Nullable String swingCommandTopic;
+ @SerializedName("swing_state_template")
+ protected @Nullable String swingStateTemplate;
+ @SerializedName("swing_state_topic")
+ protected @Nullable String swingStateTopic;
+ @SerializedName("swing_modes")
+ protected List<String> swingModes = Arrays.asList("on", "off");
+
+ @SerializedName("temperature_command_template")
+ protected @Nullable String temperatureCommandTemplate;
+ @SerializedName("temperature_command_topic")
+ protected @Nullable String temperatureCommandTopic;
+ @SerializedName("temperature_state_template")
+ protected @Nullable String temperatureStateTemplate;
+ @SerializedName("temperature_state_topic")
+ protected @Nullable String temperatureStateTopic;
+
+ @SerializedName("temperature_high_command_template")
+ protected @Nullable String temperatureHighCommandTemplate;
+ @SerializedName("temperature_high_command_topic")
+ protected @Nullable String temperatureHighCommandTopic;
+ @SerializedName("temperature_high_state_template")
+ protected @Nullable String temperatureHighStateTemplate;
+ @SerializedName("temperature_high_state_topic")
+ protected @Nullable String temperatureHighStateTopic;
+
+ @SerializedName("temperature_low_command_template")
+ protected @Nullable String temperatureLowCommandTemplate;
+ @SerializedName("temperature_low_command_topic")
+ protected @Nullable String temperatureLowCommandTopic;
+ @SerializedName("temperature_low_state_template")
+ protected @Nullable String temperatureLowStateTemplate;
+ @SerializedName("temperature_low_state_topic")
+ protected @Nullable String temperatureLowStateTopic;
+
+ @SerializedName("power_command_topic")
+ protected @Nullable String powerCommandTopic;
protected Integer initial = 21;
- protected @Nullable Float max_temp;
- protected @Nullable Float min_temp;
- protected String temperature_unit = CELSIUM; // System unit by default
- protected Float temp_step = 1f;
+ @SerializedName("max_temp")
+ protected @Nullable Float maxTemp;
+ @SerializedName("min_temp")
+ protected @Nullable Float minTemp;
+ @SerializedName("temperature_unit")
+ protected String temperatureUnit = CELSIUM; // System unit by default
+ @SerializedName("temp_step")
+ protected Float tempStep = 1f;
protected @Nullable Float precision;
- protected Boolean send_if_off = true;
+ @SerializedName("send_if_off")
+ protected Boolean sendIfOff = true;
}
public Climate(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
- BigDecimal minTemp = channelConfiguration.min_temp != null ? BigDecimal.valueOf(channelConfiguration.min_temp)
+ BigDecimal minTemp = channelConfiguration.minTemp != null ? BigDecimal.valueOf(channelConfiguration.minTemp)
: null;
- BigDecimal maxTemp = channelConfiguration.max_temp != null ? BigDecimal.valueOf(channelConfiguration.max_temp)
+ BigDecimal maxTemp = channelConfiguration.maxTemp != null ? BigDecimal.valueOf(channelConfiguration.maxTemp)
: null;
float precision = channelConfiguration.precision != null ? channelConfiguration.precision
- : (FAHRENHEIT.equals(channelConfiguration.temperature_unit) ? DEFAULT_FAHRENHEIT_PRECISION
+ : (FAHRENHEIT.equals(channelConfiguration.temperatureUnit) ? DEFAULT_FAHRENHEIT_PRECISION
: DEFAULT_CELSIUM_PRECISION);
final ChannelStateUpdateListener updateListener = componentConfiguration.getUpdateListener();
ComponentChannel actionChannel = buildOptionalChannel(ACTION_CH_ID,
new TextValue(ACTION_MODES.toArray(new String[0])), updateListener, null, null,
- channelConfiguration.action_template, channelConfiguration.action_topic, null);
+ channelConfiguration.actionTemplate, channelConfiguration.actionTopic, null);
- final Predicate<Command> commandFilter = channelConfiguration.send_if_off ? null
+ final Predicate<Command> commandFilter = channelConfiguration.sendIfOff ? null
: getCommandFilter(actionChannel);
- buildOptionalChannel(AUX_CH_ID, new OnOffValue(), updateListener, null, channelConfiguration.aux_command_topic,
- channelConfiguration.aux_state_template, channelConfiguration.aux_state_topic, commandFilter);
+ buildOptionalChannel(AUX_CH_ID, new OnOffValue(), updateListener, null, channelConfiguration.auxCommandTopic,
+ channelConfiguration.auxStateTemplate, channelConfiguration.auxStateTopic, commandFilter);
buildOptionalChannel(AWAY_MODE_CH_ID, new OnOffValue(), updateListener, null,
- channelConfiguration.away_mode_command_topic, channelConfiguration.away_mode_state_template,
- channelConfiguration.away_mode_state_topic, commandFilter);
+ channelConfiguration.awayModeCommandTopic, channelConfiguration.awayModeStateTemplate,
+ channelConfiguration.awayModeStateTopic, commandFilter);
buildOptionalChannel(CURRENT_TEMPERATURE_CH_ID,
- new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(precision), channelConfiguration.temperature_unit),
- updateListener, null, null, channelConfiguration.current_temperature_template,
- channelConfiguration.current_temperature_topic, commandFilter);
-
- buildOptionalChannel(FAN_MODE_CH_ID, new TextValue(channelConfiguration.fan_modes.toArray(new String[0])),
- updateListener, channelConfiguration.fan_mode_command_template,
- channelConfiguration.fan_mode_command_topic, channelConfiguration.fan_mode_state_template,
- channelConfiguration.fan_mode_state_topic, commandFilter);
-
- if (channelConfiguration.hold_modes != null && !channelConfiguration.hold_modes.isEmpty()) {
- buildOptionalChannel(HOLD_CH_ID, new TextValue(channelConfiguration.hold_modes.toArray(new String[0])),
- updateListener, channelConfiguration.hold_command_template, channelConfiguration.hold_command_topic,
- channelConfiguration.hold_state_template, channelConfiguration.hold_state_topic, commandFilter);
+ new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(precision), channelConfiguration.temperatureUnit),
+ updateListener, null, null, channelConfiguration.currentTemperatureTemplate,
+ channelConfiguration.currentTemperatureTopic, commandFilter);
+
+ buildOptionalChannel(FAN_MODE_CH_ID, new TextValue(channelConfiguration.fanModes.toArray(new String[0])),
+ updateListener, channelConfiguration.fanModeCommandTemplate, channelConfiguration.fanModeCommandTopic,
+ channelConfiguration.fanModeStateTemplate, channelConfiguration.fanModeStateTopic, commandFilter);
+
+ if (channelConfiguration.holdModes != null && !channelConfiguration.holdModes.isEmpty()) {
+ buildOptionalChannel(HOLD_CH_ID, new TextValue(channelConfiguration.holdModes.toArray(new String[0])),
+ updateListener, channelConfiguration.holdCommandTemplate, channelConfiguration.holdCommandTopic,
+ channelConfiguration.holdStateTemplate, channelConfiguration.holdStateTopic, commandFilter);
}
buildOptionalChannel(MODE_CH_ID, new TextValue(channelConfiguration.modes.toArray(new String[0])),
- updateListener, channelConfiguration.mode_command_template, channelConfiguration.mode_command_topic,
- channelConfiguration.mode_state_template, channelConfiguration.mode_state_topic, commandFilter);
+ updateListener, channelConfiguration.modeCommandTemplate, channelConfiguration.modeCommandTopic,
+ channelConfiguration.modeStateTemplate, channelConfiguration.modeStateTopic, commandFilter);
- buildOptionalChannel(SWING_CH_ID, new TextValue(channelConfiguration.swing_modes.toArray(new String[0])),
- updateListener, channelConfiguration.swing_command_template, channelConfiguration.swing_command_topic,
- channelConfiguration.swing_state_template, channelConfiguration.swing_state_topic, commandFilter);
+ buildOptionalChannel(SWING_CH_ID, new TextValue(channelConfiguration.swingModes.toArray(new String[0])),
+ updateListener, channelConfiguration.swingCommandTemplate, channelConfiguration.swingCommandTopic,
+ channelConfiguration.swingStateTemplate, channelConfiguration.swingStateTopic, commandFilter);
buildOptionalChannel(TEMPERATURE_CH_ID,
- new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.temp_step),
- channelConfiguration.temperature_unit),
- updateListener, channelConfiguration.temperature_command_template,
- channelConfiguration.temperature_command_topic, channelConfiguration.temperature_state_template,
- channelConfiguration.temperature_state_topic, commandFilter);
+ new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.tempStep),
+ channelConfiguration.temperatureUnit),
+ updateListener, channelConfiguration.temperatureCommandTemplate,
+ channelConfiguration.temperatureCommandTopic, channelConfiguration.temperatureStateTemplate,
+ channelConfiguration.temperatureStateTopic, commandFilter);
buildOptionalChannel(TEMPERATURE_HIGH_CH_ID,
- new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.temp_step),
- channelConfiguration.temperature_unit),
- updateListener, channelConfiguration.temperature_high_command_template,
- channelConfiguration.temperature_high_command_topic,
- channelConfiguration.temperature_high_state_template, channelConfiguration.temperature_high_state_topic,
- commandFilter);
+ new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.tempStep),
+ channelConfiguration.temperatureUnit),
+ updateListener, channelConfiguration.temperatureHighCommandTemplate,
+ channelConfiguration.temperatureHighCommandTopic, channelConfiguration.temperatureHighStateTemplate,
+ channelConfiguration.temperatureHighStateTopic, commandFilter);
buildOptionalChannel(TEMPERATURE_LOW_CH_ID,
- new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.temp_step),
- channelConfiguration.temperature_unit),
- updateListener, channelConfiguration.temperature_low_command_template,
- channelConfiguration.temperature_low_command_topic, channelConfiguration.temperature_low_state_template,
- channelConfiguration.temperature_low_state_topic, commandFilter);
+ new NumberValue(minTemp, maxTemp, BigDecimal.valueOf(channelConfiguration.tempStep),
+ channelConfiguration.temperatureUnit),
+ updateListener, channelConfiguration.temperatureLowCommandTemplate,
+ channelConfiguration.temperatureLowCommandTopic, channelConfiguration.temperatureLowStateTemplate,
+ channelConfiguration.temperatureLowStateTopic, commandFilter);
buildOptionalChannel(POWER_CH_ID, new OnOffValue(), updateListener, null,
- channelConfiguration.power_command_topic, null, null, null);
+ channelConfiguration.powerCommandTopic, null, null, null);
}
@Nullable
*/
@NonNullByDefault
public class ComponentFactory {
- private static final Logger logger = LoggerFactory.getLogger(ComponentFactory.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(ComponentFactory.class);
/**
* Create a HA MQTT component. The configuration JSon string is required.
return new Switch(componentConfiguration);
}
} catch (UnsupportedOperationException e) {
- logger.warn("Not supported", e);
+ LOGGER.warn("Not supported", e);
}
return null;
}
import org.openhab.binding.mqtt.generic.values.RollershutterValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT Cover component, following the https://www.home-assistant.io/components/cover.mqtt/ specification.
*
*/
@NonNullByDefault
public class Cover extends AbstractComponent<Cover.ChannelConfiguration> {
- public static final String switchChannelID = "cover"; // Randomly chosen channel "ID"
+ public static final String SWITCH_CHANNEL_ID = "cover"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
super("MQTT Cover");
}
- protected @Nullable String state_topic;
- protected @Nullable String command_topic;
- protected String payload_open = "OPEN";
- protected String payload_close = "CLOSE";
- protected String payload_stop = "STOP";
+ @SerializedName("state_topic")
+ protected @Nullable String stateTopic;
+ @SerializedName("command_topic")
+ protected @Nullable String commandTopic;
+ @SerializedName("payload_open")
+ protected String payloadOpen = "OPEN";
+ @SerializedName("payload_close")
+ protected String payloadClose = "CLOSE";
+ @SerializedName("payload_stop")
+ protected String payloadStop = "STOP";
}
public Cover(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
- RollershutterValue value = new RollershutterValue(channelConfiguration.payload_open,
- channelConfiguration.payload_close, channelConfiguration.payload_stop);
+ RollershutterValue value = new RollershutterValue(channelConfiguration.payloadOpen,
+ channelConfiguration.payloadClose, channelConfiguration.payloadStop);
- buildChannel(switchChannelID, value, channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())
- .commandTopic(channelConfiguration.command_topic, channelConfiguration.isRetain(),
- channelConfiguration.getQos())
- .build();
+ buildChannel(SWITCH_CHANNEL_ID, value, channelConfiguration.getName(),
+ componentConfiguration.getUpdateListener())
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
+ .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
+ channelConfiguration.getQos())
+ .build();
}
}
import org.openhab.binding.mqtt.generic.values.OnOffValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT Fan component, following the https://www.home-assistant.io/components/fan.mqtt/ specification.
*
*/
@NonNullByDefault
public class Fan extends AbstractComponent<Fan.ChannelConfiguration> {
- public static final String switchChannelID = "fan"; // Randomly chosen channel "ID"
+ public static final String SWITCH_CHANNEL_ID = "fan"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
super("MQTT Fan");
}
- protected @Nullable String state_topic;
- protected String command_topic = "";
- protected String payload_on = "ON";
- protected String payload_off = "OFF";
+ @SerializedName("state_topic")
+ protected @Nullable String stateTopic;
+ @SerializedName("command_topic")
+ protected String commandTopic = "";
+ @SerializedName("payload_on")
+ protected String payloadOn = "ON";
+ @SerializedName("payload_off")
+ protected String payloadOff = "OFF";
}
public Fan(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
- OnOffValue value = new OnOffValue(channelConfiguration.payload_on, channelConfiguration.payload_off);
- buildChannel(switchChannelID, value, channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())
- .commandTopic(channelConfiguration.command_topic, channelConfiguration.isRetain(),
- channelConfiguration.getQos())
- .build();
+ OnOffValue value = new OnOffValue(channelConfiguration.payloadOn, channelConfiguration.payloadOff);
+ buildChannel(SWITCH_CHANNEL_ID, value, channelConfiguration.getName(),
+ componentConfiguration.getUpdateListener())
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
+ .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
+ channelConfiguration.getQos())
+ .build();
}
}
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT light, following the https://www.home-assistant.io/components/light.mqtt/ specification.
*
*/
@NonNullByDefault
public class Light extends AbstractComponent<Light.ChannelConfiguration> implements ChannelStateUpdateListener {
- public static final String switchChannelID = "light"; // Randomly chosen channel "ID"
- public static final String brightnessChannelID = "brightness"; // Randomly chosen channel "ID"
- public static final String colorChannelID = "color"; // Randomly chosen channel "ID"
+ public static final String SWITCH_CHANNEL_ID = "light"; // Randomly chosen channel "ID"
+ public static final String BRIGHTNESS_CHANNEL_ID = "brightness"; // Randomly chosen channel "ID"
+ public static final String COLOR_CHANNEL_ID = "color"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
super("MQTT Light");
}
- protected int brightness_scale = 255;
+ @SerializedName("brightness_scale")
+ protected int brightnessScale = 255;
protected boolean optimistic = false;
- protected @Nullable List<String> effect_list;
+ @SerializedName("effect_list")
+ protected @Nullable List<String> effectList;
// Defines when on the payload_on is sent. Using last (the default) will send any style (brightness, color, etc)
// topics first and then a payload_on to the command_topic. Using first will send the payload_on and then any
// style topics. Using brightness will only send brightness commands instead of the payload_on to turn the light
// on.
- protected String on_command_type = "last";
-
- protected @Nullable String state_topic;
- protected @Nullable String command_topic;
- protected @Nullable String state_value_template;
-
- protected @Nullable String brightness_state_topic;
- protected @Nullable String brightness_command_topic;
- protected @Nullable String brightness_value_template;
-
- protected @Nullable String color_temp_state_topic;
- protected @Nullable String color_temp_command_topic;
- protected @Nullable String color_temp_value_template;
-
- protected @Nullable String effect_command_topic;
- protected @Nullable String effect_state_topic;
- protected @Nullable String effect_value_template;
-
- protected @Nullable String rgb_command_topic;
- protected @Nullable String rgb_state_topic;
- protected @Nullable String rgb_value_template;
- protected @Nullable String rgb_command_template;
-
- protected @Nullable String white_value_command_topic;
- protected @Nullable String white_value_state_topic;
- protected @Nullable String white_value_template;
-
- protected @Nullable String xy_command_topic;
- protected @Nullable String xy_state_topic;
- protected @Nullable String xy_value_template;
-
- protected String payload_on = "ON";
- protected String payload_off = "OFF";
+ @SerializedName("on_command_type")
+ protected String onCommandType = "last";
+
+ @SerializedName("state_topic")
+ protected @Nullable String stateTopic;
+ @SerializedName("command_topic")
+ protected @Nullable String commandTopic;
+ @SerializedName("state_value_template")
+ protected @Nullable String stateValueTemplate;
+
+ @SerializedName("brightness_state_topic")
+ protected @Nullable String brightnessStateTopic;
+ @SerializedName("brightness_command_topic")
+ protected @Nullable String brightnessCommandTopic;
+ @SerializedName("brightness_value_template")
+ protected @Nullable String brightnessValueTemplate;
+
+ @SerializedName("color_temp_state_topic")
+ protected @Nullable String colorTempStateTopic;
+ @SerializedName("color_temp_command_topic")
+ protected @Nullable String colorTempCommandTopic;
+ @SerializedName("color_temp_value_template")
+ protected @Nullable String colorTempValueTemplate;
+
+ @SerializedName("effect_command_topic")
+ protected @Nullable String effectCommandTopic;
+ @SerializedName("effect_state_topic")
+ protected @Nullable String effectStateTopic;
+ @SerializedName("effect_value_template")
+ protected @Nullable String effectValueTemplate;
+
+ @SerializedName("rgb_command_topic")
+ protected @Nullable String rgbCommandTopic;
+ @SerializedName("rgb_state_topic")
+ protected @Nullable String rgbStateTopic;
+ @SerializedName("rgb_value_template")
+ protected @Nullable String rgbValueTemplate;
+ @SerializedName("rgb_command_template")
+ protected @Nullable String rgbCommandTemplate;
+
+ @SerializedName("white_value_command_topic")
+ protected @Nullable String whiteValueCommandTopic;
+ @SerializedName("white_value_state_topic")
+ protected @Nullable String whiteValueStateTopic;
+ @SerializedName("white_value_template")
+ protected @Nullable String whiteValueTemplate;
+
+ @SerializedName("xy_command_topic")
+ protected @Nullable String xyCommandTopic;
+ @SerializedName("xy_state_topic")
+ protected @Nullable String xyStateTopic;
+ @SerializedName("xy_value_template")
+ protected @Nullable String xyValueTemplate;
+
+ @SerializedName("payload_on")
+ protected String payloadOn = "ON";
+ @SerializedName("payload_off")
+ protected String payloadOff = "OFF";
}
protected ComponentChannel colorChannel;
public Light(ComponentFactory.ComponentConfiguration builder) {
super(builder, ChannelConfiguration.class);
this.channelStateUpdateListener = builder.getUpdateListener();
- ColorValue value = new ColorValue(ColorMode.RGB, channelConfiguration.payload_on,
- channelConfiguration.payload_off, 100);
+ ColorValue value = new ColorValue(ColorMode.RGB, channelConfiguration.payloadOn,
+ channelConfiguration.payloadOff, 100);
// Create three MQTT subscriptions and use this class object as update listener
- switchChannel = buildChannel(switchChannelID, value, channelConfiguration.getName(), this)
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.state_value_template,
+ switchChannel = buildChannel(SWITCH_CHANNEL_ID, value, channelConfiguration.getName(), this)
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.stateValueTemplate,
channelConfiguration.getValueTemplate())
- .commandTopic(channelConfiguration.command_topic, channelConfiguration.isRetain(),
+ .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build(false);
- colorChannel = buildChannel(colorChannelID, value, channelConfiguration.getName(), this)
- .stateTopic(channelConfiguration.rgb_state_topic, channelConfiguration.rgb_value_template)
- .commandTopic(channelConfiguration.rgb_command_topic, channelConfiguration.isRetain(),
+ colorChannel = buildChannel(COLOR_CHANNEL_ID, value, channelConfiguration.getName(), this)
+ .stateTopic(channelConfiguration.rgbStateTopic, channelConfiguration.rgbValueTemplate)
+ .commandTopic(channelConfiguration.rgbCommandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build(false);
- brightnessChannel = buildChannel(brightnessChannelID, value, channelConfiguration.getName(), this)
- .stateTopic(channelConfiguration.brightness_state_topic, channelConfiguration.brightness_value_template)
- .commandTopic(channelConfiguration.brightness_command_topic, channelConfiguration.isRetain(),
+ brightnessChannel = buildChannel(BRIGHTNESS_CHANNEL_ID, value, channelConfiguration.getName(), this)
+ .stateTopic(channelConfiguration.brightnessStateTopic, channelConfiguration.brightnessValueTemplate)
+ .commandTopic(channelConfiguration.brightnessCommandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build(false);
- channels.put(colorChannelID, colorChannel);
+ channels.put(COLOR_CHANNEL_ID, colorChannel);
}
@Override
import org.openhab.binding.mqtt.generic.values.OnOffValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT lock, following the https://www.home-assistant.io/components/lock.mqtt/ specification.
*
*/
@NonNullByDefault
public class Lock extends AbstractComponent<Lock.ChannelConfiguration> {
- public static final String switchChannelID = "lock"; // Randomly chosen channel "ID"
+ public static final String SWITCH_CHANNEL_ID = "lock"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
protected boolean optimistic = false;
- protected String state_topic = "";
- protected String payload_lock = "LOCK";
- protected String payload_unlock = "UNLOCK";
- protected @Nullable String command_topic;
+ @SerializedName("state_topic")
+ protected String stateTopic = "";
+ @SerializedName("payload_lock")
+ protected String payloadLock = "LOCK";
+ @SerializedName("payload_unlock")
+ protected String payloadUnlock = "UNLOCK";
+ @SerializedName("command_topic")
+ protected @Nullable String commandTopic;
}
public Lock(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
// We do not support all HomeAssistant quirks
- if (channelConfiguration.optimistic && !channelConfiguration.state_topic.isBlank()) {
+ if (channelConfiguration.optimistic && !channelConfiguration.stateTopic.isBlank()) {
throw new UnsupportedOperationException("Component:Lock does not support forced optimistic mode");
}
- buildChannel(switchChannelID,
- new OnOffValue(channelConfiguration.payload_lock, channelConfiguration.payload_unlock),
+ buildChannel(SWITCH_CHANNEL_ID,
+ new OnOffValue(channelConfiguration.payloadLock, channelConfiguration.payloadUnlock),
channelConfiguration.getName(), componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())
- .commandTopic(channelConfiguration.command_topic, channelConfiguration.isRetain(),
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
+ .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build();
}
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
import org.openhab.binding.mqtt.homeassistant.internal.listener.ExpireUpdateStateListener;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT sensor, following the https://www.home-assistant.io/components/sensor.mqtt/ specification.
*
*/
@NonNullByDefault
public class Sensor extends AbstractComponent<Sensor.ChannelConfiguration> {
- public static final String sensorChannelID = "sensor"; // Randomly chosen channel "ID"
- private static final Pattern triggerIcons = Pattern.compile("^mdi:(toggle|gesture).*$");
+ public static final String SENSOR_CHANNEL_ID = "sensor"; // Randomly chosen channel "ID"
+ private static final Pattern TRIGGER_ICONS = Pattern.compile("^mdi:(toggle|gesture).*$");
/**
* Configuration class for MQTT component
super("MQTT Sensor");
}
- protected @Nullable String unit_of_measurement;
- protected @Nullable String device_class;
- protected boolean force_update = false;
- protected @Nullable Integer expire_after;
+ @SerializedName("unit_of_measurement")
+ protected @Nullable String unitOfMeasurement;
+ @SerializedName("device_class")
+ protected @Nullable String deviceClass;
+ @SerializedName("force_update")
+ protected boolean forceUpdate = false;
+ @SerializedName("expire_after")
+ protected @Nullable Integer expireAfter;
- protected String state_topic = "";
+ @SerializedName("state_topic")
+ protected String stateTopic = "";
- protected @Nullable String json_attributes_topic;
- protected @Nullable String json_attributes_template;
- protected @Nullable List<String> json_attributes;
+ @SerializedName("json_attributes_topic")
+ protected @Nullable String jsonAttributesTopic;
+ @SerializedName("json_attributes_template")
+ protected @Nullable String jsonAttributesTemplate;
+ @SerializedName("json_attributes")
+ protected @Nullable List<String> jsonAttributes;
}
public Sensor(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
Value value;
- String uom = channelConfiguration.unit_of_measurement;
+ String uom = channelConfiguration.unitOfMeasurement;
if (uom != null && !uom.isBlank()) {
value = new NumberValue(null, null, null, uom);
String icon = channelConfiguration.getIcon();
- boolean trigger = triggerIcons.matcher(icon).matches();
+ boolean trigger = TRIGGER_ICONS.matcher(icon).matches();
- buildChannel(sensorChannelID, value, channelConfiguration.getName(), getListener(componentConfiguration, value))
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())//
- .trigger(trigger).build();
+ buildChannel(SENSOR_CHANNEL_ID, value, channelConfiguration.getName(),
+ getListener(componentConfiguration, value))
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())//
+ .trigger(trigger).build();
}
private ChannelStateUpdateListener getListener(ComponentFactory.ComponentConfiguration componentConfiguration,
Value value) {
ChannelStateUpdateListener updateListener = componentConfiguration.getUpdateListener();
- if (channelConfiguration.expire_after != null) {
- updateListener = new ExpireUpdateStateListener(updateListener, channelConfiguration.expire_after, value,
+ if (channelConfiguration.expireAfter != null) {
+ updateListener = new ExpireUpdateStateListener(updateListener, channelConfiguration.expireAfter, value,
componentConfiguration.getTracker(), componentConfiguration.getScheduler());
}
return updateListener;
import org.openhab.binding.mqtt.generic.values.OnOffValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
+import com.google.gson.annotations.SerializedName;
+
/**
* A MQTT switch, following the https://www.home-assistant.io/components/switch.mqtt/ specification.
*
*/
@NonNullByDefault
public class Switch extends AbstractComponent<Switch.ChannelConfiguration> {
- public static final String switchChannelID = "switch"; // Randomly chosen channel "ID"
+ public static final String SWITCH_CHANNEL_ID = "switch"; // Randomly chosen channel "ID"
/**
* Configuration class for MQTT component
protected @Nullable Boolean optimistic;
- protected @Nullable String command_topic;
- protected String state_topic = "";
+ @SerializedName("command_topic")
+ protected @Nullable String commandTopic;
+ @SerializedName("state_topic")
+ protected String stateTopic = "";
- protected @Nullable String state_on;
- protected @Nullable String state_off;
- protected String payload_on = "ON";
- protected String payload_off = "OFF";
+ @SerializedName("state_on")
+ protected @Nullable String stateOn;
+ @SerializedName("state_off")
+ protected @Nullable String stateOff;
+ @SerializedName("payload_on")
+ protected String payloadOn = "ON";
+ @SerializedName("payload_off")
+ protected String payloadOff = "OFF";
- protected @Nullable String json_attributes_topic;
- protected @Nullable String json_attributes_template;
+ @SerializedName("json_attributes_topic")
+ protected @Nullable String jsonAttributesTopic;
+ @SerializedName("json_attributes_template")
+ protected @Nullable String jsonAttributesTemplate;
}
public Switch(ComponentFactory.ComponentConfiguration componentConfiguration) {
super(componentConfiguration, ChannelConfiguration.class);
boolean optimistic = channelConfiguration.optimistic != null ? channelConfiguration.optimistic
- : channelConfiguration.state_topic.isBlank();
+ : channelConfiguration.stateTopic.isBlank();
- if (optimistic && !channelConfiguration.state_topic.isBlank()) {
+ if (optimistic && !channelConfiguration.stateTopic.isBlank()) {
throw new UnsupportedOperationException("Component:Switch does not support forced optimistic mode");
}
- String state_on = channelConfiguration.state_on != null ? channelConfiguration.state_on
- : channelConfiguration.payload_on;
- String state_off = channelConfiguration.state_off != null ? channelConfiguration.state_off
- : channelConfiguration.payload_off;
+ String stateOn = channelConfiguration.stateOn != null ? channelConfiguration.stateOn
+ : channelConfiguration.payloadOn;
+ String stateOff = channelConfiguration.stateOff != null ? channelConfiguration.stateOff
+ : channelConfiguration.payloadOff;
- OnOffValue value = new OnOffValue(state_on, state_off, channelConfiguration.payload_on,
- channelConfiguration.payload_off);
+ OnOffValue value = new OnOffValue(stateOn, stateOff, channelConfiguration.payloadOn,
+ channelConfiguration.payloadOff);
- buildChannel(switchChannelID, value, "state", componentConfiguration.getUpdateListener())
- .stateTopic(channelConfiguration.state_topic, channelConfiguration.getValueTemplate())
- .commandTopic(channelConfiguration.command_topic, channelConfiguration.isRetain(),
+ buildChannel(SWITCH_CHANNEL_ID, value, "state", componentConfiguration.getUpdateListener())
+ .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
+ .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build();
}
import java.io.IOException;
import java.lang.reflect.Field;
+import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
+import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
* that abbreviated names are replaces with their long versions during the read.
*
* <p>
- * In elements, whose name end in'_topic' '~' replacement is performed.
+ * In elements, whose JSON name end in'_topic' '~' replacement is performed.
*
* <p>
* The adapters also handle {@link Device}
*/
@NonNullByDefault
public class ChannelConfigurationTypeAdapterFactory implements TypeAdapterFactory {
+ private static final String MQTT_TOPIC_FIELD_SUFFIX = "_topic";
@Override
@Nullable
private void expandTidleInTopics(AbstractChannelConfiguration config) {
Class<?> type = config.getClass();
- String tilde = config.getTilde();
+ String parentTopic = config.getParentTopic();
while (type != Object.class) {
- Field[] fields = type.getDeclaredFields();
-
- for (Field field : fields) {
- if (String.class.isAssignableFrom(field.getType()) && field.getName().endsWith("_topic")) {
- field.setAccessible(true);
-
- try {
- final String oldValue = (String) field.get(config);
-
- String newValue = oldValue;
- if (oldValue != null && !oldValue.isBlank()) {
- if (oldValue.charAt(0) == '~') {
- newValue = tilde + oldValue.substring(1);
- } else if (oldValue.charAt(oldValue.length() - 1) == '~') {
- newValue = oldValue.substring(0, oldValue.length() - 1) + tilde;
- }
- }
-
- field.set(config, newValue);
- } catch (IllegalArgumentException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
+ Arrays.stream(type.getDeclaredFields()).filter(this::isMqttTopicField)
+ .forEach(field -> replacePlaceholderByParentTopic(config, field, parentTopic));
+ type = type.getSuperclass();
+ }
+ }
+
+ private boolean isMqttTopicField(Field field) {
+ if (String.class.isAssignableFrom(field.getType())) {
+ final var serializedNameAnnotation = field.getAnnotation(SerializedName.class);
+ if (serializedNameAnnotation != null && serializedNameAnnotation.value() != null
+ && serializedNameAnnotation.value().endsWith(MQTT_TOPIC_FIELD_SUFFIX)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void replacePlaceholderByParentTopic(AbstractChannelConfiguration config, Field field, String parentTopic) {
+ field.setAccessible(true);
+
+ try {
+ final String oldValue = (String) field.get(config);
+
+ String newValue = oldValue;
+ if (oldValue != null && !oldValue.isBlank()) {
+ if (oldValue.charAt(0) == AbstractChannelConfiguration.PARENT_TOPIC_PLACEHOLDER) {
+ newValue = parentTopic + oldValue.substring(1);
+ } else if (oldValue
+ .charAt(oldValue.length() - 1) == AbstractChannelConfiguration.PARENT_TOPIC_PLACEHOLDER) {
+ newValue = oldValue.substring(0, oldValue.length() - 1) + parentTopic;
}
}
- type = type.getSuperclass();
+ field.set(config, newValue);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new RuntimeException(e);
}
}
}
import java.lang.reflect.Type;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.Connection;
import com.google.gson.JsonArray;
*
* @author Jan N. Klug - Initial contribution
*/
+@NonNullByDefault
public class ConnectionDeserializer implements JsonDeserializer<Connection> {
- @Override
- public Connection deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ public @Nullable Connection deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
- JsonArray list = json.getAsJsonArray();
+ JsonArray list;
+ if (json == null) {
+ throw new JsonParseException("JSON element is null");
+ }
+ try {
+ list = json.getAsJsonArray();
+ } catch (IllegalStateException e) {
+ throw new JsonParseException("Cannot parse JSON array", e);
+ }
+ if (list.size() != 2) {
+ throw new JsonParseException(
+ "Connection information must be a tuple, but has " + list.size() + " elements!");
+ }
return new Connection(list.get(0).getAsString(), list.get(1).getAsString());
}
}
import java.util.List;
import java.util.Objects;
-import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import com.google.gson.TypeAdapter;
*
* @author Jochen Klein - Initial contribution
*/
+@NonNullByDefault
public class ListOrStringDeserializer extends TypeAdapter<List<String>> {
@Override
}
}
- private @NonNull List<String> readList(@NonNull JsonReader in) throws IOException {
+ private List<String> readList(JsonReader in) throws IOException {
in.beginArray();
List<String> result = new ArrayList<>();
*/
@NonNullByDefault
public abstract class AbstractChannelConfiguration {
+ public static final char PARENT_TOPIC_PLACEHOLDER = '~';
+
protected String name;
protected String icon = "";
protected int qos; // defaults to 0 according to HA specification
protected boolean retain; // defaults to false according to HA specification
- protected @Nullable String value_template;
- protected @Nullable String unique_id;
-
- protected AvailabilityMode availability_mode = AvailabilityMode.LATEST;
- protected @Nullable String availability_topic;
- protected String payload_available = "online";
- protected String payload_not_available = "offline";
+ @SerializedName("value_template")
+ protected @Nullable String valueTemplate;
+ @SerializedName("unique_id")
+ protected @Nullable String uniqueId;
+
+ @SerializedName("availability_mode")
+ protected AvailabilityMode availabilityMode = AvailabilityMode.LATEST;
+ @SerializedName("availability_topic")
+ protected @Nullable String availabilityTopic;
+ @SerializedName("payload_available")
+ protected String payloadAvailable = "online";
+ @SerializedName("payload_not_available")
+ protected String payloadNotAvailable = "offline";
/**
* A list of MQTT topics subscribed to receive availability (online/offline) updates. Must not be used together with
protected @Nullable List<Availability> availability;
@SerializedName(value = "~")
- protected String tilde = "";
+ protected String parentTopic = "";
protected @Nullable Device device;
this.name = defaultName;
}
- public @Nullable String expand(@Nullable String value) {
- return value == null ? null : value.replaceAll("~", tilde);
- }
-
public String getThingName() {
String result = null;
result = this.device.getId();
}
if (result == null) {
- result = unique_id;
+ result = uniqueId;
}
return UIDUtils.encode(result != null ? result : defaultId);
}
public Map<String, Object> appendToProperties(Map<String, Object> properties) {
- final Device device_ = device;
- if (device_ == null) {
+ final Device d = device;
+ if (d == null) {
return properties;
}
- final String manufacturer = device_.manufacturer;
+ final String manufacturer = d.manufacturer;
if (manufacturer != null) {
properties.put(Thing.PROPERTY_VENDOR, manufacturer);
}
- final String model = device_.model;
+ final String model = d.model;
if (model != null) {
properties.put(Thing.PROPERTY_MODEL_ID, model);
}
- final String sw_version = device_.swVersion;
- if (sw_version != null) {
- properties.put(Thing.PROPERTY_FIRMWARE_VERSION, sw_version);
+ final String swVersion = d.swVersion;
+ if (swVersion != null) {
+ properties.put(Thing.PROPERTY_FIRMWARE_VERSION, swVersion);
}
return properties;
}
@Nullable
public String getValueTemplate() {
- return value_template;
+ return valueTemplate;
}
@Nullable
public String getUniqueId() {
- return unique_id;
+ return uniqueId;
}
@Nullable
public String getAvailabilityTopic() {
- return availability_topic;
+ return availabilityTopic;
}
public String getPayloadAvailable() {
- return payload_available;
+ return payloadAvailable;
}
public String getPayloadNotAvailable() {
- return payload_not_available;
+ return payloadNotAvailable;
}
@Nullable
return availability;
}
- public String getTilde() {
- return tilde;
+ public String getParentTopic() {
+ return parentTopic;
}
public AvailabilityMode getAvailabilityMode() {
- return availability_mode;
+ return availabilityMode;
}
/**
*/
package org.openhab.binding.mqtt.homeassistant.internal.config.dto;
+import com.google.gson.annotations.SerializedName;
+
/**
* MQTT topic subscribed to receive availability (online/offline) updates. Must not be used together with
* availability_topic
* @author Anton Kharuzhy - Initial contribution
*/
public class Availability {
- protected String payload_available = "online";
- protected String payload_not_available = "offline";
+ @SerializedName("payload_available")
+ protected String payloadAvailable = "online";
+ @SerializedName("payload_not_available")
+ protected String payloadNotAvailable = "offline";
protected String topic;
- public String getPayload_available() {
- return payload_available;
+ public String getPayloadAvailable() {
+ return payloadAvailable;
}
- public String getPayload_not_available() {
- return payload_not_available;
+ public String getPayloadNotAvailable() {
+ return payloadNotAvailable;
}
public String getTopic() {
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mqtt.discovery.AbstractMQTTDiscovery;
}
@Override
- public Set<@NonNull ThingTypeUID> getSupportedThingTypes() {
+ public Set<ThingTypeUID> getSupportedThingTypes() {
return typeProvider.getThingTypeUIDs();
}
*/
package org.openhab.binding.mqtt.homeassistant.internal.listener;
-import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
import org.openhab.core.thing.ChannelUID;
}
@Override
- public void updateChannelState(@NonNull ChannelUID channelUID, @NonNull State value) {
+ public void updateChannelState(ChannelUID channelUID, State value) {
original.updateChannelState(channelUID, value);
}
@Override
- public void postChannelCommand(@NonNull ChannelUID channelUID, @NonNull Command value) {
+ public void postChannelCommand(ChannelUID channelUID, Command value) {
original.postChannelCommand(channelUID, value);
}
@Override
- public void triggerChannel(@NonNull ChannelUID channelUID, @NonNull String eventPayload) {
+ public void triggerChannel(ChannelUID channelUID, String eventPayload) {
original.triggerChannel(channelUID, eventPayload);
}
}
/**
* Abstract class for components tests.
- * TODO: need a way to test all channel properties, not only topics.
*
* @author Anton Kharuzhy - Initial contribution
*/
assertThat(component.channels.size(), is(4));
assertThat(component.getName(), is("alarm"));
- assertChannel(component, AlarmControlPanel.stateChannelID, "zigbee2mqtt/alarm/state", "", "alarm",
+ assertChannel(component, AlarmControlPanel.STATE_CHANNEL_ID, "zigbee2mqtt/alarm/state", "", "alarm",
TextValue.class);
- assertChannel(component, AlarmControlPanel.switchDisarmChannelID, "", "zigbee2mqtt/alarm/set/state", "alarm",
- TextValue.class);
- assertChannel(component, AlarmControlPanel.switchArmAwayChannelID, "", "zigbee2mqtt/alarm/set/state", "alarm",
- TextValue.class);
- assertChannel(component, AlarmControlPanel.switchArmHomeChannelID, "", "zigbee2mqtt/alarm/set/state", "alarm",
+ assertChannel(component, AlarmControlPanel.SWITCH_DISARM_CHANNEL_ID, "", "zigbee2mqtt/alarm/set/state", "alarm",
TextValue.class);
+ assertChannel(component, AlarmControlPanel.SWITCH_ARM_AWAY_CHANNEL_ID, "", "zigbee2mqtt/alarm/set/state",
+ "alarm", TextValue.class);
+ assertChannel(component, AlarmControlPanel.SWITCH_ARM_HOME_CHANNEL_ID, "", "zigbee2mqtt/alarm/set/state",
+ "alarm", TextValue.class);
publishMessage("zigbee2mqtt/alarm/state", "armed_home");
- assertState(component, AlarmControlPanel.stateChannelID, new StringType("armed_home"));
+ assertState(component, AlarmControlPanel.STATE_CHANNEL_ID, new StringType("armed_home"));
publishMessage("zigbee2mqtt/alarm/state", "armed_away");
- assertState(component, AlarmControlPanel.stateChannelID, new StringType("armed_away"));
+ assertState(component, AlarmControlPanel.STATE_CHANNEL_ID, new StringType("armed_away"));
- component.getChannel(AlarmControlPanel.switchDisarmChannelID).getState()
+ component.getChannel(AlarmControlPanel.SWITCH_DISARM_CHANNEL_ID).getState()
.publishValue(new StringType("DISARM_"));
assertPublished("zigbee2mqtt/alarm/set/state", "DISARM_");
- component.getChannel(AlarmControlPanel.switchArmAwayChannelID).getState()
+ component.getChannel(AlarmControlPanel.SWITCH_ARM_AWAY_CHANNEL_ID).getState()
.publishValue(new StringType("ARM_AWAY_"));
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_AWAY_");
- component.getChannel(AlarmControlPanel.switchArmHomeChannelID).getState()
+ component.getChannel(AlarmControlPanel.SWITCH_ARM_HOME_CHANNEL_ID).getState()
.publishValue(new StringType("ARM_HOME_"));
assertPublished("zigbee2mqtt/alarm/set/state", "ARM_HOME_");
}
assertThat(component.getName(), is("onoffsensor"));
assertThat(component.getGroupUID().getId(), is("sn1"));
- assertChannel(component, BinarySensor.sensorChannelID, "zigbee2mqtt/sensor/state", "", "value",
+ assertChannel(component, BinarySensor.SENSOR_CHANNEL_ID, "zigbee2mqtt/sensor/state", "", "value",
OnOffValue.class);
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"ON_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.ON);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"ON_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.ON);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"OFF_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.OFF);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.OFF);
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"ON_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.ON);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.ON);
}
@Test
// @formatter:on
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"ON_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.ON);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.ON);
- waitForAssert(() -> assertState(component, BinarySensor.sensorChannelID, OnOffType.OFF), 10000, 200);
+ waitForAssert(() -> assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.OFF), 10000, 200);
}
@Test
// @formatter:on
publishMessage("zigbee2mqtt/sensor/state", "{ \"state\": \"OFF_\" }");
- assertState(component, BinarySensor.sensorChannelID, OnOffType.OFF);
+ assertState(component, BinarySensor.SENSOR_CHANNEL_ID, OnOffType.OFF);
- waitForAssert(() -> assertState(component, BinarySensor.sensorChannelID, UnDefType.UNDEF), 10000, 200);
+ waitForAssert(() -> assertState(component, BinarySensor.SENSOR_CHANNEL_ID, UnDefType.UNDEF), 10000, 200);
}
protected Set<String> getConfigTopics() {
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("cam1"));
- assertChannel(component, Camera.cameraChannelID, "zigbee2mqtt/cam1/state", "", "cam1", ImageValue.class);
+ assertChannel(component, Camera.CAMERA_CHANNEL_ID, "zigbee2mqtt/cam1/state", "", "cam1", ImageValue.class);
var imageBytes = getResourceAsByteArray("component/image.png");
publishMessage("zigbee2mqtt/cam1/state", imageBytes);
- assertState(component, Camera.cameraChannelID, new RawType(imageBytes, "image/png"));
+ assertState(component, Camera.CAMERA_CHANNEL_ID, new RawType(imageBytes, "image/png"));
}
protected Set<String> getConfigTopics() {
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("cover"));
- assertChannel(component, Cover.switchChannelID, "zigbee2mqtt/cover/state", "zigbee2mqtt/cover/set/state",
+ assertChannel(component, Cover.SWITCH_CHANNEL_ID, "zigbee2mqtt/cover/state", "zigbee2mqtt/cover/set/state",
"cover", RollershutterValue.class);
publishMessage("zigbee2mqtt/cover/state", "100");
- assertState(component, Cover.switchChannelID, PercentType.HUNDRED);
+ assertState(component, Cover.SWITCH_CHANNEL_ID, PercentType.HUNDRED);
publishMessage("zigbee2mqtt/cover/state", "0");
- assertState(component, Cover.switchChannelID, PercentType.ZERO);
+ assertState(component, Cover.SWITCH_CHANNEL_ID, PercentType.ZERO);
- component.getChannel(Cover.switchChannelID).getState().publishValue(PercentType.ZERO);
+ component.getChannel(Cover.SWITCH_CHANNEL_ID).getState().publishValue(PercentType.ZERO);
assertPublished("zigbee2mqtt/cover/set/state", "OPEN_");
- component.getChannel(Cover.switchChannelID).getState().publishValue(PercentType.HUNDRED);
+ component.getChannel(Cover.SWITCH_CHANNEL_ID).getState().publishValue(PercentType.HUNDRED);
assertPublished("zigbee2mqtt/cover/set/state", "CLOSE_");
- component.getChannel(Cover.switchChannelID).getState().publishValue(StopMoveType.STOP);
+ component.getChannel(Cover.SWITCH_CHANNEL_ID).getState().publishValue(StopMoveType.STOP);
assertPublished("zigbee2mqtt/cover/set/state", "STOP_");
- component.getChannel(Cover.switchChannelID).getState().publishValue(PercentType.ZERO);
+ component.getChannel(Cover.SWITCH_CHANNEL_ID).getState().publishValue(PercentType.ZERO);
assertPublished("zigbee2mqtt/cover/set/state", "OPEN_", 2);
- component.getChannel(Cover.switchChannelID).getState().publishValue(StopMoveType.STOP);
+ component.getChannel(Cover.SWITCH_CHANNEL_ID).getState().publishValue(StopMoveType.STOP);
assertPublished("zigbee2mqtt/cover/set/state", "STOP_", 2);
}
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("fan"));
- assertChannel(component, Fan.switchChannelID, "zigbee2mqtt/fan/state", "zigbee2mqtt/fan/set/state", "fan",
+ assertChannel(component, Fan.SWITCH_CHANNEL_ID, "zigbee2mqtt/fan/state", "zigbee2mqtt/fan/set/state", "fan",
OnOffValue.class);
publishMessage("zigbee2mqtt/fan/state", "ON_");
- assertState(component, Fan.switchChannelID, OnOffType.ON);
+ assertState(component, Fan.SWITCH_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/fan/state", "ON_");
- assertState(component, Fan.switchChannelID, OnOffType.ON);
+ assertState(component, Fan.SWITCH_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/fan/state", "OFF_");
- assertState(component, Fan.switchChannelID, OnOffType.OFF);
+ assertState(component, Fan.SWITCH_CHANNEL_ID, OnOffType.OFF);
publishMessage("zigbee2mqtt/fan/state", "ON_");
- assertState(component, Fan.switchChannelID, OnOffType.ON);
+ assertState(component, Fan.SWITCH_CHANNEL_ID, OnOffType.ON);
- component.getChannel(Fan.switchChannelID).getState().publishValue(OnOffType.OFF);
+ component.getChannel(Fan.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
assertPublished("zigbee2mqtt/fan/set/state", "OFF_");
- component.getChannel(Fan.switchChannelID).getState().publishValue(OnOffType.ON);
+ component.getChannel(Fan.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.ON);
assertPublished("zigbee2mqtt/fan/set/state", "ON_");
}
Switch.ChannelConfiguration.class);
assertThat(config.getAvailabilityTopic(), is("D/E"));
- assertThat(config.state_topic, is("O/D/"));
- assertThat(config.command_topic, is("P~Q"));
+ assertThat(config.stateTopic, is("O/D/"));
+ assertThat(config.commandTopic, is("P~Q"));
assertThat(config.getDevice(), is(notNullValue()));
Device device = config.getDevice();
assertThat(config.getDevice().getName(), is("th1"));
assertThat(config.getDevice().getSwVersion(), is("Zigbee2MQTT 1.18.2"));
- assertThat(config.action_template, is(
+ assertThat(config.actionTemplate, is(
"{% set values = {'idle':'off','heat':'heating','cool':'cooling','fan only':'fan'} %}{{ values[value_json.running_state] }}"));
- assertThat(config.action_topic, is("zigbee2mqtt/th1"));
- assertThat(config.away_mode_command_topic, is("zigbee2mqtt/th1/set/away_mode"));
- assertThat(config.away_mode_state_template, is("{{ value_json.away_mode }}"));
- assertThat(config.away_mode_state_topic, is("zigbee2mqtt/th1"));
- assertThat(config.current_temperature_template, is("{{ value_json.local_temperature }}"));
- assertThat(config.current_temperature_topic, is("zigbee2mqtt/th1"));
- assertThat(config.hold_command_topic, is("zigbee2mqtt/th1/set/preset"));
- assertThat(config.hold_modes, is(List.of("schedule", "manual", "boost", "complex", "comfort", "eco")));
- assertThat(config.hold_state_template, is("{{ value_json.preset }}"));
- assertThat(config.hold_state_topic, is("zigbee2mqtt/th1"));
- assertThat(config.json_attributes_topic, is("zigbee2mqtt/th1"));
- assertThat(config.max_temp, is(35f));
- assertThat(config.min_temp, is(5f));
- assertThat(config.mode_command_topic, is("zigbee2mqtt/th1/set/system_mode"));
- assertThat(config.mode_state_template, is("{{ value_json.system_mode }}"));
- assertThat(config.mode_state_topic, is("zigbee2mqtt/th1"));
+ assertThat(config.actionTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.awayModeCommandTopic, is("zigbee2mqtt/th1/set/away_mode"));
+ assertThat(config.awayModeStateTemplate, is("{{ value_json.away_mode }}"));
+ assertThat(config.awayModeStateTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.currentTemperatureTemplate, is("{{ value_json.local_temperature }}"));
+ assertThat(config.currentTemperatureTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.holdCommandTopic, is("zigbee2mqtt/th1/set/preset"));
+ assertThat(config.holdModes, is(List.of("schedule", "manual", "boost", "complex", "comfort", "eco")));
+ assertThat(config.holdStateTemplate, is("{{ value_json.preset }}"));
+ assertThat(config.holdStateTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.jsonAttributesTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.maxTemp, is(35f));
+ assertThat(config.minTemp, is(5f));
+ assertThat(config.modeCommandTopic, is("zigbee2mqtt/th1/set/system_mode"));
+ assertThat(config.modeStateTemplate, is("{{ value_json.system_mode }}"));
+ assertThat(config.modeStateTopic, is("zigbee2mqtt/th1"));
assertThat(config.modes, is(List.of("heat", "auto", "off")));
assertThat(config.getName(), is("th1"));
- assertThat(config.temp_step, is(0.5f));
- assertThat(config.temperature_command_topic, is("zigbee2mqtt/th1/set/current_heating_setpoint"));
- assertThat(config.temperature_state_template, is("{{ value_json.current_heating_setpoint }}"));
- assertThat(config.temperature_state_topic, is("zigbee2mqtt/th1"));
- assertThat(config.temperature_unit, is("C"));
+ assertThat(config.tempStep, is(0.5f));
+ assertThat(config.temperatureCommandTopic, is("zigbee2mqtt/th1/set/current_heating_setpoint"));
+ assertThat(config.temperatureStateTemplate, is("{{ value_json.current_heating_setpoint }}"));
+ assertThat(config.temperatureStateTopic, is("zigbee2mqtt/th1"));
+ assertThat(config.temperatureUnit, is("C"));
assertThat(config.getUniqueId(), is("0x847127fffe11dd6a_climate_zigbee2mqtt"));
assertThat(config.initial, is(21));
- assertThat(config.send_if_off, is(true));
+ assertThat(config.sendIfOff, is(true));
}
@Test
String json = readTestJson("configClimate.json");
Climate.ChannelConfiguration config = AbstractChannelConfiguration.fromString(json, gson,
Climate.ChannelConfiguration.class);
- assertThat(config.action_template, is("a"));
- assertThat(config.action_topic, is("b"));
- assertThat(config.aux_command_topic, is("c"));
- assertThat(config.aux_state_template, is("d"));
- assertThat(config.aux_state_topic, is("e"));
- assertThat(config.away_mode_command_topic, is("f"));
- assertThat(config.away_mode_state_template, is("g"));
- assertThat(config.away_mode_state_topic, is("h"));
- assertThat(config.current_temperature_template, is("i"));
- assertThat(config.current_temperature_topic, is("j"));
- assertThat(config.fan_mode_command_template, is("k"));
- assertThat(config.fan_mode_command_topic, is("l"));
- assertThat(config.fan_mode_state_template, is("m"));
- assertThat(config.fan_mode_state_topic, is("n"));
- assertThat(config.fan_modes, is(List.of("p1", "p2")));
- assertThat(config.hold_command_template, is("q"));
- assertThat(config.hold_command_topic, is("r"));
- assertThat(config.hold_state_template, is("s"));
- assertThat(config.hold_state_topic, is("t"));
- assertThat(config.hold_modes, is(List.of("u1", "u2", "u3")));
- assertThat(config.json_attributes_template, is("v"));
- assertThat(config.json_attributes_topic, is("w"));
- assertThat(config.mode_command_template, is("x"));
- assertThat(config.mode_command_topic, is("y"));
- assertThat(config.mode_state_template, is("z"));
- assertThat(config.mode_state_topic, is("A"));
+ assertThat(config.actionTemplate, is("a"));
+ assertThat(config.actionTopic, is("b"));
+ assertThat(config.auxCommandTopic, is("c"));
+ assertThat(config.auxStateTemplate, is("d"));
+ assertThat(config.auxStateTopic, is("e"));
+ assertThat(config.awayModeCommandTopic, is("f"));
+ assertThat(config.awayModeStateTemplate, is("g"));
+ assertThat(config.awayModeStateTopic, is("h"));
+ assertThat(config.currentTemperatureTemplate, is("i"));
+ assertThat(config.currentTemperatureTopic, is("j"));
+ assertThat(config.fanModeCommandTemplate, is("k"));
+ assertThat(config.fanModeCommandTopic, is("l"));
+ assertThat(config.fanModeStateTemplate, is("m"));
+ assertThat(config.fanModeStateTopic, is("n"));
+ assertThat(config.fanModes, is(List.of("p1", "p2")));
+ assertThat(config.holdCommandTemplate, is("q"));
+ assertThat(config.holdCommandTopic, is("r"));
+ assertThat(config.holdStateTemplate, is("s"));
+ assertThat(config.holdStateTopic, is("t"));
+ assertThat(config.holdModes, is(List.of("u1", "u2", "u3")));
+ assertThat(config.jsonAttributesTemplate, is("v"));
+ assertThat(config.jsonAttributesTopic, is("w"));
+ assertThat(config.modeCommandTemplate, is("x"));
+ assertThat(config.modeCommandTopic, is("y"));
+ assertThat(config.modeStateTemplate, is("z"));
+ assertThat(config.modeStateTopic, is("A"));
assertThat(config.modes, is(List.of("B1", "B2")));
- assertThat(config.swing_command_template, is("C"));
- assertThat(config.swing_command_topic, is("D"));
- assertThat(config.swing_state_template, is("E"));
- assertThat(config.swing_state_topic, is("F"));
- assertThat(config.swing_modes, is(List.of("G1")));
- assertThat(config.temperature_command_template, is("H"));
- assertThat(config.temperature_command_topic, is("I"));
- assertThat(config.temperature_state_template, is("J"));
- assertThat(config.temperature_state_topic, is("K"));
- assertThat(config.temperature_high_command_template, is("L"));
- assertThat(config.temperature_high_command_topic, is("N"));
- assertThat(config.temperature_high_state_template, is("O"));
- assertThat(config.temperature_high_state_topic, is("P"));
- assertThat(config.temperature_low_command_template, is("Q"));
- assertThat(config.temperature_low_command_topic, is("R"));
- assertThat(config.temperature_low_state_template, is("S"));
- assertThat(config.temperature_low_state_topic, is("T"));
- assertThat(config.power_command_topic, is("U"));
+ assertThat(config.swingCommandTemplate, is("C"));
+ assertThat(config.swingCommandTopic, is("D"));
+ assertThat(config.swingStateTemplate, is("E"));
+ assertThat(config.swingStateTopic, is("F"));
+ assertThat(config.swingModes, is(List.of("G1")));
+ assertThat(config.temperatureCommandTemplate, is("H"));
+ assertThat(config.temperatureCommandTopic, is("I"));
+ assertThat(config.temperatureStateTemplate, is("J"));
+ assertThat(config.temperatureStateTopic, is("K"));
+ assertThat(config.temperatureHighCommandTemplate, is("L"));
+ assertThat(config.temperatureHighCommandTopic, is("N"));
+ assertThat(config.temperatureHighStateTemplate, is("O"));
+ assertThat(config.temperatureHighStateTopic, is("P"));
+ assertThat(config.temperatureLowCommandTemplate, is("Q"));
+ assertThat(config.temperatureLowCommandTopic, is("R"));
+ assertThat(config.temperatureLowStateTemplate, is("S"));
+ assertThat(config.temperatureLowStateTopic, is("T"));
+ assertThat(config.powerCommandTopic, is("U"));
assertThat(config.initial, is(10));
- assertThat(config.max_temp, is(40f));
- assertThat(config.min_temp, is(0f));
- assertThat(config.temperature_unit, is("F"));
- assertThat(config.temp_step, is(1f));
+ assertThat(config.maxTemp, is(40f));
+ assertThat(config.minTemp, is(0f));
+ assertThat(config.temperatureUnit, is("F"));
+ assertThat(config.tempStep, is(1f));
assertThat(config.precision, is(0.5f));
- assertThat(config.send_if_off, is(false));
+ assertThat(config.sendIfOff, is(false));
}
}
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("light"));
- assertChannel(component, Light.colorChannelID, "zigbee2mqtt/light/rgb", "zigbee2mqtt/light/set/rgb", "light",
+ assertChannel(component, Light.COLOR_CHANNEL_ID, "zigbee2mqtt/light/rgb", "zigbee2mqtt/light/set/rgb", "light",
ColorValue.class);
assertChannel(component.switchChannel, "zigbee2mqtt/light/state", "zigbee2mqtt/light/set/state", "light",
"light", ColorValue.class);
publishMessage("zigbee2mqtt/light/rgb", "{\"rgb\": \"255,255,255\"}");
- assertState(component, Light.colorChannelID, HSBType.fromRGB(255, 255, 255));
+ assertState(component, Light.COLOR_CHANNEL_ID, HSBType.fromRGB(255, 255, 255));
publishMessage("zigbee2mqtt/light/rgb", "{\"rgb\": \"10,20,30\"}");
- assertState(component, Light.colorChannelID, HSBType.fromRGB(10, 20, 30));
+ assertState(component, Light.COLOR_CHANNEL_ID, HSBType.fromRGB(10, 20, 30));
component.switchChannel.getState().publishValue(OnOffType.OFF);
assertPublished("zigbee2mqtt/light/set/state", "0,0,0");
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("lock"));
- assertChannel(component, Lock.switchChannelID, "zigbee2mqtt/lock/state", "zigbee2mqtt/lock/set/state", "lock",
+ assertChannel(component, Lock.SWITCH_CHANNEL_ID, "zigbee2mqtt/lock/state", "zigbee2mqtt/lock/set/state", "lock",
OnOffValue.class);
publishMessage("zigbee2mqtt/lock/state", "LOCK_");
- assertState(component, Lock.switchChannelID, OnOffType.ON);
+ assertState(component, Lock.SWITCH_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/lock/state", "LOCK_");
- assertState(component, Lock.switchChannelID, OnOffType.ON);
+ assertState(component, Lock.SWITCH_CHANNEL_ID, OnOffType.ON);
publishMessage("zigbee2mqtt/lock/state", "UNLOCK_");
- assertState(component, Lock.switchChannelID, OnOffType.OFF);
+ assertState(component, Lock.SWITCH_CHANNEL_ID, OnOffType.OFF);
publishMessage("zigbee2mqtt/lock/state", "LOCK_");
- assertState(component, Lock.switchChannelID, OnOffType.ON);
+ assertState(component, Lock.SWITCH_CHANNEL_ID, OnOffType.ON);
- component.getChannel(Lock.switchChannelID).getState().publishValue(OnOffType.OFF);
+ component.getChannel(Lock.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
assertPublished("zigbee2mqtt/lock/set/state", "UNLOCK_");
- component.getChannel(Lock.switchChannelID).getState().publishValue(OnOffType.ON);
+ component.getChannel(Lock.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.ON);
assertPublished("zigbee2mqtt/lock/set/state", "LOCK_");
}
assertThat(component.getName(), is("sensor1"));
assertThat(component.getGroupUID().getId(), is("sn1"));
- assertChannel(component, Sensor.sensorChannelID, "zigbee2mqtt/sensor/state", "", "sensor1", NumberValue.class);
+ assertChannel(component, Sensor.SENSOR_CHANNEL_ID, "zigbee2mqtt/sensor/state", "", "sensor1",
+ NumberValue.class);
publishMessage("zigbee2mqtt/sensor/state", "10");
- assertState(component, Sensor.sensorChannelID, DecimalType.valueOf("10"));
+ assertState(component, Sensor.SENSOR_CHANNEL_ID, DecimalType.valueOf("10"));
publishMessage("zigbee2mqtt/sensor/state", "20");
- assertState(component, Sensor.sensorChannelID, DecimalType.valueOf("20"));
- assertThat(component.getChannel(Sensor.sensorChannelID).getState().getCache().createStateDescription(true)
+ assertState(component, Sensor.SENSOR_CHANNEL_ID, DecimalType.valueOf("20"));
+ assertThat(component.getChannel(Sensor.SENSOR_CHANNEL_ID).getState().getCache().createStateDescription(true)
.build().getPattern(), is("%s W"));
- waitForAssert(() -> assertState(component, Sensor.sensorChannelID, UnDefType.UNDEF), 10000, 200);
+ waitForAssert(() -> assertState(component, Sensor.SENSOR_CHANNEL_ID, UnDefType.UNDEF), 10000, 200);
}
protected Set<String> getConfigTopics() {
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("th1 auto lock"));
- assertChannel(component, Switch.switchChannelID, "zigbee2mqtt/th1", "zigbee2mqtt/th1/set/auto_lock", "state",
+ assertChannel(component, Switch.SWITCH_CHANNEL_ID, "zigbee2mqtt/th1", "zigbee2mqtt/th1/set/auto_lock", "state",
OnOffValue.class);
publishMessage("zigbee2mqtt/th1", "{\"auto_lock\": \"MANUAL\"}");
- assertState(component, Switch.switchChannelID, OnOffType.OFF);
+ assertState(component, Switch.SWITCH_CHANNEL_ID, OnOffType.OFF);
publishMessage("zigbee2mqtt/th1", "{\"auto_lock\": \"AUTO\"}");
- assertState(component, Switch.switchChannelID, OnOffType.ON);
+ assertState(component, Switch.SWITCH_CHANNEL_ID, OnOffType.ON);
- component.getChannel(Switch.switchChannelID).getState().publishValue(OnOffType.OFF);
+ component.getChannel(Switch.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
assertPublished("zigbee2mqtt/th1/set/auto_lock", "MANUAL");
- component.getChannel(Switch.switchChannelID).getState().publishValue(OnOffType.ON);
+ component.getChannel(Switch.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.ON);
assertPublished("zigbee2mqtt/th1/set/auto_lock", "AUTO");
}
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("th1 auto lock"));
- assertChannel(component, Switch.switchChannelID, "zigbee2mqtt/th1", "", "state", OnOffValue.class);
+ assertChannel(component, Switch.SWITCH_CHANNEL_ID, "zigbee2mqtt/th1", "", "state", OnOffValue.class);
publishMessage("zigbee2mqtt/th1", "{\"auto_lock\": \"MANUAL\"}");
- assertState(component, Switch.switchChannelID, OnOffType.OFF);
+ assertState(component, Switch.SWITCH_CHANNEL_ID, OnOffType.OFF);
publishMessage("zigbee2mqtt/th1", "{\"auto_lock\": \"AUTO\"}");
- assertState(component, Switch.switchChannelID, OnOffType.ON);
+ assertState(component, Switch.SWITCH_CHANNEL_ID, OnOffType.ON);
}
@Test
assertThat(component.channels.size(), is(1));
assertThat(component.getName(), is("th1 auto lock"));
- assertChannel(component, Switch.switchChannelID, "", "zigbee2mqtt/th1/set/auto_lock", "state",
+ assertChannel(component, Switch.SWITCH_CHANNEL_ID, "", "zigbee2mqtt/th1/set/auto_lock", "state",
OnOffValue.class);
- component.getChannel(Switch.switchChannelID).getState().publishValue(OnOffType.OFF);
+ component.getChannel(Switch.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.OFF);
assertPublished("zigbee2mqtt/th1/set/auto_lock", "MANUAL");
- component.getChannel(Switch.switchChannelID).getState().publishValue(OnOffType.ON);
+ component.getChannel(Switch.SWITCH_CHANNEL_ID).getState().publishValue(OnOffType.ON);
assertPublished("zigbee2mqtt/th1/set/auto_lock", "AUTO");
}
@SuppressWarnings({ "ConstantConditions" })
@ExtendWith(MockitoExtension.class)
public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests {
- private final static int SUBSCRIBE_TIMEOUT = 10000;
- private final static int ATTRIBUTE_RECEIVE_TIMEOUT = 2000;
+ private static final int SUBSCRIBE_TIMEOUT = 10000;
+ private static final int ATTRIBUTE_RECEIVE_TIMEOUT = 2000;
private static final List<String> CONFIG_TOPICS = Arrays.asList("climate/0x847127fffe11dd6a_climate_zigbee2mqtt",
"switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt",
+++ /dev/null
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.mqtt.homeassistant.internal.handler;
-
-import static org.openhab.binding.mqtt.homeassistant.generic.internal.MqttBindingConstants.*;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.core.config.core.Configuration;
-import org.openhab.core.thing.Channel;
-import org.openhab.core.thing.ThingUID;
-import org.openhab.core.thing.type.ChannelTypeUID;
-
-/**
- * Static test definitions, like thing, bridge and channel definitions
- *
- * @author David Graeff - Initial contribution
- */
-@NonNullByDefault
-public class ThingChannelConstants {
- // Common ThingUID and ChannelUIDs
- public static final ThingUID testHomeAssistantThing = new ThingUID(HOMEASSISTANT_MQTT_THING, "device234");
-
- public static final ChannelTypeUID unknownChannel = new ChannelTypeUID(BINDING_ID, "unknown");
-
- public static final String jsonPathJSON = "{ \"device\": { \"status\": { \"temperature\": 23.2 }}}";
- public static final String jsonPathPattern = "$.device.status.temperature";
-
- public static final List<Channel> thingChannelList = new ArrayList<>();
- public static final List<Channel> thingChannelListWithJson = new ArrayList<>();
-
- static Configuration textConfiguration() {
- Map<String, Object> data = new HashMap<>();
- data.put("stateTopic", "test/state");
- data.put("commandTopic", "test/command");
- return new Configuration(data);
- }
-
- static Configuration textConfigurationWithJson() {
- Map<String, Object> data = new HashMap<>();
- data.put("stateTopic", "test/state");
- data.put("commandTopic", "test/command");
- data.put("transformationPattern", "JSONPATH:" + jsonPathPattern);
- return new Configuration(data);
- }
-}