]> git.basschouten.com Git - openhab-addons.git/blob
d7002b7f50dbeaff5d2ca10f7bc1f6e53ae09f51
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.amazonechocontrol.internal.discovery;
14
15 import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.*;
16
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.concurrent.ScheduledFuture;
24 import java.util.concurrent.TimeUnit;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.openhab.binding.amazonechocontrol.internal.Connection;
29 import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
30 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonDevices.Device;
31 import org.openhab.core.config.discovery.AbstractDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResult;
33 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
34 import org.openhab.core.thing.ThingTypeUID;
35 import org.openhab.core.thing.ThingUID;
36 import org.osgi.service.component.annotations.Activate;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link AmazonEchoDiscovery} is responsible for discovering echo devices on
42  * the amazon account specified in the binding.
43  *
44  * @author Michael Geramb - Initial contribution
45  */
46 @NonNullByDefault
47 public class AmazonEchoDiscovery extends AbstractDiscoveryService {
48
49     AccountHandler accountHandler;
50     private final Logger logger = LoggerFactory.getLogger(AmazonEchoDiscovery.class);
51     private final Set<String> discoveredFlashBriefings = new HashSet<>();
52
53     private @Nullable ScheduledFuture<?> startScanStateJob;
54     private @Nullable Long activateTimeStamp;
55
56     public AmazonEchoDiscovery(AccountHandler accountHandler) {
57         super(SUPPORTED_ECHO_THING_TYPES_UIDS, 10);
58         this.accountHandler = accountHandler;
59     }
60
61     public void activate() {
62         activate(new HashMap<>());
63     }
64
65     @Override
66     public void deactivate() {
67         super.deactivate();
68     }
69
70     @Override
71     protected void startScan() {
72         stopScanJob();
73         final Long activateTimeStamp = this.activateTimeStamp;
74         if (activateTimeStamp != null) {
75             removeOlderResults(activateTimeStamp);
76         }
77         setDevices(accountHandler.updateDeviceList());
78
79         String currentFlashBriefingConfiguration = accountHandler.getNewCurrentFlashbriefingConfiguration();
80         discoverFlashBriefingProfiles(currentFlashBriefingConfiguration);
81     }
82
83     protected void startAutomaticScan() {
84         if (!this.accountHandler.getThing().getThings().isEmpty()) {
85             stopScanJob();
86             return;
87         }
88         Connection connection = this.accountHandler.findConnection();
89         if (connection == null) {
90             return;
91         }
92         Date verifyTime = connection.tryGetVerifyTime();
93         if (verifyTime == null) {
94             return;
95         }
96         if (new Date().getTime() - verifyTime.getTime() < 10000) {
97             return;
98         }
99         startScan();
100     }
101
102     @Override
103     protected void startBackgroundDiscovery() {
104         stopScanJob();
105         startScanStateJob = scheduler.scheduleWithFixedDelay(this::startAutomaticScan, 3000, 1000,
106                 TimeUnit.MILLISECONDS);
107     }
108
109     @Override
110     protected void stopBackgroundDiscovery() {
111         stopScanJob();
112     }
113
114     void stopScanJob() {
115         @Nullable
116         ScheduledFuture<?> currentStartScanStateJob = startScanStateJob;
117         if (currentStartScanStateJob != null) {
118             currentStartScanStateJob.cancel(false);
119             startScanStateJob = null;
120         }
121     }
122
123     @Override
124     @Activate
125     public void activate(@Nullable Map<String, Object> config) {
126         super.activate(config);
127         if (config != null) {
128             modified(config);
129         }
130         if (activateTimeStamp == null) {
131             activateTimeStamp = new Date().getTime();
132         }
133     }
134
135     synchronized void setDevices(List<Device> deviceList) {
136         for (Device device : deviceList) {
137             String serialNumber = device.serialNumber;
138             if (serialNumber != null) {
139                 String deviceFamily = device.deviceFamily;
140                 if (deviceFamily != null) {
141                     ThingTypeUID thingTypeId;
142                     if ("ECHO".equals(deviceFamily)) {
143                         thingTypeId = THING_TYPE_ECHO;
144                     } else if ("ROOK".equals(deviceFamily)) {
145                         thingTypeId = THING_TYPE_ECHO_SPOT;
146                     } else if ("KNIGHT".equals(deviceFamily)) {
147                         thingTypeId = THING_TYPE_ECHO_SHOW;
148                     } else if ("WHA".equals(deviceFamily)) {
149                         thingTypeId = THING_TYPE_ECHO_WHA;
150                     } else {
151                         logger.debug("Unknown thing type '{}'", deviceFamily);
152                         continue;
153                     }
154
155                     ThingUID bridgeThingUID = this.accountHandler.getThing().getUID();
156                     ThingUID thingUID = new ThingUID(thingTypeId, bridgeThingUID, serialNumber);
157
158                     DiscoveryResult result = DiscoveryResultBuilder.create(thingUID).withLabel(device.accountName)
159                             .withProperty(DEVICE_PROPERTY_SERIAL_NUMBER, serialNumber)
160                             .withProperty(DEVICE_PROPERTY_FAMILY, deviceFamily)
161                             .withRepresentationProperty(DEVICE_PROPERTY_SERIAL_NUMBER).withBridge(bridgeThingUID)
162                             .build();
163
164                     logger.debug("Device [{}: {}] found. Mapped to thing type {}", device.deviceFamily, serialNumber,
165                             thingTypeId.getAsString());
166
167                     thingDiscovered(result);
168                 }
169             }
170         }
171     }
172
173     public synchronized void discoverFlashBriefingProfiles(String currentFlashBriefingJson) {
174         if (currentFlashBriefingJson.isEmpty()) {
175             return;
176         }
177
178         if (!discoveredFlashBriefings.contains(currentFlashBriefingJson)) {
179             ThingUID bridgeThingUID = this.accountHandler.getThing().getUID();
180             ThingUID freeThingUID = new ThingUID(THING_TYPE_FLASH_BRIEFING_PROFILE, bridgeThingUID,
181                     Integer.toString(currentFlashBriefingJson.hashCode()));
182             DiscoveryResult result = DiscoveryResultBuilder.create(freeThingUID).withLabel("FlashBriefing")
183                     .withProperty(DEVICE_PROPERTY_FLASH_BRIEFING_PROFILE, currentFlashBriefingJson)
184                     .withBridge(accountHandler.getThing().getUID()).build();
185             logger.debug("Flash Briefing {} discovered", currentFlashBriefingJson);
186             thingDiscovered(result);
187             discoveredFlashBriefings.add(currentFlashBriefingJson);
188         }
189     }
190
191     public synchronized void removeExistingFlashBriefingProfile(@Nullable String currentFlashBriefingJson) {
192         if (currentFlashBriefingJson != null) {
193             discoveredFlashBriefings.remove(currentFlashBriefingJson);
194         }
195     }
196 }