mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 13:21:53 +01:00
removed 1.x compatibility layer (#1284)
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
parent
32e20111f0
commit
650f895620
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
Warning: Note that this is most likely not the project you are looking for.
|
Warning: Note that this is most likely not the project you are looking for.
|
||||||
|
|
||||||
openHAB mainly consist out of the core components, extensions that are openHAB1-compatible from
|
openHAB mainly consist out of the core components and extensions that are from
|
||||||
https://github.com/openhab/openhab1-addons and extensions that are openHAB2-compatible from
|
https://github.com/openhab/openhab-addons. All is then packaged into a distribution in
|
||||||
https://github.com/openhab/openhab2-addons. All is then packaged into a distribution in
|
|
||||||
https://github.com/openhab/openhab-distro.
|
https://github.com/openhab/openhab-distro.
|
||||||
|
|
||||||
## Contribution guidelines
|
## Contribution guidelines
|
||||||
|
@ -38,12 +38,6 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
|
||||||
<artifactId>org.openhab.core.compat1x</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
<groupId>org.openhab.core.bundles</groupId>
|
||||||
<artifactId>org.openhab.core.karaf</artifactId>
|
<artifactId>org.openhab.core.karaf</artifactId>
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
<?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 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-1.8">
|
|
||||||
<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>
|
|
@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>org.openhab.core.compat1x</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>
|
|
@ -1,13 +0,0 @@
|
|||||||
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-core
|
|
@ -1,2 +0,0 @@
|
|||||||
Bundle-SymbolicName: ${project.artifactId}
|
|
||||||
Bundle-Activator: org.openhab.core.compat1x.internal.CompatibilityActivator
|
|
@ -1,38 +0,0 @@
|
|||||||
<?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.core.bundles</groupId>
|
|
||||||
<artifactId>org.openhab.core.reactor.bundles</artifactId>
|
|
||||||
<version>3.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>org.openhab.core.compat1x</artifactId>
|
|
||||||
|
|
||||||
<name>openHAB Core :: Bundles :: 1.x Compatibility Layer</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openhab.core.bom</groupId>
|
|
||||||
<artifactId>org.openhab.core.bom.compile-model</artifactId>
|
|
||||||
<type>pom</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
|
||||||
<artifactId>org.openhab.core.model.item</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
|
||||||
<artifactId>org.openhab.core.model.script</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
|
||||||
<artifactId>org.openhab.core.ui</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.autoupdate;
|
|
||||||
|
|
||||||
import org.openhab.core.binding.BindingProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface is implemented by classes that can provide configuration
|
|
||||||
* information of the AutoUpdate feature.
|
|
||||||
*
|
|
||||||
* Implementing classes should register themselves as a service in order to be
|
|
||||||
* taken into account.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface AutoUpdateBindingProvider extends BindingProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether an Item with the given <code>itemName</code> is
|
|
||||||
* configured to automatically update it's State after receiving a Command
|
|
||||||
* or not.
|
|
||||||
*
|
|
||||||
* @param itemName the name of the Item for which to find the configuration
|
|
||||||
* @return <code>false</code> to disable the automatic update,
|
|
||||||
* <code>true</code> to enable the automatic update and <code>null</code>
|
|
||||||
* if there is no configuration for this item.
|
|
||||||
*/
|
|
||||||
Boolean autoUpdate(String itemName);
|
|
||||||
|
|
||||||
}
|
|
@ -1,226 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.autoupdate.internal;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.eclipse.smarthome.core.common.registry.ProviderChangeListener;
|
|
||||||
import org.eclipse.smarthome.core.common.registry.RegistryChangeListener;
|
|
||||||
import org.eclipse.smarthome.core.items.Item;
|
|
||||||
import org.eclipse.smarthome.core.items.ItemRegistry;
|
|
||||||
import org.eclipse.smarthome.core.items.Metadata;
|
|
||||||
import org.eclipse.smarthome.core.items.MetadataKey;
|
|
||||||
import org.eclipse.smarthome.core.items.MetadataProvider;
|
|
||||||
import org.openhab.core.autoupdate.AutoUpdateBindingProvider;
|
|
||||||
import org.openhab.core.binding.BindingChangeListener;
|
|
||||||
import org.openhab.core.binding.BindingProvider;
|
|
||||||
import org.osgi.service.component.annotations.Activate;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Deactivate;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome
|
|
||||||
* namespace for the auto update provider. It gathers all services that implement the old interface
|
|
||||||
* and makes them available as single provider of the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@NonNullByDefault
|
|
||||||
@Component(service = MetadataProvider.class)
|
|
||||||
public class AutoUpdateProviderDelegate
|
|
||||||
implements MetadataProvider, RegistryChangeListener<Item>, BindingChangeListener {
|
|
||||||
|
|
||||||
private static final String AUTOUPDATE_KEY = "autoupdate";
|
|
||||||
|
|
||||||
private Set<AutoUpdateBindingProvider> providers = new CopyOnWriteArraySet<>();
|
|
||||||
private Set<ProviderChangeListener<Metadata>> listeners = new CopyOnWriteArraySet<>();
|
|
||||||
private Set<String> itemUpdateVetos = new HashSet<>();
|
|
||||||
private boolean started = false;
|
|
||||||
|
|
||||||
private @NonNullByDefault({}) ItemRegistry itemRegistry;
|
|
||||||
|
|
||||||
@Activate
|
|
||||||
protected void activate() {
|
|
||||||
refreshItemUpdateVetos();
|
|
||||||
started = true;
|
|
||||||
itemRegistry.addRegistryChangeListener(this);
|
|
||||||
for (AutoUpdateBindingProvider provider : providers) {
|
|
||||||
provider.addBindingChangeListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deactivate
|
|
||||||
protected void deactivate() {
|
|
||||||
for (AutoUpdateBindingProvider provider : providers) {
|
|
||||||
provider.removeBindingChangeListener(this);
|
|
||||||
}
|
|
||||||
itemRegistry.removeRegistryChangeListener(this);
|
|
||||||
started = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE)
|
|
||||||
public void addAutoUpdateBindingProvider(AutoUpdateBindingProvider provider) {
|
|
||||||
providers.add(provider);
|
|
||||||
if (started) {
|
|
||||||
refreshItemUpdateVetos();
|
|
||||||
provider.addBindingChangeListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAutoUpdateBindingProvider(AutoUpdateBindingProvider provider) {
|
|
||||||
providers.remove(provider);
|
|
||||||
if (started) {
|
|
||||||
refreshItemUpdateVetos();
|
|
||||||
provider.removeBindingChangeListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference
|
|
||||||
protected void setItemRegistry(ItemRegistry itemRegistry) {
|
|
||||||
this.itemRegistry = itemRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void unsetItemRegistry(ItemRegistry itemRegistry) {
|
|
||||||
this.itemRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addProviderChangeListener(ProviderChangeListener<Metadata> listener) {
|
|
||||||
this.listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Metadata> getAll() {
|
|
||||||
Set<Metadata> metadataSet = new HashSet<>();
|
|
||||||
for (Item item : itemRegistry.getAll()) {
|
|
||||||
synchronized (itemUpdateVetos) {
|
|
||||||
if (itemUpdateVetos.contains(item.getName())) {
|
|
||||||
Metadata metadata = getMetadata(item.getName());
|
|
||||||
metadataSet.add(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metadataSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeProviderChangeListener(ProviderChangeListener<Metadata> listener) {
|
|
||||||
this.listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshItemUpdateVetos() {
|
|
||||||
Set<String> newVetos = new HashSet<>();
|
|
||||||
synchronized (itemUpdateVetos) {
|
|
||||||
itemUpdateVetos.clear();
|
|
||||||
for (Item item : itemRegistry.getAll()) {
|
|
||||||
for (AutoUpdateBindingProvider provider : providers) {
|
|
||||||
Boolean autoUpdate = provider.autoUpdate(item.getName());
|
|
||||||
if (Boolean.FALSE.equals(autoUpdate)) {
|
|
||||||
newVetos.add(item.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the removed ones
|
|
||||||
Set<String> removedVetos = new HashSet<>(itemUpdateVetos);
|
|
||||||
removedVetos.removeAll(newVetos);
|
|
||||||
for (String itemName : removedVetos) {
|
|
||||||
if (itemUpdateVetos.contains(itemName)) {
|
|
||||||
Metadata md = getMetadata(itemName);
|
|
||||||
for (ProviderChangeListener<Metadata> listener : listeners) {
|
|
||||||
listener.removed(this, md);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the added ones
|
|
||||||
Set<String> addedVetos = new HashSet<>(newVetos);
|
|
||||||
addedVetos.removeAll(itemUpdateVetos);
|
|
||||||
for (String itemName : addedVetos) {
|
|
||||||
notifyAboutAddedMetadata(itemName);
|
|
||||||
}
|
|
||||||
itemUpdateVetos = newVetos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyAboutAddedMetadata(String itemName) {
|
|
||||||
if (itemUpdateVetos.contains(itemName)) {
|
|
||||||
Metadata md = getMetadata(itemName);
|
|
||||||
for (ProviderChangeListener<Metadata> listener : listeners) {
|
|
||||||
listener.added(this, md);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyAboutRemovedMetadata(String itemName) {
|
|
||||||
for (ProviderChangeListener<Metadata> listener : listeners) {
|
|
||||||
listener.removed(this, getMetadata(itemName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Metadata getMetadata(String itemName) {
|
|
||||||
return new Metadata(new MetadataKey(AUTOUPDATE_KEY, itemName), "false", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void added(Item element) {
|
|
||||||
String itemName = element.getName();
|
|
||||||
refreshVetoForItem(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshVetoForItem(String itemName) {
|
|
||||||
synchronized (itemUpdateVetos) {
|
|
||||||
boolean removed = itemUpdateVetos.remove(itemName);
|
|
||||||
for (AutoUpdateBindingProvider provider : providers) {
|
|
||||||
Boolean autoUpdate = provider.autoUpdate(itemName);
|
|
||||||
if (Boolean.FALSE.equals(autoUpdate)) {
|
|
||||||
itemUpdateVetos.add(itemName);
|
|
||||||
notifyAboutAddedMetadata(itemName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (removed) {
|
|
||||||
notifyAboutRemovedMetadata(itemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removed(Item element) {
|
|
||||||
itemUpdateVetos.remove(element.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updated(Item oldElement, Item element) {
|
|
||||||
refreshVetoForItem(element.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bindingChanged(@Nullable BindingProvider provider, @Nullable String itemName) {
|
|
||||||
if (itemName != null) {
|
|
||||||
refreshVetoForItem(itemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void allBindingsChanged(@Nullable BindingProvider provider) {
|
|
||||||
refreshItemUpdateVetos();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,161 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding;
|
|
||||||
|
|
||||||
import org.openhab.core.service.AbstractActiveService;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for active bindings which polls something and sends events frequently.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class AbstractActiveBinding<P extends BindingProvider> extends AbstractBinding<P> {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractActiveBinding.class);
|
|
||||||
|
|
||||||
/** embedded active service to allow the binding to have some code executed in a given interval. */
|
|
||||||
protected AbstractActiveService activeService = new BindingActiveService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds <code>provider</code> to the list of {@link BindingProvider}s and
|
|
||||||
* adds <code>this</code> as {@link BindingConfigChangeListener}. If
|
|
||||||
* <code>provider</code> contains any binding an the refresh-Thread is
|
|
||||||
* stopped it will be started.
|
|
||||||
*
|
|
||||||
* @param provider the new {@link BindingProvider} to add
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addBindingProvider(BindingProvider provider) {
|
|
||||||
super.addBindingProvider(provider);
|
|
||||||
activeService.activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes <code>provider</code> from the list of providers. If there is no
|
|
||||||
* provider left the refresh thread is getting interrupted.
|
|
||||||
*
|
|
||||||
* @param provider the {@link BindingProvider} to remove
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void removeBindingProvider(BindingProvider provider) {
|
|
||||||
super.removeBindingProvider(provider);
|
|
||||||
|
|
||||||
// if there are no binding providers there is no need to run this
|
|
||||||
// refresh thread any longer ...
|
|
||||||
if (this.providers.isEmpty()) {
|
|
||||||
activeService.deactivate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bindingChanged(BindingProvider provider, String itemName) {
|
|
||||||
super.bindingChanged(provider, itemName);
|
|
||||||
|
|
||||||
if (bindingsExist()) {
|
|
||||||
activeService.activate();
|
|
||||||
} else {
|
|
||||||
activeService.deactivate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void allBindingsChanged(BindingProvider provider) {
|
|
||||||
super.allBindingsChanged(provider);
|
|
||||||
|
|
||||||
if (bindingsExist()) {
|
|
||||||
activeService.activate();
|
|
||||||
} else {
|
|
||||||
activeService.deactivate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to define whether this binding is fully configured so that it can be
|
|
||||||
* activated and used.
|
|
||||||
* Note that the implementation will automatically start the active service if
|
|
||||||
* <code>true</code> is passed as a parameter and there are binding providers available.
|
|
||||||
*
|
|
||||||
* @param properlyConfigured
|
|
||||||
*/
|
|
||||||
protected void setProperlyConfigured(boolean properlyConfigured) {
|
|
||||||
if (!providers.isEmpty()) {
|
|
||||||
activeService.setProperlyConfigured(properlyConfigured);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if this binding is configured properly which means
|
|
||||||
* that all necessary data is available
|
|
||||||
*/
|
|
||||||
protected boolean isProperlyConfigured() {
|
|
||||||
return activeService.isProperlyConfigured();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The working method which is called by the refresh thread frequently.
|
|
||||||
* Developers should put their binding code here.
|
|
||||||
*/
|
|
||||||
protected abstract void execute();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the refresh interval to be used by the RefreshThread between to
|
|
||||||
* calls of the execute method.
|
|
||||||
*
|
|
||||||
* @return the refresh interval
|
|
||||||
*/
|
|
||||||
protected abstract long getRefreshInterval();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the Refresh thread.
|
|
||||||
*
|
|
||||||
* @return the name of the refresh thread.
|
|
||||||
*/
|
|
||||||
protected abstract String getName();
|
|
||||||
|
|
||||||
/** private inner class, which delegates method calls to the outer binding instance */
|
|
||||||
private class BindingActiveService extends AbstractActiveService {
|
|
||||||
@Override
|
|
||||||
protected void start() {
|
|
||||||
super.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void interrupt() {
|
|
||||||
if (!bindingsExist()) {
|
|
||||||
super.interrupt();
|
|
||||||
} else {
|
|
||||||
LOGGER.trace("{} won't be interrupted because bindings exist.", getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void execute() {
|
|
||||||
AbstractActiveBinding.this.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long getRefreshInterval() {
|
|
||||||
return AbstractActiveBinding.this.getRefreshInterval();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getName() {
|
|
||||||
return AbstractActiveBinding.this.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
import org.openhab.core.events.AbstractEventSubscriber;
|
|
||||||
import org.openhab.core.events.EventPublisher;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for bindings which send events.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class AbstractBinding<P extends BindingProvider> extends AbstractEventSubscriber
|
|
||||||
implements BindingChangeListener {
|
|
||||||
|
|
||||||
/** to keep track of all binding providers */
|
|
||||||
|
|
||||||
protected Collection<P> providers = new CopyOnWriteArraySet<>();
|
|
||||||
|
|
||||||
protected EventPublisher eventPublisher = null;
|
|
||||||
|
|
||||||
public void setEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unsetEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void activate() {
|
|
||||||
};
|
|
||||||
|
|
||||||
public void deactivate() {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds <code>provider</code> to the list of {@link BindingProvider}s and
|
|
||||||
* adds <code>this</code> as {@link BindingConfigChangeListener}. If
|
|
||||||
* <code>provider</code> contains any binding an the refresh-Thread is
|
|
||||||
* stopped it will be started.
|
|
||||||
*
|
|
||||||
* @param provider the new {@link BindingProvider} to add
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void addBindingProvider(BindingProvider provider) {
|
|
||||||
this.providers.add((P) provider);
|
|
||||||
provider.addBindingChangeListener(this);
|
|
||||||
allBindingsChanged(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes <code>provider</code> from the list of providers. If there is no
|
|
||||||
* provider left the refresh thread is getting interrupted.
|
|
||||||
*
|
|
||||||
* @param provider the {@link BindingProvider} to remove
|
|
||||||
*/
|
|
||||||
public void removeBindingProvider(BindingProvider provider) {
|
|
||||||
this.providers.remove(provider);
|
|
||||||
provider.removeBindingChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if any of the {@link BindingProvider}s provides
|
|
||||||
* a binding
|
|
||||||
*/
|
|
||||||
protected boolean bindingsExist() {
|
|
||||||
for (BindingProvider provider : providers) {
|
|
||||||
if (provider.providesBinding()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void receiveCommand(String itemName, Command command) {
|
|
||||||
// does any provider contain a binding config?
|
|
||||||
if (!providesBindingFor(itemName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
internalReceiveCommand(itemName, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is called by <code>receiveCommand()</code> only if one of the
|
|
||||||
* {@link BindingProvider}s provide a binding for <code>itemName</code>.
|
|
||||||
*
|
|
||||||
* @param itemName the item on which <code>command</code> will be executed
|
|
||||||
* @param command the {@link Command} to be executed on <code>itemName</code>
|
|
||||||
*/
|
|
||||||
protected void internalReceiveCommand(String itemName, Command command) {
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void receiveUpdate(String itemName, State newState) {
|
|
||||||
// does any provider contain a binding config?
|
|
||||||
if (!providesBindingFor(itemName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
internalReceiveUpdate(itemName, newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is called by <code>receiveUpdate()</code> only if one of the
|
|
||||||
* {@link BindingProvider}s provide a binding for <code>itemName</code>.
|
|
||||||
*
|
|
||||||
* @param itemName the item on which <code>command</code> will be executed
|
|
||||||
* @param newState the {@link State} to be update
|
|
||||||
*/
|
|
||||||
protected void internalReceiveUpdate(String itemName, State newState) {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* checks if any of the bindingProviders contains an adequate mapping
|
|
||||||
*
|
|
||||||
* @param itemName the itemName to check
|
|
||||||
* @return <code>true</code> if any of the bindingProviders contains an
|
|
||||||
* adequate mapping for <code>itemName</code> and <code>false</code>
|
|
||||||
* otherwise
|
|
||||||
*/
|
|
||||||
protected boolean providesBindingFor(String itemName) {
|
|
||||||
for (P provider : providers) {
|
|
||||||
if (provider.providesBindingFor(itemName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void allBindingsChanged(BindingProvider provider) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bindingChanged(BindingProvider provider, String itemName) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface must be implemented by classes which want to be notified by a
|
|
||||||
* {@link BindingProvider} about changes in the binding configuration.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface BindingChangeListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called, if a single binding has changed. The given item could have been
|
|
||||||
* added or removed.
|
|
||||||
*
|
|
||||||
* @param provider the binding provider where the binding has changed
|
|
||||||
* @param itemName the item name for which the binding has changed
|
|
||||||
*/
|
|
||||||
public void bindingChanged(BindingProvider provider, String itemName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called, if all bindings (might) have changed.
|
|
||||||
*
|
|
||||||
* @param provider the binding provider whose bindings have changed
|
|
||||||
*/
|
|
||||||
public void allBindingsChanged(BindingProvider provider);
|
|
||||||
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a simple marker interface to define data structures that are
|
|
||||||
* used as binding configurations.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface BindingConfig {
|
|
||||||
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface BindingProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a binding change listener, which gets notified whenever there
|
|
||||||
* are changes in the binding configuration
|
|
||||||
*
|
|
||||||
* @param listener the binding change listener to add
|
|
||||||
*/
|
|
||||||
public void addBindingChangeListener(BindingChangeListener listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a binding change listener again.
|
|
||||||
* Does nothing, if this listener has not been added before.
|
|
||||||
*
|
|
||||||
* @param listener the binding listener to remove
|
|
||||||
*/
|
|
||||||
public void removeBindingChangeListener(BindingChangeListener listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this binding provider contains a binding for the given
|
|
||||||
* <code>itemName</code>
|
|
||||||
*
|
|
||||||
* @param itemName the itemName to check
|
|
||||||
* @return <code>true</code> if this provider contains an adequate mapping
|
|
||||||
* for <code>itemName</code> and <code>false</code> otherwise.
|
|
||||||
*/
|
|
||||||
boolean providesBindingFor(String itemName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this binding provider contains any binding
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if this provider contains any binding
|
|
||||||
* configuration and <code>false</code> otherwise
|
|
||||||
*/
|
|
||||||
boolean providesBinding();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all items which are mapped to this binding
|
|
||||||
*
|
|
||||||
* @return items which are mapped to this binding
|
|
||||||
*/
|
|
||||||
Collection<String> getItemNames();
|
|
||||||
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding.internal;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.config.core.Configuration;
|
|
||||||
import org.eclipse.smarthome.core.items.ItemUtil;
|
|
||||||
import org.eclipse.smarthome.model.item.BindingConfigParseException;
|
|
||||||
import org.eclipse.smarthome.model.item.BindingConfigReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome
|
|
||||||
* namespace for the binding config readers. It wraps an instance with the old interface
|
|
||||||
* into a class with the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class BindingConfigReaderDelegate implements BindingConfigReader {
|
|
||||||
|
|
||||||
private org.openhab.model.item.binding.BindingConfigReader reader;
|
|
||||||
|
|
||||||
public BindingConfigReaderDelegate(org.openhab.model.item.binding.BindingConfigReader reader) {
|
|
||||||
this.reader = reader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBindingType() {
|
|
||||||
return reader.getBindingType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateItemType(String itemType, String bindingConfig) throws BindingConfigParseException {
|
|
||||||
try {
|
|
||||||
reader.validateItemType(getOpenHABItem(itemType), bindingConfig);
|
|
||||||
} catch (org.openhab.model.item.binding.BindingConfigParseException e) {
|
|
||||||
throw new BindingConfigParseException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processBindingConfiguration(String context, String itemType, String itemName, String bindingConfig,
|
|
||||||
Configuration configuration) throws BindingConfigParseException {
|
|
||||||
try {
|
|
||||||
reader.processBindingConfiguration(context, getOpenHABItem(itemType, itemName), bindingConfig);
|
|
||||||
} catch (org.openhab.model.item.binding.BindingConfigParseException e) {
|
|
||||||
throw new BindingConfigParseException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.openhab.core.items.Item getOpenHABItem(String itemType) throws BindingConfigParseException {
|
|
||||||
return getOpenHABItem(itemType, "itemName");
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.openhab.core.items.Item getOpenHABItem(String itemType, String itemName)
|
|
||||||
throws BindingConfigParseException {
|
|
||||||
String mainType = ItemUtil.getMainItemType(itemType);
|
|
||||||
|
|
||||||
switch (mainType) {
|
|
||||||
case "Group":
|
|
||||||
return new org.openhab.core.items.GroupItem(itemName);
|
|
||||||
case "Switch":
|
|
||||||
return new org.openhab.core.library.items.SwitchItem(itemName);
|
|
||||||
case "Dimmer":
|
|
||||||
return new org.openhab.core.library.items.DimmerItem(itemName);
|
|
||||||
case "Color":
|
|
||||||
return new org.openhab.core.library.items.ColorItem(itemName);
|
|
||||||
case "String":
|
|
||||||
return new org.openhab.core.library.items.StringItem(itemName);
|
|
||||||
case "Number":
|
|
||||||
return new org.openhab.core.library.items.NumberItem(itemName);
|
|
||||||
case "Contact":
|
|
||||||
return new org.openhab.core.library.items.ContactItem(itemName);
|
|
||||||
case "Rollershutter":
|
|
||||||
return new org.openhab.core.library.items.RollershutterItem(itemName);
|
|
||||||
case "DateTime":
|
|
||||||
return new org.openhab.core.library.items.DateTimeItem(itemName);
|
|
||||||
case "Location":
|
|
||||||
return new org.openhab.core.library.items.LocationItem(itemName);
|
|
||||||
case "Call":
|
|
||||||
return new org.openhab.library.tel.items.CallItem(itemName);
|
|
||||||
}
|
|
||||||
throw new BindingConfigParseException("cannot process unknown item type " + itemType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startConfigurationUpdate(String context) {
|
|
||||||
reader.removeConfigurations(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stopConfigurationUpdate(String context) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.binding.internal;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.openhab.model.item.binding.BindingConfigReader;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.ServiceRegistration;
|
|
||||||
import org.osgi.service.component.annotations.Activate;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Deactivate;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
|
||||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class listens for services that implement the old binding config reader interface and registers
|
|
||||||
* an according service for each under the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class BindingConfigReaderFactory {
|
|
||||||
|
|
||||||
private Map<String, ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader>> delegates = new HashMap<>();
|
|
||||||
private BundleContext context;
|
|
||||||
|
|
||||||
private Set<BindingConfigReader> readers = new HashSet<>();
|
|
||||||
|
|
||||||
@Activate
|
|
||||||
public void activate(BundleContext context) {
|
|
||||||
this.context = context;
|
|
||||||
for (BindingConfigReader reader : readers) {
|
|
||||||
registerDelegateService(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deactivate
|
|
||||||
public void deactivate() {
|
|
||||||
for (ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader> serviceReg : delegates
|
|
||||||
.values()) {
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
delegates.clear();
|
|
||||||
this.context = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
|
||||||
public void addBindingConfigReader(BindingConfigReader reader) {
|
|
||||||
if (context != null) {
|
|
||||||
registerDelegateService(reader);
|
|
||||||
} else {
|
|
||||||
readers.add(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeBindingConfigReader(BindingConfigReader reader) {
|
|
||||||
if (context != null) {
|
|
||||||
unregisterDelegateService(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerDelegateService(BindingConfigReader reader) {
|
|
||||||
if (!delegates.containsKey(reader.getBindingType())) {
|
|
||||||
BindingConfigReaderDelegate service = new BindingConfigReaderDelegate(reader);
|
|
||||||
Dictionary<String, Object> props = new Hashtable<>();
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader> serviceReg = context
|
|
||||||
.registerService(org.eclipse.smarthome.model.item.BindingConfigReader.class, service, props);
|
|
||||||
delegates.put(reader.getBindingType(), serviceReg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterDelegateService(BindingConfigReader reader) {
|
|
||||||
if (delegates.containsKey(reader.getBindingType())) {
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader> serviceReg = delegates
|
|
||||||
.get(reader.getBindingType());
|
|
||||||
delegates.remove(reader.getBindingType());
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.compat1x.internal;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.model.script.engine.ScriptEngine;
|
|
||||||
import org.openhab.core.events.EventPublisher;
|
|
||||||
import org.openhab.core.items.ItemRegistry;
|
|
||||||
import org.osgi.framework.BundleActivator;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class CompatibilityActivator implements BundleActivator {
|
|
||||||
|
|
||||||
private static BundleContext context;
|
|
||||||
|
|
||||||
public static ServiceTracker<ItemRegistry, ItemRegistry> itemRegistryTracker;
|
|
||||||
public static ServiceTracker<EventPublisher, EventPublisher> eventPublisherTracker;
|
|
||||||
public static ServiceTracker<ScriptEngine, ScriptEngine> scriptEngineTracker;
|
|
||||||
|
|
||||||
public static BundleContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void start(BundleContext bundleContext) throws Exception {
|
|
||||||
CompatibilityActivator.context = bundleContext;
|
|
||||||
|
|
||||||
itemRegistryTracker = new ServiceTracker<>(bundleContext, ItemRegistry.class, null);
|
|
||||||
itemRegistryTracker.open();
|
|
||||||
|
|
||||||
eventPublisherTracker = new ServiceTracker<>(bundleContext, EventPublisher.class, null);
|
|
||||||
eventPublisherTracker.open();
|
|
||||||
|
|
||||||
scriptEngineTracker = new ServiceTracker<>(bundleContext, ScriptEngine.class, null);
|
|
||||||
scriptEngineTracker.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void stop(BundleContext bundleContext) throws Exception {
|
|
||||||
CompatibilityActivator.context = null;
|
|
||||||
itemRegistryTracker.close();
|
|
||||||
eventPublisherTracker.close();
|
|
||||||
scriptEngineTracker.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.compat1x.internal;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.items.GroupItem;
|
|
||||||
import org.eclipse.smarthome.core.items.Item;
|
|
||||||
import org.eclipse.smarthome.core.library.items.CallItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.ColorItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.ContactItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.DateTimeItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.DimmerItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.NumberItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.RollershutterItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.StringItem;
|
|
||||||
import org.eclipse.smarthome.core.library.items.SwitchItem;
|
|
||||||
import org.eclipse.smarthome.core.types.State;
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ItemMapper {
|
|
||||||
|
|
||||||
public static org.openhab.core.items.Item mapToOpenHABItem(Item item) {
|
|
||||||
if (item == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
org.openhab.core.items.Item result = null;
|
|
||||||
Class<? extends Item> itemClass = item.getClass();
|
|
||||||
|
|
||||||
if (itemClass.equals(StringItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.StringItem(item.getName());
|
|
||||||
} else if (itemClass.equals(SwitchItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.SwitchItem(item.getName());
|
|
||||||
} else if (itemClass.equals(ContactItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.ContactItem(item.getName());
|
|
||||||
} else if (itemClass.equals(NumberItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.NumberItem(item.getName());
|
|
||||||
} else if (itemClass.equals(RollershutterItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.RollershutterItem(item.getName());
|
|
||||||
} else if (itemClass.equals(DimmerItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.DimmerItem(item.getName());
|
|
||||||
} else if (itemClass.equals(ColorItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.ColorItem(item.getName());
|
|
||||||
} else if (itemClass.equals(DateTimeItem.class)) {
|
|
||||||
result = new org.openhab.core.library.items.DateTimeItem(item.getName());
|
|
||||||
} else if (itemClass.equals(CallItem.class)) {
|
|
||||||
result = new org.openhab.library.tel.items.CallItem(item.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item instanceof GroupItem) {
|
|
||||||
GroupItem gItem = (GroupItem) item;
|
|
||||||
|
|
||||||
org.openhab.core.items.Item baseItem = ItemMapper.mapToOpenHABItem(gItem.getBaseItem());
|
|
||||||
org.openhab.core.items.GroupItem ohgItem;
|
|
||||||
|
|
||||||
if (baseItem instanceof GenericItem) {
|
|
||||||
ohgItem = new org.openhab.core.items.GroupItem(item.getName(), (GenericItem) baseItem);
|
|
||||||
} else {
|
|
||||||
ohgItem = new org.openhab.core.items.GroupItem(item.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Item member : gItem.getMembers()) {
|
|
||||||
org.openhab.core.items.Item ohMember = ItemMapper.mapToOpenHABItem(member);
|
|
||||||
if (ohMember != null) {
|
|
||||||
ohgItem.addMember(ohMember);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = ohgItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result instanceof org.openhab.core.items.GenericItem) {
|
|
||||||
org.openhab.core.items.GenericItem genericItem = (GenericItem) result;
|
|
||||||
State state = item.getState();
|
|
||||||
if (state != null) {
|
|
||||||
org.openhab.core.types.State ohState = (org.openhab.core.types.State) TypeMapper
|
|
||||||
.mapToOpenHABType(state);
|
|
||||||
if (ohState != null) {
|
|
||||||
genericItem.setState(ohState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,157 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.compat1x.internal;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.library.types.DateTimeType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.HSBType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.OnOffType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.OpenClosedType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.PercentType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.PointType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.QuantityType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.StopMoveType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.StringListType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.StringType;
|
|
||||||
import org.eclipse.smarthome.core.library.types.UpDownType;
|
|
||||||
import org.eclipse.smarthome.core.types.Type;
|
|
||||||
import org.eclipse.smarthome.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class TypeMapper {
|
|
||||||
|
|
||||||
public static org.openhab.core.types.Type mapToOpenHABType(Type type) {
|
|
||||||
if (type == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
org.openhab.core.types.Type result = org.openhab.core.types.UnDefType.UNDEF;
|
|
||||||
Class<? extends Type> typeClass = type.getClass();
|
|
||||||
|
|
||||||
if (type == UnDefType.NULL) {
|
|
||||||
result = org.openhab.core.types.UnDefType.NULL;
|
|
||||||
} else if (type == UnDefType.UNDEF) {
|
|
||||||
result = org.openhab.core.types.UnDefType.UNDEF;
|
|
||||||
} else if (type == OnOffType.ON) {
|
|
||||||
result = org.openhab.core.library.types.OnOffType.ON;
|
|
||||||
} else if (type == OnOffType.OFF) {
|
|
||||||
result = org.openhab.core.library.types.OnOffType.OFF;
|
|
||||||
} else if (type == OpenClosedType.OPEN) {
|
|
||||||
result = org.openhab.core.library.types.OpenClosedType.OPEN;
|
|
||||||
} else if (type == OpenClosedType.CLOSED) {
|
|
||||||
result = org.openhab.core.library.types.OpenClosedType.CLOSED;
|
|
||||||
} else if (type == IncreaseDecreaseType.INCREASE) {
|
|
||||||
result = org.openhab.core.library.types.IncreaseDecreaseType.INCREASE;
|
|
||||||
} else if (type == IncreaseDecreaseType.DECREASE) {
|
|
||||||
result = org.openhab.core.library.types.IncreaseDecreaseType.DECREASE;
|
|
||||||
} else if (type == StopMoveType.MOVE) {
|
|
||||||
result = org.openhab.core.library.types.StopMoveType.MOVE;
|
|
||||||
} else if (type == StopMoveType.STOP) {
|
|
||||||
result = org.openhab.core.library.types.StopMoveType.STOP;
|
|
||||||
} else if (type == UpDownType.UP) {
|
|
||||||
result = org.openhab.core.library.types.UpDownType.UP;
|
|
||||||
} else if (type == UpDownType.DOWN) {
|
|
||||||
result = org.openhab.core.library.types.UpDownType.DOWN;
|
|
||||||
} else if (typeClass.equals(StringType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.StringType(type.toString());
|
|
||||||
} else if (typeClass.equals(DecimalType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.DecimalType(type.toString());
|
|
||||||
} else if (typeClass.equals(QuantityType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.DecimalType(((QuantityType<?>) type).toBigDecimal());
|
|
||||||
} else if (typeClass.equals(HSBType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.HSBType(type.toString());
|
|
||||||
} else if (typeClass.equals(PercentType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.PercentType(type.toString());
|
|
||||||
} else if (typeClass.equals(DateTimeType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.DateTimeType(
|
|
||||||
GregorianCalendar.from(((DateTimeType) type).getZonedDateTime()));
|
|
||||||
} else if (typeClass.equals(PointType.class)) {
|
|
||||||
result = new org.openhab.core.library.types.PointType(type.toString());
|
|
||||||
} else if (typeClass.equals(StringListType.class)) {
|
|
||||||
result = new org.openhab.library.tel.types.CallType(type.toString().replace(",", "##"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type mapToESHType(org.openhab.core.types.Type type) {
|
|
||||||
if (type == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type result = UnDefType.UNDEF;
|
|
||||||
Class<? extends org.openhab.core.types.Type> typeClass = type.getClass();
|
|
||||||
|
|
||||||
if (type == org.openhab.core.types.UnDefType.NULL) {
|
|
||||||
result = UnDefType.NULL;
|
|
||||||
} else if (type == org.openhab.core.types.UnDefType.UNDEF) {
|
|
||||||
result = UnDefType.UNDEF;
|
|
||||||
} else if (type == org.openhab.core.library.types.OnOffType.ON) {
|
|
||||||
result = OnOffType.ON;
|
|
||||||
} else if (type == org.openhab.core.library.types.OnOffType.OFF) {
|
|
||||||
result = OnOffType.OFF;
|
|
||||||
} else if (type == org.openhab.core.library.types.OpenClosedType.OPEN) {
|
|
||||||
result = OpenClosedType.OPEN;
|
|
||||||
} else if (type == org.openhab.core.library.types.OpenClosedType.CLOSED) {
|
|
||||||
result = OpenClosedType.CLOSED;
|
|
||||||
} else if (type == org.openhab.core.library.types.IncreaseDecreaseType.INCREASE) {
|
|
||||||
result = IncreaseDecreaseType.INCREASE;
|
|
||||||
} else if (type == org.openhab.core.library.types.IncreaseDecreaseType.DECREASE) {
|
|
||||||
result = IncreaseDecreaseType.DECREASE;
|
|
||||||
} else if (type == org.openhab.core.library.types.StopMoveType.MOVE) {
|
|
||||||
result = StopMoveType.MOVE;
|
|
||||||
} else if (type == org.openhab.core.library.types.StopMoveType.STOP) {
|
|
||||||
result = StopMoveType.STOP;
|
|
||||||
} else if (type == org.openhab.core.library.types.UpDownType.UP) {
|
|
||||||
result = UpDownType.UP;
|
|
||||||
} else if (type == org.openhab.core.library.types.UpDownType.DOWN) {
|
|
||||||
result = UpDownType.DOWN;
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.StringType.class)) {
|
|
||||||
result = new StringType(type.toString());
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.DecimalType.class)) {
|
|
||||||
result = new DecimalType(type.toString());
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.HSBType.class)) {
|
|
||||||
result = new HSBType(type.toString());
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.PercentType.class)) {
|
|
||||||
result = new PercentType(type.toString());
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.DateTimeType.class)) {
|
|
||||||
result = new DateTimeType(cloneCalendar(type));
|
|
||||||
} else if (typeClass.equals(org.openhab.core.library.types.PointType.class)) {
|
|
||||||
result = new PointType(type.toString());
|
|
||||||
} else if (typeClass.equals(org.openhab.library.tel.types.CallType.class)) {
|
|
||||||
result = new StringListType(type.toString().replace("##", ","));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Calendar cloneCalendar(Object type) {
|
|
||||||
try {
|
|
||||||
Field calField = type.getClass().getDeclaredField("calendar");
|
|
||||||
calField.setAccessible(true);
|
|
||||||
Calendar cal = (Calendar) calField.get(type);
|
|
||||||
return (Calendar) cal.clone();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events;
|
|
||||||
|
|
||||||
import static org.openhab.core.events.EventConstants.*;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.EventType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.osgi.service.event.Event;
|
|
||||||
import org.osgi.service.event.EventHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class AbstractEventSubscriber implements EventHandler {
|
|
||||||
@Override
|
|
||||||
public void handleEvent(Event event) {
|
|
||||||
String itemName = (String) event.getProperty("item");
|
|
||||||
|
|
||||||
String topic = event.getTopic();
|
|
||||||
String[] topicParts = topic.split(TOPIC_SEPERATOR);
|
|
||||||
|
|
||||||
if (!(topicParts.length > 2) || !topicParts[0].equals(TOPIC_PREFIX)) {
|
|
||||||
return; // we have received an event with an invalid topic
|
|
||||||
}
|
|
||||||
String operation = topicParts[1];
|
|
||||||
|
|
||||||
if (operation.equals(EventType.UPDATE.toString())) {
|
|
||||||
State newState = (State) event.getProperty("state");
|
|
||||||
if (newState != null) {
|
|
||||||
receiveUpdate(itemName, newState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (operation.equals(EventType.COMMAND.toString())) {
|
|
||||||
Command command = (Command) event.getProperty("command");
|
|
||||||
if (command != null) {
|
|
||||||
receiveCommand(itemName, command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receiveCommand(String itemName, Command command) {
|
|
||||||
// default implementation: do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receiveUpdate(String itemName, State newState) {
|
|
||||||
// default implementation: do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface defines constants required for using the OSGi Event Admin service.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface EventConstants {
|
|
||||||
|
|
||||||
public static final String TOPIC_PREFIX = "openhab";
|
|
||||||
|
|
||||||
public static final String TOPIC_SEPERATOR = "/";
|
|
||||||
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An EventPublisher is used to send commands or status updates to the openHAB event bus.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface EventPublisher {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate synchronous sending of a command.
|
|
||||||
* This method does not return to the caller until all subscribers have processed the command.
|
|
||||||
*
|
|
||||||
* @param itemName name of the item to send the command for
|
|
||||||
* @param command the command to send
|
|
||||||
*/
|
|
||||||
public abstract void sendCommand(String itemName, Command command);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate asynchronous sending of a command.
|
|
||||||
* This method returns immediately to the caller.
|
|
||||||
*
|
|
||||||
* @param itemName name of the item to send the command for
|
|
||||||
* @param command the command to send
|
|
||||||
*/
|
|
||||||
public abstract void postCommand(String itemName, Command command);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate asynchronous sending of a status update.
|
|
||||||
* This method returns immediately to the caller.
|
|
||||||
*
|
|
||||||
* @param itemName name of the item to send the update for
|
|
||||||
* @param newState the new state to send
|
|
||||||
*/
|
|
||||||
public abstract void postUpdate(String itemName, State newState);
|
|
||||||
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.events.EventPublisher;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemCommandEvent;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemStateEvent;
|
|
||||||
import org.openhab.core.compat1x.internal.TypeMapper;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component(immediate = true)
|
|
||||||
public class EventPublisherDelegate implements org.openhab.core.events.EventPublisher {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(EventPublisherDelegate.class);
|
|
||||||
|
|
||||||
private EventPublisher eventPublisher;
|
|
||||||
|
|
||||||
@Reference
|
|
||||||
public void setEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unsetEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendCommand(String itemName, Command command) {
|
|
||||||
// we do not offer synchronous sending of commands anymore
|
|
||||||
postCommand(itemName, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postCommand(String itemName, Command command) {
|
|
||||||
org.eclipse.smarthome.core.types.Command eshCommand = (org.eclipse.smarthome.core.types.Command) TypeMapper
|
|
||||||
.mapToESHType(command);
|
|
||||||
if (eshCommand != null) {
|
|
||||||
ItemCommandEvent event = ItemEventFactory.createCommandEvent(itemName, eshCommand);
|
|
||||||
eventPublisher.post(event);
|
|
||||||
} else if (command != null) {
|
|
||||||
logger.warn("Compatibility layer could not convert {} of type {}.", command,
|
|
||||||
command.getClass().getSimpleName());
|
|
||||||
} else {
|
|
||||||
logger.warn("given command is NULL, couldn't post command for '{}'", itemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postUpdate(String itemName, State newState) {
|
|
||||||
org.eclipse.smarthome.core.types.State eshState = (org.eclipse.smarthome.core.types.State) TypeMapper
|
|
||||||
.mapToESHType(newState);
|
|
||||||
if (eshState != null) {
|
|
||||||
ItemStateEvent event = ItemEventFactory.createStateEvent(itemName, eshState);
|
|
||||||
eventPublisher.post(event);
|
|
||||||
} else if (newState != null) {
|
|
||||||
logger.warn("Compatibility layer could not convert {} of type {}.", newState,
|
|
||||||
newState.getClass().getSimpleName());
|
|
||||||
} else {
|
|
||||||
logger.warn("given new state is NULL, couldn't post update for '{}'", itemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An EventSubscriber receives events from the openHAB event bus for further processing.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface EventSubscriber {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method if a command was sent on the event bus
|
|
||||||
*
|
|
||||||
* @param itemName the item for which a command was sent
|
|
||||||
* @param command the command that was sent
|
|
||||||
*/
|
|
||||||
public void receiveCommand(String itemName, Command command);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method if a state update was sent on the event bus
|
|
||||||
*
|
|
||||||
* @param itemName the item for which a state update was sent
|
|
||||||
* @param state the state that was sent
|
|
||||||
*/
|
|
||||||
public void receiveUpdate(String itemName, State newStatus);
|
|
||||||
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.events.internal;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.events.EventFilter;
|
|
||||||
import org.eclipse.smarthome.core.events.EventPublisher;
|
|
||||||
import org.eclipse.smarthome.core.events.EventSubscriber;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemCommandEvent;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
|
|
||||||
import org.eclipse.smarthome.core.items.events.ItemStateEvent;
|
|
||||||
import org.openhab.core.compat1x.internal.TypeMapper;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.EventType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.Type;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
|
||||||
import org.osgi.service.event.Event;
|
|
||||||
import org.osgi.service.event.EventAdmin;
|
|
||||||
import org.osgi.service.event.EventHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class acts as a bridge between events from openHAB 1.x (using "openhab" as a topic prefix) and
|
|
||||||
* openHAB (using "smarthome" as a topic prefix).
|
|
||||||
* It simply duplicates events with an updated topic prefix and works both ways.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component(immediate = true, property = "event.topics=smarthome/*")
|
|
||||||
public class EventBridge implements EventHandler, EventSubscriber {
|
|
||||||
|
|
||||||
private static final String BRIDGEMARKER = "bridgemarker";
|
|
||||||
private EventAdmin eventAdmin;
|
|
||||||
private EventPublisher eventPublisher;
|
|
||||||
|
|
||||||
@Reference(policy = ReferencePolicy.DYNAMIC)
|
|
||||||
public void setEventAdmin(EventAdmin eventAdmin) {
|
|
||||||
this.eventAdmin = eventAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unsetEventAdmin(EventAdmin eventAdmin) {
|
|
||||||
this.eventAdmin = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference
|
|
||||||
public void setEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unsetEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleEvent(Event event) {
|
|
||||||
if (!Boolean.TRUE.equals(event.getProperty(BRIDGEMARKER))) {
|
|
||||||
// map event from openHAB to ESH
|
|
||||||
if (event.getTopic().startsWith(org.openhab.core.events.EventConstants.TOPIC_PREFIX)) {
|
|
||||||
if (event.getTopic().endsWith(EventType.COMMAND.name())) {
|
|
||||||
String itemName = (String) event.getProperty("item");
|
|
||||||
Command ohCommand = (Command) event.getProperty("command");
|
|
||||||
ItemCommandEvent eshEvent = ItemEventFactory.createCommandEvent(itemName,
|
|
||||||
(org.eclipse.smarthome.core.types.Command) TypeMapper.mapToESHType(ohCommand));
|
|
||||||
eventPublisher.post(eshEvent);
|
|
||||||
} else if (event.getTopic().endsWith(EventType.UPDATE.name())) {
|
|
||||||
String itemName = (String) event.getProperty("item");
|
|
||||||
State ohState = (State) event.getProperty("state");
|
|
||||||
ItemStateEvent eshEvent = ItemEventFactory.createStateEvent(itemName,
|
|
||||||
(org.eclipse.smarthome.core.types.State) TypeMapper.mapToESHType(ohState));
|
|
||||||
eventPublisher.post(eshEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Object> constructProperties(org.eclipse.smarthome.core.events.Event event) {
|
|
||||||
Map<String, Object> properties = new HashMap<>();
|
|
||||||
if (event instanceof ItemCommandEvent) {
|
|
||||||
ItemCommandEvent icEvent = (ItemCommandEvent) event;
|
|
||||||
String itemName = icEvent.getItemName();
|
|
||||||
properties.put("item", itemName);
|
|
||||||
Type eshType = TypeMapper.mapToOpenHABType(icEvent.getItemCommand());
|
|
||||||
if (eshType instanceof Command) {
|
|
||||||
properties.put("command", eshType);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ItemStateEvent isEvent = (ItemStateEvent) event;
|
|
||||||
String itemName = isEvent.getItemName();
|
|
||||||
properties.put("item", itemName);
|
|
||||||
Type eshType = TypeMapper.mapToOpenHABType(isEvent.getItemState());
|
|
||||||
if (eshType instanceof State) {
|
|
||||||
properties.put("state", eshType);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
properties.put(BRIDGEMARKER, true);
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getSubscribedEventTypes() {
|
|
||||||
Set<String> types = new HashSet<>(2);
|
|
||||||
types.add(ItemCommandEvent.TYPE);
|
|
||||||
types.add(ItemStateEvent.TYPE);
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EventFilter getEventFilter() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void receive(org.eclipse.smarthome.core.events.Event event) {
|
|
||||||
if (event.getType().equals(ItemCommandEvent.TYPE)) {
|
|
||||||
Map<String, Object> properties = constructProperties(event);
|
|
||||||
if (properties != null) {
|
|
||||||
String topic = org.openhab.core.events.EventConstants.TOPIC_PREFIX + "/" + EventType.COMMAND + "/"
|
|
||||||
+ properties.get("item");
|
|
||||||
eventAdmin.postEvent(new Event(topic, properties));
|
|
||||||
}
|
|
||||||
} else if (event.getType().equals(ItemStateEvent.TYPE)) {
|
|
||||||
Map<String, Object> properties = constructProperties(event);
|
|
||||||
if (properties != null) {
|
|
||||||
String topic = org.openhab.core.events.EventConstants.TOPIC_PREFIX + "/" + EventType.UPDATE + "/"
|
|
||||||
+ properties.get("item");
|
|
||||||
;
|
|
||||||
eventAdmin.postEvent(new Event(topic, properties));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
import org.openhab.core.events.EventPublisher;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The abstract base class for all items. It provides all relevant logic
|
|
||||||
* for the infrastructure, such as publishing updates to the event bus
|
|
||||||
* or notifying listeners.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class GenericItem implements Item {
|
|
||||||
|
|
||||||
protected EventPublisher eventPublisher;
|
|
||||||
|
|
||||||
protected Set<StateChangeListener> listeners = new CopyOnWriteArraySet<>(
|
|
||||||
Collections.newSetFromMap(new WeakHashMap<>()));
|
|
||||||
|
|
||||||
protected List<String> groupNames = new ArrayList<>();
|
|
||||||
|
|
||||||
protected final String name;
|
|
||||||
|
|
||||||
protected State state = UnDefType.NULL;
|
|
||||||
|
|
||||||
public GenericItem(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (typeClass != null && typeClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose() {
|
|
||||||
this.eventPublisher = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getGroupNames() {
|
|
||||||
return groupNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void internalSend(Command command) {
|
|
||||||
// try to send the command to the bus
|
|
||||||
if (eventPublisher != null) {
|
|
||||||
eventPublisher.sendCommand(this.getName(), command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(State state) {
|
|
||||||
State oldState = this.state;
|
|
||||||
this.state = state;
|
|
||||||
notifyListeners(oldState, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyListeners(State oldState, State newState) {
|
|
||||||
// if nothing has changed, we send update notifications
|
|
||||||
Set<StateChangeListener> clonedListeners = null;
|
|
||||||
clonedListeners = new CopyOnWriteArraySet<>(listeners);
|
|
||||||
for (StateChangeListener listener : clonedListeners) {
|
|
||||||
listener.stateUpdated(this, newState);
|
|
||||||
}
|
|
||||||
if (!oldState.equals(newState)) {
|
|
||||||
for (StateChangeListener listener : clonedListeners) {
|
|
||||||
listener.stateChanged(this, oldState, newState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getName() + " (" + "Type=" + getClass().getSimpleName() + ", " + "State=" + getState() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addStateChangeListener(StateChangeListener listener) {
|
|
||||||
synchronized (listeners) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeStateChangeListener(StateChangeListener listener) {
|
|
||||||
synchronized (listeners) {
|
|
||||||
listeners.remove(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((groupNames == null) ? 0 : groupNames.hashCode());
|
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
|
||||||
result = prime * result + ((state == null) ? 0 : state.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
GenericItem other = (GenericItem) obj;
|
|
||||||
if (groupNames == null) {
|
|
||||||
if (other.groupNames != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!groupNames.equals(other.groupNames)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (name == null) {
|
|
||||||
if (other.name != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!name.equals(other.name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (state == null) {
|
|
||||||
if (other.state != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!state.equals(other.state)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group functions are used by active group items to calculate a state for the group
|
|
||||||
* out of the states of all its member items.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract interface GroupFunction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the current state of a group based on a list of items
|
|
||||||
*
|
|
||||||
* @param items the items to calculate a group state for
|
|
||||||
* @return the calculated group state
|
|
||||||
*/
|
|
||||||
public State calculate(List<Item> items);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the group state and returns it as a state of the requested type.
|
|
||||||
*
|
|
||||||
* @param items the items to calculate a group state for
|
|
||||||
* @param stateClass the type in which the state should be returned
|
|
||||||
* @return the calculated group state of the requested type or null, if type is not supported
|
|
||||||
*/
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the default group function that does nothing else than to check if all member items
|
|
||||||
* have the same state. If this is the case, this state is returned, otherwise UNDEF is returned.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Equality implements GroupFunction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
if (!items.isEmpty()) {
|
|
||||||
State state = items.get(0).getState();
|
|
||||||
for (int i = 1; i < items.size(); i++) {
|
|
||||||
if (!state.equals(items.get(i).getState())) {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,216 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class GroupItem extends GenericItem implements StateChangeListener {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(GroupItem.class);
|
|
||||||
|
|
||||||
protected final GenericItem baseItem;
|
|
||||||
|
|
||||||
protected final List<Item> members;
|
|
||||||
|
|
||||||
protected GroupFunction function;
|
|
||||||
|
|
||||||
public GroupItem(String name) {
|
|
||||||
this(name, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupItem(String name, GenericItem baseItem) {
|
|
||||||
this(name, baseItem, new GroupFunction.Equality());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupItem(String name, GenericItem baseItem, GroupFunction function) {
|
|
||||||
super(name);
|
|
||||||
members = new CopyOnWriteArrayList<>();
|
|
||||||
this.function = function;
|
|
||||||
this.baseItem = baseItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base item of this {@link GroupItem}. This method is only
|
|
||||||
* intended to allow instance checks of the underlying BaseItem. It must
|
|
||||||
* not be changed in any way.
|
|
||||||
*
|
|
||||||
* @return the base item of this GroupItem
|
|
||||||
*/
|
|
||||||
public GenericItem getBaseItem() {
|
|
||||||
return baseItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the direct members of this {@link GroupItem} regardless if these
|
|
||||||
* members are {@link GroupItem}s as well.
|
|
||||||
*
|
|
||||||
* @return the direct members of this {@link GroupItem}
|
|
||||||
*/
|
|
||||||
public List<Item> getMembers() {
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the direct members of this {@link GroupItem} and recursively all
|
|
||||||
* members of the potentially contained {@link GroupItem}s as well. The
|
|
||||||
* {@link GroupItem}s itself aren't contained. The returned items are unique.
|
|
||||||
*
|
|
||||||
* @return all members of this and all contained {@link GroupItem}s
|
|
||||||
*/
|
|
||||||
public List<Item> getAllMembers() {
|
|
||||||
Set<Item> allMembers = new HashSet<>();
|
|
||||||
collectMembers(allMembers, members);
|
|
||||||
return new ArrayList<>(allMembers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void collectMembers(Set<Item> allMembers, List<Item> members) {
|
|
||||||
for (Item member : members) {
|
|
||||||
if (member instanceof GroupItem) {
|
|
||||||
collectMembers(allMembers, ((GroupItem) member).members);
|
|
||||||
} else {
|
|
||||||
allMembers.add(member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMember(Item item) {
|
|
||||||
members.add(item);
|
|
||||||
if (item instanceof GenericItem) {
|
|
||||||
GenericItem genericItem = (GenericItem) item;
|
|
||||||
genericItem.addStateChangeListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeMember(Item item) {
|
|
||||||
members.remove(item);
|
|
||||||
if (item instanceof GenericItem) {
|
|
||||||
GenericItem genericItem = (GenericItem) item;
|
|
||||||
genericItem.removeStateChangeListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The accepted data types of a group item is the same as of the underlying base item.
|
|
||||||
* If none is defined, the intersection of all sets of accepted data types of all group
|
|
||||||
* members is used instead.
|
|
||||||
*
|
|
||||||
* @return the accepted data types of this group item
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
if (baseItem != null) {
|
|
||||||
return baseItem.getAcceptedDataTypes();
|
|
||||||
} else {
|
|
||||||
List<Class<? extends State>> acceptedDataTypes = null;
|
|
||||||
for (Item item : members) {
|
|
||||||
if (acceptedDataTypes == null || acceptedDataTypes.isEmpty()) {
|
|
||||||
acceptedDataTypes = item.getAcceptedDataTypes();
|
|
||||||
} else {
|
|
||||||
acceptedDataTypes = item.getAcceptedDataTypes().stream().distinct()
|
|
||||||
.filter(acceptedDataTypes::contains).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return acceptedDataTypes == null ? Collections.emptyList() : acceptedDataTypes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The accepted command types of a group item is the same as of the underlying base item.
|
|
||||||
* If none is defined, the intersection of all sets of accepted command types of all group
|
|
||||||
* members is used instead.
|
|
||||||
*
|
|
||||||
* @return the accepted command types of this group item
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
if (baseItem != null) {
|
|
||||||
return baseItem.getAcceptedCommandTypes();
|
|
||||||
} else {
|
|
||||||
List<Class<? extends Command>> acceptedCommandTypes = null;
|
|
||||||
for (Item item : members) {
|
|
||||||
if (acceptedCommandTypes == null || acceptedCommandTypes.isEmpty()) {
|
|
||||||
acceptedCommandTypes = item.getAcceptedCommandTypes();
|
|
||||||
} else {
|
|
||||||
acceptedCommandTypes = item.getAcceptedCommandTypes().stream().distinct()
|
|
||||||
.filter(acceptedCommandTypes::contains).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return acceptedCommandTypes == null ? Collections.emptyList() : acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(Command command) {
|
|
||||||
if (getAcceptedCommandTypes().contains(command.getClass())) {
|
|
||||||
internalSend(command);
|
|
||||||
} else {
|
|
||||||
logger.warn("Command '{}' has been ignored for group '{}' as it is not accepted.", command.toString(),
|
|
||||||
getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void internalSend(Command command) {
|
|
||||||
if (eventPublisher != null) {
|
|
||||||
for (Item member : members) {
|
|
||||||
// try to send the command to the bus
|
|
||||||
eventPublisher.sendCommand(member.getName(), command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
State newState = function.getStateAs(getAllMembers(), typeClass);
|
|
||||||
if (newState == null && baseItem != null) {
|
|
||||||
// we use the transformation method from the base item
|
|
||||||
baseItem.setState(state);
|
|
||||||
newState = baseItem.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
if (newState == null) {
|
|
||||||
newState = super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getName() + " (" + "Type=" + getClass().getSimpleName() + ", "
|
|
||||||
+ (baseItem != null ? "BaseType=" + baseItem.getClass().getSimpleName() + ", " : "") + "Members="
|
|
||||||
+ members.size() + ", " + "State=" + getState() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateChanged(Item item, State oldState, State newState) {
|
|
||||||
setState(function.calculate(members));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateUpdated(Item item, State state) {
|
|
||||||
setState(function.calculate(members));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This interface defines the core features of an openHAB item.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Item instances are used for all stateful services and are especially
|
|
||||||
* important for the {@link ItemRegistry}.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface Item {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the current state of the item
|
|
||||||
*
|
|
||||||
* @return the current state
|
|
||||||
*/
|
|
||||||
public State getState();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the current state of the item as a specific type
|
|
||||||
*
|
|
||||||
* @return the current state in the requested type or
|
|
||||||
* null, if state cannot be provided as the requested type
|
|
||||||
*/
|
|
||||||
public State getStateAs(Class<? extends State> typeClass);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the name of the item
|
|
||||||
*
|
|
||||||
* @return the name of the item
|
|
||||||
*/
|
|
||||||
public String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method provides a list of all data types that can be used to update the item state
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Imagine e.g. a dimmer device: It's status could be 0%, 10%, 50%, 100%, but also OFF or ON and
|
|
||||||
* maybe UNDEFINED. So the accepted data types would be in this case {@link PercentType}, {@link OnOffType}
|
|
||||||
* and {@link UnDefType}
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a list of data types that can be used to update the item state
|
|
||||||
*/
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method provides a list of all command types that can be used for this item
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Imagine e.g. a dimmer device: You could ask it to dim to 0%, 10%, 50%, 100%, but
|
|
||||||
* also to turn OFF or ON. So the accepted command types would be in this case {@link PercentType},
|
|
||||||
* {@link OnOffType}
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a list of all command types that can be used for this item
|
|
||||||
*/
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of the names of the groups this item belongs to.
|
|
||||||
*
|
|
||||||
* @return list of item group names
|
|
||||||
*/
|
|
||||||
public List<String> getGroupNames();
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This Factory creates concrete instances of the known ItemTypes.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ItemFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new Item instance of type <code>itemTypeName</code> and the name
|
|
||||||
* <code>itemName</code>
|
|
||||||
*
|
|
||||||
* @param itemTypeName
|
|
||||||
* @param itemName
|
|
||||||
* @return a new Item of type <code>itemTypeName</code> or
|
|
||||||
* <code>null</code> if no matching class is known.
|
|
||||||
*/
|
|
||||||
GenericItem createItem(String itemTypeName, String itemName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of all supported ItemTypes of this Factory.
|
|
||||||
*
|
|
||||||
* @return the supported ItemTypes
|
|
||||||
*/
|
|
||||||
String[] getSupportedItemTypes();
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an abstract parent exception to be extended by any exceptions
|
|
||||||
* related to item lookups in the item registry.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class ItemLookupException extends Exception {
|
|
||||||
|
|
||||||
public ItemLookupException(String string) {
|
|
||||||
super(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -4617708589675048859L;
|
|
||||||
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This exception is thrown by the {@link ItemRegistry} if an item could
|
|
||||||
* not be found.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ItemNotFoundException extends ItemLookupException {
|
|
||||||
|
|
||||||
public ItemNotFoundException(String name) {
|
|
||||||
super("Item '" + name + "' could not be found in the item registry");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -3720784568250902711L;
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This exception can be thrown whenever a search pattern does not uniquely identify
|
|
||||||
* an item. The list of matching items must be made available through this exception.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ItemNotUniqueException extends ItemLookupException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 5154625234283910124L;
|
|
||||||
|
|
||||||
private final Collection<Item> matchingItems;
|
|
||||||
|
|
||||||
public ItemNotUniqueException(String string, Collection<Item> items) {
|
|
||||||
super("Item cannot be uniquely identified by '" + string + "'");
|
|
||||||
this.matchingItems = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all items that match the search pattern
|
|
||||||
*
|
|
||||||
* @return collection of items matching the search pattern
|
|
||||||
*/
|
|
||||||
public Collection<Item> getMatchingItems() {
|
|
||||||
return matchingItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An item provider provides instances of {@link GenericItem}. These
|
|
||||||
* items can be constructed from some static configuration files or
|
|
||||||
* they can be derived from some dynamic logic.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ItemProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides an array of items.
|
|
||||||
*
|
|
||||||
* @return a collection of items
|
|
||||||
*/
|
|
||||||
Collection<Item> getItems();
|
|
||||||
|
|
||||||
public void addItemChangeListener(ItemsChangeListener listener);
|
|
||||||
|
|
||||||
public void removeItemChangeListener(ItemsChangeListener listener);
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ItemRegistry is the central place, where items are kept in memory and their state
|
|
||||||
* is permanently tracked. So any code that requires the current state of items should use
|
|
||||||
* this service (instead of trying to keep their own local copy of the items).
|
|
||||||
*
|
|
||||||
* Items are registered by {@link ItemProvider}s, which can provision them from any source
|
|
||||||
* they like and also dynamically remove or add items.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ItemRegistry {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves a single item from the registry.
|
|
||||||
*
|
|
||||||
* @param name the item name
|
|
||||||
* @return the uniquely identified item
|
|
||||||
* @throws ItemNotFoundException if no item matches the input
|
|
||||||
*/
|
|
||||||
public Item getItem(String name) throws ItemNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves a single item from the registry.
|
|
||||||
* Search patterns and shortened versions are supported, if they uniquely identify an item
|
|
||||||
*
|
|
||||||
* @param name the item name, a part of the item name or a search pattern
|
|
||||||
* @return the uniquely identified item
|
|
||||||
* @throws ItemNotFoundException if no item matches the input
|
|
||||||
* @throws ItemNotUniqueException if multiply items match the input
|
|
||||||
*/
|
|
||||||
public Item getItemByPattern(String name) throws ItemNotFoundException, ItemNotUniqueException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves all items that are currently available in the registry
|
|
||||||
*
|
|
||||||
* @return a collection of all available items
|
|
||||||
*/
|
|
||||||
public Collection<Item> getItems();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves all items that match a given search pattern
|
|
||||||
*
|
|
||||||
* @return a collection of all items matching the search pattern
|
|
||||||
*/
|
|
||||||
public Collection<Item> getItems(String pattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether itemName matches the item name conventions.
|
|
||||||
* Item names must only consist out of alpha-numerical characters and
|
|
||||||
* underscores (_).
|
|
||||||
*
|
|
||||||
* @param itemName the item name to validate
|
|
||||||
* @return true, if the name is valid
|
|
||||||
*/
|
|
||||||
public boolean isValidItemName(String itemName);
|
|
||||||
|
|
||||||
public void addItemRegistryChangeListener(ItemRegistryChangeListener listener);
|
|
||||||
|
|
||||||
public void removeItemRegistryChangeListener(ItemRegistryChangeListener listener);
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a listener interface which should be implemented where ever the item registry is
|
|
||||||
* used in order to be notified of any dynamic changes in the provided items.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ItemRegistryChangeListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that all items in the registry have changed and thus should be reloaded.
|
|
||||||
*
|
|
||||||
* @param oldItemNames a collection of all previous item names, so that references can be removed
|
|
||||||
*/
|
|
||||||
public void allItemsChanged(Collection<String> oldItemNames);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that a single item has been added
|
|
||||||
*
|
|
||||||
* @param item the item that has been added
|
|
||||||
*/
|
|
||||||
public void itemAdded(Item item);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that a single item has been removed
|
|
||||||
*
|
|
||||||
* @param item the item that has been removed
|
|
||||||
*/
|
|
||||||
public void itemRemoved(Item item);
|
|
||||||
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a listener interface which should be implemented where ever item providers or
|
|
||||||
* the item registry are used in order to be notified of any dynamic changes in the provided items.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ItemsChangeListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that all items of a provider have changed and thus should be reloaded.
|
|
||||||
*
|
|
||||||
* @param provider the concerned item provider
|
|
||||||
* @param oldItemNames a collection of all previous item names, so that references can be removed
|
|
||||||
*/
|
|
||||||
public void allItemsChanged(ItemProvider provider, Collection<String> oldItemNames);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that a single item has been added
|
|
||||||
*
|
|
||||||
* @param provider the concerned item provider
|
|
||||||
* @param item the item that has been added
|
|
||||||
*/
|
|
||||||
public void itemAdded(ItemProvider provider, Item item);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies the listener that a single item has been removed
|
|
||||||
*
|
|
||||||
* @param provider the concerned item provider
|
|
||||||
* @param item the item that has been removed
|
|
||||||
*/
|
|
||||||
public void itemRemoved(ItemProvider provider, Item item);
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items;
|
|
||||||
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This interface must be implemented by all classes that want to be notified
|
|
||||||
* about changes in the state of an item.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* The {@link GenericItem} class provides the possibility to register such
|
|
||||||
* listeners.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface StateChangeListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called, if a state has changed.
|
|
||||||
*
|
|
||||||
* @param item the item whose state has changed
|
|
||||||
* @param oldState the previous state
|
|
||||||
* @param newState the new state
|
|
||||||
*/
|
|
||||||
public void stateChanged(Item item, State oldState, State newState);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called, if a state was updated, but has not changed
|
|
||||||
*
|
|
||||||
* @param item the item whose state was updated
|
|
||||||
* @param state the current state, same before and after the update
|
|
||||||
*/
|
|
||||||
public void stateUpdated(Item item, State state);
|
|
||||||
|
|
||||||
}
|
|
@ -1,223 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.items.internal;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.emf.common.util.EList;
|
|
||||||
import org.eclipse.smarthome.core.common.registry.RegistryChangeListener;
|
|
||||||
import org.eclipse.smarthome.core.items.ItemUtil;
|
|
||||||
import org.openhab.core.compat1x.internal.ItemMapper;
|
|
||||||
import org.openhab.core.items.Item;
|
|
||||||
import org.openhab.core.items.ItemNotFoundException;
|
|
||||||
import org.openhab.core.items.ItemNotUniqueException;
|
|
||||||
import org.openhab.core.items.ItemRegistry;
|
|
||||||
import org.openhab.core.items.ItemRegistryChangeListener;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.model.sitemap.LinkableWidget;
|
|
||||||
import org.openhab.model.sitemap.Sitemap;
|
|
||||||
import org.openhab.model.sitemap.Widget;
|
|
||||||
import org.openhab.ui.items.ItemUIRegistry;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component(service = { ItemRegistry.class, ItemUIRegistry.class })
|
|
||||||
public class ItemUIRegistryDelegate
|
|
||||||
implements ItemUIRegistry, RegistryChangeListener<org.eclipse.smarthome.core.items.Item> {
|
|
||||||
|
|
||||||
private org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry;
|
|
||||||
private final Set<ItemRegistryChangeListener> listeners = new HashSet<>();
|
|
||||||
|
|
||||||
@Reference
|
|
||||||
protected void setItemUIRegistry(org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry) {
|
|
||||||
this.itemUIRegistry = itemUIRegistry;
|
|
||||||
itemUIRegistry.addRegistryChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void unsetItemUIRegistry(org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry) {
|
|
||||||
this.itemUIRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Item getItem(String name) throws ItemNotFoundException {
|
|
||||||
org.eclipse.smarthome.core.items.Item eshItem;
|
|
||||||
try {
|
|
||||||
eshItem = itemUIRegistry.getItem(name);
|
|
||||||
} catch (org.eclipse.smarthome.core.items.ItemNotFoundException e) {
|
|
||||||
throw new ItemNotFoundException(name);
|
|
||||||
}
|
|
||||||
return ItemMapper.mapToOpenHABItem(eshItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Item getItemByPattern(String name) throws ItemNotFoundException, ItemNotUniqueException {
|
|
||||||
org.eclipse.smarthome.core.items.Item eshItem;
|
|
||||||
try {
|
|
||||||
eshItem = itemUIRegistry.getItemByPattern(name);
|
|
||||||
} catch (org.eclipse.smarthome.core.items.ItemNotFoundException e) {
|
|
||||||
throw new ItemNotFoundException(name);
|
|
||||||
} catch (org.eclipse.smarthome.core.items.ItemNotUniqueException e) {
|
|
||||||
throw new ItemNotUniqueException(name, null);
|
|
||||||
}
|
|
||||||
return ItemMapper.mapToOpenHABItem(eshItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Item> getItems() {
|
|
||||||
Collection<org.eclipse.smarthome.core.items.Item> eshItems = itemUIRegistry.getItems();
|
|
||||||
Collection<Item> ohItems = new HashSet<>(eshItems.size());
|
|
||||||
|
|
||||||
for (org.eclipse.smarthome.core.items.Item eshItem : eshItems) {
|
|
||||||
ohItems.add(ItemMapper.mapToOpenHABItem(eshItem));
|
|
||||||
}
|
|
||||||
return ohItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Item> getItems(String pattern) {
|
|
||||||
Collection<org.eclipse.smarthome.core.items.Item> eshItems = itemUIRegistry.getItems(pattern);
|
|
||||||
Collection<Item> ohItems = new HashSet<>(eshItems.size());
|
|
||||||
|
|
||||||
for (org.eclipse.smarthome.core.items.Item eshItem : eshItems) {
|
|
||||||
ohItems.add(ItemMapper.mapToOpenHABItem(eshItem));
|
|
||||||
}
|
|
||||||
return ohItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidItemName(String itemName) {
|
|
||||||
return ItemUtil.isValidItemName(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addItemRegistryChangeListener(ItemRegistryChangeListener listener) {
|
|
||||||
this.listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeItemRegistryChangeListener(ItemRegistryChangeListener listener) {
|
|
||||||
this.listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void added(org.eclipse.smarthome.core.items.Item element) {
|
|
||||||
Item ohItem = ItemMapper.mapToOpenHABItem(element);
|
|
||||||
for (ItemRegistryChangeListener listener : listeners) {
|
|
||||||
listener.itemAdded(ohItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removed(org.eclipse.smarthome.core.items.Item element) {
|
|
||||||
Item ohItem = ItemMapper.mapToOpenHABItem(element);
|
|
||||||
for (ItemRegistryChangeListener listener : listeners) {
|
|
||||||
listener.itemRemoved(ohItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updated(org.eclipse.smarthome.core.items.Item oldElement,
|
|
||||||
org.eclipse.smarthome.core.items.Item element) {
|
|
||||||
Item ohItem = ItemMapper.mapToOpenHABItem(element);
|
|
||||||
for (ItemRegistryChangeListener listener : listeners) {
|
|
||||||
listener.itemRemoved(ohItem);
|
|
||||||
listener.itemAdded(ohItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIcon(String itemName) {
|
|
||||||
return itemUIRegistry.getCategory(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel(String itemName) {
|
|
||||||
return itemUIRegistry.getLabel(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Widget getDefaultWidget(Class<? extends Item> itemType, String itemName) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Widget getWidget(String itemName) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel(Widget w) {
|
|
||||||
return itemUIRegistry.getLabel(w.getItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIcon(Widget w) {
|
|
||||||
return itemUIRegistry.getCategory(w.getItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getState(Widget w) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Widget getWidget(Sitemap sitemap, String id) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getWidgetId(Widget w) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EList<Widget> getChildren(LinkableWidget w) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean iconExists(String icon) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabelColor(Widget w) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValueColor(Widget w) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getVisiblity(Widget w) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getItemState(String itemName) {
|
|
||||||
try {
|
|
||||||
return getItem(itemName).getState();
|
|
||||||
} catch (ItemNotFoundException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.HSBType;
|
|
||||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
|
||||||
import org.openhab.core.library.types.OnOffType;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ColorItem can be used for color values, e.g. for LED lights
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ColorItem extends DimmerItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(OnOffType.class);
|
|
||||||
acceptedDataTypes.add(PercentType.class);
|
|
||||||
acceptedDataTypes.add(HSBType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(OnOffType.class);
|
|
||||||
acceptedCommandTypes.add(IncreaseDecreaseType.class);
|
|
||||||
acceptedCommandTypes.add(PercentType.class);
|
|
||||||
acceptedCommandTypes.add(HSBType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ColorItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(HSBType command) {
|
|
||||||
internalSend(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setState(State state) {
|
|
||||||
State currentState = this.state;
|
|
||||||
|
|
||||||
if (currentState instanceof HSBType) {
|
|
||||||
DecimalType hue = ((HSBType) currentState).getHue();
|
|
||||||
PercentType saturation = ((HSBType) currentState).getSaturation();
|
|
||||||
// we map ON/OFF values to dark/bright, so that the hue and saturation values are not changed
|
|
||||||
if (state == OnOffType.OFF) {
|
|
||||||
super.setState(new HSBType(hue, saturation, PercentType.ZERO));
|
|
||||||
} else if (state == OnOffType.ON) {
|
|
||||||
super.setState(new HSBType(hue, saturation, PercentType.HUNDRED));
|
|
||||||
} else if (state instanceof PercentType && !(state instanceof HSBType)) {
|
|
||||||
super.setState(new HSBType(hue, saturation, (PercentType) state));
|
|
||||||
} else {
|
|
||||||
super.setState(state);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// we map ON/OFF values to black/white and percentage values to grey scale
|
|
||||||
if (state == OnOffType.OFF) {
|
|
||||||
super.setState(HSBType.BLACK);
|
|
||||||
} else if (state == OnOffType.ON) {
|
|
||||||
super.setState(HSBType.WHITE);
|
|
||||||
} else if (state instanceof PercentType && !(state instanceof HSBType)) {
|
|
||||||
super.setState(new HSBType(DecimalType.ZERO, PercentType.ZERO, (PercentType) state));
|
|
||||||
} else {
|
|
||||||
super.setState(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (typeClass == HSBType.class) {
|
|
||||||
return this.state;
|
|
||||||
} else if (typeClass == OnOffType.class) {
|
|
||||||
if (state instanceof HSBType) {
|
|
||||||
HSBType hsbState = (HSBType) state;
|
|
||||||
// if brightness is not completely off, we consider the state to be on
|
|
||||||
return hsbState.getBrightness().equals(PercentType.ZERO) ? OnOffType.OFF : OnOffType.ON;
|
|
||||||
}
|
|
||||||
} else if (typeClass == DecimalType.class) {
|
|
||||||
if (state instanceof HSBType) {
|
|
||||||
HSBType hsbState = (HSBType) state;
|
|
||||||
return new DecimalType(
|
|
||||||
hsbState.getBrightness().toBigDecimal().divide(new BigDecimal(100), 8, RoundingMode.UP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.OpenClosedType;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ContactItem can be used for sensors that return an "open" or "close" as a state.
|
|
||||||
* This is useful for doors, windows, etc.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ContactItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(OpenClosedType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(OpenClosedType command) {
|
|
||||||
internalSend(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (typeClass == DecimalType.class) {
|
|
||||||
return state == OpenClosedType.OPEN ? new DecimalType(1) : DecimalType.ZERO;
|
|
||||||
} else if (typeClass == PercentType.class) {
|
|
||||||
return state == OpenClosedType.OPEN ? PercentType.HUNDRED : PercentType.ZERO;
|
|
||||||
} else {
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DateTimeType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A DateTimeItem stores a timestamp including a valid time zone.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class DateTimeItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add((DateTimeType.class));
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
|
||||||
import org.openhab.core.library.types.OnOffType;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A DimmerItem can be used as a switch (ON/OFF), but it also accepts percent values
|
|
||||||
* to reflect the dimmed state.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class DimmerItem extends SwitchItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(OnOffType.class);
|
|
||||||
acceptedDataTypes.add(PercentType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(OnOffType.class);
|
|
||||||
acceptedCommandTypes.add(IncreaseDecreaseType.class);
|
|
||||||
acceptedCommandTypes.add(PercentType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimmerItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(PercentType command) {
|
|
||||||
internalSend(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setState(State state) {
|
|
||||||
// we map ON/OFF values to the percent values 0 and 100
|
|
||||||
if (state == OnOffType.OFF) {
|
|
||||||
super.setState(PercentType.ZERO);
|
|
||||||
} else if (state == OnOffType.ON) {
|
|
||||||
super.setState(PercentType.HUNDRED);
|
|
||||||
} else {
|
|
||||||
super.setState(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (state.getClass() == typeClass) {
|
|
||||||
return state;
|
|
||||||
} else if (typeClass == OnOffType.class) {
|
|
||||||
// if it is not completely off, we consider the dimmer to be on
|
|
||||||
return state.equals(PercentType.ZERO) ? OnOffType.OFF : OnOffType.ON;
|
|
||||||
} else if (typeClass == DecimalType.class) {
|
|
||||||
if (state instanceof PercentType) {
|
|
||||||
return new DecimalType(
|
|
||||||
((PercentType) state).toBigDecimal().divide(new BigDecimal(100), 8, RoundingMode.UP));
|
|
||||||
}
|
|
||||||
} else if (typeClass == PercentType.class) {
|
|
||||||
if (state instanceof DecimalType) {
|
|
||||||
return new PercentType(((DecimalType) state).toBigDecimal().multiply(new BigDecimal(100)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.PointType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A LocationItem can be used to store GPS related informations, addresses...
|
|
||||||
* This is useful for location awareness related functions
|
|
||||||
*
|
|
||||||
* @author Gaël L'hopital - Initial contribution
|
|
||||||
*/
|
|
||||||
public class LocationItem extends GenericItem {
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(PointType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the distance with another Point type,
|
|
||||||
* http://stackoverflow.com/questions/837872/calculate-distance-in-meters-when-you-know-longitude-and-latitude-in-java
|
|
||||||
*
|
|
||||||
* @return distance between the two points in meters
|
|
||||||
*/
|
|
||||||
public DecimalType distanceFrom(PointType away) {
|
|
||||||
double dist = -1;
|
|
||||||
|
|
||||||
if ((away != null) && (this.state instanceof PointType)) {
|
|
||||||
PointType me = (PointType) this.state;
|
|
||||||
|
|
||||||
double dLat = Math.pow(
|
|
||||||
Math.sin(Math.toRadians(away.getLatitude().doubleValue() - me.getLatitude().doubleValue()) / 2), 2);
|
|
||||||
double dLng = Math.pow(
|
|
||||||
Math.sin(Math.toRadians(away.getLongitude().doubleValue() - me.getLongitude().doubleValue()) / 2),
|
|
||||||
2);
|
|
||||||
double a = dLat + Math.cos(Math.toRadians(me.getLatitude().doubleValue()))
|
|
||||||
* Math.cos(Math.toRadians(away.getLatitude().doubleValue())) * dLng;
|
|
||||||
|
|
||||||
dist = PointType.WGS84_A * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DecimalType(dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A NumberItem has a decimal value and is usually used for all kinds
|
|
||||||
* of sensors, like temperature, brightness, wind, etc.
|
|
||||||
* It can also be used as a counter or as any other thing that can be expressed
|
|
||||||
* as a number.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class NumberItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(DecimalType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(DecimalType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
|
||||||
import org.openhab.core.library.types.StopMoveType;
|
|
||||||
import org.openhab.core.library.types.UpDownType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A RollershutterItem allows the control of roller shutters, i.e.
|
|
||||||
* moving them up, down, stopping or setting it to close to a certain percentage.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class RollershutterItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
acceptedDataTypes.add(UpDownType.class);
|
|
||||||
acceptedDataTypes.add(PercentType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(UpDownType.class);
|
|
||||||
acceptedCommandTypes.add(StopMoveType.class);
|
|
||||||
acceptedCommandTypes.add(PercentType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RollershutterItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setState(State state) {
|
|
||||||
// we map UP/DOWN values to the percent values 0 and 100
|
|
||||||
if (state == UpDownType.UP) {
|
|
||||||
super.setState(PercentType.ZERO);
|
|
||||||
} else if (state == UpDownType.DOWN) {
|
|
||||||
super.setState(PercentType.HUNDRED);
|
|
||||||
} else {
|
|
||||||
super.setState(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (typeClass == UpDownType.class) {
|
|
||||||
if (state.equals(PercentType.ZERO)) {
|
|
||||||
return UpDownType.UP;
|
|
||||||
} else if (state.equals(PercentType.HUNDRED)) {
|
|
||||||
return UpDownType.DOWN;
|
|
||||||
} else {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
} else if (typeClass == DecimalType.class) {
|
|
||||||
if (state instanceof PercentType) {
|
|
||||||
return new DecimalType(
|
|
||||||
((PercentType) state).toBigDecimal().divide(new BigDecimal(100), 8, RoundingMode.UP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DateTimeType;
|
|
||||||
import org.openhab.core.library.types.StringType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.TypeParser;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A StringItem can be used for any kind of string to either send or receive
|
|
||||||
* from a device.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class StringItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(StringType.class);
|
|
||||||
acceptedDataTypes.add((DateTimeType.class));
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(StringType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
List<Class<? extends State>> list = new ArrayList<>();
|
|
||||||
list.add(typeClass);
|
|
||||||
State convertedState = TypeParser.parseState(list, state.toString());
|
|
||||||
if (convertedState != null) {
|
|
||||||
return convertedState;
|
|
||||||
} else {
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.OnOffType;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A SwitchItem represents a normal switch that can be ON or OFF.
|
|
||||||
* Useful for normal lights, presence detection etc.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class SwitchItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(OnOffType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
|
|
||||||
acceptedCommandTypes.add(OnOffType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SwitchItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(OnOffType command) {
|
|
||||||
internalSend(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getStateAs(Class<? extends State> typeClass) {
|
|
||||||
if (typeClass == DecimalType.class) {
|
|
||||||
return state == OnOffType.ON ? new DecimalType(1) : DecimalType.ZERO;
|
|
||||||
} else if (typeClass == PercentType.class) {
|
|
||||||
return state == OnOffType.ON ? PercentType.HUNDRED : PercentType.ZERO;
|
|
||||||
} else {
|
|
||||||
return super.getStateAs(typeClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,406 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GroupFunction;
|
|
||||||
import org.openhab.core.items.Item;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface is only a container for functions that require the core type library
|
|
||||||
* for its calculations.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ArithmeticGroupFunction extends GroupFunction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This does a logical 'and' operation. Only if all items are of 'activeState' this
|
|
||||||
* is returned, otherwise the 'passiveState' is returned.
|
|
||||||
*
|
|
||||||
* Through the getStateAs() method, it can be determined, how many
|
|
||||||
* items actually are not in the 'activeState'.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class And implements GroupFunction {
|
|
||||||
|
|
||||||
protected final State activeState;
|
|
||||||
protected final State passiveState;
|
|
||||||
|
|
||||||
public And(State activeValue, State passiveValue) {
|
|
||||||
if (activeValue == null || passiveValue == null) {
|
|
||||||
throw new IllegalArgumentException("Parameters must not be null!");
|
|
||||||
}
|
|
||||||
this.activeState = activeValue;
|
|
||||||
this.passiveState = passiveValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
if (items != null && !items.isEmpty()) {
|
|
||||||
for (Item item : items) {
|
|
||||||
if (!activeState.equals(item.getStateAs(activeState.getClass()))) {
|
|
||||||
return passiveState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return activeState;
|
|
||||||
} else {
|
|
||||||
// if we do not have any items, we return the passive state
|
|
||||||
return passiveState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
if (stateClass == DecimalType.class) {
|
|
||||||
if (items != null) {
|
|
||||||
return new DecimalType(items.size() - count(items, activeState));
|
|
||||||
} else {
|
|
||||||
return DecimalType.ZERO;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int count(List<Item> items, State state) {
|
|
||||||
int count = 0;
|
|
||||||
if (items != null && state != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
if (state.equals(item.getStateAs(state.getClass()))) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This does a logical 'or' operation. If at least one item is of 'activeState' this
|
|
||||||
* is returned, otherwise the 'passiveState' is returned.
|
|
||||||
*
|
|
||||||
* Through the getStateAs() method, it can be determined, how many
|
|
||||||
* items actually are in the 'activeState'.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Or implements GroupFunction {
|
|
||||||
|
|
||||||
protected final State activeState;
|
|
||||||
protected final State passiveState;
|
|
||||||
|
|
||||||
public Or(State activeValue, State passiveValue) {
|
|
||||||
if (activeValue == null || passiveValue == null) {
|
|
||||||
throw new IllegalArgumentException("Parameters must not be null!");
|
|
||||||
}
|
|
||||||
this.activeState = activeValue;
|
|
||||||
this.passiveState = passiveValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
if (items != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
if (activeState.equals(item.getStateAs(activeState.getClass()))) {
|
|
||||||
return activeState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return passiveState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
if (stateClass == DecimalType.class) {
|
|
||||||
return new DecimalType(count(items, activeState));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int count(List<Item> items, State state) {
|
|
||||||
int count = 0;
|
|
||||||
if (items != null && state != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
if (state.equals(item.getStateAs(state.getClass()))) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This does a logical 'nand' operation. The state is 'calculated' by
|
|
||||||
* the normal 'and' operation and than negated by returning the opposite
|
|
||||||
* value. E.g. when the 'and' operation calculates the activeValue the
|
|
||||||
* passiveValue will be returned and vice versa.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
static class NAnd extends And {
|
|
||||||
|
|
||||||
public NAnd(State activeValue, State passiveValue) {
|
|
||||||
super(activeValue, passiveValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
State result = super.calculate(items);
|
|
||||||
State notResult = result.equals(activeState) ? passiveState : activeState;
|
|
||||||
return notResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This does a logical 'nor' operation. The state is 'calculated' by
|
|
||||||
* the normal 'or' operation and than negated by returning the opposite
|
|
||||||
* value. E.g. when the 'or' operation calculates the activeValue the
|
|
||||||
* passiveValue will be returned and vice versa.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
static class NOr extends Or {
|
|
||||||
|
|
||||||
public NOr(State activeValue, State passiveValue) {
|
|
||||||
super(activeValue, passiveValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
State result = super.calculate(items);
|
|
||||||
State notResult = result.equals(activeState) ? passiveState : activeState;
|
|
||||||
return notResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calculates the numeric average over all item states of decimal type.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Avg implements GroupFunction {
|
|
||||||
|
|
||||||
public Avg() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
BigDecimal sum = BigDecimal.ZERO;
|
|
||||||
int count = 0;
|
|
||||||
if (items != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
DecimalType itemState = (DecimalType) item.getStateAs(DecimalType.class);
|
|
||||||
if (itemState != null) {
|
|
||||||
sum = sum.add(itemState.toBigDecimal());
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count > 0) {
|
|
||||||
return new DecimalType(sum.divide(new BigDecimal(count), RoundingMode.HALF_UP));
|
|
||||||
} else {
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calculates the numeric sum over all item states of decimal type.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Sum implements GroupFunction {
|
|
||||||
|
|
||||||
public Sum() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
BigDecimal sum = BigDecimal.ZERO;
|
|
||||||
if (items != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
DecimalType itemState = (DecimalType) item.getStateAs(DecimalType.class);
|
|
||||||
if (itemState != null) {
|
|
||||||
sum = sum.add(itemState.toBigDecimal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new DecimalType(sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calculates the minimum value of all item states of decimal type.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Min implements GroupFunction {
|
|
||||||
|
|
||||||
public Min() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
if (items != null && !items.isEmpty()) {
|
|
||||||
BigDecimal min = null;
|
|
||||||
for (Item item : items) {
|
|
||||||
DecimalType itemState = (DecimalType) item.getStateAs(DecimalType.class);
|
|
||||||
if (itemState != null) {
|
|
||||||
if (min == null || min.compareTo(itemState.toBigDecimal()) > 0) {
|
|
||||||
min = itemState.toBigDecimal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (min != null) {
|
|
||||||
return new DecimalType(min);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calculates the maximum value of all item states of decimal type.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static class Max implements GroupFunction {
|
|
||||||
|
|
||||||
public Max() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State calculate(List<Item> items) {
|
|
||||||
if (items != null && !items.isEmpty()) {
|
|
||||||
BigDecimal max = null;
|
|
||||||
for (Item item : items) {
|
|
||||||
DecimalType itemState = (DecimalType) item.getStateAs(DecimalType.class);
|
|
||||||
if (itemState != null) {
|
|
||||||
if (max == null || max.compareTo(itemState.toBigDecimal()) < 0) {
|
|
||||||
max = itemState.toBigDecimal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (max != null) {
|
|
||||||
return new DecimalType(max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UnDefType.UNDEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public State getStateAs(List<Item> items, Class<? extends State> stateClass) {
|
|
||||||
State state = calculate(items);
|
|
||||||
if (stateClass.isInstance(state)) {
|
|
||||||
return state;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class DateTimeType implements PrimitiveType, State, Command {
|
|
||||||
|
|
||||||
public static final String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
|
|
||||||
public static final String DATE_PATTERN_WITH_TZ = "yyyy-MM-dd'T'HH:mm:ssz";
|
|
||||||
|
|
||||||
protected Calendar calendar;
|
|
||||||
|
|
||||||
public DateTimeType() {
|
|
||||||
this(Calendar.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeType(Calendar calendar) {
|
|
||||||
this.calendar = calendar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeType(String calendarValue) {
|
|
||||||
Date date = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
date = new SimpleDateFormat(DATE_PATTERN_WITH_TZ).parse(calendarValue);
|
|
||||||
} catch (ParseException fpe2) {
|
|
||||||
date = new SimpleDateFormat(DATE_PATTERN).parse(calendarValue);
|
|
||||||
}
|
|
||||||
} catch (ParseException fpe) {
|
|
||||||
throw new IllegalArgumentException(calendarValue + " is not in a valid format.", fpe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (date != null) {
|
|
||||||
calendar = Calendar.getInstance();
|
|
||||||
calendar.setTime(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Calendar getCalendar() {
|
|
||||||
return calendar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTimeType valueOf(String value) {
|
|
||||||
return new DateTimeType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
try {
|
|
||||||
return String.format(pattern, calendar);
|
|
||||||
} catch (NullPointerException npe) {
|
|
||||||
return new SimpleDateFormat(DATE_PATTERN).format(calendar.getTime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String format(Locale locale, String pattern) {
|
|
||||||
return String.format(locale, pattern, calendar);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new SimpleDateFormat(DATE_PATTERN).format(calendar.getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((calendar == null) ? 0 : calendar.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DateTimeType other = (DateTimeType) obj;
|
|
||||||
if (calendar == null) {
|
|
||||||
if (other.calendar != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!calendar.equals(other.calendar)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The decimal type uses a BigDecimal internally and thus can be used for
|
|
||||||
* integers, longs and floating point numbers alike.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class DecimalType extends Number implements PrimitiveType, State, Command, Comparable<DecimalType> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 4226845847123464690L;
|
|
||||||
|
|
||||||
public static final DecimalType ZERO = new DecimalType(0);
|
|
||||||
|
|
||||||
protected BigDecimal value;
|
|
||||||
|
|
||||||
public DecimalType() {
|
|
||||||
this.value = BigDecimal.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType(BigDecimal value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType(long value) {
|
|
||||||
this.value = BigDecimal.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType(double value) {
|
|
||||||
this.value = BigDecimal.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType(String value) {
|
|
||||||
this.value = new BigDecimal(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return value.toPlainString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DecimalType valueOf(String value) {
|
|
||||||
return new DecimalType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
if (pattern.contains("%d")) {
|
|
||||||
return String.format(pattern, value.toBigInteger());
|
|
||||||
} else {
|
|
||||||
return String.format(pattern, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal toBigDecimal() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof DecimalType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DecimalType other = (DecimalType) obj;
|
|
||||||
if (value == null) {
|
|
||||||
if (other.value != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (value.compareTo(other.value) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(DecimalType o) {
|
|
||||||
return value.compareTo(o.toBigDecimal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return value.doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return value.floatValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return value.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return value.longValue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.ComplexType;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The HSBType is a complex type with constituents for hue, saturation and
|
|
||||||
* brightness and can be used for color items.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class HSBType extends PercentType implements ComplexType, State, Command {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 322902950356613226L;
|
|
||||||
|
|
||||||
// constants for the constituents
|
|
||||||
public static final String KEY_HUE = "h";
|
|
||||||
public static final String KEY_SATURATION = "s";
|
|
||||||
public static final String KEY_BRIGHTNESS = "b";
|
|
||||||
|
|
||||||
// constants for colors
|
|
||||||
public static final HSBType BLACK = new HSBType(Color.BLACK);
|
|
||||||
public static final HSBType WHITE = new HSBType(Color.WHITE);
|
|
||||||
public static final HSBType RED = new HSBType(Color.RED);
|
|
||||||
public static final HSBType GREEN = new HSBType(Color.GREEN);
|
|
||||||
public static final HSBType BLUE = new HSBType(Color.BLUE);
|
|
||||||
|
|
||||||
protected BigDecimal hue;
|
|
||||||
protected BigDecimal saturation;
|
|
||||||
|
|
||||||
// the inherited field "value" of the parent DecimalType corresponds to the
|
|
||||||
// "brightness"
|
|
||||||
|
|
||||||
public HSBType(Color color) {
|
|
||||||
if (color != null) {
|
|
||||||
float[] hsbValues = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
|
|
||||||
this.hue = BigDecimal.valueOf(hsbValues[0] * 360);
|
|
||||||
this.saturation = BigDecimal.valueOf(hsbValues[1] * 100);
|
|
||||||
this.value = BigDecimal.valueOf(hsbValues[2] * 100);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Constructor argument must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HSBType(DecimalType h, PercentType s, PercentType b) {
|
|
||||||
this.hue = h.toBigDecimal();
|
|
||||||
this.saturation = s.toBigDecimal();
|
|
||||||
this.value = b.toBigDecimal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public HSBType(String value) {
|
|
||||||
if (value != null) {
|
|
||||||
String[] constituents = value.split(",");
|
|
||||||
if (constituents.length == 3) {
|
|
||||||
this.hue = new BigDecimal(constituents[0]);
|
|
||||||
this.saturation = new BigDecimal(constituents[1]);
|
|
||||||
this.value = new BigDecimal(constituents[2]);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(value + " is not a valid HSBType syntax");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Constructor argument must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HSBType valueOf(String value) {
|
|
||||||
return new HSBType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SortedMap<String, PrimitiveType> getConstituents() {
|
|
||||||
TreeMap<String, PrimitiveType> map = new TreeMap<>();
|
|
||||||
map.put(KEY_HUE, getHue());
|
|
||||||
map.put(KEY_SATURATION, getSaturation());
|
|
||||||
map.put(KEY_BRIGHTNESS, getBrightness());
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType getHue() {
|
|
||||||
return new DecimalType(hue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType getSaturation() {
|
|
||||||
return new PercentType(saturation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType getBrightness() {
|
|
||||||
return new PercentType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType getRed() {
|
|
||||||
return byteToPercentType(toColor().getRed());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType getGreen() {
|
|
||||||
return byteToPercentType(toColor().getGreen());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType getBlue() {
|
|
||||||
return byteToPercentType(toColor().getBlue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private PercentType byteToPercentType(int byteValue) {
|
|
||||||
BigDecimal percentValue = new BigDecimal(byteValue).multiply(BigDecimal.valueOf(100))
|
|
||||||
.divide(BigDecimal.valueOf(255), 2, BigDecimal.ROUND_HALF_UP);
|
|
||||||
return new PercentType(percentValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color toColor() {
|
|
||||||
return Color.getHSBColor(hue.floatValue() / 360, saturation.floatValue() / 100, value.floatValue() / 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getHue() + "," + getSaturation() + "," + getBrightness();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int tmp = 10000 * (getHue() == null ? 0 : getHue().hashCode());
|
|
||||||
tmp += 100 * (getSaturation() == null ? 0 : getSaturation().hashCode());
|
|
||||||
tmp += (getBrightness() == null ? 0 : getBrightness().hashCode());
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof HSBType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
HSBType other = (HSBType) obj;
|
|
||||||
if ((getHue() != null && other.getHue() == null) || (getHue() == null && other.getHue() != null)
|
|
||||||
|| (getSaturation() != null && other.getSaturation() == null)
|
|
||||||
|| (getSaturation() == null && other.getSaturation() != null)
|
|
||||||
|| (getBrightness() != null && other.getBrightness() == null)
|
|
||||||
|| (getBrightness() == null && other.getBrightness() != null)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!getHue().equals(other.getHue()) || !getSaturation().equals(other.getSaturation())
|
|
||||||
|| !getBrightness().equals(other.getBrightness())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum IncreaseDecreaseType implements PrimitiveType, Command {
|
|
||||||
INCREASE,
|
|
||||||
DECREASE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum OnOffType implements PrimitiveType, State, Command {
|
|
||||||
ON,
|
|
||||||
OFF;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum OpenClosedType implements PrimitiveType, State, Command {
|
|
||||||
OPEN,
|
|
||||||
CLOSED;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PercentType extends the {@link DecimalType} by putting constraints for its value on top (0-100).
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class PercentType extends DecimalType {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -9066279845951780879L;
|
|
||||||
|
|
||||||
public static final PercentType ZERO = new PercentType(0);
|
|
||||||
public static final PercentType HUNDRED = new PercentType(100);
|
|
||||||
|
|
||||||
public PercentType() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType(int value) {
|
|
||||||
super(value);
|
|
||||||
validateValue(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType(String value) {
|
|
||||||
super(value);
|
|
||||||
validateValue(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PercentType(BigDecimal value) {
|
|
||||||
super(value);
|
|
||||||
validateValue(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateValue(BigDecimal value) {
|
|
||||||
if (BigDecimal.ZERO.compareTo(value) > 0 || new BigDecimal(100).compareTo(value) < 0) {
|
|
||||||
throw new IllegalArgumentException("Value must be between 0 and 100");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PercentType valueOf(String value) {
|
|
||||||
return new PercentType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,241 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Formatter;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.ComplexType;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This type can be used for items that are dealing with GPS functionality.
|
|
||||||
*
|
|
||||||
* @author Gaël L'hopital - Initial contribution
|
|
||||||
*/
|
|
||||||
public class PointType implements ComplexType, Command, State {
|
|
||||||
|
|
||||||
public static final double EARTH_GRAVITATIONAL_CONSTANT = 3.986004418e14;
|
|
||||||
public static final double WGS84_A = 6378137; // The equatorial radius of
|
|
||||||
// WGS84 ellipsoid (6378137
|
|
||||||
// m).
|
|
||||||
private BigDecimal latitude = BigDecimal.ZERO; // in decimal degrees
|
|
||||||
private BigDecimal longitude = BigDecimal.ZERO; // in decimal degrees
|
|
||||||
private BigDecimal altitude = BigDecimal.ZERO; // in decimal meters
|
|
||||||
// constants for the constituents
|
|
||||||
public static final String KEY_LATITUDE = "lat";
|
|
||||||
public static final String KEY_LONGITUDE = "long";
|
|
||||||
public static final String KEY_ALTITUDE = "alt";
|
|
||||||
private static final BigDecimal CIRCLE = new BigDecimal(360);
|
|
||||||
private static final BigDecimal FLAT = new BigDecimal(180);
|
|
||||||
private static final BigDecimal RIGHT = new BigDecimal(90);
|
|
||||||
public static final PointType EMPTY = new PointType(new DecimalType(0), new DecimalType(0));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor creates a point at sea level where the equator
|
|
||||||
* (0° latitude) and the prime meridian (0° longitude) intersect. (A
|
|
||||||
* nullary constructor is needed by
|
|
||||||
* {@link org.openhab.core.internal.items.ItemUpdater#receiveUpdate})
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("restriction")
|
|
||||||
public PointType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointType(DecimalType latitude, DecimalType longitude) {
|
|
||||||
canonicalize(latitude, longitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointType(DecimalType latitude, DecimalType longitude, DecimalType altitude) {
|
|
||||||
this(latitude, longitude);
|
|
||||||
setAltitude(altitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointType(StringType latitude, StringType longitude) {
|
|
||||||
this(new DecimalType(latitude.toString()), new DecimalType(longitude.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointType(StringType latitude, StringType longitude, StringType altitude) {
|
|
||||||
this(new DecimalType(latitude.toString()), new DecimalType(longitude.toString()),
|
|
||||||
new DecimalType(altitude.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointType(String value) {
|
|
||||||
if (StringUtils.isNotBlank(value)) {
|
|
||||||
String[] elements = value.split(",");
|
|
||||||
if (elements.length >= 2) {
|
|
||||||
canonicalize(new DecimalType(elements[0]), new DecimalType(elements[1]));
|
|
||||||
if (elements.length == 3) {
|
|
||||||
setAltitude(new DecimalType(elements[2]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(value + " is not a valid PointType syntax");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Constructor argument must not be blank");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType getLatitude() {
|
|
||||||
return new DecimalType(latitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType getLongitude() {
|
|
||||||
return new DecimalType(longitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType getAltitude() {
|
|
||||||
return new DecimalType(altitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAltitude(DecimalType altitude) {
|
|
||||||
this.altitude = altitude.toBigDecimal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecimalType getGravity() {
|
|
||||||
double latRad = Math.toRadians(latitude.doubleValue());
|
|
||||||
double deltaG = -2000.0 * (altitude.doubleValue() / 1000) * EARTH_GRAVITATIONAL_CONSTANT
|
|
||||||
/ (Math.pow(WGS84_A, 3.0));
|
|
||||||
double sin2lat = Math.sin(latRad) * Math.sin(latRad);
|
|
||||||
double sin22lat = Math.sin(2.0 * latRad) * Math.sin(2.0 * latRad);
|
|
||||||
double result = (9.780327 * (1.0 + 5.3024e-3 * sin2lat - 5.8e-6 * sin22lat) + deltaG);
|
|
||||||
return new DecimalType(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the distance in meters from otherPoint, ignoring altitude. This algorithm also
|
|
||||||
* ignores the oblate spheroid shape of Earth and assumes a perfect sphere, so results
|
|
||||||
* are inexact.
|
|
||||||
*
|
|
||||||
* @param otherPoint
|
|
||||||
* @return distance in meters
|
|
||||||
* @see <a href="https://en.wikipedia.org/wiki/Haversine_formula">Haversine formula</a>
|
|
||||||
*/
|
|
||||||
public DecimalType distanceFrom(PointType otherPoint) {
|
|
||||||
double dLat = Math.toRadians(otherPoint.latitude.doubleValue() - this.latitude.doubleValue());
|
|
||||||
double dLong = Math.toRadians(otherPoint.longitude.doubleValue() - this.longitude.doubleValue());
|
|
||||||
double a = Math.pow(Math.sin(dLat / 2D), 2D) + Math.cos(Math.toRadians(this.latitude.doubleValue()))
|
|
||||||
* Math.cos(Math.toRadians(otherPoint.latitude.doubleValue())) * Math.pow(Math.sin(dLong / 2D), 2D);
|
|
||||||
double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
|
|
||||||
return new DecimalType(WGS84_A * c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Formats the value of this type according to a pattern (@see
|
|
||||||
* {@link Formatter}). One single value of this type can be referenced by
|
|
||||||
* the pattern using an index. The item order is defined by the natural
|
|
||||||
* (alphabetical) order of their keys.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param pattern the pattern to use containing indexes to reference the single
|
|
||||||
* elements of this type.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, getConstituents().values().toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PointType valueOf(String value) {
|
|
||||||
return new PointType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder(latitude.toPlainString());
|
|
||||||
sb.append(',');
|
|
||||||
sb.append(longitude.toPlainString());
|
|
||||||
if (!altitude.equals(BigDecimal.ZERO)) {
|
|
||||||
sb.append(',');
|
|
||||||
sb.append(altitude.toPlainString());
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SortedMap<String, PrimitiveType> getConstituents() {
|
|
||||||
SortedMap<String, PrimitiveType> result = new TreeMap<>();
|
|
||||||
result.put(KEY_LATITUDE, getLatitude());
|
|
||||||
result.put(KEY_LONGITUDE, getLongitude());
|
|
||||||
result.put(KEY_ALTITUDE, getAltitude());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Canonicalize the current latitude and longitude values such that:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* -90 <= latitude <= +90 - 180 < longitude <= +180
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
private void canonicalize(DecimalType aLat, DecimalType aLon) {
|
|
||||||
latitude = FLAT.add(aLat.toBigDecimal()).remainder(CIRCLE);
|
|
||||||
longitude = aLon.toBigDecimal();
|
|
||||||
if (latitude.compareTo(BigDecimal.ZERO) == -1) {
|
|
||||||
latitude.add(CIRCLE);
|
|
||||||
}
|
|
||||||
latitude = latitude.subtract(FLAT);
|
|
||||||
if (latitude.compareTo(RIGHT) == 1) {
|
|
||||||
latitude = FLAT.subtract(latitude);
|
|
||||||
longitude = longitude.add(FLAT);
|
|
||||||
} else if (latitude.compareTo(RIGHT.negate()) == -1) {
|
|
||||||
latitude = FLAT.negate().subtract(latitude);
|
|
||||||
longitude = longitude.add(FLAT);
|
|
||||||
}
|
|
||||||
longitude = FLAT.add(longitude).remainder(CIRCLE);
|
|
||||||
if (longitude.compareTo(BigDecimal.ZERO) <= 0) {
|
|
||||||
longitude = longitude.add(CIRCLE);
|
|
||||||
}
|
|
||||||
longitude = longitude.subtract(FLAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int tmp = 10000 * (getLatitude() == null ? 0 : getLatitude().hashCode());
|
|
||||||
tmp += 100 * (getLongitude() == null ? 0 : getLongitude().hashCode());
|
|
||||||
tmp += (getAltitude() == null ? 0 : getAltitude().hashCode());
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof PointType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PointType other = (PointType) obj;
|
|
||||||
if ((getLatitude() != null && other.getLatitude() == null)
|
|
||||||
|| (getLatitude() == null && other.getLatitude() != null)
|
|
||||||
|| (getLongitude() != null && other.getLongitude() == null)
|
|
||||||
|| (getLongitude() == null && other.getLongitude() != null)
|
|
||||||
|| (getAltitude() != null && other.getAltitude() == null)
|
|
||||||
|| (getAltitude() == null && other.getAltitude() != null)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!getLatitude().equals(other.getLatitude()) || !getLongitude().equals(other.getLongitude())
|
|
||||||
|| !getAltitude().equals(other.getAltitude())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum StopMoveType implements PrimitiveType, Command {
|
|
||||||
STOP,
|
|
||||||
MOVE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class StringType implements PrimitiveType, State, Command {
|
|
||||||
|
|
||||||
public static final StringType EMPTY = new StringType("");
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
public StringType(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StringType valueOf(String value) {
|
|
||||||
return new StringType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return value.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj instanceof String) {
|
|
||||||
return obj.equals(value);
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
StringType other = (StringType) obj;
|
|
||||||
if (!value.equals(other.value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.library.types;
|
|
||||||
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum UpDownType implements PrimitiveType, State, Command {
|
|
||||||
UP,
|
|
||||||
DOWN;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,163 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is used to define a filter for queries to a {@link PersistenceService}.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* It is designed as a Java bean, for which the different properties are constraints
|
|
||||||
* on the query result. These properties include the item name, begin and end date and
|
|
||||||
* the item state. A compare operator can be defined to compare not only state equality,
|
|
||||||
* but also its decimal value (<,>).
|
|
||||||
* <p>
|
|
||||||
* <p>
|
|
||||||
* Additionally, the filter criteria supports ordering and paging of the result, so the
|
|
||||||
* caller can ask to only return chunks of the result of a certain size (=pageSize) from a
|
|
||||||
* starting index (pageNumber*pageSize).
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* All setter methods return the filter criteria instance, so that the methods can be
|
|
||||||
* easily chained in order to define a filter.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class FilterCriteria {
|
|
||||||
|
|
||||||
/** Enumeration with all possible compare options */
|
|
||||||
public enum Operator {
|
|
||||||
EQ("="),
|
|
||||||
NEQ("!="),
|
|
||||||
GT(">"),
|
|
||||||
LT("<"),
|
|
||||||
GTE(">="),
|
|
||||||
LTE("<=");
|
|
||||||
|
|
||||||
private final String symbol;
|
|
||||||
|
|
||||||
Operator(String symbol) {
|
|
||||||
this.symbol = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getSymbol() {
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Enumeration with all ordering options */
|
|
||||||
public enum Ordering {
|
|
||||||
ASCENDING,
|
|
||||||
DESCENDING
|
|
||||||
}
|
|
||||||
|
|
||||||
/** filter result to only contain entries for the given item */
|
|
||||||
private String itemName;
|
|
||||||
|
|
||||||
/** filter result to only contain entries that are newer than the given date */
|
|
||||||
private Date beginDate;
|
|
||||||
|
|
||||||
/** filter result to only contain entries that are older than the given date */
|
|
||||||
private Date endDate;
|
|
||||||
|
|
||||||
/** return the result list from starting index pageNumber*pageSize only */
|
|
||||||
private int pageNumber = 0;
|
|
||||||
|
|
||||||
/** return at most this many results */
|
|
||||||
private int pageSize = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
/** use this operator to compare the item state */
|
|
||||||
private Operator operator = Operator.EQ;
|
|
||||||
|
|
||||||
/** how to sort the result list by date */
|
|
||||||
private Ordering ordering = Ordering.DESCENDING;
|
|
||||||
|
|
||||||
/** filter result to only contain entries that evaluate to true with the given operator and state */
|
|
||||||
private State state;
|
|
||||||
|
|
||||||
public String getItemName() {
|
|
||||||
return itemName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getBeginDate() {
|
|
||||||
return beginDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getEndDate() {
|
|
||||||
return endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPageNumber() {
|
|
||||||
return pageNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPageSize() {
|
|
||||||
return pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Operator getOperator() {
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ordering getOrdering() {
|
|
||||||
return ordering;
|
|
||||||
}
|
|
||||||
|
|
||||||
public State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setItemName(String itemName) {
|
|
||||||
this.itemName = itemName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setBeginDate(Date beginDate) {
|
|
||||||
this.beginDate = beginDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setEndDate(Date endDate) {
|
|
||||||
this.endDate = endDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setPageNumber(int pageNumber) {
|
|
||||||
this.pageNumber = pageNumber;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setPageSize(int pageSize) {
|
|
||||||
this.pageSize = pageSize;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setOperator(Operator operator) {
|
|
||||||
this.operator = operator;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setOrdering(Ordering ordering) {
|
|
||||||
this.ordering = ordering;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterCriteria setState(State state) {
|
|
||||||
this.state = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface is used by persistence services to represent an item
|
|
||||||
* with a certain state at a given point in time.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Note that this interface does not extend {@link Item} as the persistence
|
|
||||||
* services could not provide an implementation that correctly implement
|
|
||||||
* getAcceptedXTypes() and getGroupNames().
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface HistoricItem {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the timestamp of the persisted item
|
|
||||||
*
|
|
||||||
* @return the timestamp of the item
|
|
||||||
*/
|
|
||||||
Date getTimestamp();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the current state of the item
|
|
||||||
*
|
|
||||||
* @return the current state
|
|
||||||
*/
|
|
||||||
public State getState();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the name of the item
|
|
||||||
*
|
|
||||||
* @return the name of the item
|
|
||||||
*/
|
|
||||||
public String getName();
|
|
||||||
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence;
|
|
||||||
|
|
||||||
import org.openhab.core.items.Item;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A persistence service which can be used to store data from openHAB.
|
|
||||||
* This must not necessarily be a local database, a persistence service
|
|
||||||
* can also be cloud-based or a simply data-export facility (e.g.
|
|
||||||
* for sending data to an IoT (Internet of Things) service.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface PersistenceService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of this {@link PersistenceService}.
|
|
||||||
* This name is used to uniquely identify the {@link PersistenceService}.
|
|
||||||
*
|
|
||||||
* @return the name to uniquely identify the {@link PersistenceService}.
|
|
||||||
*/
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the current value of the given item.
|
|
||||||
* <p>
|
|
||||||
* Implementors should keep in mind that all registered
|
|
||||||
* {@link PersistenceService}s are called synchronously. Hence long running
|
|
||||||
* operations should be processed asynchronously. E.g. <code>store</code>
|
|
||||||
* adds things to a queue which is processed by some asynchronous workers
|
|
||||||
* (Quartz Job, Thread, etc.).
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param item the item which state should be persisted.
|
|
||||||
*/
|
|
||||||
void store(Item item);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Stores the current value of the given item under a specified alias.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Implementors should keep in mind that all registered
|
|
||||||
* {@link PersistenceService}s are called synchronously. Hence long running
|
|
||||||
* operations should be processed asynchronously. E.g. <code>store</code>
|
|
||||||
* adds things to a queue which is processed by some asynchronous workers
|
|
||||||
* (Quartz Job, Thread, etc.).
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param item the item which state should be persisted.
|
|
||||||
* @param alias the alias under which the item should be persisted.
|
|
||||||
*/
|
|
||||||
void store(Item item, String alias);
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A queryable persistence service which can be used to store and retrieve
|
|
||||||
* data from openHAB. This is most likely some kind of database system.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface QueryablePersistenceService extends PersistenceService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the {@link PersistenceService} for data with a given filter criteria
|
|
||||||
*
|
|
||||||
* @param filter the filter to apply to the query
|
|
||||||
* @return a time series of items
|
|
||||||
*/
|
|
||||||
Iterable<HistoricItem> query(FilterCriteria filter);
|
|
||||||
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence.internal;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.items.Item;
|
|
||||||
import org.eclipse.smarthome.core.persistence.PersistenceService;
|
|
||||||
import org.openhab.core.compat1x.internal.ItemMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome
|
|
||||||
* namespace for the persistence service. It wraps an instance with the old interface
|
|
||||||
* into a class with the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
* @author Chris Jackson - updated API to support getId/getLabel
|
|
||||||
*/
|
|
||||||
public class PersistenceServiceDelegate implements PersistenceService {
|
|
||||||
|
|
||||||
protected org.openhab.core.persistence.PersistenceService service;
|
|
||||||
|
|
||||||
public PersistenceServiceDelegate(org.openhab.core.persistence.PersistenceService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return service.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel(Locale locale) {
|
|
||||||
return service.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void store(Item item) {
|
|
||||||
org.openhab.core.items.Item ohItem = ItemMapper.mapToOpenHABItem(item);
|
|
||||||
if (ohItem != null) {
|
|
||||||
service.store(ohItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void store(Item item, String alias) {
|
|
||||||
org.openhab.core.items.Item ohItem = ItemMapper.mapToOpenHABItem(item);
|
|
||||||
if (ohItem != null) {
|
|
||||||
service.store(ohItem, alias);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence.internal;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.openhab.core.persistence.PersistenceService;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.ServiceRegistration;
|
|
||||||
import org.osgi.service.component.annotations.Activate;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Deactivate;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
|
||||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class listens for services that implement the old persistence service interface and registers
|
|
||||||
* an according service for each under the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component(immediate = true)
|
|
||||||
public class PersistenceServiceFactory {
|
|
||||||
|
|
||||||
private Map<String, ServiceRegistration<org.eclipse.smarthome.core.persistence.PersistenceService>> delegates = new HashMap<>();
|
|
||||||
private BundleContext context;
|
|
||||||
|
|
||||||
private Set<PersistenceService> persistenceServices = new HashSet<>();
|
|
||||||
|
|
||||||
@Activate
|
|
||||||
public void activate(BundleContext context) {
|
|
||||||
this.context = context;
|
|
||||||
for (PersistenceService service : persistenceServices) {
|
|
||||||
registerDelegateService(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deactivate
|
|
||||||
public void deactivate() {
|
|
||||||
for (ServiceRegistration<org.eclipse.smarthome.core.persistence.PersistenceService> serviceReg : delegates
|
|
||||||
.values()) {
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
delegates.clear();
|
|
||||||
this.context = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
|
||||||
public void addPersistenceService(PersistenceService service) {
|
|
||||||
if (context != null) {
|
|
||||||
registerDelegateService(service);
|
|
||||||
} else {
|
|
||||||
persistenceServices.add(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePersistenceService(PersistenceService service) {
|
|
||||||
if (context != null) {
|
|
||||||
unregisterDelegateService(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerDelegateService(PersistenceService persistenceService) {
|
|
||||||
if (!delegates.containsKey(persistenceService.getName())) {
|
|
||||||
org.eclipse.smarthome.core.persistence.PersistenceService service = (persistenceService instanceof org.openhab.core.persistence.QueryablePersistenceService)
|
|
||||||
? new QueryablePersistenceServiceDelegate(persistenceService)
|
|
||||||
: new PersistenceServiceDelegate(persistenceService);
|
|
||||||
Dictionary<String, Object> props = new Hashtable<>();
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.core.persistence.PersistenceService> serviceReg = context
|
|
||||||
.registerService(org.eclipse.smarthome.core.persistence.PersistenceService.class, service, props);
|
|
||||||
delegates.put(persistenceService.getName(), serviceReg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterDelegateService(PersistenceService service) {
|
|
||||||
if (delegates.containsKey(service.getName())) {
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.core.persistence.PersistenceService> serviceReg = delegates
|
|
||||||
.get(service.getName());
|
|
||||||
delegates.remove(service.getName());
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.persistence.internal;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.core.persistence.FilterCriteria;
|
|
||||||
import org.eclipse.smarthome.core.persistence.HistoricItem;
|
|
||||||
import org.eclipse.smarthome.core.persistence.PersistenceItemInfo;
|
|
||||||
import org.eclipse.smarthome.core.persistence.QueryablePersistenceService;
|
|
||||||
import org.eclipse.smarthome.core.types.State;
|
|
||||||
import org.openhab.core.compat1x.internal.TypeMapper;
|
|
||||||
import org.openhab.core.persistence.FilterCriteria.Operator;
|
|
||||||
import org.openhab.core.persistence.FilterCriteria.Ordering;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome
|
|
||||||
* namespace for the queryable persistence service. It wraps an instance with the old interface
|
|
||||||
* into a class with the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class QueryablePersistenceServiceDelegate extends PersistenceServiceDelegate
|
|
||||||
implements QueryablePersistenceService {
|
|
||||||
|
|
||||||
public QueryablePersistenceServiceDelegate(org.openhab.core.persistence.PersistenceService persistenceService) {
|
|
||||||
super(persistenceService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
|
||||||
org.openhab.core.persistence.FilterCriteria mappedFilter = new org.openhab.core.persistence.FilterCriteria()
|
|
||||||
.setBeginDate(filter.getBeginDate()).setEndDate(filter.getEndDate()).setItemName(filter.getItemName())
|
|
||||||
.setOperator(mapOperator(filter.getOperator())).setOrdering(mapOrdering(filter.getOrdering()))
|
|
||||||
.setPageNumber(filter.getPageNumber()).setPageSize(filter.getPageSize())
|
|
||||||
.setState(mapState(filter.getState()));
|
|
||||||
org.openhab.core.persistence.QueryablePersistenceService pService = (org.openhab.core.persistence.QueryablePersistenceService) service;
|
|
||||||
Iterable<org.openhab.core.persistence.HistoricItem> historicItems = pService.query(mappedFilter);
|
|
||||||
List<HistoricItem> result = new ArrayList<>();
|
|
||||||
if (historicItems != null) {
|
|
||||||
for (final org.openhab.core.persistence.HistoricItem item : historicItems) {
|
|
||||||
result.add(new HistoricItem() {
|
|
||||||
@Override
|
|
||||||
public Date getTimestamp() {
|
|
||||||
return item.getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getState() {
|
|
||||||
return (State) TypeMapper.mapToESHType(item.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return item.getName();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.openhab.core.types.State mapState(State state) {
|
|
||||||
return (org.openhab.core.types.State) TypeMapper.mapToOpenHABType(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Ordering mapOrdering(FilterCriteria.Ordering ordering) {
|
|
||||||
if (ordering == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return org.openhab.core.persistence.FilterCriteria.Ordering.valueOf(ordering.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Operator mapOperator(FilterCriteria.Operator operator) {
|
|
||||||
if (operator == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return org.openhab.core.persistence.FilterCriteria.Operator.valueOf(operator.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<PersistenceItemInfo> getItemInfo() {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.scriptengine.action;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@Inherited
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface ActionDoc {
|
|
||||||
String text();
|
|
||||||
|
|
||||||
String returns() default "";
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.scriptengine.action;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface must be implemented by services that want to contribute script actions.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ActionService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the FQCN of the action class.
|
|
||||||
*
|
|
||||||
* @return the FQCN of the action class
|
|
||||||
*/
|
|
||||||
String getActionClassName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the action class itself
|
|
||||||
*
|
|
||||||
* @return the action class
|
|
||||||
*/
|
|
||||||
Class<?> getActionClass();
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.scriptengine.action;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Target(ElementType.PARAMETER)
|
|
||||||
@Inherited
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface ParamDoc {
|
|
||||||
String name();
|
|
||||||
|
|
||||||
String text() default "";
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.scriptengine.action.internal;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.model.script.engine.action.ActionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome
|
|
||||||
* namespace for the action service. It wraps an instance with the old interface
|
|
||||||
* into a class with the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ActionServiceDelegate implements ActionService {
|
|
||||||
|
|
||||||
private org.openhab.core.scriptengine.action.ActionService service;
|
|
||||||
|
|
||||||
public ActionServiceDelegate(org.openhab.core.scriptengine.action.ActionService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getActionClassName() {
|
|
||||||
return service.getActionClassName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getActionClass() {
|
|
||||||
return service.getActionClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.scriptengine.action.internal;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.openhab.core.scriptengine.action.ActionService;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.ServiceRegistration;
|
|
||||||
import org.osgi.service.component.annotations.Activate;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
import org.osgi.service.component.annotations.Deactivate;
|
|
||||||
import org.osgi.service.component.annotations.Reference;
|
|
||||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
|
||||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class listens for services that implement the old action service interface and registers
|
|
||||||
* an according service for each under the new interface.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class ActionServiceFactory {
|
|
||||||
|
|
||||||
private Map<String, ServiceRegistration<org.eclipse.smarthome.model.script.engine.action.ActionService>> delegates = new HashMap<>();
|
|
||||||
private BundleContext context;
|
|
||||||
|
|
||||||
private Set<ActionService> actionServices = new HashSet<>();
|
|
||||||
|
|
||||||
@Activate
|
|
||||||
public void activate(BundleContext context) {
|
|
||||||
this.context = context;
|
|
||||||
for (ActionService service : actionServices) {
|
|
||||||
registerDelegateService(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deactivate
|
|
||||||
public void deactivate() {
|
|
||||||
for (ServiceRegistration<org.eclipse.smarthome.model.script.engine.action.ActionService> serviceReg : delegates
|
|
||||||
.values()) {
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
delegates.clear();
|
|
||||||
this.context = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
|
||||||
public void addActionService(ActionService service) {
|
|
||||||
if (context != null) {
|
|
||||||
registerDelegateService(service);
|
|
||||||
} else {
|
|
||||||
actionServices.add(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeActionService(ActionService service) {
|
|
||||||
if (context != null) {
|
|
||||||
unregisterDelegateService(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerDelegateService(ActionService actionService) {
|
|
||||||
if (!delegates.containsKey(actionService.getActionClassName())) {
|
|
||||||
ActionServiceDelegate service = new ActionServiceDelegate(actionService);
|
|
||||||
Dictionary<String, Object> props = new Hashtable<>();
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.model.script.engine.action.ActionService> serviceReg = context
|
|
||||||
.registerService(org.eclipse.smarthome.model.script.engine.action.ActionService.class, service,
|
|
||||||
props);
|
|
||||||
delegates.put(actionService.getActionClassName(), serviceReg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterDelegateService(ActionService service) {
|
|
||||||
if (delegates.containsKey(service.getActionClassName())) {
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.model.script.engine.action.ActionService> serviceReg = delegates
|
|
||||||
.get(service.getActionClassName());
|
|
||||||
delegates.remove(service.getActionClassName());
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,196 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.service;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for services that frequently run some action in a separate thread in the
|
|
||||||
* background.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class AbstractActiveService {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(AbstractActiveService.class);
|
|
||||||
|
|
||||||
/** <code>true</code> if this binding is configured properly which means that all necessary data is available */
|
|
||||||
private boolean properlyConfigured = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* indicates that the background thread will shutdown after the current
|
|
||||||
* execution cycle.
|
|
||||||
*/
|
|
||||||
protected boolean shutdown = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* holds the instance of the refresh thread or is <code>null</code> if
|
|
||||||
* there is no thread active at the moment
|
|
||||||
*/
|
|
||||||
private Thread refreshThread;
|
|
||||||
|
|
||||||
public AbstractActiveService() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void activate() {
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deactivate() {
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes care about starting the refresh thread. It creates a new
|
|
||||||
* RefreshThread if no instance exists.
|
|
||||||
*/
|
|
||||||
protected void start() {
|
|
||||||
if (!isProperlyConfigured()) {
|
|
||||||
logger.trace("{} won't be started because it isn't yet properly configured.", getName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
shutdown = false;
|
|
||||||
if (!isRunning()) {
|
|
||||||
this.refreshThread = new RefreshThread(getName(), getRefreshInterval());
|
|
||||||
this.refreshThread.start();
|
|
||||||
} else {
|
|
||||||
logger.trace("{} is already started > calling start() changed nothing.", getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gracefully shuts down the refresh background thread. It will shuts down
|
|
||||||
* after the current execution cycle.
|
|
||||||
*/
|
|
||||||
public void shutdown() {
|
|
||||||
this.shutdown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interrupts the refresh thread immediately.
|
|
||||||
*/
|
|
||||||
public void interrupt() {
|
|
||||||
if (isRunning()) {
|
|
||||||
this.refreshThread.interrupt();
|
|
||||||
logger.trace("{} has been interrupted.", getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRunning() {
|
|
||||||
if (this.refreshThread != null) {
|
|
||||||
return this.refreshThread.isAlive();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if this binding is configured properly which means
|
|
||||||
* that all necessary data is available
|
|
||||||
*/
|
|
||||||
public final boolean isProperlyConfigured() {
|
|
||||||
return properlyConfigured;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to define whether this binding is fully configured so that it can be
|
|
||||||
* activated and used.
|
|
||||||
* Note that the implementation will automatically start the active service if
|
|
||||||
* <code>true</code> is passed as a parameter.
|
|
||||||
*
|
|
||||||
* @param properlyConfigured
|
|
||||||
*/
|
|
||||||
public void setProperlyConfigured(boolean properlyConfigured) {
|
|
||||||
this.properlyConfigured = properlyConfigured;
|
|
||||||
if (properlyConfigured && !isRunning()) {
|
|
||||||
start();
|
|
||||||
} else if (!properlyConfigured && isRunning()) {
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The working method which is called by the refresh thread frequently.
|
|
||||||
* Developers should put their binding code here.
|
|
||||||
*/
|
|
||||||
protected abstract void execute();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the refresh interval to be used by the RefreshThread between to
|
|
||||||
* calls of the execute method.
|
|
||||||
*
|
|
||||||
* @return the refresh interval
|
|
||||||
*/
|
|
||||||
protected abstract long getRefreshInterval();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the Refresh thread.
|
|
||||||
*
|
|
||||||
* @return the name of the refresh thread.
|
|
||||||
*/
|
|
||||||
protected abstract String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Worker thread which calls the execute method frequently.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
class RefreshThread extends Thread {
|
|
||||||
|
|
||||||
private long refreshInterval;
|
|
||||||
|
|
||||||
public RefreshThread(String name, long refreshInterval) {
|
|
||||||
super(name);
|
|
||||||
this.setDaemon(true);
|
|
||||||
this.refreshInterval = refreshInterval;
|
|
||||||
|
|
||||||
// reset 'interrupted' after stopping this refresh thread ...
|
|
||||||
shutdown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
logger.info("{} has been started", getName());
|
|
||||||
|
|
||||||
while (!shutdown) {
|
|
||||||
try {
|
|
||||||
execute();
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
logger.error("Error while executing background thread {}", getName(), e);
|
|
||||||
}
|
|
||||||
pause(refreshInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshThread = null;
|
|
||||||
logger.info("{} has been shut down", getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pause polling for the given <code>refreshInterval</code>. Possible
|
|
||||||
* {@link InterruptedException} is logged with no further action.
|
|
||||||
*
|
|
||||||
* @param refreshInterval
|
|
||||||
*/
|
|
||||||
protected void pause(long refreshInterval) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(refreshInterval);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.debug("pausing thread {} interrupted", super.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.transform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A TransformationException is thrown when any step of a transformation went
|
|
||||||
* wrong. The originating exception should be attached to increase traceability.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
public class TransformationException extends Exception {
|
|
||||||
|
|
||||||
/** generated serial Version UID */
|
|
||||||
private static final long serialVersionUID = -535237375844795145L;
|
|
||||||
|
|
||||||
public TransformationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformationException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.transform;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.InvalidSyntaxException;
|
|
||||||
import org.osgi.framework.ServiceReference;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class TransformationHelper {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TransformationHelper.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the OSGi service registry for a service that provides a transformation service of
|
|
||||||
* a given transformation type (e.g. REGEX, XSLT, etc.)
|
|
||||||
*
|
|
||||||
* @param transformationType the desired transformation type
|
|
||||||
* @return a service instance or null, if none could be found
|
|
||||||
*/
|
|
||||||
public static TransformationService getTransformationService(BundleContext context, String transformationType) {
|
|
||||||
if (context != null) {
|
|
||||||
String filter = "(smarthome.transform=" + transformationType + ")";
|
|
||||||
try {
|
|
||||||
Collection<ServiceReference<org.eclipse.smarthome.core.transform.TransformationService>> refs = context
|
|
||||||
.getServiceReferences(org.eclipse.smarthome.core.transform.TransformationService.class, filter);
|
|
||||||
if (refs != null && !refs.isEmpty()) {
|
|
||||||
return new TransformationServiceDelegate(context.getService(refs.iterator().next()));
|
|
||||||
} else {
|
|
||||||
LOGGER.warn("Cannot get service reference for transformation service of type {}",
|
|
||||||
transformationType);
|
|
||||||
}
|
|
||||||
} catch (InvalidSyntaxException e) {
|
|
||||||
LOGGER.warn("Cannot get service reference for transformation service of type {}", transformationType,
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TransformationServiceDelegate implements TransformationService {
|
|
||||||
|
|
||||||
org.eclipse.smarthome.core.transform.TransformationService delegate;
|
|
||||||
|
|
||||||
public TransformationServiceDelegate(org.eclipse.smarthome.core.transform.TransformationService delegate) {
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String transform(String function, String source) throws TransformationException {
|
|
||||||
try {
|
|
||||||
return delegate.transform(function, source);
|
|
||||||
} catch (org.eclipse.smarthome.core.transform.TransformationException e) {
|
|
||||||
throw new TransformationException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.transform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A TransformationProcessor transforms a given input and returns the transformed
|
|
||||||
* result. Transformations could make sense in various situations, for example:
|
|
||||||
* <ul>
|
|
||||||
* <li>extract certain informations from a weather forecast website</li>
|
|
||||||
* <li>extract the status of your TV which provides it's status on a webpage</li>
|
|
||||||
* <li>postprocess the output from a serial device to be human readable</li>
|
|
||||||
* </ul>
|
|
||||||
* One could provide his own processors by providing a new implementation of this
|
|
||||||
* Interface.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface TransformationService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms the input <code>source</code> by means of the given <code>function</code>
|
|
||||||
* and returns the transformed output. If the transformation couldn't be completed
|
|
||||||
* for any reason, one should return the unchanged <code>source</code>. This
|
|
||||||
* method should never return <code>null</code>. In case of any error an
|
|
||||||
* {@link TransformationException} should be thrown.
|
|
||||||
*
|
|
||||||
* @param function the function to be used to transform the input
|
|
||||||
* @param source the input to be transformed
|
|
||||||
* @return the transformed result or the unchanged <code>source</code> if the
|
|
||||||
* transformation couldn't be completed for any reason.
|
|
||||||
* @throws TransformationException if any error occurs
|
|
||||||
*/
|
|
||||||
String transform(String function, String source) throws TransformationException;
|
|
||||||
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.transform.actions;
|
|
||||||
|
|
||||||
import org.openhab.core.compat1x.internal.CompatibilityActivator;
|
|
||||||
import org.openhab.core.transform.TransformationException;
|
|
||||||
import org.openhab.core.transform.TransformationHelper;
|
|
||||||
import org.openhab.core.transform.TransformationService;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class holds static "action" methods that can be used from within rules to execute
|
|
||||||
* transformations.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class Transformation {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Transformation.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies a transformation of a given type with some function to a value.
|
|
||||||
*
|
|
||||||
* @param type the transformation type, e.g. REGEX or MAP
|
|
||||||
* @param function the function to call, this value depends on the transformation type
|
|
||||||
* @param value the value to apply the transformation to
|
|
||||||
* @return the transformed value or the original one, if there was no service registered for the
|
|
||||||
* given type or a transformation exception occurred.
|
|
||||||
*/
|
|
||||||
public static String transform(String type, String function, String value) {
|
|
||||||
String result;
|
|
||||||
TransformationService service = TransformationHelper
|
|
||||||
.getTransformationService(CompatibilityActivator.getContext(), type);
|
|
||||||
if (service != null) {
|
|
||||||
try {
|
|
||||||
result = service.transform(function, value);
|
|
||||||
} catch (TransformationException e) {
|
|
||||||
LOGGER.error("Error executing the transformation '{}': {}", type, e.getMessage());
|
|
||||||
result = value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGGER.warn("No transformation service '{}' could be found.", type);
|
|
||||||
result = value;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a marker interface for all command types.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface Command extends Type {
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
import java.util.SortedMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A complex type consists out of a sorted list of primitive constituents.
|
|
||||||
* Each constituent can be referred to by a unique name.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface ComplexType extends Type {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all constituents with their names as a sorted map
|
|
||||||
*
|
|
||||||
* @return all constituents with their names
|
|
||||||
*/
|
|
||||||
public SortedMap<String, PrimitiveType> getConstituents();
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Due to the duality of some types (which can be states and commands at the
|
|
||||||
* same time), we need to be able to differentiate what the meaning of a
|
|
||||||
* message on the bus is - does "item ON" mean that its state has changed to
|
|
||||||
* ON or that it should turn itself ON? To decide this, we send the event
|
|
||||||
* type as an additional information on the event bus for each message.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum EventType {
|
|
||||||
COMMAND,
|
|
||||||
UPDATE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch (this) {
|
|
||||||
case COMMAND:
|
|
||||||
return "command";
|
|
||||||
case UPDATE:
|
|
||||||
return "update";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A primitive type consists of a single value like a string, a number, etc.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface PrimitiveType extends Type {
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a marker interface for all state types.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface State extends Type {
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
import java.util.Formatter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a parent interface for all states and commands.
|
|
||||||
* It was introduced as many states can be commands at the same time and
|
|
||||||
* vice versa. E.g a light can have the state ON or OFF and one can
|
|
||||||
* also send ON and OFF as commands to the device. This duality is
|
|
||||||
* captured by this marker interface and allows implementing classes
|
|
||||||
* to be both state and command at the same time.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface Type {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the value of this type according to a pattern (see {@link Formatter}).
|
|
||||||
*
|
|
||||||
* @param pattern the pattern to use
|
|
||||||
* @return the formatted string
|
|
||||||
*/
|
|
||||||
public String format(String pattern);
|
|
||||||
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a helper class that helps parsing a string into an openHAB type (state or command).
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class TypeParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Determines a state from a string. Possible state types are passed as a parameter.
|
|
||||||
* Note that the order matters here; the first type that accepts the string as a valid
|
|
||||||
* value, will be used for the state.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Example: The type list is OnOffType.class,StringType.class. The string "ON" is now
|
|
||||||
* accepted by the OnOffType and thus OnOffType.ON will be returned (and not a StringType
|
|
||||||
* with value "ON").
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param types possible types of the state to consider
|
|
||||||
* @param s the string to parse
|
|
||||||
* @return the corresponding State instance or <code>null</code>
|
|
||||||
*/
|
|
||||||
public static State parseState(List<Class<? extends State>> types, String s) {
|
|
||||||
for (Class<? extends Type> type : types) {
|
|
||||||
try {
|
|
||||||
Method valueOf = type.getMethod("valueOf", String.class);
|
|
||||||
State state = (State) valueOf.invoke(type, s);
|
|
||||||
if (state != null) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Determines a command from a string. Possible command types are passed as a parameter.
|
|
||||||
* Note that the order matters here; the first type that accepts the string as a valid
|
|
||||||
* value, will be used for the command.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Example: The type list is OnOffType.class,StringType.class. The string "ON" is now
|
|
||||||
* accepted by the OnOffType and thus OnOffType.ON will be returned (and not a StringType
|
|
||||||
* with value "ON").
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param types possible types of the command to consider
|
|
||||||
* @param s the string to parse
|
|
||||||
* @return the corresponding Command instance or <code>null</code>
|
|
||||||
*/
|
|
||||||
public static Command parseCommand(List<Class<? extends Command>> types, String s) {
|
|
||||||
if (s != null) {
|
|
||||||
for (Class<? extends Command> type : types) {
|
|
||||||
try {
|
|
||||||
Method valueOf = type.getMethod("valueOf", String.class);
|
|
||||||
Command value = (Command) valueOf.invoke(type, s);
|
|
||||||
if (value != null) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.core.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* There are situations when item states do not have any defined value.
|
|
||||||
* This might be because they have not been initialized yet (never
|
|
||||||
* received an state update so far) or because their state is ambiguous
|
|
||||||
* (e.g. a dimmed light that is treated as a switch (ON/OFF) will have
|
|
||||||
* an undefined state if it is dimmed to 50%).
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public enum UnDefType implements PrimitiveType, State {
|
|
||||||
UNDEF,
|
|
||||||
NULL;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch (this) {
|
|
||||||
case UNDEF:
|
|
||||||
return "Undefined";
|
|
||||||
case NULL:
|
|
||||||
return "Uninitialized";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.console;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface must be implemented by consoles which want to use the
|
|
||||||
* {@link ConsoleInterpreter}.
|
|
||||||
* It allows basic output commands.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface Console {
|
|
||||||
|
|
||||||
public void print(String s);
|
|
||||||
|
|
||||||
public void println(String s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* usage output is treated differently from other output as it might
|
|
||||||
* differ between different kinds of consoles
|
|
||||||
*
|
|
||||||
* @param s the main usage string (console independent)
|
|
||||||
*/
|
|
||||||
public void printUsage(String s);
|
|
||||||
}
|
|
@ -1,124 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.console;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides generic methods for handling console input (i.e. pure strings).
|
|
||||||
*
|
|
||||||
* NOTE: This class is only kept for backward compatibility so that openHAB 1 Add-ons still compile.
|
|
||||||
* It must not be used productively!
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class ConsoleInterpreter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method simply takes a list of arguments, where the first one is treated
|
|
||||||
* as the console command (such as "update", "send" etc.). The following entries
|
|
||||||
* are then the arguments for this command.
|
|
||||||
* If the command is unknown, the complete usage is printed to the console.
|
|
||||||
*
|
|
||||||
* @param args array which contains the console command and all its arguments
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleRequest(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method handles an update command.
|
|
||||||
*
|
|
||||||
* @param args array which contains the arguments for the update command
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleUpdate(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method handles a send command.
|
|
||||||
*
|
|
||||||
* @param args array which contains the arguments for the send command
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleSend(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method handles an items command.
|
|
||||||
*
|
|
||||||
* @param args array which contains the arguments for the items command
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleItems(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method handles a status command.
|
|
||||||
*
|
|
||||||
* @param args array which contains the arguments for the status command
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleStatus(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method handles a say command.
|
|
||||||
*
|
|
||||||
* @param args array which contains the arguments for the status command
|
|
||||||
* @param console the console for printing messages for the user
|
|
||||||
*/
|
|
||||||
public static void handleSay(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handleScript(String[] args, Console console) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns a CR-separated list of usage texts for all available commands */
|
|
||||||
private static String getUsage() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (String usage : ConsoleInterpreter.getUsages()) {
|
|
||||||
sb.append(usage + "\n");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns an array of the usage texts for all available commands */
|
|
||||||
public static String[] getUsages() {
|
|
||||||
return new String[] { getUpdateUsage(), getCommandUsage(), getStatusUsage(), getItemsUsage(), getSayUsage(),
|
|
||||||
getScriptUsage() };
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getUpdateUsage() {
|
|
||||||
return "update <item> <state> - sends a status update for an item";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCommandUsage() {
|
|
||||||
return "send <item> <command> - sends a command for an item";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getStatusUsage() {
|
|
||||||
return "status <item> - shows the current status of an item";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getItemsUsage() {
|
|
||||||
return "items [<pattern>] - lists names and types of all items matching the pattern";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSayUsage() {
|
|
||||||
return "say <sentence to say> - Says a message through TTS on the host machine";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getScriptUsage() {
|
|
||||||
return "> <script to execute> - Executes a script";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.multimedia.tts;
|
|
||||||
|
|
||||||
// NOTE: This interface is only kept in order to allow openHAB 1.x TTS services to correctly compile.
|
|
||||||
// openHAB 2 is NOT compatible with these services, not even through the compatibility layer.
|
|
||||||
// Instead, ESH/openHAB2 compatible TTS services should be used.
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface TTSService {
|
|
||||||
|
|
||||||
void say(String text, String voiceName, String outputDevice);
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.actions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.openhab.core.scriptengine.action.ActionDoc;
|
|
||||||
import org.openhab.core.scriptengine.action.ParamDoc;
|
|
||||||
import org.openhab.io.net.exec.ExecUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides static methods that can be used in automation rules for
|
|
||||||
* executing commands on command line.
|
|
||||||
*
|
|
||||||
* @author Pauli Anttila - Initial contribution
|
|
||||||
*/
|
|
||||||
public class Exec {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Executes <code>commandLine</code>. Sometimes (especially observed on
|
|
||||||
* MacOS) the commandLine isn't executed properly. In that cases another
|
|
||||||
* exec-method is to be used. To accomplish this please use the special
|
|
||||||
* delimiter '<code>@@</code>'. If <code>commandLine</code> contains this
|
|
||||||
* delimiter it is split into a String[] array and the special exec-method
|
|
||||||
* is used.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* A possible {@link IOException} gets logged but no further processing is
|
|
||||||
* done.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param commandLine the command line to execute
|
|
||||||
* @see http://www.peterfriese.de/running-applescript-from-java/
|
|
||||||
*/
|
|
||||||
@ActionDoc(text = "Executes <code>commandLine</code>.")
|
|
||||||
public static void executeCommandLine(@ParamDoc(name = "commandLine") String commandLine) {
|
|
||||||
ExecUtil.executeCommandLine(commandLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Executes <code>commandLine</code>. Sometimes (especially observed on
|
|
||||||
* MacOS) the commandLine isn't executed properly. In that cases another
|
|
||||||
* exec-method is to be used. To accomplish this please use the special
|
|
||||||
* delimiter '<code>@@</code>'. If <code>commandLine</code> contains this
|
|
||||||
* delimiter it is split into a String[] array and the special exec-method
|
|
||||||
* is used.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* A possible {@link IOException} gets logged but no further processing is
|
|
||||||
* done.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param commandLine the command line to execute
|
|
||||||
* @param timeout timeout for execution in milliseconds
|
|
||||||
* @return response data from executed command line
|
|
||||||
*/
|
|
||||||
@ActionDoc(text = "Executes <code>commandLine</code>.")
|
|
||||||
public static String executeCommandLine(@ParamDoc(name = "commandLine") String commandLine,
|
|
||||||
@ParamDoc(name = "timeout", text = "timeout for execution in milliseconds") int timeout) {
|
|
||||||
return ExecUtil.executeCommandLineAndWaitResponse(commandLine, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.actions;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.openhab.io.net.http.HttpUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides static methods that can be used in automation rules
|
|
||||||
* for sending HTTP requests
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class HTTP {
|
|
||||||
|
|
||||||
/** Constant which represents the content type <code>application/json</code> */
|
|
||||||
public static final String CONTENT_TYPE_JSON = "application/json";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a GET-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the GET request.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpGetRequest(String url) {
|
|
||||||
return HttpUtil.executeUrl("GET", url, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the PUT request.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpPutRequest(String url) {
|
|
||||||
return HttpUtil.executeUrl("PUT", url, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a PUT-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the PUT request.
|
|
||||||
* @param contentType the content type of the given <code>content</code>
|
|
||||||
* @param content the content to be send to the given <code>url</code> or
|
|
||||||
* <code>null</code> if no content should be send.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpPutRequest(String url, String contentType, String content) {
|
|
||||||
return HttpUtil.executeUrl("PUT", url, IOUtils.toInputStream(content), contentType, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the POST request.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpPostRequest(String url) {
|
|
||||||
return HttpUtil.executeUrl("POST", url, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a POST-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the POST request.
|
|
||||||
* @param contentType the content type of the given <code>content</code>
|
|
||||||
* @param content the content to be send to the given <code>url</code> or
|
|
||||||
* <code>null</code> if no content should be send.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpPostRequest(String url, String contentType, String content) {
|
|
||||||
return HttpUtil.executeUrl("POST", url, IOUtils.toInputStream(content), contentType, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send out a DELETE-HTTP request. Errors will be logged, returned values just ignored.
|
|
||||||
*
|
|
||||||
* @param url the URL to be used for the DELETE request.
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String sendHttpDeleteRequest(String url) {
|
|
||||||
return HttpUtil.executeUrl("DELETE", url, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.actions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This Action checks the vitality of the given host.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
public class Ping {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the vitality of <code>host</code>. If <code>port</code> '0'
|
|
||||||
* is specified (which is the default when configuring just the host), a
|
|
||||||
* regular ping is issued. If other ports are specified we try open a new
|
|
||||||
* Socket with the given <code>timeout</code>.
|
|
||||||
*
|
|
||||||
* @param host
|
|
||||||
* @param port
|
|
||||||
* @param timeout
|
|
||||||
* @return <code>true</code> when <code>host</code> is reachable on <code>port</code>
|
|
||||||
* within the given <code>timeout</code> and <code>false</code> in all other
|
|
||||||
* cases.
|
|
||||||
* @throws IOException
|
|
||||||
* @throws SocketTimeoutException
|
|
||||||
*/
|
|
||||||
public static boolean checkVitality(String host, int port, int timeout) throws IOException, SocketTimeoutException {
|
|
||||||
boolean success = false;
|
|
||||||
|
|
||||||
if (host != null && timeout > 0) {
|
|
||||||
if (port == 0) {
|
|
||||||
success = InetAddress.getByName(host).isReachable(timeout);
|
|
||||||
} else {
|
|
||||||
SocketAddress socketAddress = new InetSocketAddress(host, port);
|
|
||||||
|
|
||||||
try (Socket socket = new Socket()) {
|
|
||||||
socket.connect(socketAddress, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.exec;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.apache.commons.exec.CommandLine;
|
|
||||||
import org.apache.commons.exec.DefaultExecuteResultHandler;
|
|
||||||
import org.apache.commons.exec.DefaultExecutor;
|
|
||||||
import org.apache.commons.exec.ExecuteWatchdog;
|
|
||||||
import org.apache.commons.exec.Executor;
|
|
||||||
import org.apache.commons.exec.PumpStreamHandler;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some common methods to execute commands on command line.
|
|
||||||
*
|
|
||||||
* @author Pauli Anttila - Initial contribution
|
|
||||||
* @author Kai Kreuzer - added exception logging
|
|
||||||
*/
|
|
||||||
public class ExecUtil {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExecUtil.class);
|
|
||||||
|
|
||||||
private static final String CMD_LINE_DELIMITER = "@@";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Executes <code>commandLine</code>. Sometimes (especially observed on
|
|
||||||
* MacOS) the commandLine isn't executed properly. In that cases another
|
|
||||||
* exec-method is to be used. To accomplish this please use the special
|
|
||||||
* delimiter '<code>@@</code>'. If <code>commandLine</code> contains this
|
|
||||||
* delimiter it is split into a String[] array and the special exec-method
|
|
||||||
* is used.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* A possible {@link IOException} gets logged but no further processing is
|
|
||||||
* done.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param commandLine the command line to execute
|
|
||||||
* @see http://www.peterfriese.de/running-applescript-from-java/
|
|
||||||
*/
|
|
||||||
public static void executeCommandLine(String commandLine) {
|
|
||||||
try {
|
|
||||||
if (commandLine.contains(CMD_LINE_DELIMITER)) {
|
|
||||||
String[] cmdArray = commandLine.split(CMD_LINE_DELIMITER);
|
|
||||||
Runtime.getRuntime().exec(cmdArray);
|
|
||||||
LOGGER.info("executed commandLine '{}'", Arrays.asList(cmdArray));
|
|
||||||
} else {
|
|
||||||
Runtime.getRuntime().exec(commandLine);
|
|
||||||
LOGGER.info("executed commandLine '{}'", commandLine);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("couldn't execute commandLine '{}'", commandLine, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Executes <code>commandLine</code>. Sometimes (especially observed on
|
|
||||||
* MacOS) the commandLine isn't executed properly. In that cases another
|
|
||||||
* exec-method is to be used. To accomplish this please use the special
|
|
||||||
* delimiter '<code>@@</code>'. If <code>commandLine</code> contains this
|
|
||||||
* delimiter it is split into a String[] array and the special exec-method
|
|
||||||
* is used.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* A possible {@link IOException} gets logged but no further processing is
|
|
||||||
* done.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param commandLine the command line to execute
|
|
||||||
* @param timeout timeout for execution in milliseconds
|
|
||||||
* @return response data from executed command line
|
|
||||||
*/
|
|
||||||
public static String executeCommandLineAndWaitResponse(String commandLine, int timeout) {
|
|
||||||
String retval = null;
|
|
||||||
|
|
||||||
CommandLine cmdLine = null;
|
|
||||||
|
|
||||||
if (commandLine.contains(CMD_LINE_DELIMITER)) {
|
|
||||||
String[] cmdArray = commandLine.split(CMD_LINE_DELIMITER);
|
|
||||||
cmdLine = new CommandLine(cmdArray[0]);
|
|
||||||
|
|
||||||
for (int i = 1; i < cmdArray.length; i++) {
|
|
||||||
cmdLine.addArgument(cmdArray[i], false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cmdLine = CommandLine.parse(commandLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
|
|
||||||
|
|
||||||
ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
|
|
||||||
Executor executor = new DefaultExecutor();
|
|
||||||
|
|
||||||
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
|
|
||||||
PumpStreamHandler streamHandler = new PumpStreamHandler(stdout);
|
|
||||||
|
|
||||||
executor.setExitValue(1);
|
|
||||||
executor.setStreamHandler(streamHandler);
|
|
||||||
executor.setWatchdog(watchdog);
|
|
||||||
|
|
||||||
try {
|
|
||||||
executor.execute(cmdLine, resultHandler);
|
|
||||||
LOGGER.debug("executed commandLine '{}'", commandLine);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("couldn't execute commandLine '{}'", commandLine, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// some time later the result handler callback was invoked so we
|
|
||||||
// can safely request the exit code
|
|
||||||
try {
|
|
||||||
resultHandler.waitFor();
|
|
||||||
int exitCode = resultHandler.getExitValue();
|
|
||||||
retval = StringUtils.chomp(stdout.toString());
|
|
||||||
if (resultHandler.getException() != null) {
|
|
||||||
LOGGER.warn("{}", resultHandler.getException().getMessage());
|
|
||||||
} else {
|
|
||||||
LOGGER.debug("exit code '{}', result '{}'", exitCode, retval);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
LOGGER.error("Timeout occurred when executing commandLine '{}'", commandLine, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,315 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.http;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Credentials;
|
|
||||||
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
|
|
||||||
import org.apache.commons.httpclient.Header;
|
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
|
||||||
import org.apache.commons.httpclient.HttpException;
|
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
|
||||||
import org.apache.commons.httpclient.URIException;
|
|
||||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
|
||||||
import org.apache.commons.httpclient.auth.AuthScope;
|
|
||||||
import org.apache.commons.httpclient.methods.DeleteMethod;
|
|
||||||
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
|
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
|
||||||
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
|
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
|
||||||
import org.apache.commons.httpclient.methods.PutMethod;
|
|
||||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some common methods to be used in both HTTP-In-Binding and HTTP-Out-Binding
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class HttpUtil {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);
|
|
||||||
|
|
||||||
/** {@link Pattern} which matches the credentials out of an URL */
|
|
||||||
private static final Pattern URL_CREDENTIALS_PATTERN = Pattern.compile("http://(.*?):(.*?)@.*");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the given <code>url</code> with the given <code>httpMethod</code>.
|
|
||||||
* Furthermore the <code>http.proxyXXX</code> System variables are read and
|
|
||||||
* set into the {@link HttpClient}.
|
|
||||||
*
|
|
||||||
* @param httpMethod the HTTP method to use
|
|
||||||
* @param url the url to execute (in milliseconds)
|
|
||||||
* @param timeout the socket timeout to wait for data
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String executeUrl(String httpMethod, String url, int timeout) {
|
|
||||||
return executeUrl(httpMethod, url, null, null, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the given <code>url</code> with the given <code>httpMethod</code>.
|
|
||||||
* Furthermore the <code>http.proxyXXX</code> System variables are read and
|
|
||||||
* set into the {@link HttpClient}.
|
|
||||||
*
|
|
||||||
* @param httpMethod the HTTP method to use
|
|
||||||
* @param url the url to execute (in milliseconds)
|
|
||||||
* @param content the content to be send to the given <code>url</code> or
|
|
||||||
* <code>null</code> if no content should be send.
|
|
||||||
* @param contentType the content type of the given <code>content</code>
|
|
||||||
* @param timeout the socket timeout to wait for data
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String executeUrl(String httpMethod, String url, InputStream content, String contentType,
|
|
||||||
int timeout) {
|
|
||||||
return executeUrl(httpMethod, url, null, content, contentType, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the given <code>url</code> with the given <code>httpMethod</code>.
|
|
||||||
* Furthermore the <code>http.proxyXXX</code> System variables are read and
|
|
||||||
* set into the {@link HttpClient}.
|
|
||||||
*
|
|
||||||
* @param httpMethod the HTTP method to use
|
|
||||||
* @param url the url to execute (in milliseconds)
|
|
||||||
* @param httpHeaders optional http request headers which has to be sent within request
|
|
||||||
* @param content the content to be send to the given <code>url</code> or
|
|
||||||
* <code>null</code> if no content should be send.
|
|
||||||
* @param contentType the content type of the given <code>content</code>
|
|
||||||
* @param timeout the socket timeout to wait for data
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String executeUrl(String httpMethod, String url, Properties httpHeaders, InputStream content,
|
|
||||||
String contentType, int timeout) {
|
|
||||||
String proxySet = System.getProperty("http.proxySet");
|
|
||||||
|
|
||||||
String proxyHost = null;
|
|
||||||
int proxyPort = 80;
|
|
||||||
String proxyUser = null;
|
|
||||||
String proxyPassword = null;
|
|
||||||
String nonProxyHosts = null;
|
|
||||||
|
|
||||||
if ("true".equalsIgnoreCase(proxySet)) {
|
|
||||||
proxyHost = System.getProperty("http.proxyHost");
|
|
||||||
String proxyPortString = System.getProperty("http.proxyPort");
|
|
||||||
if (StringUtils.isNotBlank(proxyPortString)) {
|
|
||||||
try {
|
|
||||||
proxyPort = Integer.valueOf(proxyPortString);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
LOGGER.warn("'{}' is not a valid proxy port - using port 80 instead", proxyPortString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
proxyUser = System.getProperty("http.proxyUser");
|
|
||||||
proxyPassword = System.getProperty("http.proxyPassword");
|
|
||||||
nonProxyHosts = System.getProperty("http.nonProxyHosts");
|
|
||||||
}
|
|
||||||
|
|
||||||
return executeUrl(httpMethod, url, httpHeaders, content, contentType, timeout, proxyHost, proxyPort, proxyUser,
|
|
||||||
proxyPassword, nonProxyHosts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the given <code>url</code> with the given <code>httpMethod</code>
|
|
||||||
*
|
|
||||||
* @param httpMethod the HTTP method to use
|
|
||||||
* @param url the url to execute (in milliseconds)
|
|
||||||
* @param httpHeaders optional HTTP headers which has to be set on request
|
|
||||||
* @param content the content to be send to the given <code>url</code> or
|
|
||||||
* <code>null</code> if no content should be send.
|
|
||||||
* @param contentType the content type of the given <code>content</code>
|
|
||||||
* @param timeout the socket timeout to wait for data
|
|
||||||
* @param proxyHost the hostname of the proxy
|
|
||||||
* @param proxyPort the port of the proxy
|
|
||||||
* @param proxyUser the username to authenticate with the proxy
|
|
||||||
* @param proxyPassword the password to authenticate with the proxy
|
|
||||||
* @param nonProxyHosts the hosts that won't be routed through the proxy
|
|
||||||
* @return the response body or <code>NULL</code> when the request went wrong
|
|
||||||
*/
|
|
||||||
public static String executeUrl(String httpMethod, String url, Properties httpHeaders, InputStream content,
|
|
||||||
String contentType, int timeout, String proxyHost, Integer proxyPort, String proxyUser,
|
|
||||||
String proxyPassword, String nonProxyHosts) {
|
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
|
|
||||||
// only configure a proxy if a host is provided
|
|
||||||
if (StringUtils.isNotBlank(proxyHost) && proxyPort != null && shouldUseProxy(url, nonProxyHosts)) {
|
|
||||||
client.getHostConfiguration().setProxy(proxyHost, proxyPort);
|
|
||||||
if (StringUtils.isNotBlank(proxyUser)) {
|
|
||||||
client.getState().setProxyCredentials(AuthScope.ANY,
|
|
||||||
new UsernamePasswordCredentials(proxyUser, proxyPassword));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpMethod method = HttpUtil.createHttpMethod(httpMethod, url);
|
|
||||||
method.getParams().setSoTimeout(timeout);
|
|
||||||
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
|
|
||||||
if (httpHeaders != null) {
|
|
||||||
for (String httpHeaderKey : httpHeaders.stringPropertyNames()) {
|
|
||||||
method.addRequestHeader(new Header(httpHeaderKey, httpHeaders.getProperty(httpHeaderKey)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add content if a valid method is given ...
|
|
||||||
if (method instanceof EntityEnclosingMethod && content != null) {
|
|
||||||
EntityEnclosingMethod eeMethod = (EntityEnclosingMethod) method;
|
|
||||||
eeMethod.setRequestEntity(new InputStreamRequestEntity(content, contentType));
|
|
||||||
}
|
|
||||||
|
|
||||||
Credentials credentials = extractCredentials(url);
|
|
||||||
if (credentials != null) {
|
|
||||||
client.getParams().setAuthenticationPreemptive(true);
|
|
||||||
client.getState().setCredentials(AuthScope.ANY, credentials);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
try {
|
|
||||||
LOGGER.debug("About to execute '{}'", method.getURI());
|
|
||||||
} catch (URIException e) {
|
|
||||||
LOGGER.debug("{}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
int statusCode = client.executeMethod(method);
|
|
||||||
if (statusCode != HttpStatus.SC_OK) {
|
|
||||||
LOGGER.debug("Method failed: {}", method.getStatusLine());
|
|
||||||
}
|
|
||||||
|
|
||||||
String responseBody = IOUtils.toString(method.getResponseBodyAsStream());
|
|
||||||
if (!responseBody.isEmpty()) {
|
|
||||||
LOGGER.debug("{}", responseBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseBody;
|
|
||||||
} catch (HttpException he) {
|
|
||||||
LOGGER.error("Fatal protocol violation: {}", he.toString());
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOGGER.error("Fatal transport error: {}", ioe.toString());
|
|
||||||
} finally {
|
|
||||||
method.releaseConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the list of <code>nonProxyHosts</code> contains the
|
|
||||||
* host (which is part of the given <code>urlString</code> or not.
|
|
||||||
*
|
|
||||||
* @param urlString
|
|
||||||
* @param nonProxyHosts
|
|
||||||
* @return <code>false</code> if the host of the given <code>urlString</code>
|
|
||||||
* is contained in <code>nonProxyHosts</code>-list and <code>true</code>
|
|
||||||
* otherwise
|
|
||||||
*/
|
|
||||||
private static boolean shouldUseProxy(String urlString, String nonProxyHosts) {
|
|
||||||
if (StringUtils.isNotBlank(nonProxyHosts)) {
|
|
||||||
String givenHost = urlString;
|
|
||||||
|
|
||||||
try {
|
|
||||||
URL url = new URL(urlString);
|
|
||||||
givenHost = url.getHost();
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
LOGGER.error("the given url {} is malformed", urlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] hosts = nonProxyHosts.split("\\|");
|
|
||||||
for (String host : hosts) {
|
|
||||||
if (host.contains("*")) {
|
|
||||||
// the nonProxyHots-pattern allows wildcards '*' which must
|
|
||||||
// be masked to be used with regular expressions
|
|
||||||
String hostRegexp = host.replaceAll("\\.", "\\\\.");
|
|
||||||
hostRegexp = hostRegexp.replaceAll("\\*", ".*");
|
|
||||||
if (givenHost.matches(hostRegexp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (givenHost.equals(host)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts username and password from the given <code>url</code>. A valid
|
|
||||||
* url to extract {@link Credentials} from looks like:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* http://username:password@www.domain.org
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param url the URL to extract {@link Credentials} from
|
|
||||||
* @return the exracted Credentials or <code>null</code> if the given
|
|
||||||
* <code>url</code> does not contain credentials
|
|
||||||
*/
|
|
||||||
protected static Credentials extractCredentials(String url) {
|
|
||||||
Matcher matcher = URL_CREDENTIALS_PATTERN.matcher(url);
|
|
||||||
|
|
||||||
if (matcher.matches()) {
|
|
||||||
matcher.reset();
|
|
||||||
|
|
||||||
String username = "";
|
|
||||||
String password = "";
|
|
||||||
|
|
||||||
while (matcher.find()) {
|
|
||||||
username = matcher.group(1);
|
|
||||||
password = matcher.group(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Credentials credentials = new UsernamePasswordCredentials(username, password);
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory method to create a {@link HttpMethod}-object according to the
|
|
||||||
* given String <code>httpMethod</code>
|
|
||||||
*
|
|
||||||
* @param httpMethodString the name of the {@link HttpMethod} to create
|
|
||||||
* @param url
|
|
||||||
* @return an object of type {@link GetMethod}, {@link PutMethod},
|
|
||||||
* {@link PostMethod} or {@link DeleteMethod}
|
|
||||||
* @throws IllegalArgumentException if <code>httpMethod</code> is none of
|
|
||||||
* <code>GET</code>, <code>PUT</code>, <code>POST</POST> or <code>DELETE</code>
|
|
||||||
*/
|
|
||||||
public static HttpMethod createHttpMethod(String httpMethodString, String url) {
|
|
||||||
if ("GET".equals(httpMethodString)) {
|
|
||||||
return new GetMethod(url);
|
|
||||||
} else if ("PUT".equals(httpMethodString)) {
|
|
||||||
return new PutMethod(url);
|
|
||||||
} else if ("POST".equals(httpMethodString)) {
|
|
||||||
return new PostMethod(url);
|
|
||||||
} else if ("DELETE".equals(httpMethodString)) {
|
|
||||||
return new DeleteMethod(url);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("given httpMethod '" + httpMethodString + "' is unknown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.io.net.http;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.osgi.service.http.HttpContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link HttpContext} which adds Basic-Authentication
|
|
||||||
* functionality to openHAB.
|
|
||||||
*
|
|
||||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
|
||||||
*/
|
|
||||||
public class SecureHttpContext implements HttpContext {
|
|
||||||
|
|
||||||
private HttpContext defaultContext = null;
|
|
||||||
|
|
||||||
public SecureHttpContext() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecureHttpContext(HttpContext defaultContext, final String realm) {
|
|
||||||
this.defaultContext = defaultContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @{inheritDoc}
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Delegates to <code>defaultContext.getMimeType()</code>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getMimeType(String name) {
|
|
||||||
return this.defaultContext.getMimeType(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @{inheritDoc}
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Delegates to <code>defaultContext.getResource()</code>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public URL getResource(String name) {
|
|
||||||
return this.defaultContext.getResource(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.library.tel.items;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openhab.core.items.GenericItem;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
import org.openhab.library.tel.types.CallType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class CallItem extends GenericItem {
|
|
||||||
|
|
||||||
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<>();
|
|
||||||
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
acceptedDataTypes.add(CallType.class);
|
|
||||||
acceptedDataTypes.add(UnDefType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallItem(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
|
||||||
return acceptedDataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Command>> getAcceptedCommandTypes() {
|
|
||||||
return acceptedCommandTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.library.tel.types;
|
|
||||||
|
|
||||||
import java.util.Formatter;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.openhab.core.library.types.StringType;
|
|
||||||
import org.openhab.core.types.Command;
|
|
||||||
import org.openhab.core.types.ComplexType;
|
|
||||||
import org.openhab.core.types.PrimitiveType;
|
|
||||||
import org.openhab.core.types.State;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class CallType implements ComplexType, Command, State {
|
|
||||||
|
|
||||||
protected static final String DEST_NUM = "destNum";
|
|
||||||
protected static final String ORIG_NUM = "origNum";
|
|
||||||
private static final String SEPARATOR = "##";
|
|
||||||
|
|
||||||
private SortedMap<String, PrimitiveType> callDetails;
|
|
||||||
|
|
||||||
public static final State EMPTY = new CallType(new StringType(""), new StringType(""));
|
|
||||||
|
|
||||||
public CallType() {
|
|
||||||
callDetails = new TreeMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallType(String value) {
|
|
||||||
this();
|
|
||||||
if (StringUtils.isNotBlank(value)) {
|
|
||||||
String[] elements = value.split(SEPARATOR);
|
|
||||||
if (elements.length == 2) {
|
|
||||||
callDetails.put(DEST_NUM, new StringType(elements[1]));
|
|
||||||
callDetails.put(ORIG_NUM, new StringType(elements[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallType(String origNum, String destNum) {
|
|
||||||
this(new StringType(origNum), new StringType(destNum));
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallType(StringType origNum, StringType destNum) {
|
|
||||||
this();
|
|
||||||
callDetails.put(DEST_NUM, destNum);
|
|
||||||
callDetails.put(ORIG_NUM, origNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SortedMap<String, PrimitiveType> getConstituents() {
|
|
||||||
return callDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrimitiveType getDestNum() {
|
|
||||||
return callDetails.get(DEST_NUM);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrimitiveType getOrigNum() {
|
|
||||||
return callDetails.get(ORIG_NUM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Formats the value of this type according to a pattern (@see
|
|
||||||
* {@link Formatter}). One single value of this type can be referenced
|
|
||||||
* by the pattern using an index. The item order is defined by the natural
|
|
||||||
* (alphabetical) order of their keys.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Index '1' will reference the call's destination number and index '2'
|
|
||||||
* will reference the call's origination number.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param pattern the pattern to use containing indexes to reference the
|
|
||||||
* single elements of this type.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String format(String pattern) {
|
|
||||||
return String.format(pattern, callDetails.values().toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallType valueOf(String value) {
|
|
||||||
return new CallType(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getOrigNum() + SEPARATOR + getDestNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((callDetails == null) ? 0 : callDetails.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CallType other = (CallType) obj;
|
|
||||||
if (callDetails == null) {
|
|
||||||
if (other.callDetails != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!callDetails.equals(other.callDetails)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.model.item.binding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
|
|
||||||
import org.openhab.core.binding.BindingChangeListener;
|
|
||||||
import org.openhab.core.binding.BindingConfig;
|
|
||||||
import org.openhab.core.binding.BindingProvider;
|
|
||||||
import org.openhab.core.items.Item;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This abstract class serves as a basis for implementations of binding providers that retrieve binding
|
|
||||||
* information from the items configuration file(s), i.e. they register as {@link BindingConfigReader}s.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This class takes care of tracking all changes in the binding config strings and makes sure that all
|
|
||||||
* listeners are correctly notified of any change.
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public abstract class AbstractGenericBindingProvider implements BindingConfigReader, BindingProvider {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(AbstractGenericBindingProvider.class);
|
|
||||||
|
|
||||||
private Set<BindingChangeListener> listeners = new CopyOnWriteArraySet<>();
|
|
||||||
|
|
||||||
/** caches binding configurations. maps itemNames to {@link BindingConfig}s */
|
|
||||||
protected Map<String, BindingConfig> bindingConfigs = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stores information about the context of items. The map has this content
|
|
||||||
* structure: context -> Set of Items
|
|
||||||
*/
|
|
||||||
protected Map<String, Set<Item>> contextMap = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public AbstractGenericBindingProvider() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addBindingChangeListener(BindingChangeListener listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeBindingChangeListener(BindingChangeListener listener) {
|
|
||||||
listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processBindingConfiguration(String context, Item item, String bindingConfig)
|
|
||||||
throws BindingConfigParseException {
|
|
||||||
if (context == null) {
|
|
||||||
throw new BindingConfigParseException("null context is not permitted for item " + item.getName());
|
|
||||||
}
|
|
||||||
synchronized (contextMap) {
|
|
||||||
Set<Item> items = contextMap.get(context);
|
|
||||||
if (items == null) {
|
|
||||||
items = new HashSet<>();
|
|
||||||
contextMap.put(context, items);
|
|
||||||
}
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeConfigurations(String context) {
|
|
||||||
Set<Item> items = null;
|
|
||||||
synchronized (contextMap) {
|
|
||||||
items = contextMap.get(context);
|
|
||||||
if (items != null) {
|
|
||||||
contextMap.remove(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (items != null) {
|
|
||||||
for (Item item : items) {
|
|
||||||
// we remove all binding configurations for all items
|
|
||||||
bindingConfigs.remove(item.getName());
|
|
||||||
notifyListeners(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addBindingConfig(Item item, BindingConfig config) {
|
|
||||||
bindingConfigs.put(item.getName(), config);
|
|
||||||
notifyListeners(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyListeners(Item item) {
|
|
||||||
for (BindingChangeListener listener : listeners) {
|
|
||||||
try {
|
|
||||||
listener.bindingChanged(this, item.getName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Binding {} threw an exception: ", listener.getClass().getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean providesBindingFor(String itemName) {
|
|
||||||
return bindingConfigs.get(itemName) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean providesBinding() {
|
|
||||||
return !bindingConfigs.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getItemNames() {
|
|
||||||
return new ArrayList<>(bindingConfigs.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.model.item.binding;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public class BindingConfigParseException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1434607160082879845L;
|
|
||||||
|
|
||||||
public BindingConfigParseException(String msg) {
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.model.item.binding;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.model.item.internal.GenericItemProvider;
|
|
||||||
import org.openhab.core.items.Item;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface must be implemented by services, which can parse the generic
|
|
||||||
* binding configuration string used in the {@link GenericItemProvider}.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface BindingConfigReader {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This defines the type of binding this reader will process, e.g. "knx".
|
|
||||||
*
|
|
||||||
* @return the type of the binding
|
|
||||||
*/
|
|
||||||
public String getBindingType();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates if the type of <code>item</code> is valid for this binding.
|
|
||||||
*
|
|
||||||
* @param item the item whose type is validated
|
|
||||||
* @param bindingConfig the config string which could be used to refine the
|
|
||||||
* validation
|
|
||||||
* @throws BindingConfigParseException if the type of <code>item</code> is
|
|
||||||
* invalid for this binding
|
|
||||||
*/
|
|
||||||
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called by the {@link GenericItemProvider} whenever it comes
|
|
||||||
* across a binding configuration string for an item.
|
|
||||||
*
|
|
||||||
* @param context a string of the context from where this item comes from. Usually the file name of the config file
|
|
||||||
* @param item the item for which the binding is defined
|
|
||||||
* @param bindingConfig the configuration string that must be processed
|
|
||||||
* @throws BindingConfigParseException if the configuration string is not valid
|
|
||||||
*/
|
|
||||||
public void processBindingConfiguration(String context, Item item, String bindingConfig)
|
|
||||||
throws BindingConfigParseException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all configuration information for a given context. This is usually called if a config file is reloaded,
|
|
||||||
* so that the old values are removed, before the new ones are processed.
|
|
||||||
*
|
|
||||||
* @param context the context of the configurations that should be removed
|
|
||||||
*/
|
|
||||||
public void removeConfigurations(String context);
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2019 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.model.sitemap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* A representation of the model object '<em><b>Chart</b></em>'.
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The following features are supported:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link org.openhab.model.sitemap.Chart#getService <em>Service</em>}</li>
|
|
||||||
* <li>{@link org.openhab.model.sitemap.Chart#getRefresh <em>Refresh</em>}</li>
|
|
||||||
* <li>{@link org.openhab.model.sitemap.Chart#getPeriod <em>Period</em>}</li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see org.openhab.model.sitemap.SitemapPackage#getChart()
|
|
||||||
* @model
|
|
||||||
* @author Kai Kreuzer - Initial contribution
|
|
||||||
*/
|
|
||||||
public interface Chart extends NonLinkableWidget {
|
|
||||||
/**
|
|
||||||
* Returns the value of the '<em><b>Service</b></em>' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <p>
|
|
||||||
* If the meaning of the '<em>Service</em>' attribute isn't clear,
|
|
||||||
* there really should be more of a description here...
|
|
||||||
* </p>
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @return the value of the '<em>Service</em>' attribute.
|
|
||||||
* @see #setService(String)
|
|
||||||
* @see org.openhab.model.sitemap.SitemapPackage#getChart_Service()
|
|
||||||
* @model
|
|
||||||
*/
|
|
||||||
String getService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of the '{@link org.openhab.model.sitemap.Chart#getService <em>Service</em>}' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @param value the new value of the '<em>Service</em>' attribute.
|
|
||||||
* @see #getService()
|
|
||||||
*/
|
|
||||||
void setService(String value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the '<em><b>Refresh</b></em>' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <p>
|
|
||||||
* If the meaning of the '<em>Refresh</em>' attribute isn't clear,
|
|
||||||
* there really should be more of a description here...
|
|
||||||
* </p>
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @return the value of the '<em>Refresh</em>' attribute.
|
|
||||||
* @see #setRefresh(int)
|
|
||||||
* @see org.openhab.model.sitemap.SitemapPackage#getChart_Refresh()
|
|
||||||
* @model
|
|
||||||
*/
|
|
||||||
int getRefresh();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of the '{@link org.openhab.model.sitemap.Chart#getRefresh <em>Refresh</em>}' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @param value the new value of the '<em>Refresh</em>' attribute.
|
|
||||||
* @see #getRefresh()
|
|
||||||
*/
|
|
||||||
void setRefresh(int value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the '<em><b>Period</b></em>' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <p>
|
|
||||||
* If the meaning of the '<em>Period</em>' attribute isn't clear,
|
|
||||||
* there really should be more of a description here...
|
|
||||||
* </p>
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @return the value of the '<em>Period</em>' attribute.
|
|
||||||
* @see #setPeriod(String)
|
|
||||||
* @see org.openhab.model.sitemap.SitemapPackage#getChart_Period()
|
|
||||||
* @model
|
|
||||||
*/
|
|
||||||
String getPeriod();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of the '{@link org.openhab.model.sitemap.Chart#getPeriod <em>Period</em>}' attribute.
|
|
||||||
* <!-- begin-user-doc -->
|
|
||||||
* <!-- end-user-doc -->
|
|
||||||
*
|
|
||||||
* @param value the new value of the '<em>Period</em>' attribute.
|
|
||||||
* @see #getPeriod()
|
|
||||||
*/
|
|
||||||
void setPeriod(String value);
|
|
||||||
|
|
||||||
} // Chart
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user