]> git.basschouten.com Git - openhab-addons.git/blob
1dc040e706675dc993caf501abec060838ac1e7f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.astro.internal.discovery;
14
15 import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
16
17 import java.util.Arrays;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.Objects;
21 import java.util.Set;
22 import java.util.concurrent.ScheduledFuture;
23 import java.util.concurrent.TimeUnit;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.core.config.discovery.AbstractDiscoveryService;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.DiscoveryService;
30 import org.openhab.core.i18n.LocaleProvider;
31 import org.openhab.core.i18n.LocationProvider;
32 import org.openhab.core.i18n.TranslationProvider;
33 import org.openhab.core.library.types.PointType;
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.osgi.service.component.annotations.Component;
38 import org.osgi.service.component.annotations.Reference;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * The {@link AstroDiscoveryService} creates things based on the configured location.
44  *
45  * @author Gerhard Riegler - Initial Contribution
46  * @author Stefan Triller - Use configured location
47  */
48 @NonNullByDefault
49 @Component(service = DiscoveryService.class, configurationPid = "discovery.astro")
50 public class AstroDiscoveryService extends AbstractDiscoveryService {
51     private static final int DISCOVER_TIMEOUT_SECONDS = 2;
52     private static final int LOCATION_CHANGED_CHECK_INTERVAL = 60;
53     private static final Set<String> METEO_BASED_COUNTRIES = new HashSet<>(Arrays.asList("NZ", "AU"));
54     private static final ThingUID SUN_THING = new ThingUID(THING_TYPE_SUN, LOCAL);
55     private static final ThingUID MOON_THING = new ThingUID(THING_TYPE_MOON, LOCAL);
56
57     private final Logger logger = LoggerFactory.getLogger(AstroDiscoveryService.class);
58
59     private final LocationProvider locationProvider;
60
61     private @Nullable ScheduledFuture<?> astroDiscoveryJob;
62     private @Nullable PointType previousLocation;
63
64     @Activate
65     public AstroDiscoveryService(final @Reference LocationProvider locationProvider,
66             final @Reference LocaleProvider localeProvider, final @Reference TranslationProvider i18nProvider,
67             @Nullable Map<String, @Nullable Object> configProperties) {
68         super(new HashSet<>(Arrays.asList(new ThingTypeUID(BINDING_ID, "-"))), DISCOVER_TIMEOUT_SECONDS, true);
69         this.locationProvider = locationProvider;
70         this.localeProvider = localeProvider;
71         this.i18nProvider = i18nProvider;
72         activate(configProperties);
73     }
74
75     @Override
76     protected void startScan() {
77         logger.debug("Starting Astro discovery scan");
78         PointType location = locationProvider.getLocation();
79         if (location == null) {
80             logger.debug("LocationProvider.getLocation() is not set -> Will not provide any discovery results");
81             return;
82         }
83         createResults(location);
84     }
85
86     @Override
87     protected void startBackgroundDiscovery() {
88         if (astroDiscoveryJob == null) {
89             astroDiscoveryJob = scheduler.scheduleWithFixedDelay(() -> {
90                 PointType currentLocation = locationProvider.getLocation();
91                 if (currentLocation != null && !Objects.equals(currentLocation, previousLocation)) {
92                     logger.debug("Location has been changed from {} to {}: Creating new discovery results",
93                             previousLocation, currentLocation);
94                     createResults(currentLocation);
95                     previousLocation = currentLocation;
96                 }
97             }, 0, LOCATION_CHANGED_CHECK_INTERVAL, TimeUnit.SECONDS);
98             logger.debug("Scheduled astro location-changed job every {} seconds", LOCATION_CHANGED_CHECK_INTERVAL);
99         }
100     }
101
102     @Override
103     protected void stopBackgroundDiscovery() {
104         logger.debug("Stopping Astro device background discovery");
105         ScheduledFuture<?> discoveryJob = astroDiscoveryJob;
106         if (discoveryJob != null) {
107             discoveryJob.cancel(true);
108         }
109         astroDiscoveryJob = null;
110     }
111
112     public void createResults(PointType location) {
113         String propGeolocation;
114         String country = localeProvider.getLocale().getCountry();
115         propGeolocation = String.format("%s,%s,%s", location.getLatitude(), location.getLongitude(),
116                 location.getAltitude());
117         thingDiscovered(DiscoveryResultBuilder.create(SUN_THING).withLabel("Local Sun")
118                 .withProperty("geolocation", propGeolocation)
119                 .withProperty("useMeteorologicalSeason", METEO_BASED_COUNTRIES.contains(country))
120                 .withRepresentationProperty("geolocation").build());
121         thingDiscovered(DiscoveryResultBuilder.create(MOON_THING).withLabel("Local Moon")
122                 .withProperty("geolocation", propGeolocation).withRepresentationProperty("geolocation").build());
123     }
124 }