Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mqtt-homeassistant] climate.mqtt support #10690

Merged
merged 23 commits into from
Aug 15, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d434a9c
MQTT.Homeassistant Climate support
Apr 19, 2021
ce62448
MQTT.Homeassistant synthetic config test added
Apr 26, 2021
8b622df
MQTT.Homeassistant refactoring
Apr 29, 2021
2e2e06a
MQTT.Homeassistant discovery test added
Apr 30, 2021
720ef5b
MQTT.Homeassistant thing handler test added
May 13, 2021
2901820
MQTT.Homeassistant switch test added
May 13, 2021
b907c4e
MQTT.Homeassistant Climate test added
May 13, 2021
7edef9d
MQTT.Homeassistant author header added
May 13, 2021
5ac0699
MQTT.Homeassistant copyright header added
May 13, 2021
eebc828
MQTT.Homeassistant test fixed
May 13, 2021
15f49dc
MQTT.Homeassistant test fixed
May 14, 2021
f1ae619
MQTT.Homeassistant test infrastructure updated. Added tests with mqtt…
May 17, 2021
93173b0
MQTT.Homeassistant fixed Climate#send_if_off handling
May 17, 2021
aababd2
MQTT.Homeassistant do not filter the power command
May 18, 2021
cba1d07
MQTT.Homeassistant climate unit test added
May 18, 2021
595fa0f
Update bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/o…
antroids Jun 22, 2021
0f7960d
MQTT.Homeassistant Redundant @Nullable annotations removed
Jun 24, 2021
3906c9d
MQTT.Homeassistant Unit tests added for all components
Jun 29, 2021
37d74f7
MQTT.Homeassistant Unit tests stability fix
Jul 14, 2021
5bb66a8
MQTT.Homeassistant @NonNullByDefault removed from Device, config.dto …
Jul 14, 2021
c65e0eb
MQTT.Homeassistant Climate author added
Jul 14, 2021
adefec0
MQTT.Homeassistant Device.sw_version renamed
Jul 15, 2021
ce46197
MQTT.Homeassistant tests wait timeout increased to 10s
Jul 18, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions bundles/org.openhab.binding.mqtt.homeassistant/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,12 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.jinja</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.net.URI;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Predicate;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -26,7 +27,7 @@
import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
import org.openhab.binding.mqtt.generic.values.Value;
import org.openhab.binding.mqtt.homeassistant.generic.internal.MqttBindingConstants;
import org.openhab.binding.mqtt.homeassistant.internal.CFactory.ComponentConfiguration;
import org.openhab.binding.mqtt.homeassistant.internal.component.AbstractComponent;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.thing.Channel;
Expand All @@ -37,6 +38,7 @@
import org.openhab.core.thing.type.ChannelType;
import org.openhab.core.thing.type.ChannelTypeBuilder;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.StateDescriptionFragment;

