[mqtt.homeassistant] ensure availability topics get subscribed (#13466)

HASS registers availability topics before calling start(), so
the AbstractMQTTThingHandler was never subscribing/starting the
availability channel(s). So do so in start() of the base class.

I checked other implementations, and either they already handle
re-registering availabilityTopics in their start()
(GenericMQTTThingHandler), or they don't use availabilityTopics
at all from the base class and manage it themselves (Homie).

Note that this shows up as newly-added HASS things not having
a problem (because the components aren't discovered until after
the ThingHandler is started), but if you restart OpenHAB or
disable/enable the thing, the channels (and components) are
cached, thus how availabilityTopics are known before starting.

Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
Cody Cutrer 2022-10-08 01:12:28 -06:00 committed by GitHub
parent 959e65814b
commit 98677c18b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 8 deletions

View File

@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mqtt.generic.utils.FutureCollector;
import org.openhab.binding.mqtt.generic.values.OnOffValue;
import org.openhab.binding.mqtt.generic.values.Value;
import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
@ -103,7 +104,10 @@ public abstract class AbstractMQTTThingHandler extends BaseThingHandler
* @param connection A started broker connection
* @return A future that completes normal on success and exceptionally on any errors.
*/
protected abstract CompletableFuture<@Nullable Void> start(MqttBrokerConnection connection);
protected CompletableFuture<@Nullable Void> start(MqttBrokerConnection connection) {
return availabilityStates.values().parallelStream().map(cChannel -> cChannel.start(connection, scheduler, 0))
.collect(FutureCollector.allOf());
}
/**
* Called when the MQTT connection disappeared.

View File

@ -194,13 +194,14 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
// Start all known components and channels within the components and put the Thing offline
// if any subscribing failed ( == broker connection lost)
CompletableFuture<@Nullable Void> future = haComponents.values().parallelStream()
.map(e -> e.start(connection, scheduler, attributeReceiveTimeout))
.reduce(CompletableFuture.completedFuture(null), (a, v) -> a.thenCompose(b -> v)) // reduce to one
CompletableFuture<@Nullable Void> future = CompletableFuture.allOf(super.start(connection),
haComponents.values().parallelStream().map(e -> e.start(connection, scheduler, attributeReceiveTimeout))
.reduce(CompletableFuture.completedFuture(null), (a, v) -> a.thenCompose(b -> v)) // reduce to
// one
.exceptionally(e -> {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
return null;
});
}));
return future
.thenCompose(b -> discoverComponents.startDiscovery(connection, 0, discoveryHomeAssistantIDs, this));