added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View 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>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.openhab.binding.ipp</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>

View File

@@ -0,0 +1,20 @@
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
== Third-party Content
cups4j
* License: LGPL 3.0 License
* Project: http://cups4j.org
* Source: https://github.com/harwey/cups4j

View File

@@ -0,0 +1,28 @@
# IPP Binding
This binding integrates printers, which implement the Internet Printing protocol (IPP). This is the successor of the CUPS binding.
The main purpose is to check if there are waiting print jobs on a printer, which can be switched on in this case.
## Supported Things
The binding has been tested against a CUPS Server (which implements the Internet Printing Protocol).
So all printers in a CUPS envorinment should work fine. Many network printers also use IPP,
but there are many differencies on which parts of IPP are supported, is is not guaranteed, that every printer will work.
## Discovery
The printers are discovered through mDNS in the local network. As mentioned before: a printer may be discoverable but not
usable by the binding.
## Thing Configuration
## Channels
| Channel Type ID | Item Type | Description |
|-----------------|-----------|-----------------------------------------------|
| jobs | Number | Total number of print jobs on the printer |
| waitingJobs | Number | Number of waiting print jobs on the printer |
| doneJobs | Number | Number of completed print jobs on the printer |
<!-- TOTO Create example
## Full Example -->

View File

@@ -0,0 +1,59 @@
<?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.ipp</artifactId>
<name>openHAB Add-ons :: Bundles :: IPP Binding</name>
<properties>
<bnd.importpackage>!org.simpleframework.xml.*,!org.cups4j,!net.sf.ehcache.*,!net.spy.*</bnd.importpackage>
</properties>
<dependencies>
<dependency>
<groupId>org.cups4j</groupId>
<artifactId>cups4j</artifactId>
<version>0.7.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>2.7.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>xmlpull</groupId>
<artifactId>xmlpull</artifactId>
<version>1.1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-osgi</artifactId>
<version>4.4.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-osgi</artifactId>
<version>4.5.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.ipp-${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-ipp" description="IPP 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.ipp/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,45 @@
/**
* 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.ipp.internal;
import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link IppBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Tobias Braeutigam - Initial contribution
*/
@NonNullByDefault
public class IppBindingConstants {
public static final String BINDING_ID = "ipp";
// List of all Thing Type UIDs
public static final ThingTypeUID PRINTER_THING_TYPE = new ThingTypeUID(BINDING_ID, "printer");
// List of all Channel ids
public static final String JOBS_CHANNEL = "jobs";
public static final String WAITING_JOBS_CHANNEL = "waitingJobs";
public static final String DONE_JOBS_CHANNEL = "doneJobs";
public static final String PRINTER_PARAMETER_URL = "url";
public static final String PRINTER_PARAMETER_NAME = "name";
public static final String PRINTER_PARAMETER_REFRESH_INTERVAL = "refresh";
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(PRINTER_THING_TYPE);
}

View File

@@ -0,0 +1,85 @@
/**
* 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.ipp.internal;
import static org.openhab.binding.ipp.internal.IppBindingConstants.PRINTER_THING_TYPE;
import org.openhab.binding.ipp.internal.handler.IppPrinterHandler;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.discovery.DiscoveryServiceRegistry;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
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.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link IppHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Tobias Braeutigam - Initial contribution
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.ipp")
public class IppHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(IppHandlerFactory.class);
private DiscoveryServiceRegistry discoveryServiceRegistry;
@Reference
protected void setDiscoveryServiceRegistry(DiscoveryServiceRegistry discoveryServiceRegistry) {
this.discoveryServiceRegistry = discoveryServiceRegistry;
}
protected void unsetDiscoveryServiceRegistry(DiscoveryServiceRegistry discoveryServiceRegistry) {
this.discoveryServiceRegistry = null;
}
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return IppBindingConstants.SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}
@Override
public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
ThingUID bridgeUID) {
logger.trace("createThing({},{},{},{})", thingTypeUID, configuration, thingUID, bridgeUID);
if (IppBindingConstants.PRINTER_THING_TYPE.equals(thingTypeUID)) {
ThingUID deviceUID = getIppPrinterUID(thingTypeUID, thingUID, configuration);
logger.debug("creating thing {} from deviceUID: {}", thingTypeUID, deviceUID);
return super.createThing(thingTypeUID, configuration, deviceUID, null);
}
throw new IllegalArgumentException("The thing type {} " + thingTypeUID + " is not supported by the binding.");
}
private ThingUID getIppPrinterUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
if (thingUID == null) {
String name = (String) configuration.get(IppBindingConstants.PRINTER_PARAMETER_NAME);
thingUID = new ThingUID(thingTypeUID, name);
}
return thingUID;
}
@Override
protected ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(PRINTER_THING_TYPE)) {
return new IppPrinterHandler(thing, discoveryServiceRegistry);
}
return null;
}
}

View File

@@ -0,0 +1,113 @@
/**
* 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.ipp.internal.discovery;
import java.net.InetAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.jmdns.ServiceInfo;
import org.openhab.binding.ipp.internal.IppBindingConstants;
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;
/**
* discovers ipp printers announced by mDNS
*
* @author Tobias Bräutigam - Initial contribution
*/
@Component(immediate = true)
public class IppPrinterDiscoveryParticipant implements MDNSDiscoveryParticipant {
private final Logger logger = LoggerFactory.getLogger(IppPrinterDiscoveryParticipant.class);
@Override
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
return Collections.singleton(IppBindingConstants.PRINTER_THING_TYPE);
}
@Override
public String getServiceType() {
return "_ipp._tcp.local.";
}
@Override
public ThingUID getThingUID(ServiceInfo service) {
if (service != null) {
logger.trace("ServiceInfo: {}", service);
if (service.getType() != null) {
if (service.getType().equals(getServiceType())) {
String uidName = getUIDName(service);
return new ThingUID(IppBindingConstants.PRINTER_THING_TYPE, uidName);
}
}
}
return null;
}
private String getUIDName(ServiceInfo service) {
return service.getName().replaceAll("[^A-Za-z0-9_]", "_");
}
private InetAddress getIpAddress(ServiceInfo service) {
InetAddress address = null;
for (InetAddress addr : service.getInet4Addresses()) {
return addr;
}
// Fallback for Inet6addresses
for (InetAddress addr : service.getInet6Addresses()) {
return addr;
}
return address;
}
@Override
public DiscoveryResult createResult(ServiceInfo service) {
DiscoveryResult result = null;
String rp = service.getPropertyString("rp");
if (rp == null) {
return null;
}
ThingUID uid = getThingUID(service);
if (uid != null) {
Map<String, Object> properties = new HashMap<>(2);
// remove the domain from the name
InetAddress ip = getIpAddress(service);
if (ip == null) {
return null;
}
String inetAddress = ip.toString().substring(1); // trim leading slash
String label = service.getName();
int port = service.getPort();
properties.put(IppBindingConstants.PRINTER_PARAMETER_URL, "http://" + inetAddress + ":" + port + "/" + rp);
properties.put(IppBindingConstants.PRINTER_PARAMETER_NAME, label);
result = DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build();
logger.debug("Created a DiscoveryResult {} for ipp printer on host '{}' name '{}'", result,
properties.get(IppBindingConstants.PRINTER_PARAMETER_URL), label);
}
return result;
}
}