/**
Expand All @@ -55,7 +57,7 @@
* @author David Graeff - Initial contribution
*/
@NonNullByDefault
public class CChannel {
public class ComponentChannel {
private static final String JINJA = "JINJA";

private final ChannelUID channelUID;
Expand All @@ -65,7 +67,7 @@ public class CChannel {
private final ChannelTypeUID channelTypeUID;
private final ChannelStateUpdateListener channelStateUpdateListener;

private CChannel(ChannelUID channelUID, ChannelState channelState, Channel channel, ChannelType type,
private ComponentChannel(ChannelUID channelUID, ChannelState channelState, Channel channel, ChannelType type,
ChannelTypeUID channelTypeUID, ChannelStateUpdateListener channelStateUpdateListener) {
super();
this.channelUID = channelUID;
Expand Down Expand Up @@ -117,24 +119,25 @@ public void resetState() {
}

public static class Builder {
private AbstractComponent<?> component;
private ComponentConfiguration componentConfiguration;
private String channelID;
private Value valueState;
private String label;
private final AbstractComponent<?> component;
private final String channelID;
private final Value valueState;
private final String label;
private final ChannelStateUpdateListener channelStateUpdateListener;

private @Nullable String state_topic;
private @Nullable String command_topic;
private boolean retain;
private boolean trigger;
private @Nullable Integer qos;
private ChannelStateUpdateListener channelStateUpdateListener;
private @Nullable Predicate<Command> commandFilter;

private @Nullable String templateIn;
private @Nullable String templateOut;

public Builder(AbstractComponent<?> component, ComponentConfiguration componentConfiguration, String channelID,
Value valueState, String label, ChannelStateUpdateListener channelStateUpdateListener) {
public Builder(AbstractComponent<?> component, String channelID, Value valueState, String label,
ChannelStateUpdateListener channelStateUpdateListener) {
this.component = component;
this.componentConfiguration = componentConfiguration;
this.channelID = channelID;
this.valueState = valueState;
this.label = label;
Expand All @@ -161,9 +164,9 @@ public Builder stateTopic(@Nullable String state_topic, @Nullable String... temp

/**
* @deprecated use commandTopic(String, boolean, int)
* @param command_topic
* @param retain
* @return
* @param command_topic topic
* @param retain retain
* @return this
*/
@Deprecated
public Builder commandTopic(@Nullable String command_topic, boolean retain) {
Expand All @@ -173,9 +176,17 @@ public Builder commandTopic(@Nullable String command_topic, boolean retain) {
}

public Builder commandTopic(@Nullable String command_topic, boolean retain, int qos) {
return commandTopic(command_topic, retain, qos, null);
}

public Builder commandTopic(@Nullable String command_topic, boolean retain, int qos,
@Nullable String template) {
this.command_topic = command_topic;
this.retain = retain;
this.qos = qos;
if (command_topic != null && !command_topic.isBlank()) {
this.templateOut = template;
}
return this;
}

Expand All @@ -184,24 +195,29 @@ public Builder trigger(boolean trigger) {
return this;
}

public CChannel build() {
public Builder commandFilter(@Nullable Predicate<Command> commandFilter) {
this.commandFilter = commandFilter;
return this;
}

public ComponentChannel build() {
return build(true);
}

public CChannel build(boolean addToComponent) {
public ComponentChannel build(boolean addToComponent) {
ChannelUID channelUID;
ChannelState channelState;
Channel channel;
ChannelType type;
ChannelTypeUID channelTypeUID;

channelUID = new ChannelUID(component.channelGroupUID, channelID);
channelUID = new ChannelUID(component.getGroupUID(), channelID);
channelTypeUID = new ChannelTypeUID(MqttBindingConstants.BINDING_ID,
channelUID.getGroupId() + "_" + channelID);
channelState = new ChannelState(
channelState = new HomeAssistantChannelState(
ChannelConfigBuilder.create().withRetain(retain).withQos(qos).withStateTopic(state_topic)
.withCommandTopic(command_topic).makeTrigger(trigger).build(),
channelUID, valueState, channelStateUpdateListener);
channelUID, valueState, channelStateUpdateListener, commandFilter);

String localStateTopic = state_topic;
if (localStateTopic == null || localStateTopic.isBlank() || this.trigger) {
Expand All @@ -215,26 +231,29 @@ public CChannel build(boolean addToComponent) {
}

Configuration configuration = new Configuration();
configuration.put("config", component.channelConfigurationJson);
component.haID.toConfig(configuration);
configuration.put("config", component.getChannelConfigurationJson());
component.getHaID().toConfig(configuration);

channel = ChannelBuilder.create(channelUID, channelState.getItemType()).withType(channelTypeUID)
.withKind(type.getKind()).withLabel(label).withConfiguration(configuration).build();

CChannel result = new CChannel(channelUID, channelState, channel, type, channelTypeUID,
ComponentChannel result = new ComponentChannel(channelUID, channelState, channel, type, channelTypeUID,
channelStateUpdateListener);

@Nullable
TransformationServiceProvider transformationProvider = componentConfiguration
.getTransformationServiceProvider();
TransformationServiceProvider transformationProvider = component.getTransformationServiceProvider();

final String templateIn = this.templateIn;
if (templateIn != null && transformationProvider != null) {
channelState
.addTransformation(new ChannelStateTransformation(JINJA, templateIn, transformationProvider));
}
final String templateOut = this.templateOut;
if (templateOut != null && transformationProvider != null) {
channelState.addTransformationOut(
new ChannelStateTransformation(JINJA, templateOut, transformationProvider));
}
if (addToComponent) {
component.channels.put(channelID, result);
component.getChannelMap().put(channelID, result);
}
return result;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
import org.openhab.binding.mqtt.generic.utils.FutureCollector;
import org.openhab.binding.mqtt.homeassistant.internal.component.AbstractComponent;
import org.openhab.binding.mqtt.homeassistant.internal.component.ComponentFactory;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttMessageSubscriber;
import org.openhab.core.thing.ThingUID;
Expand Down Expand Up @@ -55,7 +57,7 @@ public class DiscoverComponents implements MqttMessageSubscriber {

private @Nullable ScheduledFuture<?> stopDiscoveryFuture;
private WeakReference<@Nullable MqttBrokerConnection> connectionRef = new WeakReference<>(null);
protected @NonNullByDefault({}) ComponentDiscovered discoveredListener;
protected @Nullable ComponentDiscovered discoveredListener;
private int discoverTime;
private Set<String> topics = new HashSet<>();

Expand Down Expand Up @@ -92,12 +94,11 @@ public void processMessage(String topic, byte[] payload) {

HaID haID = new HaID(topic);
String config = new String(payload);

AbstractComponent<?> component = null;

if (config.length() > 0) {
component = CFactory.createComponent(thingUID, haID, config, updateListener, tracker, scheduler, gson,
transformationServiceProvider);
component = ComponentFactory.createComponent(thingUID, haID, config, updateListener, tracker, scheduler,
gson, transformationServiceProvider);
}
if (component != null) {
component.setConfigSeen();
Expand All @@ -122,9 +123,9 @@ public void processMessage(String topic, byte[] payload) {
* @param connection A MQTT broker connection
* @param discoverTime The time in milliseconds for the discovery to run. Can be 0 to disable the
* timeout.
* You need to call {@link #stopDiscovery(MqttBrokerConnection)} at some
* You need to call {@link #stopDiscovery()} at some
* point in that case.
* @param topicDescription Contains the object-id (=device id) and potentially a node-id as well.
* @param topicDescriptions Contains the object-id (=device id) and potentially a node-id as well.
* @param componentsDiscoveredListener Listener for results
* @return A future that completes normally after the given time in milliseconds or exceptionally on any error.
* Completes immediately if the timeout is disabled.
Expand Down Expand Up @@ -177,8 +178,6 @@ private void subscribeSuccess() {

/**
* Stops an ongoing discovery or do nothing if no discovery is running.
*
* @param connection A MQTT broker connection
*/
public void stopDiscovery() {
subscribeFail(new Throwable("Stopped"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private HaID(String baseTopic, String objectID, String nodeID, String component)
this.topic = createTopic(this);
}

private static final String createTopic(HaID id) {
private static String createTopic(HaID id) {
StringBuilder str = new StringBuilder();
str.append(id.baseTopic).append('/').append(id.component).append('/');
if (!id.nodeID.isBlank()) {
Expand All @@ -104,8 +104,8 @@ private static final String createTopic(HaID id) {
* <p>
* <code>objectid</code>, <code>nodeid</code>, and <code>component</code> values are fetched from the configuration.
*
* @param baseTopic
* @param config
* @param baseTopic base topic
* @param config config
* @return newly created HaID
*/
public static HaID fromConfig(String baseTopic, Configuration config) {
Expand All @@ -120,7 +120,7 @@ public static HaID fromConfig(String baseTopic, Configuration config) {
* <p>
* <code>objectid</code>, <code>nodeid</code>, and <code>component</code> values are added to the configuration.
*
* @param config
* @param config config
* @return the modified configuration
*/
public Configuration toConfig(Configuration config) {
Expand All @@ -139,7 +139,7 @@ public Configuration toConfig(Configuration config) {
* The <code>component</code> component in the resulting HaID will be set to <code>+</code>.
* This enables the HaID to be used as an mqtt subscription topic.
*
* @param config
* @param config config
* @return newly created HaID
*/
public static Collection<HaID> fromConfig(HandlerConfiguration config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
*/
@NonNullByDefault
public class HandlerConfiguration {
public static final String PROPERTY_BASETOPIC = "basetopic";
public static final String PROPERTY_TOPICS = "topics";
public static final String DEFAULT_BASETOPIC = "homeassistant";
/**
* hint: cannot be final, or <code>getConfigAs</code> will not work.
* The MQTT prefix topic
Expand Down Expand Up @@ -64,7 +67,7 @@ public class HandlerConfiguration {
public List<String> topics;

public HandlerConfiguration() {
this("homeassistant", Collections.emptyList());
this(DEFAULT_BASETOPIC, Collections.emptyList());
}

public HandlerConfiguration(String basetopic, List<String> topics) {
Expand All @@ -76,12 +79,12 @@ public HandlerConfiguration(String basetopic, List<String> topics) {
/**
* Add the <code>basetopic</code> and <code>objectid</code> to the properties.
*
* @param properties
* @param properties properties
* @return the modified properties
*/
public <T extends Map<String, Object>> T appendToProperties(T properties) {
properties.put("basetopic", basetopic);
properties.put("topics", topics);
properties.put(PROPERTY_BASETOPIC, basetopic);
properties.put(PROPERTY_TOPICS, topics);
return properties;
}
}
Loading