2 * Copyright (c) 2010-2021 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.hpprinter.internal;
15 import static org.openhab.binding.hpprinter.internal.HPPrinterBindingConstants.*;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.ScheduledFuture;
21 import java.util.concurrent.TimeUnit;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.eclipse.jetty.client.HttpClient;
26 import org.openhab.binding.hpprinter.internal.api.HPFeatures;
27 import org.openhab.binding.hpprinter.internal.api.HPProductUsageFeatures;
28 import org.openhab.binding.hpprinter.internal.api.HPProductUsageFeatures.PrinterType;
29 import org.openhab.binding.hpprinter.internal.api.HPProperties;
30 import org.openhab.binding.hpprinter.internal.api.HPScannerStatus;
31 import org.openhab.binding.hpprinter.internal.api.HPScannerStatusFeatures;
32 import org.openhab.binding.hpprinter.internal.api.HPServerResult;
33 import org.openhab.binding.hpprinter.internal.api.HPServerResult.RequestStatus;
34 import org.openhab.binding.hpprinter.internal.api.HPStatus;
35 import org.openhab.binding.hpprinter.internal.api.HPUsage;
36 import org.openhab.binding.hpprinter.internal.api.HPWebServerClient;
37 import org.openhab.core.library.CoreItemFactory;
38 import org.openhab.core.library.types.DecimalType;
39 import org.openhab.core.library.types.OnOffType;
40 import org.openhab.core.library.types.QuantityType;
41 import org.openhab.core.library.types.StringType;
42 import org.openhab.core.library.unit.MetricPrefix;
43 import org.openhab.core.library.unit.Units;
44 import org.openhab.core.thing.Channel;
45 import org.openhab.core.thing.ChannelUID;
46 import org.openhab.core.thing.ThingStatus;
47 import org.openhab.core.thing.ThingStatusDetail;
48 import org.openhab.core.thing.ThingUID;
49 import org.openhab.core.thing.binding.builder.ChannelBuilder;
50 import org.openhab.core.types.State;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
55 * The {@link HPPrinterBinder} connects the binding to the Web Server Client
58 * @author Stewart Cossey - Initial contribution
61 public class HPPrinterBinder {
62 private final Logger logger = LoggerFactory.getLogger(HPPrinterBinder.class);
64 private static final int OFFLINE_CHECK_INTERVAL = 15;
66 private HPPrinterHandler handler;
67 private ScheduledExecutorService scheduler;
69 private final int statusCheckInterval;
70 private final int usageCheckInterval;
71 private final HPWebServerClient printerClient;
73 private @Nullable ScheduledFuture<?> statusScheduler;
74 private @Nullable ScheduledFuture<?> scannerStatusScheduler;
75 private @Nullable ScheduledFuture<?> usageScheduler;
76 private @Nullable ScheduledFuture<?> offlineScheduler;
79 * Creates a new HP Printer Binder object
81 * @param handler {HPPrinterBinderEvent} The Event handler for the binder.
82 * @param httpClient {HttpClient} The HttpClient object to use to perform HTTP
84 * @param scheduler {ScheduledExecutorService} The scheduler service object.
85 * @param config {HPPrinterConfiguration} The configuration object.
87 public HPPrinterBinder(HPPrinterHandler handler, HttpClient httpClient, ScheduledExecutorService scheduler,
88 HPPrinterConfiguration config) {
89 this.handler = handler;
90 this.scheduler = scheduler;
91 usageCheckInterval = config.usageInterval;
92 statusCheckInterval = config.statusInterval;
93 String ipAddress = config.ipAddress;
94 if (ipAddress == null) {
95 throw new IllegalStateException("ip-address should have been validated already and may not be empty.");
97 printerClient = new HPWebServerClient(httpClient, ipAddress);
100 public void retrieveProperties() {
101 HPServerResult<HPProperties> result = printerClient.getProperties();
103 if (result.getStatus() == RequestStatus.SUCCESS) {
104 handler.updateProperties(result.getData().getProperties());
108 public synchronized void channelsChanged() {
109 logger.trace("Channels have been changed");
115 * Dynamically add channels to the Thing based on the Embedded Web Server Usage
118 public void dynamicallyAddChannels(ThingUID thingUid) {
119 logger.debug("Building dynamic channels based on printer");
121 HPServerResult<HPFeatures> featureResult = printerClient.getProductUsageFeatures();
122 if (featureResult.getStatus() == RequestStatus.SUCCESS) {
123 final List<Channel> channels = new ArrayList<>();
125 HPFeatures features = featureResult.getData();
127 if (features.getProductStatusSupported()) {
128 channels.add(ChannelBuilder
129 .create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_STATUS), CoreItemFactory.STRING)
130 .withLabel("Status").withDescription("Printer status").withType(chanTypeStatus).build());
132 channels.add(ChannelBuilder
133 .create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_TRAYEMPTYOROPEN),
134 CoreItemFactory.SWITCH)
135 .withLabel("Tray Empty/Open").withDescription("The tray is empty or open")
136 .withType(chanTypeReadSwitch).build());
139 if (features.getScannerStatusSupported()) {
140 HPServerResult<HPScannerStatusFeatures> result = printerClient.getScannerFeatures();
141 if (result.getStatus() == RequestStatus.SUCCESS) {
142 HPScannerStatusFeatures feature = result.getData();
144 if (feature.hasStatus()) {
145 channels.add(ChannelBuilder
146 .create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_SCANNER_STATUS),
147 CoreItemFactory.STRING)
148 .withLabel("Scanner").withDescription("Scanner status").withType(chanTypeStatus)
152 if (feature.hasAdf()) {
153 channels.add(ChannelBuilder
154 .create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_SCANNER_ADFLOADED),
155 CoreItemFactory.SWITCH)
156 .withLabel("ADF Loaded").withDescription("The automatic document feeder is loaded")
157 .withType(chanTypeReadSwitch).build());
162 if (features.getProductUsageSupported()) {
163 HPServerResult<HPProductUsageFeatures> result = printerClient.getProductFeatures();
164 if (result.getStatus() == RequestStatus.SUCCESS) {
165 HPProductUsageFeatures feature = result.getData();
167 channels.add(ChannelBuilder
168 .create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_BLACK_LEVEL),
169 HPPrinterBindingConstants.ITEM_TYPE_INK)
170 .withLabel("Black Level").withDescription("Shows the amount of Black Ink/Toner remaining")
171 .withType(chanTypeInkLevel).build());
173 channels.add(ChannelBuilder
174 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_PAGES), CoreItemFactory.NUMBER)
175 .withLabel("Total Lifetime Pages")
176 .withDescription("The amount of pages printed over the printer lifetime")
177 .withType(chanTypeTotals).build());
179 if (feature.hasCumulativeMarking()) {
180 channels.add(ChannelBuilder
181 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_MARKING),
182 HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
183 .withLabel("Black Marking Used").withDescription("The amount of Black Marking used")
184 .withType(chanTypeMarking).build());
187 switch (feature.getType()) {
189 if (feature.hasCumulativeMarking()) {
190 channels.add(ChannelBuilder
191 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_COLOR_MARKING),
192 HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
193 .withLabel("Colour Marking Used")
194 .withDescription("The amount of Colour Marking used").withType(chanTypeMarking)
198 channels.add(ChannelBuilder
199 .create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_COLOR_LEVEL),
200 HPPrinterBindingConstants.ITEM_TYPE_INK)
201 .withLabel("Color Level")
202 .withDescription("Shows the amount of Colour Ink/Toner remaining")
203 .withType(chanTypeInkLevel).build());
205 channels.add(ChannelBuilder
206 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES),
207 CoreItemFactory.NUMBER)
208 .withLabel("Total Colour Pages")
209 .withDescription("The amount of colour pages printed").withType(chanTypeTotals)
212 channels.add(ChannelBuilder
213 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES),
214 CoreItemFactory.NUMBER)
215 .withLabel("Total Monochrome Pages")
216 .withDescription("The amount of monochrome pages printed").withType(chanTypeTotals)
219 if (feature.hasPagesRemaining()) {
220 channels.add(ChannelBuilder
221 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
222 CoreItemFactory.NUMBER)
223 .withLabel("Black Pages Remaining")
224 .withDescription("Estimated Black pages remaining")
225 .withType(chanTypeTotalsAdvanced).build());
227 channels.add(ChannelBuilder
228 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_COLOR_PAGES_REMAINING),
229 CoreItemFactory.NUMBER)
230 .withLabel("Colour Pages Remaining")
231 .withDescription("Estimated Colour pages remaining")
232 .withType(chanTypeTotalsAdvanced).build());
238 if (feature.hasCumulativeMarking()) {
239 channels.add(ChannelBuilder
240 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_CYAN_MARKING),
241 HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
242 .withLabel("Cyan Marking Used")
243 .withDescription("The amount of Cyan Marking used").withType(chanTypeMarking)
246 channels.add(ChannelBuilder
247 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MAGENTA_MARKING),
248 HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
249 .withLabel("Magenta Marking Used")
250 .withDescription("The amount of Magenta Marking used").withType(chanTypeMarking)
253 channels.add(ChannelBuilder
254 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_YELLOW_MARKING),
255 HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
256 .withLabel("Yellow Marking Used")
257 .withDescription("The amount of Yellow Marking used").withType(chanTypeMarking)
261 if (feature.hasPagesRemaining()) {
262 channels.add(ChannelBuilder
263 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
264 CoreItemFactory.NUMBER)
265 .withLabel("Black Pages Remaining")
266 .withDescription("Estimated Black pages remaining")
267 .withType(chanTypeTotalsAdvanced).build());
269 channels.add(ChannelBuilder
270 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_CYAN_PAGES_REMAINING),
271 CoreItemFactory.NUMBER)
272 .withLabel("Cyan Pages Remaining")
273 .withDescription("Estimated Cyan pages remaining")
274 .withType(chanTypeTotalsAdvanced).build());
276 channels.add(ChannelBuilder
277 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MAGENTA_PAGES_REMAINING),
278 CoreItemFactory.NUMBER)
279 .withLabel("Magenta Pages Remaining")
280 .withDescription("Estimated Magenta pages remaining")
281 .withType(chanTypeTotalsAdvanced).build());
283 channels.add(ChannelBuilder
284 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_YELLOW_PAGES_REMAINING),
285 CoreItemFactory.NUMBER)
286 .withLabel("Yellow Pages Remaining")
287 .withDescription("Estimated Yellow pages remaining")
288 .withType(chanTypeTotalsAdvanced).build());
291 channels.add(ChannelBuilder
292 .create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_CYAN_LEVEL),
293 HPPrinterBindingConstants.ITEM_TYPE_INK)
294 .withLabel("Cyan Level")
295 .withDescription("Shows the amount of Cyan Ink/Toner remaining")
296 .withType(chanTypeInkLevel).build());
298 channels.add(ChannelBuilder
299 .create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_MAGENTA_LEVEL),
300 HPPrinterBindingConstants.ITEM_TYPE_INK)
301 .withLabel("Magenta Level")
302 .withDescription("Shows the amount of Magenta Ink/Toner remaining")
303 .withType(chanTypeInkLevel).build());
305 channels.add(ChannelBuilder
306 .create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_YELLOW_LEVEL),
307 HPPrinterBindingConstants.ITEM_TYPE_INK)
308 .withLabel("Yellow Level")
309 .withDescription("Shows the amount of Yellow Ink/Toner remaining")
310 .withType(chanTypeInkLevel).build());
312 channels.add(ChannelBuilder
313 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES),
314 CoreItemFactory.NUMBER)
315 .withLabel("Total Colour Pages")
316 .withDescription("The amount of colour pages printed").withType(chanTypeTotals)
319 channels.add(ChannelBuilder
320 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES),
321 CoreItemFactory.NUMBER)
322 .withLabel("Total Monochrome Pages")
323 .withDescription("The amount of monochrome pages printed").withType(chanTypeTotals)
329 if (feature.hasPagesRemaining()) {
330 channels.add(ChannelBuilder
331 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
332 CoreItemFactory.NUMBER)
333 .withLabel("Black Pages Remaining")
334 .withDescription("Estimated Black pages remaining")
335 .withType(chanTypeTotalsAdvanced).build());
339 if (feature.hasJamEvents()) {
340 channels.add(ChannelBuilder
341 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_JAM_EVENTS),
342 CoreItemFactory.NUMBER)
343 .withLabel("Jams").withDescription("The amount of times the paper has jammed")
344 .withType(chanTypeTotalsAdvanced).build());
347 if (feature.hasMispickEvents()) {
348 channels.add(ChannelBuilder
349 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MISPICK_EVENTS),
350 CoreItemFactory.NUMBER)
351 .withLabel("Missed Picks")
352 .withDescription("The amount of times the paper failed to feed into the printer")
353 .withType(chanTypeTotalsAdvanced).build());
356 if (feature.hasSubscriptionCount()) {
357 channels.add(ChannelBuilder
358 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_SUBSCRIPTION),
359 CoreItemFactory.NUMBER)
360 .withLabel("Subscription Count")
361 .withDescription("The amount of times an item has been printed in subscription")
362 .withType(chanTypeTotalsAdvanced).build());
365 if (feature.hasTotalFrontPanelCancelPresses()) {
366 channels.add(ChannelBuilder
367 .create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_FRONT_PANEL_CANCEL),
368 CoreItemFactory.NUMBER)
369 .withLabel("Front Panel Cancel Count")
370 .withDescription("The amount of times a print has been cancelled from the Front Panel")
371 .withType(chanTypeTotalsAdvanced).build());
375 if (feature.hasCloudPrint()) {
376 channels.add(ChannelBuilder
377 .create(new ChannelUID(thingUid, CGROUP_OTHER, CHANNEL_CLOUD_PRINT),
378 CoreItemFactory.NUMBER)
379 .withLabel("Cloud Print Count")
381 "The amount of times a document has been printed via Google Cloud Print")
382 .withType(chanTypeTotalsAdvanced).build());
386 if (feature.hasScanADF()) {
387 channels.add(ChannelBuilder
388 .create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_ADF),
389 CoreItemFactory.NUMBER)
390 .withLabel("Document Feeder Count")
391 .withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
395 if (feature.hasScanFlatbed()) {
396 channels.add(ChannelBuilder
397 .create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_FLATBED),
398 CoreItemFactory.NUMBER)
399 .withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
400 .withType(chanTypeTotals).build());
403 if (feature.hasScanToEmail()) {
404 channels.add(ChannelBuilder
405 .create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOEMAIL),
406 CoreItemFactory.NUMBER)
407 .withLabel("Scan to Email Count").withDescription("Times scanned using Scan to Email")
408 .withType(chanTypeTotalsAdvanced).build());
411 if (feature.hasScanToFolder()) {
412 channels.add(ChannelBuilder
413 .create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOFOLDER),
414 CoreItemFactory.NUMBER)
415 .withLabel("Scan to Folder Count").withDescription("Times scanned using Scan to Folder")
416 .withType(chanTypeTotalsAdvanced).build());
419 if (feature.hasScanToHost()) {
420 channels.add(ChannelBuilder
421 .create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOHOST),
422 CoreItemFactory.NUMBER)
423 .withLabel("Scan to Host Count")
424 .withDescription("Times scanned using Scan to Host Device")
425 .withType(chanTypeTotalsAdvanced).build());
429 if (feature.hasScannerEngine()) {
430 if (feature.hasScanADF()) {
431 channels.add(ChannelBuilder
432 .create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_TOTAL_ADF),
433 CoreItemFactory.NUMBER)
434 .withLabel("Document Feeder Count")
435 .withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
439 if (feature.hasScanFlatbed()) {
440 channels.add(ChannelBuilder
441 .create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_TOTAL_FLATBED),
442 CoreItemFactory.NUMBER)
443 .withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
444 .withType(chanTypeTotals).build());
447 channels.add(ChannelBuilder
448 .create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_JAM_EVENTS),
449 CoreItemFactory.NUMBER)
450 .withLabel("Jams").withDescription("The amount of times the paper has jammed")
451 .withType(chanTypeTotalsAdvanced).build());
453 channels.add(ChannelBuilder
454 .create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_MISPICK_EVENTS),
455 CoreItemFactory.NUMBER)
456 .withLabel("Missed Picks")
457 .withDescription("The amount of times the paper failed to feed into the printer")
458 .withType(chanTypeTotalsAdvanced).build());
463 if (feature.hasCopyApplication()) {
464 if (feature.hasScanADF()) {
465 channels.add(ChannelBuilder
466 .create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_ADF),
467 CoreItemFactory.NUMBER)
468 .withLabel("Document Feeder Count")
469 .withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
473 if (feature.hasScanFlatbed()) {
474 channels.add(ChannelBuilder
475 .create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_FLATBED),
476 CoreItemFactory.NUMBER)
477 .withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
478 .withType(chanTypeTotals).build());
481 channels.add(ChannelBuilder
482 .create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_PAGES),
483 CoreItemFactory.NUMBER)
484 .withLabel("Total Pages").withDescription("The amount of pages copied")
485 .withType(chanTypeTotals).build());
487 if (feature.getType() == PrinterType.MULTICOLOR
488 || feature.getType() == PrinterType.SINGLECOLOR) {
489 channels.add(ChannelBuilder
490 .create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_COLORPAGES),
491 CoreItemFactory.NUMBER)
492 .withLabel("Total Colour Pages")
493 .withDescription("The amount of colour pages copied").withType(chanTypeTotals)
496 channels.add(ChannelBuilder
497 .create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_MONOPAGES),
498 CoreItemFactory.NUMBER)
499 .withLabel("Total Monochrome Pages")
500 .withDescription("The amount of monochrome pages copied").withType(chanTypeTotals)
506 if (feature.hasPrintApplication()) {
507 channels.add(ChannelBuilder
508 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_WIN), CoreItemFactory.NUMBER)
509 .withLabel("Windows").withType(chanTypeTotalsAdvanced).build());
511 channels.add(ChannelBuilder
512 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_ANDROID),
513 CoreItemFactory.NUMBER)
514 .withLabel("Android").withType(chanTypeTotalsAdvanced).build());
516 channels.add(ChannelBuilder
517 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_IOS), CoreItemFactory.NUMBER)
518 .withLabel("iOS").withType(chanTypeTotalsAdvanced).build());
520 channels.add(ChannelBuilder
521 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_OSX), CoreItemFactory.NUMBER)
522 .withLabel("OSX").withType(chanTypeTotalsAdvanced).build());
524 channels.add(ChannelBuilder
525 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_SAMSUNG),
526 CoreItemFactory.NUMBER)
527 .withLabel("Samsung").withType(chanTypeTotalsAdvanced).build());
529 if (feature.hasPrintApplicationChrome()) {
530 channels.add(ChannelBuilder
531 .create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_CHROME),
532 CoreItemFactory.NUMBER)
533 .withLabel("Chrome").withType(chanTypeTotalsAdvanced).build());
539 handler.binderAddChannels(channels);
544 * Opens the connection to the Embedded Web Server
547 runOfflineScheduler();
551 * Close the connection to the Embedded Web Server
553 public void close() {
554 stopBackgroundSchedules();
556 final ScheduledFuture<?> localOfflineScheduler = offlineScheduler;
558 if (localOfflineScheduler != null) {
559 localOfflineScheduler.cancel(true);
560 offlineScheduler = null;
565 * The device has gone offline
567 public void goneOffline() {
568 handler.updateStatus(ThingStatus.OFFLINE);
571 runOfflineScheduler();
574 private void runOfflineScheduler() {
575 offlineScheduler = scheduler.scheduleWithFixedDelay(this::checkOnline, 0, OFFLINE_CHECK_INTERVAL,
579 private synchronized void stopBackgroundSchedules() {
580 logger.debug("Stopping Interval Refreshes");
581 ScheduledFuture<?> localUsageScheduler = usageScheduler;
582 if (localUsageScheduler != null) {
583 localUsageScheduler.cancel(true);
586 ScheduledFuture<?> localStatusScheduler = statusScheduler;
587 if (localStatusScheduler != null) {
588 localStatusScheduler.cancel(true);
591 ScheduledFuture<?> localScannerStatusScheduler = scannerStatusScheduler;
592 if (localScannerStatusScheduler != null) {
593 localScannerStatusScheduler.cancel(true);
597 private synchronized void startBackgroundSchedules() {
598 stopBackgroundSchedules();
599 logger.debug("Starting Interval Refreshes");
601 usageScheduler = scheduler.scheduleWithFixedDelay(this::checkUsage, 0, usageCheckInterval, TimeUnit.SECONDS);
603 // Only schedule below items when there channels are linked
604 if (handler.areStatusChannelsLinked(new String[] { CHANNEL_STATUS, CHANNEL_TRAYEMPTYOROPEN })) {
605 statusScheduler = scheduler.scheduleWithFixedDelay(this::checkStatus, 0, statusCheckInterval,
609 if (handler.areStatusChannelsLinked(new String[] { CHANNEL_SCANNER_STATUS, CHANNEL_SCANNER_ADFLOADED })) {
610 scannerStatusScheduler = scheduler.scheduleWithFixedDelay(this::checkScannerStatus, 0, statusCheckInterval,
615 private void checkScannerStatus() {
616 HPServerResult<HPScannerStatus> result = printerClient.getScannerStatus();
618 if (result.getStatus() == RequestStatus.SUCCESS) {
619 handler.updateState(CGROUP_STATUS, CHANNEL_SCANNER_STATUS,
620 new StringType(result.getData().getScannerStatus()));
621 handler.updateState(CGROUP_STATUS, CHANNEL_SCANNER_ADFLOADED,
622 convertToOnOffType(result.getData().getAdfLoaded()));
628 private void checkStatus() {
629 HPServerResult<HPStatus> result = printerClient.getStatus();
631 if (result.getStatus() == RequestStatus.SUCCESS) {
632 handler.updateState(CGROUP_STATUS, CHANNEL_STATUS, new StringType(result.getData().getPrinterStatus()));
633 handler.updateState(CGROUP_STATUS, CHANNEL_TRAYEMPTYOROPEN,
634 convertToOnOffType(result.getData().getTrayEmptyOrOpen()));
640 private static State convertToOnOffType(Boolean bool) {
644 return OnOffType.OFF;
648 private void checkUsage() {
649 HPServerResult<HPUsage> result = printerClient.getUsage();
651 if (result.getStatus() == RequestStatus.SUCCESS) {
653 handler.updateState(CGROUP_INK, CHANNEL_BLACK_LEVEL,
654 new QuantityType<>(result.getData().getInkBlack(), Units.PERCENT));
655 handler.updateState(CGROUP_INK, CHANNEL_COLOR_LEVEL,
656 new QuantityType<>(result.getData().getInkColor(), Units.PERCENT));
657 handler.updateState(CGROUP_INK, CHANNEL_CYAN_LEVEL,
658 new QuantityType<>(result.getData().getInkCyan(), Units.PERCENT));
659 handler.updateState(CGROUP_INK, CHANNEL_MAGENTA_LEVEL,
660 new QuantityType<>(result.getData().getInkMagenta(), Units.PERCENT));
661 handler.updateState(CGROUP_INK, CHANNEL_YELLOW_LEVEL,
662 new QuantityType<>(result.getData().getInkYellow(), Units.PERCENT));
664 handler.updateState(CGROUP_USAGE, CHANNEL_JAM_EVENTS, new DecimalType(result.getData().getJamEvents()));
665 handler.updateState(CGROUP_USAGE, CHANNEL_SUBSCRIPTION,
666 new DecimalType(result.getData().getTotalSubscriptionImpressions()));
667 handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES,
668 new DecimalType(result.getData().getTotalColorImpressions()));
669 handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES,
670 new DecimalType(result.getData().getTotalMonochromeImpressions()));
671 handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_PAGES,
672 new DecimalType(result.getData().getTotalImpressions()));
673 handler.updateState(CGROUP_USAGE, CHANNEL_MISPICK_EVENTS,
674 new DecimalType(result.getData().getMispickEvents()));
675 handler.updateState(CGROUP_USAGE, CHANNEL_FRONT_PANEL_CANCEL,
676 new DecimalType(result.getData().getFrontPanelCancelCount()));
678 handler.updateState(CGROUP_USAGE, CHANNEL_BLACK_MARKING,
679 new QuantityType<>(result.getData().getInkBlackMarking(), MetricPrefix.MILLI(Units.LITRE)));
680 handler.updateState(CGROUP_USAGE, CHANNEL_COLOR_MARKING,
681 new QuantityType<>(result.getData().getInkColorMarking(), MetricPrefix.MILLI(Units.LITRE)));
682 handler.updateState(CGROUP_USAGE, CHANNEL_CYAN_MARKING,
683 new QuantityType<>(result.getData().getInkCyanMarking(), MetricPrefix.MILLI(Units.LITRE)));
684 handler.updateState(CGROUP_USAGE, CHANNEL_MAGENTA_MARKING,
685 new QuantityType<>(result.getData().getInkMagentaMarking(), MetricPrefix.MILLI(Units.LITRE)));
686 handler.updateState(CGROUP_USAGE, CHANNEL_YELLOW_MARKING,
687 new QuantityType<>(result.getData().getInkYellowMarking(), MetricPrefix.MILLI(Units.LITRE)));
689 handler.updateState(CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING,
690 new DecimalType(result.getData().getInkBlackPagesRemaining()));
692 handler.updateState(CGROUP_USAGE, CHANNEL_COLOR_PAGES_REMAINING,
693 new DecimalType(result.getData().getInkColorPagesRemaining()));
695 handler.updateState(CGROUP_USAGE, CHANNEL_CYAN_PAGES_REMAINING,
696 new DecimalType(result.getData().getInkCyanPagesRemaining()));
698 handler.updateState(CGROUP_USAGE, CHANNEL_MAGENTA_PAGES_REMAINING,
699 new DecimalType(result.getData().getInkMagentaPagesRemaining()));
701 handler.updateState(CGROUP_USAGE, CHANNEL_YELLOW_PAGES_REMAINING,
702 new DecimalType(result.getData().getInkYellowPagesRemaining()));
705 handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_ADF, new DecimalType(result.getData().getScanAdfCount()));
707 handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_FLATBED,
708 new DecimalType(result.getData().getScanFlatbedCount()));
710 handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOEMAIL,
711 new DecimalType(result.getData().getScanToEmailCount()));
713 handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOFOLDER,
714 new DecimalType(result.getData().getScanToFolderCount()));
716 handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOHOST,
717 new DecimalType(result.getData().getScanToHostCount()));
720 handler.updateState(CGROUP_SCANNER, CHANNEL_TOTAL_ADF,
721 new DecimalType(result.getData().getScannerAdfCount()));
722 handler.updateState(CGROUP_SCANNER, CHANNEL_TOTAL_FLATBED,
723 new DecimalType(result.getData().getScannerFlatbedCount()));
724 handler.updateState(CGROUP_SCANNER, CHANNEL_JAM_EVENTS,
725 new DecimalType(result.getData().getScannerJamEvents()));
726 handler.updateState(CGROUP_SCANNER, CHANNEL_MISPICK_EVENTS,
727 new DecimalType(result.getData().getScannerMispickEvents()));
730 handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_ADF, new DecimalType(result.getData().getCopyAdfCount()));
731 handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_FLATBED,
732 new DecimalType(result.getData().getCopyFlatbedCount()));
733 handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_PAGES,
734 new DecimalType(result.getData().getCopyTotalImpressions()));
735 handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_COLORPAGES,
736 new DecimalType(result.getData().getCopyTotalColorImpressions()));
737 handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_MONOPAGES,
738 new DecimalType(result.getData().getCopyTotalMonochromeImpressions()));
741 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_WIN, new DecimalType(result.getData().getAppWindowsCount()));
742 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_OSX, new DecimalType(result.getData().getAppOSXCount()));
743 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_IOS, new DecimalType(result.getData().getAppIosCount()));
744 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_ANDROID,
745 new DecimalType(result.getData().getAppAndroidCount()));
746 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_SAMSUNG,
747 new DecimalType(result.getData().getAppSamsungCount()));
748 handler.updateState(CGROUP_APP, CHANNEL_TOTAL_CHROME,
749 new DecimalType(result.getData().getAppChromeCount()));
752 handler.updateState(CGROUP_OTHER, CHANNEL_CLOUD_PRINT,
753 new DecimalType(result.getData().getCloudPrintImpressions()));
760 private void goneOnline() {
761 handler.updateStatus(ThingStatus.ONLINE);
763 final ScheduledFuture<?> localOfflineScheduler = offlineScheduler;
765 if (localOfflineScheduler != null) {
766 localOfflineScheduler.cancel(true);
767 offlineScheduler = null;
769 retrieveProperties();
771 startBackgroundSchedules();
774 private void checkOnline() {
775 HPServerResult<HPStatus> result = printerClient.getStatus();
777 if (result.getStatus() == RequestStatus.SUCCESS) {
779 } else if (result.getStatus() == RequestStatus.TIMEOUT) {
780 handler.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getErrorMessage());
782 handler.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, result.getErrorMessage());