added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.hpprinter/.classpath
Normal file
32
bundles/org.openhab.binding.hpprinter/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.hpprinter/.project
Normal file
23
bundles/org.openhab.binding.hpprinter/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.hpprinter</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.hpprinter/NOTICE
Normal file
13
bundles/org.openhab.binding.hpprinter/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
138
bundles/org.openhab.binding.hpprinter/README.md
Normal file
138
bundles/org.openhab.binding.hpprinter/README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# HP Printer Binding
|
||||
|
||||
This binding supports [HP Printers](https://store.hp.com/us/en/cv/printers), which are reachable through IP on the local network.
|
||||
|
||||
## Supported Things
|
||||
|
||||
There is only one thing type named `printer`.
|
||||
All channels are added dynamically depending on the type of printer and its capabilities.
|
||||
|
||||
## Discovery
|
||||
|
||||
This binding uses mDNS for discovering HP Printers on the local network.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
The configuration parameters are:
|
||||
|
||||
| Parameter | Name | Type | Required | Default |
|
||||
| --------------------------------- | --------------- | ------- | -------- | ------- |
|
||||
| IP Address | ipAddress | String | yes | |
|
||||
| Usage Refresh Interval (seconds) | usageInterval | Integer | | 30 |
|
||||
| Status Refresh Interval (seconds) | statusInterval | Integer | | 4 |
|
||||
|
||||
## Channels
|
||||
|
||||
| Channel | Group | Name | Data Type |
|
||||
| ------------------------------------------ | ----------- | --------------------- | -------------------- |
|
||||
| Printer Status | status | status | String |
|
||||
| Tray Empty/Open | status | trayEmptyOrOpen | Switch |
|
||||
| Scanner Status | status | scannerStatus | String |
|
||||
| ADF Loaded | status | scannerAdfLoaded | Switch |
|
||||
| Black Colour Level | usage | blackLevel | Number:Dimensionless |
|
||||
| Colour Level | usage | colorLevel | Number:Dimensionless |
|
||||
| Cyan Colour Level | usage | cyanLevel | Number:Dimensionless |
|
||||
| Magenta Colour Level | usage | magentaLevel | Number:Dimensionless |
|
||||
| Yellow Colour Level | usage | yellowLevel | Number:Dimensionless |
|
||||
| Black Marking Used | usage | blackMarker | Number:Volume |
|
||||
| Colour Marking Used | usage | colorMarker | Number:Volume |
|
||||
| Cyan Marking Used | usage | cyanMarker | Number:Volume |
|
||||
| Magenta Marking Used | usage | magentaMarker | Number:Volume |
|
||||
| Yellow Marking Used | usage | yellowMarker | Number:Volume |
|
||||
| Black Pages Remaining | usage | blackPagesRemaining | Number |
|
||||
| Colour Pages Remaining | usage | colorPagesRemaining | Number |
|
||||
| Cyan Pages Remaining | usage | cyanPagesRemaining | Number |
|
||||
| Magenta Pages Remaining | usage | magentaPagesRemaining | Number |
|
||||
| Yellow Pages Remaining | usage | yellowPagesRemaining | Number |
|
||||
| Total Number of Pages Printed Lifetime | usage | totalCount | Number |
|
||||
| Total Number of Colour Pages Printed | usage | totalColorCount | Number |
|
||||
| Total Number of Monochrome Pages Printed | usage | totalMonochromeCount | Number |
|
||||
| Paper Jams | usage | jamEvents | Number |
|
||||
| Missed Pick Events | usage | mispickEvents | Number |
|
||||
| Front Panel Cancel Count | usage | fpCancelCount | Number |
|
||||
| Subscription Count | usage | subscriptionCount | Number |
|
||||
| Scanner Document Feeder Count | scanner | totalAdf | Number |
|
||||
| Scanner Flatbed Count | scanner | totalFlatbed | Number |
|
||||
| Scanner Paper Jams | scanner | jamEvents | Number |
|
||||
| Scanner Missed Picks | scanner | mispickEvents | Number |
|
||||
| Scan Document Feeder Count | scan | totalAdf | Number |
|
||||
| Scan Flatbed Count | scan | totalFlatbed | Number |
|
||||
| Scan to Email Count | scan | totalToEmail | Number |
|
||||
| Scan to Folder Count | scan | totalToFolder | Number |
|
||||
| Scan to Host Count | scan | totalToHost | Number |
|
||||
| Copy Document Feeder Count | copy | totalAdf | Number |
|
||||
| Copy Flatbed Count | copy | totalFlatbed | Number |
|
||||
| Copy Total Pages Count | copy | totalCount | Number |
|
||||
| Copy Total Colour Pages Count | copy | totalColorCount | Number |
|
||||
| Copy Total Monochrome Pages Count | copy | totalMonochromeCount | Number |
|
||||
| Windows Page Count | app | totalWin | Number |
|
||||
| Android Page Count | app | totalAndroid | Number |
|
||||
| iOS Page Count | app | totalIos | Number |
|
||||
| OSX Page Count | app | totalOsx | Number |
|
||||
| Samsung Page Count | app | totalSamsung | Number |
|
||||
| Chrome Page Count | app | totalChrome | Number |
|
||||
| Google Cloud Print Count | other | cloudPrint | Number |
|
||||
|
||||
Notes:
|
||||
|
||||
* All channels are dynamically added at runtime.
|
||||
* The word color in channel names follows American spelling ("color").
|
||||
* The `colorLevel`, `colorMarkingUsed` and `colorPagesRemaining` channels are used on printers that have only a single color cartridge instead of separate Ccyan, magenta and yellow cartridges.
|
||||
* The `scanner` group is for the scanning engine which consists of scan, copy and other operations; the `scan` group is for scanner operations only.
|
||||
* If no `status` group channels are selected, then those relevant data endpoints on the *Embedded Web Server* are not polled for status information.
|
||||
|
||||
## Full Textual Example
|
||||
|
||||
### Thing File
|
||||
|
||||
```
|
||||
Thing hpprinter:printer:djprinter "Printer" @ "Office" [ ipAddress="192.168.1.1", usageInterval="30", statusInterval="4" ]
|
||||
```
|
||||
|
||||
### Item File
|
||||
|
||||
```
|
||||
String PrinterStatus "Status" { channel="pprinter:printer:djprinter:status#status" }
|
||||
|
||||
Number:Dimensionless PrinterBlackLevel "Black Level" { channel="hpprinter:printer:djprinter:ink#blackLevel" }
|
||||
Number:Dimensionless PrinterCyanLevel "Cyan Level" { channel="hpprinter:printer:djprinter:ink#cyanLevel" }
|
||||
Number:Dimensionless PrinterMagentaLevel "Magenta Level" { channel="hpprinter:printer:djprinter:ink#magentaLevel" }
|
||||
Number:Dimensionless PrinterYellowLevel "Yellow Level" { channel="hpprinter:printer:djprinter:ink#yellowLevel" }
|
||||
|
||||
Number PrinterTotalPages "Total Pages" { channel="hpprinter:printer:djprinter:usage#totalCount" }
|
||||
Number PrinterTotalColourPages "Total Colour Pages" { channel="hpprinter:printer:djprinter:usage#totalColorCount" }
|
||||
Number PrinterTotalMonochromePages "Total Monochrome Pages" { channel="hpprinter:printer:djprinter:usage#totalMonochromeCount" }
|
||||
```
|
||||
|
||||
### Sitemap File
|
||||
|
||||
Black Ink displayed as a whole percentage - `60 %`
|
||||
|
||||
```
|
||||
Text item=hpprinter_printer_djprinter_ink_blackLevel label="Black [%.0f %unit%]"
|
||||
```
|
||||
|
||||
Black Marker displayed in millilitres - `21 ml`
|
||||
*Default*
|
||||
|
||||
```
|
||||
Text item=hpprinter_printer_djprinter_usage_blackMarker label="Black Marker [%.0f %unit%]"
|
||||
```
|
||||
|
||||
Black Marker displayed in litres - `0.021 l`
|
||||
|
||||
```
|
||||
Text item=hpprinter_printer_djprinter_usage_blackMarker label="Black Marker [%.3f l]"
|
||||
```
|
||||
|
||||
Black Marker displayed in microlitres - `21000 µl`
|
||||
|
||||
```
|
||||
Text item=hpprinter_printer_djprinter_usage_blackMarker label="Black Marker [%.0f µl]"
|
||||
```
|
||||
|
||||
Scanner Document Feeder loaded with text status display - `ON` or `OFF`
|
||||
|
||||
```
|
||||
Text item=hpprinter_printer_djprinter_status_scannerAdfLoaded label="ADF Loaded [%s]"
|
||||
```
|
||||
17
bundles/org.openhab.binding.hpprinter/pom.xml
Normal file
17
bundles/org.openhab.binding.hpprinter/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.hpprinter</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: HP Printer Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.hpprinter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-hpprinter" description="HP Printer Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-mdns</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.hpprinter/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,785 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import static org.openhab.binding.hpprinter.internal.HPPrinterBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPFeatures;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPProductUsageFeatures;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPProductUsageFeatures.PrinterType;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPProperties;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPScannerStatus;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPScannerStatusFeatures;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPServerResult;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPServerResult.RequestStatus;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPStatus;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPUsage;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPWebServerClient;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.MetricPrefix;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterBinder} connects the binding to the Web Server Client
|
||||
* classes.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPPrinterBinder {
|
||||
private final Logger logger = LoggerFactory.getLogger(HPPrinterBinder.class);
|
||||
|
||||
private static final int OFFLINE_CHECK_INTERVAL = 15;
|
||||
|
||||
private HPPrinterHandler handler;
|
||||
private ScheduledExecutorService scheduler;
|
||||
|
||||
private final int statusCheckInterval;
|
||||
private final int usageCheckInterval;
|
||||
private final HPWebServerClient printerClient;
|
||||
|
||||
private @Nullable ScheduledFuture<?> statusScheduler;
|
||||
private @Nullable ScheduledFuture<?> scannerStatusScheduler;
|
||||
private @Nullable ScheduledFuture<?> usageScheduler;
|
||||
private @Nullable ScheduledFuture<?> offlineScheduler;
|
||||
|
||||
/**
|
||||
* Creates a new HP Printer Binder object
|
||||
*
|
||||
* @param handler {HPPrinterBinderEvent} The Event handler for the binder.
|
||||
* @param httpClient {HttpClient} The HttpClient object to use to perform HTTP
|
||||
* requests.
|
||||
* @param scheduler {ScheduledExecutorService} The scheduler service object.
|
||||
* @param config {HPPrinterConfiguration} The configuration object.
|
||||
*/
|
||||
public HPPrinterBinder(HPPrinterHandler handler, HttpClient httpClient, ScheduledExecutorService scheduler,
|
||||
HPPrinterConfiguration config) {
|
||||
this.handler = handler;
|
||||
this.scheduler = scheduler;
|
||||
usageCheckInterval = config.usageInterval;
|
||||
statusCheckInterval = config.statusInterval;
|
||||
String ipAddress = config.ipAddress;
|
||||
if (ipAddress == null) {
|
||||
throw new IllegalStateException("ip-address should have been validated already and may not be empty.");
|
||||
}
|
||||
printerClient = new HPWebServerClient(httpClient, ipAddress);
|
||||
}
|
||||
|
||||
public void retrieveProperties() {
|
||||
HPServerResult<HPProperties> result = printerClient.getProperties();
|
||||
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
handler.updateProperties(result.getData().getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void channelsChanged() {
|
||||
logger.trace("Channels have been changed");
|
||||
close();
|
||||
open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically add channels to the Thing based on the Embedded Web Server Usage
|
||||
* Feed
|
||||
*/
|
||||
public void dynamicallyAddChannels(ThingUID thingUid) {
|
||||
logger.debug("Building dynamic channels based on printer");
|
||||
|
||||
HPServerResult<HPFeatures> featureResult = printerClient.getProductUsageFeatures();
|
||||
if (featureResult.getStatus() == RequestStatus.SUCCESS) {
|
||||
final List<Channel> channels = new ArrayList<>();
|
||||
|
||||
HPFeatures features = featureResult.getData();
|
||||
|
||||
if (features.getProductStatusSupported()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_STATUS), CoreItemFactory.STRING)
|
||||
.withLabel("Status").withDescription("Printer status").withType(chanTypeStatus).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_TRAYEMPTYOROPEN),
|
||||
CoreItemFactory.SWITCH)
|
||||
.withLabel("Tray Empty/Open").withDescription("The tray is empty or open")
|
||||
.withType(chanTypeReadSwitch).build());
|
||||
}
|
||||
|
||||
if (features.getScannerStatusSupported()) {
|
||||
HPServerResult<HPScannerStatusFeatures> result = printerClient.getScannerFeatures();
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
HPScannerStatusFeatures feature = result.getData();
|
||||
|
||||
if (feature.hasStatus()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_SCANNER_STATUS),
|
||||
CoreItemFactory.STRING)
|
||||
.withLabel("Scanner").withDescription("Scanner status").withType(chanTypeStatus)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (feature.hasAdf()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_STATUS, CHANNEL_SCANNER_ADFLOADED),
|
||||
CoreItemFactory.SWITCH)
|
||||
.withLabel("ADF Loaded").withDescription("The automatic document feeder is loaded")
|
||||
.withType(chanTypeReadSwitch).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (features.getProductUsageSupported()) {
|
||||
HPServerResult<HPProductUsageFeatures> result = printerClient.getProductFeatures();
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
HPProductUsageFeatures feature = result.getData();
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_BLACK_LEVEL),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_INK)
|
||||
.withLabel("Black Level").withDescription("Shows the amount of Black Ink/Toner remaining")
|
||||
.withType(chanTypeInkLevel).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_PAGES), CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Lifetime Pages")
|
||||
.withDescription("The amount of pages printed over the printer lifetime")
|
||||
.withType(chanTypeTotals).build());
|
||||
|
||||
if (feature.hasCumulativeMarking()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_MARKING),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
|
||||
.withLabel("Black Marking Used").withDescription("The amount of Black Marking used")
|
||||
.withType(chanTypeMarking).build());
|
||||
}
|
||||
|
||||
switch (feature.getType()) {
|
||||
case SINGLECOLOR:
|
||||
if (feature.hasCumulativeMarking()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_COLOR_MARKING),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
|
||||
.withLabel("Colour Marking Used")
|
||||
.withDescription("The amount of Colour Marking used").withType(chanTypeMarking)
|
||||
.build());
|
||||
}
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_COLOR_LEVEL),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_INK)
|
||||
.withLabel("Color Level")
|
||||
.withDescription("Shows the amount of Colour Ink/Toner remaining")
|
||||
.withType(chanTypeInkLevel).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Colour Pages")
|
||||
.withDescription("The amount of colour pages printed").withType(chanTypeTotals)
|
||||
.build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Monochrome Pages")
|
||||
.withDescription("The amount of monochrome pages printed").withType(chanTypeTotals)
|
||||
.build());
|
||||
|
||||
if (feature.hasPagesRemaining()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Black Pages Remaining")
|
||||
.withDescription("Estimated Black pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_COLOR_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Colour Pages Remaining")
|
||||
.withDescription("Estimated Colour pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MULTICOLOR:
|
||||
if (feature.hasCumulativeMarking()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_CYAN_MARKING),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
|
||||
.withLabel("Cyan Marking Used")
|
||||
.withDescription("The amount of Cyan Marking used").withType(chanTypeMarking)
|
||||
.build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MAGENTA_MARKING),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
|
||||
.withLabel("Magenta Marking Used")
|
||||
.withDescription("The amount of Magenta Marking used").withType(chanTypeMarking)
|
||||
.build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_YELLOW_MARKING),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_CUMLMARK)
|
||||
.withLabel("Yellow Marking Used")
|
||||
.withDescription("The amount of Yellow Marking used").withType(chanTypeMarking)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (feature.hasPagesRemaining()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Black Pages Remaining")
|
||||
.withDescription("Estimated Black pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_CYAN_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Cyan Pages Remaining")
|
||||
.withDescription("Estimated Cyan pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MAGENTA_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Magenta Pages Remaining")
|
||||
.withDescription("Estimated Magenta pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_YELLOW_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Yellow Pages Remaining")
|
||||
.withDescription("Estimated Yellow pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_CYAN_LEVEL),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_INK)
|
||||
.withLabel("Cyan Level")
|
||||
.withDescription("Shows the amount of Cyan Ink/Toner remaining")
|
||||
.withType(chanTypeInkLevel).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_MAGENTA_LEVEL),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_INK)
|
||||
.withLabel("Magenta Level")
|
||||
.withDescription("Shows the amount of Magenta Ink/Toner remaining")
|
||||
.withType(chanTypeInkLevel).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_INK, CHANNEL_YELLOW_LEVEL),
|
||||
HPPrinterBindingConstants.ITEM_TYPE_INK)
|
||||
.withLabel("Yellow Level")
|
||||
.withDescription("Shows the amount of Yellow Ink/Toner remaining")
|
||||
.withType(chanTypeInkLevel).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Colour Pages")
|
||||
.withDescription("The amount of colour pages printed").withType(chanTypeTotals)
|
||||
.build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Monochrome Pages")
|
||||
.withDescription("The amount of monochrome pages printed").withType(chanTypeTotals)
|
||||
.build());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (feature.hasPagesRemaining()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Black Pages Remaining")
|
||||
.withDescription("Estimated Black pages remaining")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
}
|
||||
|
||||
if (feature.hasJamEvents()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_JAM_EVENTS),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Jams").withDescription("The amount of times the paper has jammed")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
if (feature.hasMispickEvents()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_MISPICK_EVENTS),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Missed Picks")
|
||||
.withDescription("The amount of times the paper failed to feed into the printer")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
if (feature.hasSubscriptionCount()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_SUBSCRIPTION),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Subscription Count")
|
||||
.withDescription("The amount of times an item has been printed in subscription")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
if (feature.hasTotalFrontPanelCancelPresses()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_USAGE, CHANNEL_FRONT_PANEL_CANCEL),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Front Panel Cancel Count")
|
||||
.withDescription("The amount of times a print has been cancelled from the Front Panel")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
// Other
|
||||
if (feature.hasCloudPrint()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_OTHER, CHANNEL_CLOUD_PRINT),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Cloud Print Count")
|
||||
.withDescription(
|
||||
"The amount of times a document has been printed via Google Cloud Print")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
// Scan
|
||||
if (feature.hasScanADF()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_ADF),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Document Feeder Count")
|
||||
.withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (feature.hasScanFlatbed()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_FLATBED),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
|
||||
.withType(chanTypeTotals).build());
|
||||
}
|
||||
|
||||
if (feature.hasScanToEmail()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOEMAIL),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Scan to Email Count").withDescription("Times scanned using Scan to Email")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
if (feature.hasScanToFolder()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOFOLDER),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Scan to Folder Count").withDescription("Times scanned using Scan to Folder")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
if (feature.hasScanToHost()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCAN, CHANNEL_TOTAL_TOHOST),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Scan to Host Count")
|
||||
.withDescription("Times scanned using Scan to Host Device")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
|
||||
// Scanner Engine
|
||||
if (feature.hasScannerEngine()) {
|
||||
if (feature.hasScanADF()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_TOTAL_ADF),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Document Feeder Count")
|
||||
.withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (feature.hasScanFlatbed()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_TOTAL_FLATBED),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
|
||||
.withType(chanTypeTotals).build());
|
||||
}
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_JAM_EVENTS),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Jams").withDescription("The amount of times the paper has jammed")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_SCANNER, CHANNEL_MISPICK_EVENTS),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Missed Picks")
|
||||
.withDescription("The amount of times the paper failed to feed into the printer")
|
||||
.withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
}
|
||||
|
||||
// Copy Engine
|
||||
if (feature.hasCopyApplication()) {
|
||||
if (feature.hasScanADF()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_ADF),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Document Feeder Count")
|
||||
.withDescription("Times scanned via the Document Feeder").withType(chanTypeTotals)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (feature.hasScanFlatbed()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_FLATBED),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Flatbed Count").withDescription("Times scanned via the Flatbed/Glass")
|
||||
.withType(chanTypeTotals).build());
|
||||
}
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_PAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Pages").withDescription("The amount of pages copied")
|
||||
.withType(chanTypeTotals).build());
|
||||
|
||||
if (feature.getType() == PrinterType.MULTICOLOR
|
||||
|| feature.getType() == PrinterType.SINGLECOLOR) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_COLORPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Colour Pages")
|
||||
.withDescription("The amount of colour pages copied").withType(chanTypeTotals)
|
||||
.build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_COPY, CHANNEL_TOTAL_MONOPAGES),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Total Monochrome Pages")
|
||||
.withDescription("The amount of monochrome pages copied").withType(chanTypeTotals)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
// App Usage
|
||||
if (feature.hasPrintApplication()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_WIN), CoreItemFactory.NUMBER)
|
||||
.withLabel("Windows").withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_ANDROID),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Android").withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_IOS), CoreItemFactory.NUMBER)
|
||||
.withLabel("iOS").withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_OSX), CoreItemFactory.NUMBER)
|
||||
.withLabel("OSX").withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_SAMSUNG),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Samsung").withType(chanTypeTotalsAdvanced).build());
|
||||
|
||||
if (feature.hasPrintApplicationChrome()) {
|
||||
channels.add(ChannelBuilder
|
||||
.create(new ChannelUID(thingUid, CGROUP_APP, CHANNEL_TOTAL_CHROME),
|
||||
CoreItemFactory.NUMBER)
|
||||
.withLabel("Chrome").withType(chanTypeTotalsAdvanced).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handler.binderAddChannels(channels);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the connection to the Embedded Web Server
|
||||
*/
|
||||
public void open() {
|
||||
runOfflineScheduler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection to the Embedded Web Server
|
||||
*/
|
||||
public void close() {
|
||||
stopBackgroundSchedules();
|
||||
|
||||
final ScheduledFuture<?> localOfflineScheduler = offlineScheduler;
|
||||
|
||||
if (localOfflineScheduler != null) {
|
||||
localOfflineScheduler.cancel(true);
|
||||
offlineScheduler = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The device has gone offline
|
||||
*/
|
||||
public void goneOffline() {
|
||||
handler.updateStatus(ThingStatus.OFFLINE);
|
||||
|
||||
close();
|
||||
runOfflineScheduler();
|
||||
}
|
||||
|
||||
private void runOfflineScheduler() {
|
||||
offlineScheduler = scheduler.scheduleWithFixedDelay(this::checkOnline, 0, OFFLINE_CHECK_INTERVAL,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private synchronized void stopBackgroundSchedules() {
|
||||
logger.debug("Stopping Interval Refreshes");
|
||||
ScheduledFuture<?> localUsageScheduler = usageScheduler;
|
||||
if (localUsageScheduler != null) {
|
||||
localUsageScheduler.cancel(true);
|
||||
}
|
||||
|
||||
ScheduledFuture<?> localStatusScheduler = statusScheduler;
|
||||
if (localStatusScheduler != null) {
|
||||
localStatusScheduler.cancel(true);
|
||||
}
|
||||
|
||||
ScheduledFuture<?> localScannerStatusScheduler = scannerStatusScheduler;
|
||||
if (localScannerStatusScheduler != null) {
|
||||
localScannerStatusScheduler.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void startBackgroundSchedules() {
|
||||
stopBackgroundSchedules();
|
||||
logger.debug("Starting Interval Refreshes");
|
||||
|
||||
usageScheduler = scheduler.scheduleWithFixedDelay(this::checkUsage, 0, usageCheckInterval, TimeUnit.SECONDS);
|
||||
|
||||
// Only schedule below items when there channels are linked
|
||||
if (handler.areStatusChannelsLinked(new String[] { CHANNEL_STATUS, CHANNEL_TRAYEMPTYOROPEN })) {
|
||||
statusScheduler = scheduler.scheduleWithFixedDelay(this::checkStatus, 0, statusCheckInterval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
if (handler.areStatusChannelsLinked(new String[] { CHANNEL_SCANNER_STATUS, CHANNEL_SCANNER_ADFLOADED })) {
|
||||
scannerStatusScheduler = scheduler.scheduleWithFixedDelay(this::checkScannerStatus, 0, statusCheckInterval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkScannerStatus() {
|
||||
HPServerResult<HPScannerStatus> result = printerClient.getScannerStatus();
|
||||
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
handler.updateState(CGROUP_STATUS, CHANNEL_SCANNER_STATUS,
|
||||
new StringType(result.getData().getScannerStatus()));
|
||||
handler.updateState(CGROUP_STATUS, CHANNEL_SCANNER_ADFLOADED,
|
||||
convertToOnOffType(result.getData().getAdfLoaded()));
|
||||
} else {
|
||||
goneOffline();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStatus() {
|
||||
HPServerResult<HPStatus> result = printerClient.getStatus();
|
||||
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
handler.updateState(CGROUP_STATUS, CHANNEL_STATUS, new StringType(result.getData().getPrinterStatus()));
|
||||
handler.updateState(CGROUP_STATUS, CHANNEL_TRAYEMPTYOROPEN,
|
||||
convertToOnOffType(result.getData().getTrayEmptyOrOpen()));
|
||||
} else {
|
||||
goneOffline();
|
||||
}
|
||||
}
|
||||
|
||||
private static State convertToOnOffType(Boolean bool) {
|
||||
if (bool) {
|
||||
return OnOffType.ON;
|
||||
} else {
|
||||
return OnOffType.OFF;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUsage() {
|
||||
HPServerResult<HPUsage> result = printerClient.getUsage();
|
||||
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
// Inks
|
||||
handler.updateState(CGROUP_INK, CHANNEL_BLACK_LEVEL,
|
||||
new QuantityType<>(result.getData().getInkBlack(), SmartHomeUnits.PERCENT));
|
||||
handler.updateState(CGROUP_INK, CHANNEL_COLOR_LEVEL,
|
||||
new QuantityType<>(result.getData().getInkColor(), SmartHomeUnits.PERCENT));
|
||||
handler.updateState(CGROUP_INK, CHANNEL_CYAN_LEVEL,
|
||||
new QuantityType<>(result.getData().getInkCyan(), SmartHomeUnits.PERCENT));
|
||||
handler.updateState(CGROUP_INK, CHANNEL_MAGENTA_LEVEL,
|
||||
new QuantityType<>(result.getData().getInkMagenta(), SmartHomeUnits.PERCENT));
|
||||
handler.updateState(CGROUP_INK, CHANNEL_YELLOW_LEVEL,
|
||||
new QuantityType<>(result.getData().getInkYellow(), SmartHomeUnits.PERCENT));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_JAM_EVENTS, new DecimalType(result.getData().getJamEvents()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_SUBSCRIPTION,
|
||||
new DecimalType(result.getData().getTotalSubscriptionImpressions()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_COLORPAGES,
|
||||
new DecimalType(result.getData().getTotalColorImpressions()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_MONOPAGES,
|
||||
new DecimalType(result.getData().getTotalMonochromeImpressions()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_TOTAL_PAGES,
|
||||
new DecimalType(result.getData().getTotalImpressions()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_MISPICK_EVENTS,
|
||||
new DecimalType(result.getData().getMispickEvents()));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_FRONT_PANEL_CANCEL,
|
||||
new DecimalType(result.getData().getFrontPanelCancelCount()));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_BLACK_MARKING, new QuantityType<>(
|
||||
result.getData().getInkBlackMarking(), MetricPrefix.MILLI(SmartHomeUnits.LITRE)));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_COLOR_MARKING, new QuantityType<>(
|
||||
result.getData().getInkColorMarking(), MetricPrefix.MILLI(SmartHomeUnits.LITRE)));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_CYAN_MARKING,
|
||||
new QuantityType<>(result.getData().getInkCyanMarking(), MetricPrefix.MILLI(SmartHomeUnits.LITRE)));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_MAGENTA_MARKING, new QuantityType<>(
|
||||
result.getData().getInkMagentaMarking(), MetricPrefix.MILLI(SmartHomeUnits.LITRE)));
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_YELLOW_MARKING, new QuantityType<>(
|
||||
result.getData().getInkYellowMarking(), MetricPrefix.MILLI(SmartHomeUnits.LITRE)));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_BLACK_PAGES_REMAINING,
|
||||
new DecimalType(result.getData().getInkBlackPagesRemaining()));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_COLOR_PAGES_REMAINING,
|
||||
new DecimalType(result.getData().getInkColorPagesRemaining()));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_CYAN_PAGES_REMAINING,
|
||||
new DecimalType(result.getData().getInkCyanPagesRemaining()));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_MAGENTA_PAGES_REMAINING,
|
||||
new DecimalType(result.getData().getInkMagentaPagesRemaining()));
|
||||
|
||||
handler.updateState(CGROUP_USAGE, CHANNEL_YELLOW_PAGES_REMAINING,
|
||||
new DecimalType(result.getData().getInkYellowPagesRemaining()));
|
||||
|
||||
// Scan
|
||||
handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_ADF, new DecimalType(result.getData().getScanAdfCount()));
|
||||
|
||||
handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_FLATBED,
|
||||
new DecimalType(result.getData().getScanFlatbedCount()));
|
||||
|
||||
handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOEMAIL,
|
||||
new DecimalType(result.getData().getScanToEmailCount()));
|
||||
|
||||
handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOFOLDER,
|
||||
new DecimalType(result.getData().getScanToFolderCount()));
|
||||
|
||||
handler.updateState(CGROUP_SCAN, CHANNEL_TOTAL_TOHOST,
|
||||
new DecimalType(result.getData().getScanToHostCount()));
|
||||
|
||||
// Scanner
|
||||
handler.updateState(CGROUP_SCANNER, CHANNEL_TOTAL_ADF,
|
||||
new DecimalType(result.getData().getScannerAdfCount()));
|
||||
handler.updateState(CGROUP_SCANNER, CHANNEL_TOTAL_FLATBED,
|
||||
new DecimalType(result.getData().getScannerFlatbedCount()));
|
||||
handler.updateState(CGROUP_SCANNER, CHANNEL_JAM_EVENTS,
|
||||
new DecimalType(result.getData().getScannerJamEvents()));
|
||||
handler.updateState(CGROUP_SCANNER, CHANNEL_MISPICK_EVENTS,
|
||||
new DecimalType(result.getData().getScannerMispickEvents()));
|
||||
|
||||
// Copy
|
||||
handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_ADF, new DecimalType(result.getData().getCopyAdfCount()));
|
||||
handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_FLATBED,
|
||||
new DecimalType(result.getData().getCopyFlatbedCount()));
|
||||
handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_PAGES,
|
||||
new DecimalType(result.getData().getCopyTotalImpressions()));
|
||||
handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_COLORPAGES,
|
||||
new DecimalType(result.getData().getCopyTotalColorImpressions()));
|
||||
handler.updateState(CGROUP_COPY, CHANNEL_TOTAL_MONOPAGES,
|
||||
new DecimalType(result.getData().getCopyTotalMonochromeImpressions()));
|
||||
|
||||
// App Usage
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_WIN, new DecimalType(result.getData().getAppWindowsCount()));
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_OSX, new DecimalType(result.getData().getAppOSXCount()));
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_IOS, new DecimalType(result.getData().getAppIosCount()));
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_ANDROID,
|
||||
new DecimalType(result.getData().getAppAndroidCount()));
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_SAMSUNG,
|
||||
new DecimalType(result.getData().getAppSamsungCount()));
|
||||
handler.updateState(CGROUP_APP, CHANNEL_TOTAL_CHROME,
|
||||
new DecimalType(result.getData().getAppChromeCount()));
|
||||
|
||||
// Other
|
||||
handler.updateState(CGROUP_OTHER, CHANNEL_CLOUD_PRINT,
|
||||
new DecimalType(result.getData().getCloudPrintImpressions()));
|
||||
|
||||
} else {
|
||||
goneOffline();
|
||||
}
|
||||
}
|
||||
|
||||
private void goneOnline() {
|
||||
handler.updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
final ScheduledFuture<?> localOfflineScheduler = offlineScheduler;
|
||||
|
||||
if (localOfflineScheduler != null) {
|
||||
localOfflineScheduler.cancel(true);
|
||||
offlineScheduler = null;
|
||||
}
|
||||
retrieveProperties();
|
||||
|
||||
startBackgroundSchedules();
|
||||
}
|
||||
|
||||
private void checkOnline() {
|
||||
HPServerResult<HPStatus> result = printerClient.getStatus();
|
||||
|
||||
if (result.getStatus() == RequestStatus.SUCCESS) {
|
||||
goneOnline();
|
||||
} else if (result.getStatus() == RequestStatus.TIMEOUT) {
|
||||
handler.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getErrorMessage());
|
||||
} else {
|
||||
handler.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, result.getErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPPrinterBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "hpprinter";
|
||||
|
||||
// ********** List of all Thing Type UIDs **********
|
||||
public static final ThingTypeUID THING_PRINTER = new ThingTypeUID(BINDING_ID, "printer");
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Stream.of(THING_PRINTER)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// ********** Channel Types **********
|
||||
public static ChannelTypeUID chanTypeStatus = new ChannelTypeUID("hpprinter:status");
|
||||
public static ChannelTypeUID chanTypeReadSwitch = new ChannelTypeUID("hpprinter:readonlyswitch");
|
||||
public static ChannelTypeUID chanTypeTotals = new ChannelTypeUID("hpprinter:totals");
|
||||
public static ChannelTypeUID chanTypeTotalsAdvanced = new ChannelTypeUID("hpprinter:totalsAdv");
|
||||
public static ChannelTypeUID chanTypeMarking = new ChannelTypeUID("hpprinter:cumlMarkingUsed");
|
||||
public static ChannelTypeUID chanTypeInkLevel = new ChannelTypeUID("hpprinter:inkLevel");
|
||||
|
||||
// ********** Item Types **********
|
||||
public static final String ITEM_TYPE_CUMLMARK = "Number:Volume";
|
||||
public static final String ITEM_TYPE_INK = "Number:Dimensionless";
|
||||
|
||||
// ********** List of all Channel ids **********
|
||||
// Status
|
||||
public static final String CHANNEL_STATUS = "status";
|
||||
public static final String CHANNEL_TRAYEMPTYOROPEN = "trayEmptyOrOpen";
|
||||
|
||||
public static final String CHANNEL_SCANNER_STATUS = "scannerStatus";
|
||||
public static final String CHANNEL_SCANNER_ADFLOADED = "scannerAdfLoaded";
|
||||
|
||||
// Colours
|
||||
public static final String CHANNEL_COLOR_LEVEL = "colorLevel";
|
||||
public static final String CHANNEL_CYAN_LEVEL = "cyanLevel";
|
||||
public static final String CHANNEL_MAGENTA_LEVEL = "magentaLevel";
|
||||
public static final String CHANNEL_YELLOW_LEVEL = "yellowLevel";
|
||||
public static final String CHANNEL_BLACK_LEVEL = "blackLevel";
|
||||
|
||||
public static final String CHANNEL_COLOR_MARKING = "colorMarker";
|
||||
public static final String CHANNEL_CYAN_MARKING = "cyanMarker";
|
||||
public static final String CHANNEL_MAGENTA_MARKING = "magentaMarker";
|
||||
public static final String CHANNEL_YELLOW_MARKING = "yellowMarker";
|
||||
public static final String CHANNEL_BLACK_MARKING = "blackMarker";
|
||||
|
||||
// Estimated Pages Remaining
|
||||
public static final String CHANNEL_COLOR_PAGES_REMAINING = "colorPagesRemaining";
|
||||
public static final String CHANNEL_CYAN_PAGES_REMAINING = "cyanPagesRemaining";
|
||||
public static final String CHANNEL_MAGENTA_PAGES_REMAINING = "magentaPagesRemaining";
|
||||
public static final String CHANNEL_YELLOW_PAGES_REMAINING = "yellowPagesRemaining";
|
||||
public static final String CHANNEL_BLACK_PAGES_REMAINING = "blackPagesRemaining";
|
||||
|
||||
// Page Counts
|
||||
public static final String CHANNEL_TOTAL_PAGES = "totalCount";
|
||||
public static final String CHANNEL_SUBSCRIPTION = "subsciptionCount";
|
||||
public static final String CHANNEL_TOTAL_COLORPAGES = "totalColorCount";
|
||||
public static final String CHANNEL_TOTAL_MONOPAGES = "totalMonochromeCount";
|
||||
public static final String CHANNEL_JAM_EVENTS = "jamEvents";
|
||||
public static final String CHANNEL_MISPICK_EVENTS = "mispickEvents";
|
||||
public static final String CHANNEL_FRONT_PANEL_CANCEL = "fpCancelCount";
|
||||
public static final String CHANNEL_CLOUD_PRINT = "cloudPrint";
|
||||
|
||||
// Scanner
|
||||
public static final String CHANNEL_TOTAL_ADF = "totalAdf";
|
||||
public static final String CHANNEL_TOTAL_FLATBED = "totalFlatbed";
|
||||
public static final String CHANNEL_TOTAL_TOEMAIL = "totalToEmail";
|
||||
public static final String CHANNEL_TOTAL_TOFOLDER = "totalToFolder";
|
||||
public static final String CHANNEL_TOTAL_TOHOST = "totalToHost";
|
||||
|
||||
// App Usage
|
||||
public static final String CHANNEL_TOTAL_WIN = "totalWin";
|
||||
public static final String CHANNEL_TOTAL_ANDROID = "totalAndroid";
|
||||
public static final String CHANNEL_TOTAL_IOS = "totalIos";
|
||||
public static final String CHANNEL_TOTAL_OSX = "totalOsx";
|
||||
public static final String CHANNEL_TOTAL_SAMSUNG = "totalSamsung";
|
||||
public static final String CHANNEL_TOTAL_CHROME = "totalChrome";
|
||||
|
||||
// ********** List of all Channel Groups **********
|
||||
public static final String CGROUP_INK = "ink";
|
||||
public static final String CGROUP_STATUS = "status";
|
||||
public static final String CGROUP_USAGE = "usage";
|
||||
public static final String CGROUP_SCANNER = "scanner"; // Scanner Engine
|
||||
public static final String CGROUP_SCAN = "scan"; // Scan Application
|
||||
public static final String CGROUP_COPY = "copy";
|
||||
public static final String CGROUP_APP = "app";
|
||||
public static final String CGROUP_OTHER = "other";
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPPrinterConfiguration {
|
||||
public static final String IP_ADDRESS = "ipAddress";
|
||||
public static final String USAGE_INTERVAL = "usageInterval";
|
||||
public static final String STATUS_INTERVAL = "statusInterval";
|
||||
|
||||
public @Nullable String ipAddress;
|
||||
public int usageInterval;
|
||||
public int statusInterval;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import static org.openhab.binding.hpprinter.internal.HPPrinterBindingConstants.THING_PRINTER;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.jmdns.ServiceInfo;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterDiscoveryParticipant} class discovers HP Printers over
|
||||
* mDNS.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true)
|
||||
public class HPPrinterDiscoveryParticipant implements MDNSDiscoveryParticipant {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HPPrinterDiscoveryParticipant.class);
|
||||
|
||||
@Override
|
||||
public @Nullable DiscoveryResult createResult(ServiceInfo service) {
|
||||
if (!service.hasData()) {
|
||||
logger.trace("Service has no data.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// We only care about HP Printers
|
||||
String ty = service.getPropertyString("ty");
|
||||
if (ty != null && ty.toLowerCase().startsWith("hp")) {
|
||||
String rp = service.getPropertyString("rp");
|
||||
if (rp == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.debug("Found HP Printer ID: {}", ty);
|
||||
ThingUID uid = getThingUID(service);
|
||||
if (uid != null) {
|
||||
Map<String, Object> properties = new HashMap<>(2);
|
||||
InetAddress ip = getIpAddress(service);
|
||||
if (ip == null) {
|
||||
return null;
|
||||
}
|
||||
String inetAddress = ip.toString().substring(1); // trim leading slash
|
||||
String label = service.getName();
|
||||
|
||||
properties.put(HPPrinterConfiguration.IP_ADDRESS, inetAddress);
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
|
||||
.build();
|
||||
logger.trace("Created a DiscoveryResult {} for printer on host '{}' name '{}'", result, inetAddress,
|
||||
label);
|
||||
return result;
|
||||
} else {
|
||||
logger.debug("Found unsupported HP Printer ID: {}", ty);
|
||||
}
|
||||
} else {
|
||||
logger.trace("Ignore non HP device {}", ty);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUIDName(ServiceInfo service) {
|
||||
return service.getName().replaceAll("[^A-Za-z0-9_]", "_");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceType() {
|
||||
return "_printer._tcp.local.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
|
||||
return HPPrinterBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingUID getThingUID(ServiceInfo service) {
|
||||
if (service.getType() != null) {
|
||||
logger.trace("ServiceInfo: {}", service);
|
||||
if (service.getType().equals(getServiceType())) {
|
||||
String uidName = getUIDName(service);
|
||||
ThingTypeUID mdl = findThingType();
|
||||
|
||||
return new ThingUID(mdl, uidName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private InetAddress getIpAddress(ServiceInfo service) {
|
||||
InetAddress address = null;
|
||||
for (InetAddress addr : service.getInet4Addresses()) {
|
||||
logger.debug("Get IP address for device {}", addr);
|
||||
return addr;
|
||||
}
|
||||
// Fallback for Inet6addresses
|
||||
for (InetAddress addr : service.getInet6Addresses()) {
|
||||
logger.debug("Get IP address for device {}", addr);
|
||||
return addr;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
private ThingTypeUID findThingType() {
|
||||
return THING_PRINTER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import static org.openhab.binding.hpprinter.internal.HPPrinterBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPPrinterHandler extends BaseThingHandler {
|
||||
private final HttpClient httpClient;
|
||||
private @Nullable HPPrinterBinder binder;
|
||||
|
||||
public HPPrinterHandler(final Thing thing, final HttpClient httpClient) {
|
||||
super(thing);
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingUpdated(final Thing thing) {
|
||||
super.thingUpdated(thing);
|
||||
|
||||
final HPPrinterBinder printerBinder = this.binder;
|
||||
if (printerBinder != null) {
|
||||
printerBinder.dynamicallyAddChannels(thing.getUID());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(final ChannelUID channelUID, final Command command) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
final HPPrinterConfiguration config = getConfigAs(HPPrinterConfiguration.class);
|
||||
|
||||
if (!"".equals(config.ipAddress)) {
|
||||
final HPPrinterBinder localBinder = binder = new HPPrinterBinder(this, httpClient, scheduler, config);
|
||||
|
||||
localBinder.dynamicallyAddChannels(thing.getUID());
|
||||
localBinder.retrieveProperties();
|
||||
localBinder.open();
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "You must set an IP Address");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
final HPPrinterBinder localBinder = binder;
|
||||
if (localBinder != null) {
|
||||
localBinder.close();
|
||||
binder = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Boolean areStatusChannelsLinked(final String[] channels) {
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
if (isLinked(new ChannelUID(thing.getUID(), CGROUP_STATUS, channels[i]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void updateStatus(final ThingStatus status) {
|
||||
super.updateStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelLinked(ChannelUID channelUID) {
|
||||
final HPPrinterBinder localBinder = binder;
|
||||
if (localBinder != null) {
|
||||
localBinder.channelsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelUnlinked(ChannelUID channelUID) {
|
||||
final HPPrinterBinder localBinder = binder;
|
||||
if (localBinder != null) {
|
||||
localBinder.channelsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateStatus(final ThingStatus status, final ThingStatusDetail thingStatusDetail,
|
||||
@Nullable final String message) {
|
||||
super.updateStatus(status, thingStatusDetail, message);
|
||||
}
|
||||
|
||||
public void updateState(final String group, final String channel, final State state) {
|
||||
super.updateState(new ChannelUID(thing.getUID(), group, channel), state);
|
||||
}
|
||||
|
||||
public void binderAddChannels(final List<Channel> channels) {
|
||||
final List<Channel> thingChannels = new ArrayList<>(getThing().getChannels());
|
||||
|
||||
for (final Channel channel : channels) {
|
||||
addOrUpdateChannel(channel, thingChannels);
|
||||
}
|
||||
|
||||
updateThing(editThing().withChannels(thingChannels).build());
|
||||
}
|
||||
|
||||
protected ThingBuilder editThing() {
|
||||
return super.editThing();
|
||||
}
|
||||
|
||||
protected @Nullable ThingHandlerCallback getCallback() {
|
||||
return super.getCallback();
|
||||
}
|
||||
|
||||
protected void updateProperties(final Map<String, String> properties) {
|
||||
super.updateProperties(properties);
|
||||
}
|
||||
|
||||
private static void addOrUpdateChannel(final Channel newChannel, final List<Channel> thingChannels) {
|
||||
removeChannelByUID(thingChannels, newChannel.getUID());
|
||||
thingChannels.add(newChannel);
|
||||
}
|
||||
|
||||
private static void removeChannelByUID(final List<Channel> thingChannels, final ChannelUID channelUIDtoRemove) {
|
||||
final Predicate<Channel> channelPredicate = c -> c.getUID().getId().equals(channelUIDtoRemove.getId());
|
||||
thingChannels.removeIf(channelPredicate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal;
|
||||
|
||||
import static org.openhab.binding.hpprinter.internal.HPPrinterBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link HPPrinterHandlerFactory} is responsible for creating things and
|
||||
* thing handlers.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.hpprinter", service = ThingHandlerFactory.class)
|
||||
public class HPPrinterHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public HPPrinterHandlerFactory(@Reference final HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
return new HPPrinterHandler(thing, httpClient);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPScannerStatus} is responsible for handling reading of scanner status data.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPFeatures {
|
||||
public static final String ENDPOINT = "/DevMgmt/DiscoveryTree.xml";
|
||||
|
||||
private final boolean productStatus;
|
||||
private final boolean productUsage;
|
||||
private final boolean scannerStatus;
|
||||
|
||||
public HPFeatures(Document document) {
|
||||
Element root = (Element) document.getDocumentElement();
|
||||
|
||||
boolean localProductStatus = false;
|
||||
boolean localProductUsage = false;
|
||||
boolean localScannerStatus = false;
|
||||
|
||||
for (Node n = root.getFirstChild(); n != null; n = n.getNextSibling()) {
|
||||
if (n instanceof Element) {
|
||||
Element feature = (Element) n;
|
||||
|
||||
NodeList resourceType = feature.getElementsByTagName("dd:ResourceType");
|
||||
|
||||
if (resourceType.getLength() > 0) {
|
||||
switch (resourceType.item(0).getTextContent()) {
|
||||
case "ledm:hpLedmProductStatusDyn":
|
||||
localProductStatus = true;
|
||||
break;
|
||||
|
||||
case "ledm:hpLedmProductUsageDyn":
|
||||
localProductUsage = true;
|
||||
break;
|
||||
|
||||
case "eSCL:eSclManifest":
|
||||
localScannerStatus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
productStatus = localProductStatus;
|
||||
productUsage = localProductUsage;
|
||||
scannerStatus = localScannerStatus;
|
||||
}
|
||||
|
||||
public boolean getProductStatusSupported() {
|
||||
return productStatus;
|
||||
}
|
||||
|
||||
public boolean getProductUsageSupported() {
|
||||
return productUsage;
|
||||
}
|
||||
|
||||
public boolean getScannerStatusSupported() {
|
||||
return scannerStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPProductUsageFeatures} is responsible for determining what type of printer usage
|
||||
* data the Web Interface supports including any features.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPProductUsageFeatures {
|
||||
public static final String ENDPOINT = "/DevMgmt/ProductUsageDyn.xml";
|
||||
|
||||
private PrinterType printerType = PrinterType.UNKNOWN;
|
||||
private boolean jamEvents;
|
||||
private boolean mispickEvents;
|
||||
private boolean subscriptionImpressions;
|
||||
private boolean frontPanelCancel;
|
||||
private boolean cumuMarking;
|
||||
private boolean pagesRemaining;
|
||||
|
||||
private boolean scanAdf;
|
||||
private boolean scanFlatbed;
|
||||
private boolean scanToHost;
|
||||
private boolean scanToEmail;
|
||||
private boolean scanToFolder;
|
||||
|
||||
private boolean printApplication;
|
||||
private boolean printApplicationChrome;
|
||||
|
||||
private boolean scannerEngine;
|
||||
private boolean copyApplication;
|
||||
|
||||
private boolean cloudPrint;
|
||||
|
||||
public enum PrinterType {
|
||||
UNKNOWN,
|
||||
MONOCHROME,
|
||||
SINGLECOLOR,
|
||||
MULTICOLOR
|
||||
}
|
||||
|
||||
public HPProductUsageFeatures(final Document document) {
|
||||
// Check what Ink/Toner colours are present
|
||||
final NodeList consumableInk = document.getDocumentElement().getElementsByTagName("pudyn:Consumable");
|
||||
|
||||
for (int i = 0; i < consumableInk.getLength(); i++) {
|
||||
final Element currInk = (Element) consumableInk.item(i);
|
||||
final String inkName = currInk.getElementsByTagName("dd:MarkerColor").item(0).getTextContent();
|
||||
final String consumeType = currInk.getElementsByTagName("dd:ConsumableTypeEnum").item(0).getTextContent();
|
||||
|
||||
if (consumeType.equalsIgnoreCase("printhead")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cumuMarking = (currInk.getElementsByTagName("dd2:CumulativeMarkingAgentUsed").getLength() > 0);
|
||||
|
||||
switch (inkName.toLowerCase()) {
|
||||
case "cyan":
|
||||
case "magenta":
|
||||
case "yellow":
|
||||
printerType = PrinterType.MULTICOLOR; // Is multicolor if it has this ink
|
||||
break;
|
||||
|
||||
case "cyanmagentayellow":
|
||||
printerType = PrinterType.SINGLECOLOR; // Is singlecolor if it has this ink
|
||||
break;
|
||||
|
||||
case "black":
|
||||
if (printerType == PrinterType.UNKNOWN) {
|
||||
printerType = PrinterType.MONOCHROME; // Is Monochrome
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pagesRemaining = (((Element) consumableInk.item(0)).getElementsByTagName("dd:EstimatedPagesRemaining")
|
||||
.getLength() > 0);
|
||||
|
||||
final NodeList printerSubUnit = document.getDocumentElement().getElementsByTagName("pudyn:PrinterSubunit");
|
||||
if (printerSubUnit.getLength() > 0) {
|
||||
final Element currPrinterSubUnit = (Element) printerSubUnit.item(0);
|
||||
|
||||
jamEvents = (currPrinterSubUnit.getElementsByTagName("dd:JamEvents").getLength() > 0);
|
||||
mispickEvents = (currPrinterSubUnit.getElementsByTagName("dd:MispickEvents").getLength() > 0);
|
||||
subscriptionImpressions = (currPrinterSubUnit.getElementsByTagName("pudyn:SubscriptionImpressions")
|
||||
.getLength() > 0);
|
||||
frontPanelCancel = (currPrinterSubUnit.getElementsByTagName("dd:TotalFrontPanelCancelPresses")
|
||||
.getLength() > 0);
|
||||
}
|
||||
|
||||
final NodeList scannerSubUnit = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:ScanApplicationSubunit");
|
||||
if (scannerSubUnit.getLength() > 0) {
|
||||
final Element currScannerSubUnit = (Element) scannerSubUnit.item(0);
|
||||
|
||||
scanAdf = (currScannerSubUnit.getElementsByTagName("dd:AdfImages").getLength() > 0);
|
||||
scanFlatbed = (currScannerSubUnit.getElementsByTagName("dd:FlatbedImages").getLength() > 0);
|
||||
scanToEmail = (currScannerSubUnit.getElementsByTagName("dd:ImagesSentToEmail").getLength() > 0);
|
||||
scanToFolder = (currScannerSubUnit.getElementsByTagName("dd:ImagesSentToFolder").getLength() > 0);
|
||||
scanToHost = (currScannerSubUnit.getElementsByTagName("dd:ScanToHostImages").getLength() > 0);
|
||||
}
|
||||
|
||||
final NodeList scanAppSubUnit = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:ScanApplicationSubunit");
|
||||
if (scanAppSubUnit.getLength() > 0) {
|
||||
printApplication = true;
|
||||
|
||||
final Element currAppSubUnit = (Element) scanAppSubUnit.item(0);
|
||||
|
||||
printApplicationChrome = (currAppSubUnit.getElementsByTagName("pudyn:RemoteDeviceType").getLength() > 0);
|
||||
}
|
||||
|
||||
final NodeList printAppSubUnit = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:PrintApplicationSubunit");
|
||||
if (printAppSubUnit.getLength() > 0) {
|
||||
final Element currPrintAppSubUnit = (Element) printAppSubUnit.item(0);
|
||||
|
||||
cloudPrint = (currPrintAppSubUnit.getElementsByTagName("dd:CloudPrintImpressions").getLength() > 0);
|
||||
}
|
||||
|
||||
final NodeList scannerEngineSubUnit = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:ScannerEngineSubunit");
|
||||
scannerEngine = (scannerEngineSubUnit.getLength() > 0);
|
||||
|
||||
final NodeList copyAppSubUnit = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:CopyApplicationSubunit");
|
||||
copyApplication = (copyAppSubUnit.getLength() > 0);
|
||||
}
|
||||
|
||||
public PrinterType getType() {
|
||||
return printerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scanner Engine.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScannerEngineSubunit
|
||||
*
|
||||
* return {boolean} True is supported.
|
||||
*/
|
||||
public boolean hasScannerEngine() {
|
||||
return scannerEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Copy Application.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScannerEngineSubunit
|
||||
*
|
||||
* return {boolean} True is supported.
|
||||
*/
|
||||
public boolean hasCopyApplication() {
|
||||
return copyApplication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Estimated Pages Remaining.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ConsumableSubunit -> pudyn:Consumable -> dd:EstimatedPagesRemaining
|
||||
*
|
||||
* return {boolean} True is supported.
|
||||
*/
|
||||
public boolean hasPagesRemaining() {
|
||||
return pagesRemaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scan to Email.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScanApplicationSubunit -> dd:ImagesSentToEmail
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasScanToEmail() {
|
||||
return scanToEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scan to Folder.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScanApplicationSubunit -> dd:ImagesSentToFolder
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasScanToFolder() {
|
||||
return scanToFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scan to Host.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScanApplicationSubunit -> dd:ScanToHostImages
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasScanToHost() {
|
||||
return scanToHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scanner Automatic Document Feeder.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScanApplicationSubunit -> dd:AdfImages
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasScanADF() {
|
||||
return scanAdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Scanner Flatbed.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ScanApplicationSubunit -> dd:FlatbedImages
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasScanFlatbed() {
|
||||
return scanFlatbed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data has Google Cloud Print impressions.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:PrintApplicationSubunit -> dd:CloudPrintImpressions
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasCloudPrint() {
|
||||
return cloudPrint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Print Application Usage Information.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:MobileApplicationSubunit
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasPrintApplication() {
|
||||
return printApplication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Chrome Print Application Usage Information.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:MobileApplicationSubunit
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasPrintApplicationChrome() {
|
||||
return printApplicationChrome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Cumulative Marking Agent Used.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:ConsumableSubunit -> pudyn:Consumable -> dd2:CumulativeMarkingAgentUsed
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasCumulativeMarking() {
|
||||
return cumuMarking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Jam Events.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:PrinterSubunit -> dd:JamEvents
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasJamEvents() {
|
||||
return jamEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Mispick Events.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:PrinterSubunit -> dd:MispickEvents
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasMispickEvents() {
|
||||
return mispickEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Subscription Impressions count.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:PrinterSubunit ->
|
||||
* pudyn:SubscriptionImpressions
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasSubscriptionCount() {
|
||||
return subscriptionImpressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Printer data contains Front panel cancel presses count.
|
||||
*
|
||||
* pudyn:ProductUsageDyn -> pudyn:PrinterSubunit ->
|
||||
* dd:TotalFrontPanelCancelPresses
|
||||
*
|
||||
* @return {boolean} True if supported.
|
||||
*/
|
||||
public boolean hasTotalFrontPanelCancelPresses() {
|
||||
return frontPanelCancel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPProperties} is responsible for returning the
|
||||
* reading of data from the HP Embedded Web Server.
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPProperties {
|
||||
public static final String ENDPOINT = "/DevMgmt/ProductConfigDyn.xml";
|
||||
private final Map<String, String> properties = new HashMap<>();
|
||||
|
||||
public HPProperties(Document document) {
|
||||
NodeList nodes = document.getDocumentElement().getElementsByTagName("prdcfgdyn:ProductInformation");
|
||||
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
properties.put(Thing.PROPERTY_SERIAL_NUMBER,
|
||||
element.getElementsByTagName("dd:SerialNumber").item(0).getTextContent());
|
||||
properties.put(Thing.PROPERTY_MODEL_ID,
|
||||
element.getElementsByTagName("dd:ProductNumber").item(0).getTextContent());
|
||||
Node firmwareDate = element.getElementsByTagName("dd:Version").item(0);
|
||||
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, firmwareDate.getChildNodes().item(0).getTextContent());
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPScannerStatus} is responsible for handling reading of scanner status data.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPScannerStatus {
|
||||
public static final String ENDPOINT = "/eSCL/ScannerStatus";
|
||||
|
||||
private final String status;
|
||||
private final Boolean adfLoaded;
|
||||
|
||||
public HPScannerStatus(Document document) {
|
||||
String localScannerStatus = "Unknown";
|
||||
Boolean localAdfLoaded = false;
|
||||
|
||||
Element nodes = (Element) document.getDocumentElement();
|
||||
|
||||
NodeList state = nodes.getElementsByTagName("pwg:State");
|
||||
if (state.getLength() > 0) {
|
||||
localScannerStatus = state.item(0).getTextContent();
|
||||
}
|
||||
|
||||
NodeList adfState = nodes.getElementsByTagName("scan:AdfState");
|
||||
if (adfState.getLength() > 0) {
|
||||
String adfStatus = adfState.item(0).getTextContent();
|
||||
localAdfLoaded = convertAdfStatus(adfStatus);
|
||||
}
|
||||
|
||||
adfLoaded = localAdfLoaded;
|
||||
status = localScannerStatus;
|
||||
}
|
||||
|
||||
private static Boolean convertAdfStatus(String status) {
|
||||
return "ScannerAdfLoaded".equals(status);
|
||||
}
|
||||
|
||||
public Boolean getAdfLoaded() {
|
||||
return adfLoaded;
|
||||
}
|
||||
|
||||
public @Nullable String getScannerStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* The {@link HPScannerStatusFeatures} is responsible for determining what type of printer scanner
|
||||
* status features the Web Interface supports.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPScannerStatusFeatures {
|
||||
public static final String ENDPOINT = "/eSCL/ScannerStatus";
|
||||
|
||||
private final boolean hasStatus;
|
||||
private final boolean hasAdf;
|
||||
|
||||
public HPScannerStatusFeatures(Document document) {
|
||||
boolean localHasStatus = false;
|
||||
boolean localHasAdf = false;
|
||||
|
||||
Element nodes = (Element) document.getDocumentElement();
|
||||
localHasStatus = (nodes.getElementsByTagName("pwg:State").getLength() > 0);
|
||||
localHasAdf = (nodes.getElementsByTagName("scan:AdfState").getLength() > 0);
|
||||
|
||||
hasStatus = localHasStatus;
|
||||
hasAdf = localHasAdf;
|
||||
}
|
||||
|
||||
public boolean hasStatus() {
|
||||
return hasStatus;
|
||||
}
|
||||
|
||||
public boolean hasAdf() {
|
||||
return hasAdf;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link HPServerResult} is responsible for returning the
|
||||
* reading of data from the HP Embedded Web Server.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPServerResult<result> {
|
||||
private final RequestStatus status;
|
||||
private final @Nullable result data;
|
||||
private final String errorMessage;
|
||||
|
||||
public HPServerResult(RequestStatus status, String errorMessage) {
|
||||
this.status = status;
|
||||
this.data = null;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public HPServerResult(result data) {
|
||||
this.status = RequestStatus.SUCCESS;
|
||||
this.data = data;
|
||||
this.errorMessage = "";
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
public result getData() {
|
||||
final result localData = data;
|
||||
if (status != RequestStatus.SUCCESS || localData == null) {
|
||||
throw new IllegalStateException("No data available for result");
|
||||
}
|
||||
return localData;
|
||||
}
|
||||
|
||||
public RequestStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public enum RequestStatus {
|
||||
SUCCESS,
|
||||
TIMEOUT,
|
||||
ERROR
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPStatus} is responsible for handling reading of status data.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPStatus {
|
||||
public static final String ENDPOINT = "/DevMgmt/ProductStatusDyn.xml";
|
||||
|
||||
private static final Map<String, String> STATUS_MESSAGES = initializeStatus();
|
||||
|
||||
private final String printerStatus;
|
||||
private final boolean trayEmptyOrOpen;
|
||||
|
||||
public HPStatus(Document document) {
|
||||
NodeList nodes = document.getDocumentElement().getElementsByTagName("psdyn:Status");
|
||||
|
||||
String localPrinterStatus = "Unknown";
|
||||
boolean localTrayEmptyOrOpen = false;
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Element element = (Element) nodes.item(i);
|
||||
String statusCategory = element.getElementsByTagName("pscat:StatusCategory").item(0).getTextContent();
|
||||
if (!"genuineHP".equals(statusCategory) && !"trayEmpty".equals(statusCategory)) {
|
||||
localPrinterStatus = STATUS_MESSAGES.getOrDefault(statusCategory, statusCategory);
|
||||
}
|
||||
if ("trayEmpty".equals(statusCategory)) {
|
||||
localTrayEmptyOrOpen = true;
|
||||
}
|
||||
}
|
||||
trayEmptyOrOpen = localTrayEmptyOrOpen;
|
||||
printerStatus = localPrinterStatus;
|
||||
}
|
||||
|
||||
private static Map<String, String> initializeStatus() {
|
||||
Map<String, String> statusMap = new HashMap<>();
|
||||
|
||||
statusMap.put("processing", "Printing...");
|
||||
statusMap.put("scanProcessing", "Scanning...");
|
||||
statusMap.put("inPowerSave", "Power Save");
|
||||
statusMap.put("ready", "Idle");
|
||||
statusMap.put("initializing", "Initializing...");
|
||||
statusMap.put("closeDoorOrCover", "Door/Cover Open");
|
||||
statusMap.put("inkSystemInitializing", "Loading Ink...");
|
||||
statusMap.put("shuttingDown", "Shutting Down...");
|
||||
return statusMap;
|
||||
}
|
||||
|
||||
public boolean getTrayEmptyOrOpen() {
|
||||
return trayEmptyOrOpen;
|
||||
}
|
||||
|
||||
public @Nullable String getPrinterStatus() {
|
||||
return printerStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* The {@link HPUsage} is responsible for handling reading of usage data.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPUsage {
|
||||
public static final String ENDPOINT = "/DevMgmt/ProductUsageDyn.xml";
|
||||
|
||||
private int totalSubscriptionImpressions;
|
||||
private int mispickEvents;
|
||||
private int totalMonochromeImpressions;
|
||||
private int totalColorImpressions;
|
||||
private int frontpanelCancelCount;
|
||||
private int totalImpressions;
|
||||
|
||||
private int jamEvents;
|
||||
private int inkBlack;
|
||||
private int inkCyan;
|
||||
private int inkMagenta;
|
||||
private int inkYellow;
|
||||
private int inkColor;
|
||||
private float inkBlackMarking;
|
||||
private float inkCyanMarking;
|
||||
private float inkMagentaMarking;
|
||||
private float inkYellowMarking;
|
||||
private float inkColorMarking;
|
||||
|
||||
private int inkBlackPagesRemaining;
|
||||
private int inkColorPagesRemaining;
|
||||
private int inkCyanPagesRemaining;
|
||||
private int inkMagentaPagesRemaining;
|
||||
private int inkYellowPagesRemaining;
|
||||
|
||||
// Scan
|
||||
private int scanAdfCount;
|
||||
private int scanFlatbedCount;
|
||||
private int scanToEmailCount;
|
||||
private int scanToFolderCount;
|
||||
private int scanToHostCount;
|
||||
|
||||
// Scanner
|
||||
private int scannerAdfCount;
|
||||
private int scannerFlatbedCount;
|
||||
private int scannerJamEvents;
|
||||
private int scannerMispickEvents;
|
||||
|
||||
// Copy
|
||||
private int copyAdfCount;
|
||||
private int copyFlatbedCount;
|
||||
private int copyTotalImpressions;
|
||||
private int copyTotalMonochromeImpressions;
|
||||
private int copyTotalColorImpressions;
|
||||
|
||||
// App
|
||||
private int appWindowsCount;
|
||||
private int appOsxCount;
|
||||
private int appIosCount;
|
||||
private int appAndroidCount;
|
||||
private int appSamsungCount;
|
||||
private int appChromeCount;
|
||||
|
||||
// Other
|
||||
private int cloudPrintImpressions;
|
||||
|
||||
public HPUsage() {
|
||||
}
|
||||
|
||||
public HPUsage(Document document) {
|
||||
// Get Ink Levels
|
||||
NodeList consumableInk = document.getDocumentElement().getElementsByTagName("pudyn:Consumable");
|
||||
|
||||
for (int i = 0; i < consumableInk.getLength(); i++) {
|
||||
Element currInk = (Element) consumableInk.item(i);
|
||||
|
||||
String inkName = currInk.getElementsByTagName("dd:MarkerColor").item(0).getTextContent();
|
||||
|
||||
String consumeType = currInk.getElementsByTagName("dd:ConsumableTypeEnum").item(0).getTextContent();
|
||||
|
||||
if ("printhead".equalsIgnoreCase(consumeType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String inkRemaining = currInk.getElementsByTagName("dd:ConsumableRawPercentageLevelRemaining").item(0)
|
||||
.getTextContent();
|
||||
|
||||
int markAgentLength = currInk.getElementsByTagName("dd2:CumulativeMarkingAgentUsed").getLength();
|
||||
Boolean hasPagesRemaining = currInk.getElementsByTagName("dd:EstimatedPagesRemaining").getLength() > 0;
|
||||
float totalMarking = 0;
|
||||
int pagesRemaining = 0;
|
||||
if (markAgentLength > 0) { // Check to make sure Cumulative Marking Agent exists
|
||||
for (int ai = 0; ai < markAgentLength; ai++) {
|
||||
Element currMarking = (Element) currInk.getElementsByTagName("dd2:CumulativeMarkingAgentUsed")
|
||||
.item(ai);
|
||||
|
||||
float marking = Integer
|
||||
.parseInt(currMarking.getElementsByTagName("dd:ValueFloat").item(0).getTextContent());
|
||||
|
||||
switch (currMarking.getElementsByTagName("dd:Unit").item(0).getTextContent().toLowerCase()) {
|
||||
case "microliters":
|
||||
marking = marking / 1000; // Convert from microlitres to millilitres
|
||||
break;
|
||||
case "liters":
|
||||
marking = marking * 1000; // Convert to litres to millilitres
|
||||
}
|
||||
|
||||
totalMarking = totalMarking + marking; // Sum the marking counts together
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPagesRemaining) {
|
||||
pagesRemaining = Integer.parseInt(((Element) currInk).getElementsByTagName("dd:EstimatedPagesRemaining")
|
||||
.item(0).getTextContent());
|
||||
}
|
||||
|
||||
switch (inkName.toLowerCase()) {
|
||||
case "black":
|
||||
inkBlack = Integer.parseInt(inkRemaining);
|
||||
inkBlackMarking = totalMarking;
|
||||
inkBlackPagesRemaining = pagesRemaining;
|
||||
break;
|
||||
|
||||
case "yellow":
|
||||
inkYellow = Integer.parseInt(inkRemaining);
|
||||
inkYellowMarking = totalMarking;
|
||||
inkYellowPagesRemaining = pagesRemaining;
|
||||
break;
|
||||
|
||||
case "magenta":
|
||||
inkMagenta = Integer.parseInt(inkRemaining);
|
||||
inkMagentaMarking = totalMarking;
|
||||
inkMagentaPagesRemaining = pagesRemaining;
|
||||
break;
|
||||
|
||||
case "cyan":
|
||||
inkCyan = Integer.parseInt(inkRemaining);
|
||||
inkCyanMarking = totalMarking;
|
||||
inkCyanPagesRemaining = pagesRemaining;
|
||||
break;
|
||||
|
||||
case "cyanmagentayellow":
|
||||
inkColor = Integer.parseInt(inkRemaining);
|
||||
inkColorMarking = totalMarking;
|
||||
inkColorPagesRemaining = pagesRemaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get other usage info
|
||||
NodeList jamEvents = document.getDocumentElement().getElementsByTagName("dd:JamEvents");
|
||||
if (jamEvents.getLength() > 0) {
|
||||
this.jamEvents = Integer.parseInt(jamEvents.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList totalImpressions = document.getDocumentElement().getElementsByTagName("dd:TotalImpressions");
|
||||
if (totalImpressions.getLength() > 0) {
|
||||
this.totalImpressions = Integer.parseInt(totalImpressions.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList totalColorImpressions = document.getDocumentElement().getElementsByTagName("dd:ColorImpressions");
|
||||
if (totalColorImpressions.getLength() > 0) {
|
||||
this.totalColorImpressions = Integer.parseInt(totalColorImpressions.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList totalMonochromeImpressions = document.getDocumentElement()
|
||||
.getElementsByTagName("dd:MonochromeImpressions");
|
||||
if (totalMonochromeImpressions.getLength() > 0) {
|
||||
this.totalMonochromeImpressions = Integer.parseInt(totalMonochromeImpressions.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList totalSubscriptionImpressions = document.getDocumentElement()
|
||||
.getElementsByTagName("pudyn:SubscriptionImpressions");
|
||||
if (totalSubscriptionImpressions.getLength() > 0) {
|
||||
this.totalSubscriptionImpressions = Integer.parseInt(totalSubscriptionImpressions.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList mispickEvents = document.getDocumentElement().getElementsByTagName("dd:MispickEvents");
|
||||
if (mispickEvents.getLength() > 0) {
|
||||
this.mispickEvents = Integer.parseInt(mispickEvents.item(0).getTextContent());
|
||||
}
|
||||
|
||||
NodeList frontpanelCancelCount = document.getDocumentElement()
|
||||
.getElementsByTagName("dd:TotalFrontPanelCancelPresses");
|
||||
if (frontpanelCancelCount.getLength() > 0) {
|
||||
this.frontpanelCancelCount = Integer.parseInt(frontpanelCancelCount.item(0).getTextContent());
|
||||
}
|
||||
|
||||
// Print Apps
|
||||
NodeList printAppsSubUnit = document.getDocumentElement().getElementsByTagName("pudyn:PrintApplicationSubunit");
|
||||
if (printAppsSubUnit.getLength() > 0) {
|
||||
Element currPrintAppsSubUnit = (Element) printAppsSubUnit.item(0);
|
||||
|
||||
NodeList cloudPrintImpressions = currPrintAppsSubUnit.getElementsByTagName("dd:CloudPrintImpressions");
|
||||
|
||||
if (cloudPrintImpressions.getLength() > 0) {
|
||||
this.cloudPrintImpressions = Integer.parseInt(cloudPrintImpressions.item(0).getTextContent());
|
||||
}
|
||||
}
|
||||
|
||||
// Scan
|
||||
NodeList scanSubUnit = document.getDocumentElement().getElementsByTagName("pudyn:ScanApplicationSubunit");
|
||||
if (scanSubUnit.getLength() > 0) {
|
||||
Element currScanSubUnit = (Element) scanSubUnit.item(0);
|
||||
|
||||
this.scanAdfCount = setInt("dd:AdfImages", currScanSubUnit);
|
||||
this.scanFlatbedCount = setInt("dd:FlatbedImages", currScanSubUnit);
|
||||
|
||||
this.scanToEmailCount = setInt("dd:ImagesSentToEmail", currScanSubUnit);
|
||||
this.scanToFolderCount = setInt("dd:ImagesSentToFolder", currScanSubUnit);
|
||||
|
||||
this.scanToHostCount = setInt("dd:ScanToHostImages", currScanSubUnit);
|
||||
}
|
||||
|
||||
// Scanner
|
||||
NodeList scannerSubUnit = document.getDocumentElement().getElementsByTagName("pudyn:ScannerEngineSubunit");
|
||||
if (scannerSubUnit.getLength() > 0) {
|
||||
Element currScannerSubUnit = (Element) scannerSubUnit.item(0);
|
||||
|
||||
this.scannerAdfCount = setInt("dd:AdfImages", currScannerSubUnit);
|
||||
this.scannerFlatbedCount = setInt("dd:FlatbedImages", currScannerSubUnit);
|
||||
this.scannerJamEvents = setInt("dd:JamEvents", currScannerSubUnit);
|
||||
this.scannerMispickEvents = setInt("dd:MispickEvents", currScannerSubUnit);
|
||||
}
|
||||
|
||||
// Copy
|
||||
NodeList copySubUnit = document.getDocumentElement().getElementsByTagName("pudyn:CopyApplicationSubunit");
|
||||
if (copySubUnit.getLength() > 0) {
|
||||
Element currCopySubUnit = (Element) copySubUnit.item(0);
|
||||
|
||||
this.copyAdfCount = setInt("dd:AdfImages", currCopySubUnit);
|
||||
this.copyFlatbedCount = setInt("dd:FlatbedImages", currCopySubUnit);
|
||||
this.copyTotalColorImpressions = setInt("dd:ColorImpressions", currCopySubUnit);
|
||||
this.copyTotalMonochromeImpressions = setInt("dd:MonochromeImpressions", currCopySubUnit);
|
||||
this.copyTotalImpressions = setInt("dd:TotalImpressions", currCopySubUnit);
|
||||
}
|
||||
|
||||
// App Usage
|
||||
NodeList appSubUnit = document.getDocumentElement().getElementsByTagName("pudyn:MobileApplicationSubunit");
|
||||
if (appSubUnit.getLength() > 0) {
|
||||
Element currAppSubUnit = (Element) appSubUnit.item(0);
|
||||
|
||||
this.appWindowsCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "Windows",
|
||||
"pudyn:TotalImpressions");
|
||||
this.appOsxCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "OSX",
|
||||
"pudyn:TotalImpressions");
|
||||
this.appIosCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "iOS",
|
||||
"pudyn:TotalImpressions");
|
||||
this.appAndroidCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "Android",
|
||||
"pudyn:TotalImpressions");
|
||||
this.appSamsungCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "samsung",
|
||||
"pudyn:TotalImpressions");
|
||||
this.appChromeCount = setIntCollateDirectChildren(currAppSubUnit, "pudyn:RemoteDeviceType", "Chrome",
|
||||
"pudyn:TotalImpressions");
|
||||
}
|
||||
}
|
||||
|
||||
private static int setIntCollateDirectChildren(Element parentNode, String collateTagName,
|
||||
String collateTagNameValue, String valueTagName) {
|
||||
int value = 0;
|
||||
|
||||
for (Node n = parentNode.getFirstChild(); n != null; n = n.getNextSibling()) {
|
||||
if (n instanceof Element) {
|
||||
Element nodeItem = (Element) n;
|
||||
if (nodeItem.getElementsByTagName(collateTagName).item(0).getTextContent()
|
||||
.equalsIgnoreCase(collateTagNameValue)) {
|
||||
int nodeValue = Integer
|
||||
.parseInt(nodeItem.getElementsByTagName(valueTagName).item(0).getTextContent());
|
||||
|
||||
value += nodeValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private int setInt(String tagName, Element parentNode) {
|
||||
NodeList nodeList = parentNode.getElementsByTagName(tagName);
|
||||
if (nodeList.getLength() > 0) {
|
||||
return Integer.parseInt(nodeList.item(0).getTextContent());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getFrontPanelCancelCount() {
|
||||
return frontpanelCancelCount;
|
||||
}
|
||||
|
||||
public int getTotalSubscriptionImpressions() {
|
||||
return totalSubscriptionImpressions;
|
||||
}
|
||||
|
||||
public int getMispickEvents() {
|
||||
return mispickEvents;
|
||||
}
|
||||
|
||||
public int getTotalMonochromeImpressions() {
|
||||
return totalMonochromeImpressions;
|
||||
}
|
||||
|
||||
public int getTotalColorImpressions() {
|
||||
return totalColorImpressions;
|
||||
}
|
||||
|
||||
public int getTotalImpressions() {
|
||||
return totalImpressions;
|
||||
}
|
||||
|
||||
public int getCloudPrintImpressions() {
|
||||
return cloudPrintImpressions;
|
||||
}
|
||||
|
||||
public int getJamEvents() {
|
||||
return jamEvents;
|
||||
}
|
||||
|
||||
public int getInkBlack() {
|
||||
return inkBlack;
|
||||
}
|
||||
|
||||
public float getInkBlackMarking() {
|
||||
return inkBlackMarking;
|
||||
}
|
||||
|
||||
public int getInkCyan() {
|
||||
return inkCyan;
|
||||
}
|
||||
|
||||
public float getInkCyanMarking() {
|
||||
return inkCyanMarking;
|
||||
}
|
||||
|
||||
public int getInkMagenta() {
|
||||
return inkMagenta;
|
||||
}
|
||||
|
||||
public float getInkMagentaMarking() {
|
||||
return inkMagentaMarking;
|
||||
}
|
||||
|
||||
public int getInkYellow() {
|
||||
return inkYellow;
|
||||
}
|
||||
|
||||
public float getInkYellowMarking() {
|
||||
return inkYellowMarking;
|
||||
}
|
||||
|
||||
public int getInkBlackPagesRemaining() {
|
||||
return inkBlackPagesRemaining;
|
||||
}
|
||||
|
||||
public int getInkColorPagesRemaining() {
|
||||
return inkColorPagesRemaining;
|
||||
}
|
||||
|
||||
public int getInkMagentaPagesRemaining() {
|
||||
return inkMagentaPagesRemaining;
|
||||
}
|
||||
|
||||
public int getInkCyanPagesRemaining() {
|
||||
return inkCyanPagesRemaining;
|
||||
}
|
||||
|
||||
public int getInkYellowPagesRemaining() {
|
||||
return inkYellowPagesRemaining;
|
||||
}
|
||||
|
||||
public int getInkColor() {
|
||||
return inkColor;
|
||||
}
|
||||
|
||||
public float getInkColorMarking() {
|
||||
return inkColorMarking;
|
||||
}
|
||||
|
||||
public int getScanAdfCount() {
|
||||
return scanAdfCount;
|
||||
}
|
||||
|
||||
public int getScanFlatbedCount() {
|
||||
return scanFlatbedCount;
|
||||
}
|
||||
|
||||
public int getScanToEmailCount() {
|
||||
return scanToEmailCount;
|
||||
}
|
||||
|
||||
public int getScanToFolderCount() {
|
||||
return scanToFolderCount;
|
||||
}
|
||||
|
||||
public int getScanToHostCount() {
|
||||
return scanToHostCount;
|
||||
}
|
||||
|
||||
public int getAppWindowsCount() {
|
||||
return appWindowsCount;
|
||||
}
|
||||
|
||||
public int getAppOSXCount() {
|
||||
return appOsxCount;
|
||||
}
|
||||
|
||||
public int getAppIosCount() {
|
||||
return appIosCount;
|
||||
}
|
||||
|
||||
public int getAppAndroidCount() {
|
||||
return appAndroidCount;
|
||||
}
|
||||
|
||||
public int getAppSamsungCount() {
|
||||
return appSamsungCount;
|
||||
}
|
||||
|
||||
public int getAppChromeCount() {
|
||||
return appChromeCount;
|
||||
}
|
||||
|
||||
public int getScannerAdfCount() {
|
||||
return scannerAdfCount;
|
||||
}
|
||||
|
||||
public int getScannerFlatbedCount() {
|
||||
return scannerFlatbedCount;
|
||||
}
|
||||
|
||||
public int getScannerJamEvents() {
|
||||
return scannerJamEvents;
|
||||
}
|
||||
|
||||
public int getScannerMispickEvents() {
|
||||
return scannerMispickEvents;
|
||||
}
|
||||
|
||||
public int getCopyAdfCount() {
|
||||
return copyAdfCount;
|
||||
}
|
||||
|
||||
public int getCopyFlatbedCount() {
|
||||
return copyFlatbedCount;
|
||||
}
|
||||
|
||||
public int getCopyTotalImpressions() {
|
||||
return copyTotalImpressions;
|
||||
}
|
||||
|
||||
public int getCopyTotalColorImpressions() {
|
||||
return copyTotalColorImpressions;
|
||||
}
|
||||
|
||||
public int getCopyTotalMonochromeImpressions() {
|
||||
return copyTotalMonochromeImpressions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hpprinter.internal.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.binding.hpprinter.internal.api.HPServerResult.RequestStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* The {@link HPWebServerClient} is responsible for handling reading of data from the HP Embedded Web Server.
|
||||
*
|
||||
* @author Stewart Cossey - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HPWebServerClient {
|
||||
public static final int REQUEST_TIMEOUT_SEC = 10;
|
||||
private final Logger logger = LoggerFactory.getLogger(HPWebServerClient.class);
|
||||
|
||||
private final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
private final HttpClient httpClient;
|
||||
private final String serverAddress;
|
||||
|
||||
/**
|
||||
* Creates a new HP Web Server Client object.
|
||||
*
|
||||
* @param httpClient {HttpClient} The HttpClient to use for HTTP requests.
|
||||
* @param address The address for the Embedded Web Server.
|
||||
*/
|
||||
public HPWebServerClient(HttpClient httpClient, String address) {
|
||||
this.httpClient = httpClient;
|
||||
serverAddress = "http://" + address;
|
||||
|
||||
logger.debug("Create printer connection {}", serverAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Status information from the Embedded Web Server.
|
||||
*
|
||||
* @return The status information.
|
||||
*/
|
||||
public HPServerResult<HPStatus> getStatus() {
|
||||
return fetchData(serverAddress + HPStatus.ENDPOINT, (HPStatus::new));
|
||||
}
|
||||
|
||||
public HPServerResult<HPProductUsageFeatures> getProductFeatures() {
|
||||
return fetchData(serverAddress + HPProductUsageFeatures.ENDPOINT, (HPProductUsageFeatures::new));
|
||||
}
|
||||
|
||||
public HPServerResult<HPFeatures> getProductUsageFeatures() {
|
||||
return fetchData(serverAddress + HPFeatures.ENDPOINT, (HPFeatures::new));
|
||||
}
|
||||
|
||||
public HPServerResult<HPScannerStatusFeatures> getScannerFeatures() {
|
||||
return fetchData(serverAddress + HPScannerStatusFeatures.ENDPOINT, (HPScannerStatusFeatures::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Usage information from the Embedded Web Server.
|
||||
*
|
||||
* @return The usage information.
|
||||
*/
|
||||
public HPServerResult<HPUsage> getUsage() {
|
||||
return fetchData(serverAddress + HPUsage.ENDPOINT, (HPUsage::new));
|
||||
}
|
||||
|
||||
public HPServerResult<HPScannerStatus> getScannerStatus() {
|
||||
return fetchData(serverAddress + HPScannerStatus.ENDPOINT, (HPScannerStatus::new));
|
||||
}
|
||||
|
||||
public HPServerResult<HPProperties> getProperties() {
|
||||
return fetchData(serverAddress + HPProperties.ENDPOINT, (HPProperties::new));
|
||||
}
|
||||
|
||||
private <T> HPServerResult<T> fetchData(String endpoint, Function<Document, T> function) {
|
||||
try {
|
||||
logger.trace("HTTP Client Load {}", endpoint);
|
||||
ContentResponse cr = httpClient.newRequest(endpoint).method(HttpMethod.GET)
|
||||
.timeout(REQUEST_TIMEOUT_SEC, TimeUnit.SECONDS).send();
|
||||
|
||||
String contentAsString = cr.getContentAsString();
|
||||
logger.trace("HTTP Client Result {} Size {}", cr.getStatus(), contentAsString.length());
|
||||
return new HPServerResult<>(function.apply(getDocument(contentAsString)));
|
||||
} catch (TimeoutException ex) {
|
||||
logger.trace("HTTP Client Timeout Exception {}", ex.getMessage());
|
||||
return new HPServerResult<>(RequestStatus.TIMEOUT, ex.getMessage());
|
||||
} catch (InterruptedException | ExecutionException | ParserConfigurationException | SAXException
|
||||
| IOException ex) {
|
||||
logger.trace("HTTP Client Exception {}", ex.getMessage());
|
||||
return new HPServerResult<>(RequestStatus.ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Document getDocument(String contentAsString)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
InputSource source = new InputSource(new StringReader(contentAsString));
|
||||
return builder.parse(source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="hpprinter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>HP Printer Binding</name>
|
||||
<description>Binding for HP Printers with Embedded Web Servers</description>
|
||||
<author>Stewart Cossey</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config-description:config-descriptions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
|
||||
https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||
|
||||
<config-description uri="thing-type:hpprinter:config">
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<label>Network Address</label>
|
||||
<description>The IP or host name of the HP Printer</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="usageInterval" type="integer" min="4">
|
||||
<label>Usage Interval</label>
|
||||
<description>The refresh interval in seconds for polling the printer usage information</description>
|
||||
<default>30</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="statusInterval" type="integer" min="4">
|
||||
<label>Status Interval</label>
|
||||
<description>The refresh interval in seconds for polling status information</description>
|
||||
<default>4</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</config-description:config-descriptions>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="hpprinter"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- Channel Groups -->
|
||||
|
||||
<channel-group-type id="ink">
|
||||
<label>Ink/Toner Levels</label>
|
||||
<description>Ink/Toner amounts for each cartridge.</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="usageInfo">
|
||||
<label>Printer</label>
|
||||
<description>Print Engine Usage Information</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="printerStatus">
|
||||
<label>Status</label>
|
||||
<description>Printer Statuses</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="scanner">
|
||||
<label>Scanner</label>
|
||||
<description>Scanner Engine Usage Information</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="scan">
|
||||
<label>Scan</label>
|
||||
<description>Scan Application Usage Information</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="copy">
|
||||
<label>Copy</label>
|
||||
<description>Copy Application Usage Information</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="app">
|
||||
<label>Application</label>
|
||||
<description>Application Usage by Device or Operating System</description>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="other">
|
||||
<label>Other</label>
|
||||
<description>Other Usage or Details</description>
|
||||
</channel-group-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<thing:thing-descriptions bindingId="hpprinter"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<channel-type id="inkLevel">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Ink Level</label>
|
||||
<description>Shows the amount of Ink/Toner remaining</description>
|
||||
<state readOnly="true" pattern="%f %%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="totals">
|
||||
<item-type>Number</item-type>
|
||||
<label>Totals</label>
|
||||
<description>Amount of pages.</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="totalsAdv" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Totals</label>
|
||||
<description>Amount of pages.</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="cumlMarkingUsed" advanced="true">
|
||||
<item-type>Number:Volume</item-type>
|
||||
<label>Cumulative Marking Used</label>
|
||||
<description>Shows the amount of Ink/Toner used</description>
|
||||
<state readOnly="true" pattern="%f mL"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="status">
|
||||
<item-type>String</item-type>
|
||||
<label>Status</label>
|
||||
<description>Printer Status</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="readonlyswitch" advanced="true">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Read Only Switch Item</label>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="hpprinter"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="printer">
|
||||
<label>HP Printer</label>
|
||||
<description>An HP Printer.</description>
|
||||
<channel-groups>
|
||||
<channel-group typeId="printerStatus" id="status"/>
|
||||
<channel-group typeId="ink" id="ink"/>
|
||||
<channel-group typeId="usageInfo" id="usage"/>
|
||||
<channel-group typeId="scanner" id="scanner"/>
|
||||
<channel-group typeId="scan" id="scan"/>
|
||||
<channel-group typeId="copy" id="copy"/>
|
||||
<channel-group typeId="app" id="app"/>
|
||||
<channel-group typeId="other" id="other"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="vendor">HP</property>
|
||||
</properties>
|
||||
<representation-property>serialNumber</representation-property>
|
||||
<config-description-ref uri="thing-type:hpprinter:config"/>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user