]> git.basschouten.com Git - openhab-addons.git/blob
f7e71484775d9e83d4265939ddcb4450330547c8
[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.folderwatcher.internal.handler;
14
15 import static org.openhab.binding.folderwatcher.internal.FolderWatcherBindingConstants.CHANNEL_NEWFILE;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.concurrent.ScheduledFuture;
22 import java.util.concurrent.TimeUnit;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.folderwatcher.internal.api.S3Actions;
27 import org.openhab.binding.folderwatcher.internal.common.WatcherCommon;
28 import org.openhab.binding.folderwatcher.internal.config.S3BucketWatcherConfiguration;
29 import org.openhab.core.OpenHAB;
30 import org.openhab.core.io.net.http.HttpClientFactory;
31 import org.openhab.core.thing.ChannelUID;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingStatus;
34 import org.openhab.core.thing.ThingStatusDetail;
35 import org.openhab.core.thing.binding.BaseThingHandler;
36 import org.openhab.core.types.Command;
37 import org.openhab.core.types.RefreshType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * The {@link S3BucketWatcherHandler} is responsible for handling commands, which are
43  * sent to one of the channels.
44  *
45  * @author Alexandr Salamatov - Initial contribution
46  */
47 @NonNullByDefault
48 public class S3BucketWatcherHandler extends BaseThingHandler {
49     private final Logger logger = LoggerFactory.getLogger(S3BucketWatcherHandler.class);
50     private S3BucketWatcherConfiguration config = new S3BucketWatcherConfiguration();
51     private File currentS3ListingFile = new File(OpenHAB.getUserDataFolder() + File.separator + "FolderWatcher"
52             + File.separator + thing.getUID().getAsString().replace(':', '_') + ".data");
53     private @Nullable ScheduledFuture<?> executionJob;
54     private List<String> previousS3Listing = new ArrayList<>();
55     private HttpClientFactory httpClientFactory;
56     private @Nullable S3Actions s3;
57
58     public S3BucketWatcherHandler(Thing thing, HttpClientFactory httpClientFactory) {
59         super(thing);
60         this.httpClientFactory = httpClientFactory;
61     }
62
63     @Override
64     public void handleCommand(ChannelUID channelUID, Command command) {
65         logger.debug("Channel {} triggered with command {}", channelUID.getId(), command);
66         if (command instanceof RefreshType) {
67             refreshS3BucketInformation();
68         }
69     }
70
71     @Override
72     public void initialize() {
73         config = getConfigAs(S3BucketWatcherConfiguration.class);
74
75         if (config.s3Anonymous) {
76             s3 = new S3Actions(httpClientFactory, config.s3BucketName, config.awsRegion);
77         } else {
78             s3 = new S3Actions(httpClientFactory, config.s3BucketName, config.awsRegion, config.awsKey,
79                     config.awsSecret);
80         }
81
82         try {
83             previousS3Listing = WatcherCommon.initStorage(currentS3ListingFile, config.s3BucketName);
84         } catch (IOException e) {
85             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
86             logger.debug("Can't write file {}: {}", currentS3ListingFile, e.getMessage());
87             return;
88         }
89
90         if (refreshS3BucketInformation()) {
91             if (config.pollIntervalS3 > 0) {
92                 updateStatus(ThingStatus.ONLINE);
93                 executionJob = scheduler.scheduleWithFixedDelay(this::refreshS3BucketInformation, config.pollIntervalS3,
94                         config.pollIntervalS3, TimeUnit.SECONDS);
95             } else {
96                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
97                         "Polling interval must be greater then 0 seconds");
98                 return;
99             }
100         }
101     }
102
103     private boolean refreshS3BucketInformation() {
104         List<String> currentS3Listing = new ArrayList<>();
105         try {
106             currentS3Listing = s3.listBucket(config.s3Path);
107             List<String> difS3Listing = new ArrayList<>(currentS3Listing);
108             difS3Listing.removeAll(previousS3Listing);
109             difS3Listing.forEach(file -> triggerChannel(CHANNEL_NEWFILE, file));
110
111             if (!difS3Listing.isEmpty()) {
112                 WatcherCommon.saveNewListing(difS3Listing, currentS3ListingFile);
113             }
114             previousS3Listing = new ArrayList<>(currentS3Listing);
115         } catch (Exception e) {
116             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Can't connect to the bucket");
117             logger.debug("Can't connect to the bucket: {}", e.getMessage());
118             return false;
119         }
120         return true;
121     }
122
123     @Override
124     public void dispose() {
125         ScheduledFuture<?> executionJob = this.executionJob;
126         if (executionJob != null) {
127             executionJob.cancel(true);
128             this.executionJob = null;
129         }
130     }
131 }