]> git.basschouten.com Git - openhab-addons.git/blob
5262304659481ce6b46b308db23b3b58a34f2029
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.ipp.internal.handler;
14
15 import java.math.BigDecimal;
16 import java.net.MalformedURLException;
17 import java.net.URL;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.concurrent.ScheduledFuture;
21 import java.util.concurrent.TimeUnit;
22
23 import org.cups4j.CupsPrinter;
24 import org.cups4j.WhichJobsEnum;
25 import org.openhab.binding.ipp.internal.IppBindingConstants;
26 import org.openhab.core.config.core.Configuration;
27 import org.openhab.core.config.discovery.DiscoveryListener;
28 import org.openhab.core.config.discovery.DiscoveryResult;
29 import org.openhab.core.config.discovery.DiscoveryService;
30 import org.openhab.core.config.discovery.DiscoveryServiceRegistry;
31 import org.openhab.core.library.types.DecimalType;
32 import org.openhab.core.thing.ChannelUID;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingTypeUID;
36 import org.openhab.core.thing.ThingUID;
37 import org.openhab.core.thing.binding.BaseThingHandler;
38 import org.openhab.core.types.Command;
39 import org.openhab.core.types.RefreshType;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * The {@link IppPrinterHandler} is responsible for handling commands, which are sent
45  * to one of the channels.
46  *
47  * @author Tobias Braeutigam - Initial contribution
48  */
49 public class IppPrinterHandler extends BaseThingHandler implements DiscoveryListener {
50
51     private final Logger logger = LoggerFactory.getLogger(IppPrinterHandler.class);
52
53     private URL url;
54     private String name;
55     private CupsPrinter printer;
56
57     private int refresh = 60; // refresh every minute as default
58     ScheduledFuture<?> refreshJob;
59
60     private DiscoveryServiceRegistry discoveryServiceRegistry;
61
62     public IppPrinterHandler(Thing thing, DiscoveryServiceRegistry discoveryServiceRegistry) {
63         super(thing);
64         if (discoveryServiceRegistry != null) {
65             this.discoveryServiceRegistry = discoveryServiceRegistry;
66         }
67     }
68
69     @Override
70     public void initialize() {
71         Configuration config = getThing().getConfiguration();
72         try {
73             Object obj = config.get(IppBindingConstants.PRINTER_PARAMETER_URL);
74             name = (String) config.get(IppBindingConstants.PRINTER_PARAMETER_NAME);
75             if (config.get(IppBindingConstants.PRINTER_PARAMETER_REFRESH_INTERVAL) != null) {
76                 BigDecimal ref = (BigDecimal) config.get(IppBindingConstants.PRINTER_PARAMETER_REFRESH_INTERVAL);
77                 refresh = ref.intValue();
78             }
79             if (obj instanceof URL) {
80                 url = (URL) obj;
81             } else if (obj instanceof String) {
82                 url = new URL((String) obj);
83             }
84             printer = new CupsPrinter(url, name, false);
85         } catch (MalformedURLException e) {
86             logger.error("malformed url {}, printer thing creation failed",
87                     config.get(IppBindingConstants.PRINTER_PARAMETER_URL));
88         }
89         // until we get an update put the Thing offline
90         updateStatus(ThingStatus.OFFLINE);
91         deviceOnlineWatchdog();
92         if (this.discoveryServiceRegistry != null) {
93             this.discoveryServiceRegistry.addDiscoveryListener(this);
94         }
95     }
96
97     @Override
98     public void dispose() {
99         if (refreshJob != null && !refreshJob.isCancelled()) {
100             refreshJob.cancel(true);
101             refreshJob = null;
102         }
103         logger.debug("IppPrinterHandler {} disposed.", url);
104         super.dispose();
105     }
106
107     private void deviceOnlineWatchdog() {
108         Runnable runnable = () -> {
109             try {
110                 onDeviceStateChanged(printer);
111             } catch (Exception e) {
112                 logger.debug("Exception occurred during execution: {}", e.getMessage(), e);
113             }
114         };
115         refreshJob = scheduler.scheduleWithFixedDelay(runnable, 0, refresh, TimeUnit.SECONDS);
116     }
117
118     @Override
119     public void handleCommand(ChannelUID channelUID, Command command) {
120         if (command instanceof RefreshType) {
121             onDeviceStateChanged(printer);
122             return;
123         }
124     }
125
126     public void onDeviceStateChanged(CupsPrinter device) {
127         if (device.getPrinterURL().equals(url)) {
128             boolean online = false;
129             try {
130                 updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.JOBS_CHANNEL),
131                         new DecimalType(device.getJobs(WhichJobsEnum.ALL, "", false).size()));
132                 online = true;
133             } catch (Exception e) {
134                 logger.debug("error updating jobs channel, reason: {}", e.getMessage());
135             }
136             try {
137                 updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.WAITING_JOBS_CHANNEL),
138                         new DecimalType(device.getJobs(WhichJobsEnum.NOT_COMPLETED, "", false).size()));
139                 online = true;
140             } catch (Exception e) {
141                 logger.debug("error updating waiting-jobs channel, reason: {}", e.getMessage());
142             }
143             try {
144                 updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.DONE_JOBS_CHANNEL),
145                         new DecimalType(device.getJobs(WhichJobsEnum.COMPLETED, "", false).size()));
146                 online = true;
147             } catch (Exception e) {
148                 logger.debug("error updating done-jobs channel, reason: {}", e.getMessage());
149             }
150             if (online) {
151                 updateStatus(ThingStatus.ONLINE);
152             }
153         }
154     }
155
156     @Override
157     public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
158         if (result.getThingUID().equals(this.getThing().getUID())) {
159             updateStatus(ThingStatus.ONLINE);
160         }
161     }
162
163     @Override
164     public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
165         if (thingUID.equals(this.getThing().getUID())) {
166             updateStatus(ThingStatus.OFFLINE);
167         }
168     }
169
170     @Override
171     public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
172             Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
173         return Collections.emptyList();
174     }
175 }