View File

@@ -0,0 +1,175 @@
/**
* 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.ipp.internal.handler;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.cups4j.CupsPrinter;
import org.cups4j.WhichJobsEnum;
import org.openhab.binding.ipp.internal.IppBindingConstants;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.discovery.DiscoveryListener;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.config.discovery.DiscoveryServiceRegistry;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link IppPrinterHandler} is responsible for handling commands, which are sent
* to one of the channels.
*
* @author Tobias Braeutigam - Initial contribution
*/
public class IppPrinterHandler extends BaseThingHandler implements DiscoveryListener {
private final Logger logger = LoggerFactory.getLogger(IppPrinterHandler.class);
private URL url;
private String name;
private CupsPrinter printer;
private int refresh = 60; // refresh every minute as default
ScheduledFuture<?> refreshJob;
private DiscoveryServiceRegistry discoveryServiceRegistry;
public IppPrinterHandler(Thing thing, DiscoveryServiceRegistry discoveryServiceRegistry) {
super(thing);
if (discoveryServiceRegistry != null) {
this.discoveryServiceRegistry = discoveryServiceRegistry;
}
}
@Override
public void initialize() {
Configuration config = getThing().getConfiguration();
try {
Object obj = config.get(IppBindingConstants.PRINTER_PARAMETER_URL);
name = (String) config.get(IppBindingConstants.PRINTER_PARAMETER_NAME);
if (config.get(IppBindingConstants.PRINTER_PARAMETER_REFRESH_INTERVAL) != null) {
BigDecimal ref = (BigDecimal) config.get(IppBindingConstants.PRINTER_PARAMETER_REFRESH_INTERVAL);
refresh = ref.intValue();
}
if (obj instanceof URL) {
url = (URL) obj;
} else if (obj instanceof String) {
url = new URL((String) obj);
}
printer = new CupsPrinter(url, name, false);
} catch (MalformedURLException e) {
logger.error("malformed url {}, printer thing creation failed",
config.get(IppBindingConstants.PRINTER_PARAMETER_URL));
}
// until we get an update put the Thing offline
updateStatus(ThingStatus.OFFLINE);
deviceOnlineWatchdog();
if (this.discoveryServiceRegistry != null) {
this.discoveryServiceRegistry.addDiscoveryListener(this);
}
}
@Override
public void dispose() {
if (refreshJob != null && !refreshJob.isCancelled()) {
refreshJob.cancel(true);
refreshJob = null;
}
logger.debug("IppPrinterHandler {} disposed.", url);
super.dispose();
}
private void deviceOnlineWatchdog() {
Runnable runnable = () -> {
try {
onDeviceStateChanged(printer);
} catch (Exception e) {
logger.debug("Exception occurred during execution: {}", e.getMessage(), e);
}
};
refreshJob = scheduler.scheduleWithFixedDelay(runnable, 0, refresh, TimeUnit.SECONDS);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (command instanceof RefreshType) {
onDeviceStateChanged(printer);
return;
}
}
public void onDeviceStateChanged(CupsPrinter device) {
if (device.getPrinterURL().equals(url)) {
boolean online = false;
try {
updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.JOBS_CHANNEL),
new DecimalType(device.getJobs(WhichJobsEnum.ALL, "", false).size()));
online = true;
} catch (Exception e) {
logger.debug("error updating jobs channel, reason: {}", e.getMessage());
}
try {
updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.WAITING_JOBS_CHANNEL),
new DecimalType(device.getJobs(WhichJobsEnum.NOT_COMPLETED, "", false).size()));
online = true;
} catch (Exception e) {
logger.debug("error updating waiting-jobs channel, reason: {}", e.getMessage());
}
try {
updateState(new ChannelUID(getThing().getUID(), IppBindingConstants.DONE_JOBS_CHANNEL),
new DecimalType(device.getJobs(WhichJobsEnum.COMPLETED, "", false).size()));
online = true;
} catch (Exception e) {
logger.debug("error updating done-jobs channel, reason: {}", e.getMessage());
}
if (online) {
updateStatus(ThingStatus.ONLINE);
}
}
}
@Override
public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
if (result.getThingUID().equals(this.getThing().getUID())) {
updateStatus(ThingStatus.ONLINE);
}
}
@Override
public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
if (thingUID.equals(this.getThing().getUID())) {
updateStatus(ThingStatus.OFFLINE);
}
}
@Override
public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="ipp" 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>IPP Binding</name>
<description>This is the binding for the Internet Printing Protocol (IPP). You can
show how many jobs are done/waiting
on an IPP/CUPS Printer</description>
<author>Tobias Braeutigam</author>
</binding:binding>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="ipp" 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>Printer</label>
<description>A IPP Printer</description>
<channels>
<channel id="jobs" typeId="jobs"/>
<channel id="waitingJobs" typeId="waitingJobs"/>
<channel id="doneJobs" typeId="doneJobs"/>
</channels>
<config-description>
<parameter name="name" type="text" required="true">
<label>Name</label>
<description>The name of the printer</description>
</parameter>
<parameter name="url" type="text" required="true">
<label>URL</label>
<description>The URL of the printer</description>
</parameter>
<parameter name="refresh" type="integer">
<label>Refresh Interval</label>
<description>Specifies the refresh interval in seconds</description>
<default>60</default>
</parameter>
</config-description>
</thing-type>
<channel-type id="jobs" advanced="true">
<item-type>Number</item-type>
<label>Total Jobs</label>
<description>Total number of print jobs on the printer</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="waitingJobs">
<item-type>Number</item-type>
<label>Waiting Jobs</label>
<description>Number of waiting print jobs on the printer</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="doneJobs" advanced="true">
<item-type>Number</item-type>
<label>Done Jobs</label>
<description>Number of completed print jobs on the printer</description>
<state readOnly="true"></state>
</channel-type>
</thing:thing-descriptions>