2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.lametrictime.internal.discovery;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
20 import org.openhab.binding.lametrictime.api.local.model.Application;
21 import org.openhab.binding.lametrictime.api.local.model.Widget;
22 import org.openhab.binding.lametrictime.api.model.CoreApps;
23 import org.openhab.binding.lametrictime.internal.LaMetricTimeBindingConstants;
24 import org.openhab.binding.lametrictime.internal.LaMetricTimeUtil;
25 import org.openhab.binding.lametrictime.internal.config.LaMetricTimeAppConfiguration;
26 import org.openhab.binding.lametrictime.internal.handler.LaMetricTimeAppHandler;
27 import org.openhab.binding.lametrictime.internal.handler.LaMetricTimeHandler;
28 import org.openhab.core.config.discovery.AbstractDiscoveryService;
29 import org.openhab.core.config.discovery.DiscoveryResult;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 import com.google.gson.JsonPrimitive;
41 * The {@link LaMetricTimeAppDiscoveryService} is responsible for processing the
42 * list of apps found on the LaMetric Time device.
44 * @author Gregory Moyer - Initial contribution
46 public class LaMetricTimeAppDiscoveryService extends AbstractDiscoveryService {
48 private static final Map<String, ThingTypeUID> CORE_APP_THING_TYPE_UIDS = new HashMap<>();
50 CORE_APP_THING_TYPE_UIDS.put(CoreApps.clock().getPackageName(),
51 LaMetricTimeBindingConstants.THING_TYPE_CLOCK_APP);
52 CORE_APP_THING_TYPE_UIDS.put(CoreApps.countdown().getPackageName(),
53 LaMetricTimeBindingConstants.THING_TYPE_COUNTDOWN_APP);
54 CORE_APP_THING_TYPE_UIDS.put(CoreApps.radio().getPackageName(),
55 LaMetricTimeBindingConstants.THING_TYPE_RADIO_APP);
56 CORE_APP_THING_TYPE_UIDS.put(CoreApps.stopwatch().getPackageName(),
57 LaMetricTimeBindingConstants.THING_TYPE_STOPWATCH_APP);
58 CORE_APP_THING_TYPE_UIDS.put(CoreApps.weather().getPackageName(),
59 LaMetricTimeBindingConstants.THING_TYPE_WEATHER_APP);
62 private static final int TIMEOUT = 60;
64 private final Logger logger = LoggerFactory.getLogger(LaMetricTimeAppDiscoveryService.class);
66 private final LaMetricTimeHandler deviceHandler;
69 * Discovers apps on the LaMetric Time device.
71 * @param deviceHandler the LaMetric Time device handler (bridge)
73 public LaMetricTimeAppDiscoveryService(final LaMetricTimeHandler deviceHandler) {
74 super(new HashSet<>(CORE_APP_THING_TYPE_UIDS.values()), TIMEOUT, false);
75 this.deviceHandler = deviceHandler;
79 protected void startScan() {
80 logger.debug("Starting scan for new apps");
82 ThingUID bridgeUID = deviceHandler.getThing().getUID();
83 List<Thing> existingThings = deviceHandler.getThing().getThings();
85 for (Application app : deviceHandler.getApps().values()) {
86 String packageName = app.getPackageName();
88 ThingTypeUID thingType = CORE_APP_THING_TYPE_UIDS.get(packageName);
89 if (thingType == null) {
94 for (Widget widget : app.getWidgets().values()) {
95 String widgetId = widget.getId();
96 ThingUID thingUID = new ThingUID(thingType, bridgeUID, widgetId);
98 // check if thing already exists
99 if (containsThing(existingThings, widgetId)) {
103 logger.debug("New app {} instance found with widget ID {}", packageName, widgetId);
105 Map<String, Object> properties = new HashMap<>();
106 properties.put(LaMetricTimeAppConfiguration.PACKAGE_NAME, app.getPackageName());
107 properties.put(LaMetricTimeAppConfiguration.WIDGET_ID, widgetId);
108 properties.put(Thing.PROPERTY_VENDOR, app.getVendor());
109 properties.put(Thing.PROPERTY_FIRMWARE_VERSION, app.getVersion());
111 Map<String, JsonPrimitive> settings = widget.getSettings();
112 if (settings != null) {
113 settings.entrySet().stream().forEach(entry -> properties.put(entry.getKey(), entry.getValue()));
116 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
117 .withBridge(bridgeUID).withLabel(LaMetricTimeUtil.getAppLabel(app, widget)).build();
118 thingDiscovered(discoveryResult);
123 private boolean containsThing(List<Thing> things, String widgetId) {
124 return things.stream().anyMatch(thing -> {
125 ThingHandler handler = thing.getHandler();
126 if (!(handler instanceof LaMetricTimeAppHandler)) {
130 Widget widget = ((LaMetricTimeAppHandler) handler).getWidget();
131 return widget.getId().equals(widgetId);