[mqtt.homeassistant] Add support for Update component (#14241)
* [mqtt.homeassistant] add support for Update component This component is fairly non-standard - it doesn't add any channels. Instead, it provides several properties to the thing, and also adds a thing configuration allowing you to trigger an OTA update on a Home Assistant device from MainUI. --------- Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
1712783945
commit
98fb791dc5
|
@ -104,7 +104,7 @@ public class DiscoverComponents implements MqttMessageSubscriber {
|
||||||
gson, transformationServiceProvider);
|
gson, transformationServiceProvider);
|
||||||
component.setConfigSeen();
|
component.setConfigSeen();
|
||||||
|
|
||||||
logger.trace("Found HomeAssistant thing {} component {}", haID.objectID, haID.component);
|
logger.trace("Found HomeAssistant component {}", haID);
|
||||||
|
|
||||||
if (discoveredListener != null) {
|
if (discoveredListener != null) {
|
||||||
discoveredListener.componentDiscovered(haID, component);
|
discoveredListener.componentDiscovered(haID, component);
|
||||||
|
|
|
@ -83,6 +83,8 @@ public class ComponentFactory {
|
||||||
return new Sensor(componentConfiguration);
|
return new Sensor(componentConfiguration);
|
||||||
case "switch":
|
case "switch":
|
||||||
return new Switch(componentConfiguration);
|
return new Switch(componentConfiguration);
|
||||||
|
case "update":
|
||||||
|
return new Update(componentConfiguration);
|
||||||
case "vacuum":
|
case "vacuum":
|
||||||
return new Vacuum(componentConfiguration);
|
return new Vacuum(componentConfiguration);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
|
||||||
|
import org.openhab.binding.mqtt.generic.values.TextValue;
|
||||||
|
import org.openhab.binding.mqtt.homeassistant.internal.ComponentChannel;
|
||||||
|
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
|
||||||
|
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
|
||||||
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A MQTT Update component, following the https://www.home-assistant.io/integrations/update.mqtt/ specification.
|
||||||
|
*
|
||||||
|
* @author Cody Cutrer - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class Update extends AbstractComponent<Update.ChannelConfiguration> implements ChannelStateUpdateListener {
|
||||||
|
public static final String UPDATE_CHANNEL_ID = "update";
|
||||||
|
public static final String LATEST_VERSION_CHANNEL_ID = "latestVersion";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration class for MQTT component
|
||||||
|
*/
|
||||||
|
static class ChannelConfiguration extends AbstractChannelConfiguration {
|
||||||
|
ChannelConfiguration() {
|
||||||
|
super("MQTT Update");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedName("latest_version_template")
|
||||||
|
protected @Nullable String latestVersionTemplate;
|
||||||
|
@SerializedName("latest_version_topic")
|
||||||
|
protected @Nullable String latestVersionTopic;
|
||||||
|
@SerializedName("command_topic")
|
||||||
|
protected @Nullable String commandTopic;
|
||||||
|
@SerializedName("state_topic")
|
||||||
|
protected @Nullable String stateTopic;
|
||||||
|
|
||||||
|
protected @Nullable String title;
|
||||||
|
@SerializedName("release_summary")
|
||||||
|
protected @Nullable String releaseSummary;
|
||||||
|
@SerializedName("release_url")
|
||||||
|
protected @Nullable String releaseUrl;
|
||||||
|
|
||||||
|
@SerializedName("payload_install")
|
||||||
|
protected @Nullable String payloadInstall;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the state payload if it's JSON
|
||||||
|
*/
|
||||||
|
public static class ReleaseState {
|
||||||
|
// these are designed to fit in with the default property of firmwareVersion
|
||||||
|
public static final String PROPERTY_LATEST_VERSION = "latestFirmwareVersion";
|
||||||
|
public static final String PROPERTY_TITLE = "firmwareTitle";
|
||||||
|
public static final String PROPERTY_RELEASE_SUMMARY = "firmwareSummary";
|
||||||
|
public static final String PROPERTY_RELEASE_URL = "firmwareURL";
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String installedVersion;
|
||||||
|
@Nullable
|
||||||
|
String latestVersion;
|
||||||
|
@Nullable
|
||||||
|
String title;
|
||||||
|
@Nullable
|
||||||
|
String releaseSummary;
|
||||||
|
@Nullable
|
||||||
|
String releaseUrl;
|
||||||
|
@Nullable
|
||||||
|
String entityPicture;
|
||||||
|
|
||||||
|
public Map<String, String> appendToProperties(Map<String, String> properties) {
|
||||||
|
String installedVersion = this.installedVersion;
|
||||||
|
if (installedVersion != null && !installedVersion.isBlank()) {
|
||||||
|
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, installedVersion);
|
||||||
|
}
|
||||||
|
// don't remove the firmwareVersion property; it might be coming from the
|
||||||
|
// device as well
|
||||||
|
|
||||||
|
String latestVersion = this.latestVersion;
|
||||||
|
if (latestVersion != null) {
|
||||||
|
properties.put(PROPERTY_LATEST_VERSION, latestVersion);
|
||||||
|
} else {
|
||||||
|
properties.remove(PROPERTY_LATEST_VERSION);
|
||||||
|
}
|
||||||
|
String title = this.title;
|
||||||
|
if (title != null) {
|
||||||
|
properties.put(PROPERTY_TITLE, title);
|
||||||
|
} else {
|
||||||
|
properties.remove(title);
|
||||||
|
}
|
||||||
|
String releaseSummary = this.releaseSummary;
|
||||||
|
if (releaseSummary != null) {
|
||||||
|
properties.put(PROPERTY_RELEASE_SUMMARY, releaseSummary);
|
||||||
|
} else {
|
||||||
|
properties.remove(PROPERTY_RELEASE_SUMMARY);
|
||||||
|
}
|
||||||
|
String releaseUrl = this.releaseUrl;
|
||||||
|
if (releaseUrl != null) {
|
||||||
|
properties.put(PROPERTY_RELEASE_URL, releaseUrl);
|
||||||
|
} else {
|
||||||
|
properties.remove(PROPERTY_RELEASE_URL);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ReleaseStateListener {
|
||||||
|
void releaseStateUpdated(ReleaseState newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(Update.class);
|
||||||
|
|
||||||
|
private ComponentChannel updateChannel;
|
||||||
|
private @Nullable ComponentChannel latestVersionChannel;
|
||||||
|
private boolean updatable = false;
|
||||||
|
private ReleaseState state = new ReleaseState();
|
||||||
|
private @Nullable ReleaseStateListener listener = null;
|
||||||
|
|
||||||
|
public Update(ComponentFactory.ComponentConfiguration componentConfiguration) {
|
||||||
|
super(componentConfiguration, ChannelConfiguration.class);
|
||||||
|
|
||||||
|
TextValue value = new TextValue();
|
||||||
|
String commandTopic = channelConfiguration.commandTopic;
|
||||||
|
String payloadInstall = channelConfiguration.payloadInstall;
|
||||||
|
|
||||||
|
var builder = buildChannel(UPDATE_CHANNEL_ID, value, getName(), this);
|
||||||
|
if (channelConfiguration.stateTopic != null) {
|
||||||
|
builder.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate());
|
||||||
|
}
|
||||||
|
if (commandTopic != null && payloadInstall != null) {
|
||||||
|
updatable = true;
|
||||||
|
builder.commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
|
||||||
|
channelConfiguration.getQos());
|
||||||
|
}
|
||||||
|
updateChannel = builder.build(false);
|
||||||
|
|
||||||
|
if (channelConfiguration.latestVersionTopic != null) {
|
||||||
|
value = new TextValue();
|
||||||
|
latestVersionChannel = buildChannel(LATEST_VERSION_CHANNEL_ID, value, getName(), this)
|
||||||
|
.stateTopic(channelConfiguration.latestVersionTopic, channelConfiguration.latestVersionTemplate)
|
||||||
|
.build(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.title = channelConfiguration.title;
|
||||||
|
state.releaseSummary = channelConfiguration.releaseSummary;
|
||||||
|
state.releaseUrl = channelConfiguration.releaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if this device can be updated
|
||||||
|
*/
|
||||||
|
public boolean isUpdatable() {
|
||||||
|
return updatable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger an OTA update for this device
|
||||||
|
*/
|
||||||
|
public void doUpdate() {
|
||||||
|
if (!updatable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String commandTopic = channelConfiguration.commandTopic;
|
||||||
|
String payloadInstall = channelConfiguration.payloadInstall;
|
||||||
|
|
||||||
|
updateChannel.getState().publishValue(new StringType(payloadInstall)).handle((v, ex) -> {
|
||||||
|
if (ex != null) {
|
||||||
|
logger.debug("Failed publishing value {} to topic {}: {}", payloadInstall, commandTopic,
|
||||||
|
ex.getMessage());
|
||||||
|
} else {
|
||||||
|
logger.debug("Successfully published value {} to topic {}", payloadInstall, commandTopic);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<@Nullable Void> start(MqttBrokerConnection connection, ScheduledExecutorService scheduler,
|
||||||
|
int timeout) {
|
||||||
|
var updateFuture = updateChannel.start(connection, scheduler, timeout);
|
||||||
|
ComponentChannel latestVersionChannel = this.latestVersionChannel;
|
||||||
|
if (latestVersionChannel == null) {
|
||||||
|
return updateFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
var latestVersionFuture = latestVersionChannel.start(connection, scheduler, timeout);
|
||||||
|
return CompletableFuture.allOf(updateFuture, latestVersionFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<@Nullable Void> stop() {
|
||||||
|
var updateFuture = updateChannel.stop();
|
||||||
|
ComponentChannel latestVersionChannel = this.latestVersionChannel;
|
||||||
|
if (latestVersionChannel == null) {
|
||||||
|
return updateFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
var latestVersionFuture = latestVersionChannel.stop();
|
||||||
|
return CompletableFuture.allOf(updateFuture, latestVersionFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateChannelState(ChannelUID channelUID, State value) {
|
||||||
|
switch (channelUID.getIdWithoutGroup()) {
|
||||||
|
case UPDATE_CHANNEL_ID:
|
||||||
|
String strValue = value.toString();
|
||||||
|
try {
|
||||||
|
// check if it's JSON first
|
||||||
|
@Nullable
|
||||||
|
final ReleaseState releaseState = getGson().fromJson(strValue, ReleaseState.class);
|
||||||
|
if (releaseState != null) {
|
||||||
|
state = releaseState;
|
||||||
|
notifyReleaseStateUpdated();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
// Ignore; it's just a string of installed_version
|
||||||
|
}
|
||||||
|
state.installedVersion = strValue;
|
||||||
|
break;
|
||||||
|
case LATEST_VERSION_CHANNEL_ID:
|
||||||
|
state.latestVersion = value.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
notifyReleaseStateUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postChannelCommand(ChannelUID channelUID, Command value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void triggerChannel(ChannelUID channelUID, String eventPayload) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReleaseStateUpdateListener(ReleaseStateListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
notifyReleaseStateUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyReleaseStateUpdated() {
|
||||||
|
var listener = this.listener;
|
||||||
|
if (listener != null) {
|
||||||
|
listener.releaseStateUpdated(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.mqtt.homeassistant.internal.handler;
|
package org.openhab.binding.mqtt.homeassistant.internal.handler;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -41,8 +42,10 @@ import org.openhab.binding.mqtt.homeassistant.internal.HaID;
|
||||||
import org.openhab.binding.mqtt.homeassistant.internal.HandlerConfiguration;
|
import org.openhab.binding.mqtt.homeassistant.internal.HandlerConfiguration;
|
||||||
import org.openhab.binding.mqtt.homeassistant.internal.component.AbstractComponent;
|
import org.openhab.binding.mqtt.homeassistant.internal.component.AbstractComponent;
|
||||||
import org.openhab.binding.mqtt.homeassistant.internal.component.ComponentFactory;
|
import org.openhab.binding.mqtt.homeassistant.internal.component.ComponentFactory;
|
||||||
|
import org.openhab.binding.mqtt.homeassistant.internal.component.Update;
|
||||||
import org.openhab.binding.mqtt.homeassistant.internal.config.ChannelConfigurationTypeAdapterFactory;
|
import org.openhab.binding.mqtt.homeassistant.internal.config.ChannelConfigurationTypeAdapterFactory;
|
||||||
import org.openhab.binding.mqtt.homeassistant.internal.exception.ConfigurationException;
|
import org.openhab.binding.mqtt.homeassistant.internal.exception.ConfigurationException;
|
||||||
|
import org.openhab.core.config.core.validation.ConfigValidationException;
|
||||||
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
|
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelGroupUID;
|
import org.openhab.core.thing.ChannelGroupUID;
|
||||||
|
@ -84,7 +87,8 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
|
||||||
implements ComponentDiscovered, Consumer<List<AbstractComponent<?>>> {
|
implements ComponentDiscovered, Consumer<List<AbstractComponent<?>>> {
|
||||||
public static final String AVAILABILITY_CHANNEL = "availability";
|
public static final String AVAILABILITY_CHANNEL = "availability";
|
||||||
private static final Comparator<Channel> CHANNEL_COMPARATOR_BY_UID = Comparator
|
private static final Comparator<Channel> CHANNEL_COMPARATOR_BY_UID = Comparator
|
||||||
.comparing(channel -> channel.getUID().toString());;
|
.comparing(channel -> channel.getUID().toString());
|
||||||
|
private static final URI UPDATABLE_CONFIG_DESCRIPTION_URI = URI.create("thing-type:mqtt:homeassistant-updatable");
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(HomeAssistantThingHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(HomeAssistantThingHandler.class);
|
||||||
|
|
||||||
|
@ -102,6 +106,7 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
|
||||||
protected final TransformationServiceProvider transformationServiceProvider;
|
protected final TransformationServiceProvider transformationServiceProvider;
|
||||||
|
|
||||||
private boolean started;
|
private boolean started;
|
||||||
|
private @Nullable Update updateComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new thing handler for HomeAssistant MQTT components.
|
* Create a new thing handler for HomeAssistant MQTT components.
|
||||||
|
@ -293,6 +298,11 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (discovered instanceof Update) {
|
||||||
|
updateComponent = (Update) discovered;
|
||||||
|
updateComponent.setReleaseStateUpdateListener(this::releaseStateUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
List<Channel> discoveredChannels = discovered.getChannelMap().values().stream()
|
List<Channel> discoveredChannels = discovered.getChannelMap().values().stream()
|
||||||
.map(ComponentChannel::getChannel).collect(Collectors.toList());
|
.map(ComponentChannel::getChannel).collect(Collectors.toList());
|
||||||
if (known != null) {
|
if (known != null) {
|
||||||
|
@ -342,6 +352,26 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleConfigurationUpdate(Map<String, Object> configurationParameters)
|
||||||
|
throws ConfigValidationException {
|
||||||
|
if (configurationParameters.containsKey("doUpdate")) {
|
||||||
|
configurationParameters = new HashMap<>(configurationParameters);
|
||||||
|
Object value = configurationParameters.remove("doUpdate");
|
||||||
|
if (value instanceof Boolean doUpdate && doUpdate) {
|
||||||
|
Update updateComponent = this.updateComponent;
|
||||||
|
if (updateComponent == null) {
|
||||||
|
logger.warn(
|
||||||
|
"Received update command for Home Assistant device {}, but it does not have an update component.",
|
||||||
|
getThing().getUID());
|
||||||
|
} else {
|
||||||
|
updateComponent.doUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.handleConfigurationUpdate(configurationParameters);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateThingType() {
|
private void updateThingType() {
|
||||||
// if this is a dynamic type, then we update the type
|
// if this is a dynamic type, then we update the type
|
||||||
ThingTypeUID typeID = thing.getThingTypeUID();
|
ThingTypeUID typeID = thing.getThingTypeUID();
|
||||||
|
@ -354,10 +384,21 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
|
||||||
channelDefs = haComponents.values().stream().map(AbstractComponent::getChannels).flatMap(List::stream)
|
channelDefs = haComponents.values().stream().map(AbstractComponent::getChannels).flatMap(List::stream)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
ThingType thingType = channelTypeProvider.derive(typeID, MqttBindingConstants.HOMEASSISTANT_MQTT_THING)
|
var builder = channelTypeProvider.derive(typeID, MqttBindingConstants.HOMEASSISTANT_MQTT_THING)
|
||||||
.withChannelDefinitions(channelDefs).withChannelGroupDefinitions(groupDefs).build();
|
.withChannelDefinitions(channelDefs).withChannelGroupDefinitions(groupDefs);
|
||||||
|
Update updateComponent = this.updateComponent;
|
||||||
|
if (updateComponent != null && updateComponent.isUpdatable()) {
|
||||||
|
builder.withConfigDescriptionURI(UPDATABLE_CONFIG_DESCRIPTION_URI);
|
||||||
|
}
|
||||||
|
ThingType thingType = builder.build();
|
||||||
|
|
||||||
channelTypeProvider.setThingType(typeID, thingType);
|
channelTypeProvider.setThingType(typeID, thingType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void releaseStateUpdated(Update.ReleaseState state) {
|
||||||
|
Map<String, String> properties = editProperties();
|
||||||
|
properties = state.appendToProperties(properties);
|
||||||
|
updateProperties(properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<config-description:config-descriptions
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
<config-description uri="thing-type:mqtt:homeassistant">
|
||||||
|
<parameter name="topics" type="text" required="true" multiple="true">
|
||||||
|
<label>MQTT Config Topic</label>
|
||||||
|
<description>List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)</description>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="basetopic" type="text" required="true">
|
||||||
|
<label>MQTT Base Prefix</label>
|
||||||
|
<description>MQTT base prefix</description>
|
||||||
|
<default>homeassistant</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
|
<config-description uri="thing-type:mqtt:homeassistant-updatable">
|
||||||
|
<parameter-group name="actions">
|
||||||
|
<label>Actions</label>
|
||||||
|
</parameter-group>
|
||||||
|
|
||||||
|
<parameter name="topics" type="text" required="true" multiple="true">
|
||||||
|
<label>MQTT Config Topic</label>
|
||||||
|
<description>List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)</description>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="basetopic" type="text" required="true">
|
||||||
|
<label>MQTT Base Prefix</label>
|
||||||
|
<description>MQTT base prefix</description>
|
||||||
|
<default>homeassistant</default>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="doUpdate" type="boolean" groupName="actions">
|
||||||
|
<label>Update</label>
|
||||||
|
<description>Request the device do an OTA update</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
<default>false</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
</config-description:config-descriptions>
|
|
@ -9,6 +9,12 @@ thing-type.config.mqtt.homeassistant.basetopic.label = MQTT Base Prefix
|
||||||
thing-type.config.mqtt.homeassistant.basetopic.description = MQTT base prefix
|
thing-type.config.mqtt.homeassistant.basetopic.description = MQTT base prefix
|
||||||
thing-type.config.mqtt.homeassistant.topics.label = MQTT Config Topic
|
thing-type.config.mqtt.homeassistant.topics.label = MQTT Config Topic
|
||||||
thing-type.config.mqtt.homeassistant.topics.description = List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)
|
thing-type.config.mqtt.homeassistant.topics.description = List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.basetopic.label = MQTT Base Prefix
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.basetopic.description = MQTT base prefix
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.topics.label = MQTT Config Topic
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.topics.description = List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.doUpdate.label = Update
|
||||||
|
thing-type.config.mqtt.homeassistant-updatable.doUpdate.description = Request the device do an OTA update
|
||||||
|
|
||||||
# channel types config
|
# channel types config
|
||||||
|
|
||||||
|
|
|
@ -11,17 +11,6 @@
|
||||||
<label>HomeAssistant MQTT Component</label>
|
<label>HomeAssistant MQTT Component</label>
|
||||||
<description>You need a configured Broker first. This Thing represents a device, that follows the "HomeAssistant MQTT
|
<description>You need a configured Broker first. This Thing represents a device, that follows the "HomeAssistant MQTT
|
||||||
Component" specification.</description>
|
Component" specification.</description>
|
||||||
<config-description>
|
<config-description-ref uri="thing-type:mqtt:homeassistant"/>
|
||||||
<parameter name="topics" type="text" required="true" multiple="true">
|
|
||||||
<label>MQTT Config Topic</label>
|
|
||||||
<description>List of HomeAssistant configuration topics (e.g. /homeassistant/switch/4711/config)</description>
|
|
||||||
</parameter>
|
|
||||||
|
|
||||||
<parameter name="basetopic" type="text" required="true">
|
|
||||||
<label>MQTT Base Prefix</label>
|
|
||||||
<description>MQTT base prefix</description>
|
|
||||||
<default>homeassistant</default>
|
|
||||||
</parameter>
|
|
||||||
</config-description>
|
|
||||||
</thing-type>
|
</thing-type>
|
||||||
</thing:thing-descriptions>
|
</thing:thing-descriptions>
|
||||||
|
|
Loading…
Reference in New Issue