[mqtt.homeassistant] More readable label for discovered things (#13402)

* [mqtt.openassistant] Better labels for discoverd things

This PR introduces more simple label for things, instead of
"My Sensor (Sensor, Sensor, Sensor, Sensor, Sensor, Switch)" we have
simply "Me Sensor (5x Sensor, Switch)".

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
This commit is contained in:
Sami Salonen 2022-09-18 22:22:06 +03:00 committed by GitHub
parent a2b6dd77b7
commit 295df504c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 2 deletions

View File

@ -26,7 +26,10 @@ import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -128,6 +131,33 @@ public class HomeAssistantDiscovery extends AbstractMQTTDiscovery {
return typeProvider.getThingTypeUIDs(); return typeProvider.getThingTypeUIDs();
} }
/**
* Summarize components such as {Switch, Switch, Sensor} into string "Sensor, 2x Switch"
*
* @param componentNames stream of component names
* @return summary string of component names and their counts
*/
static String getComponentNamesSummary(Stream<String> componentNames) {
StringBuilder summary = new StringBuilder();
Collector<String, ?, Long> countingCollector = Collectors.counting();
Map<String, Long> componentCounts = componentNames
.collect(Collectors.groupingBy(Function.identity(), countingCollector));
componentCounts.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> {
String componentName = entry.getKey();
long count = entry.getValue();
if (summary.length() > 0) {
// not the first entry, so let's add the separating comma
summary.append(", ");
}
if (count > 1) {
summary.append(count);
summary.append("x ");
}
summary.append(componentName);
});
return summary.toString();
}
@Override @Override
public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection connection, String topic, public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection connection, String topic,
byte[] payload) { byte[] payload) {
@ -184,8 +214,8 @@ public class HomeAssistantDiscovery extends AbstractMQTTDiscovery {
components.sort(Comparator.comparing(HaID::toString)); components.sort(Comparator.comparing(HaID::toString));
} }
final String componentNames = components.stream().map(id -> id.component) final String componentNames = getComponentNamesSummary(
.map(c -> HA_COMP_TO_NAME.getOrDefault(c, c)).collect(Collectors.joining(", ")); components.stream().map(id -> id.component).map(c -> HA_COMP_TO_NAME.getOrDefault(c, c)));
final List<String> topics = components.stream().map(HaID::toShortTopic).collect(Collectors.toList()); final List<String> topics = components.stream().map(HaID::toShortTopic).collect(Collectors.toList());

View File

@ -21,6 +21,7 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -54,6 +55,14 @@ public class HomeAssistantDiscoveryTests extends AbstractHomeAssistantTests {
discovery = new TestHomeAssistantDiscovery(channelTypeProvider); discovery = new TestHomeAssistantDiscovery(channelTypeProvider);
} }
@Test
public void testComponentNameSummary() {
assertThat(
HomeAssistantDiscovery.getComponentNamesSummary(
Stream.of("Sensor", "Switch", "Sensor", "Foobar", "Foobar", "Foobar")), //
is("3x Foobar, 2x Sensor, Switch"));
}
@Test @Test
public void testOneThingDiscovery() throws Exception { public void testOneThingDiscovery() throws Exception {
var discoveryListener = new LatchDiscoveryListener(); var discoveryListener = new LatchDiscoveryListener();
@ -79,6 +88,7 @@ public class HomeAssistantDiscoveryTests extends AbstractHomeAssistantTests {
assertThat(result.getProperties().get(Thing.PROPERTY_VENDOR), is("TuYa")); assertThat(result.getProperties().get(Thing.PROPERTY_VENDOR), is("TuYa"));
assertThat(result.getProperties().get(Thing.PROPERTY_FIRMWARE_VERSION), is("Zigbee2MQTT 1.18.2")); assertThat(result.getProperties().get(Thing.PROPERTY_FIRMWARE_VERSION), is("Zigbee2MQTT 1.18.2"));
assertThat(result.getProperties().get(HandlerConfiguration.PROPERTY_BASETOPIC), is("homeassistant")); assertThat(result.getProperties().get(HandlerConfiguration.PROPERTY_BASETOPIC), is("homeassistant"));
assertThat(result.getLabel(), is("th1 (Climate Control, Switch)"));
assertThat((List<String>) result.getProperties().get(HandlerConfiguration.PROPERTY_TOPICS), hasItems( assertThat((List<String>) result.getProperties().get(HandlerConfiguration.PROPERTY_TOPICS), hasItems(
"climate/0x847127fffe11dd6a_climate_zigbee2mqtt", "switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt")); "climate/0x847127fffe11dd6a_climate_zigbee2mqtt", "switch/0x847127fffe11dd6a_auto_lock_zigbee2mqtt"));
} }