Hi All,
I’m trying to make my binding work in OH 1.8.3 for a day but nothing. I have created the binding according to the description on GitHub. I use Export -> Deployable plugins and fragments in Eclipse Neon to generate the jar.
Although KeContactPActivator.start is called by OH, KeContactPBinding.activate is never called. If I wait more, the situation remains the same.
What do I do wrong?
Thank you in advance, best regards: Balazs Bamer
Here is openHAB log:
Launching the openHAB runtime...
osgi> 2016-11-16 14:00:53.659 [INFO ] [.o.core.internal.CoreActivator] - openHAB runtime has been started (v1.8.3).
2016-11-16 14:00:55.246 [INFO ] [o.o.i.s.i.DiscoveryServiceImpl] - mDNS service has been started
2016-11-16 14:00:55.406 [INFO ] [o.o.i.s.i.DiscoveryServiceImpl] - Service Discovery initialization completed.
2016-11-16 14:00:57.535 [INFO ] [penhab.io.rest.RESTApplication] - Started REST API at /rest
2016-11-16 14:01:04.849 [INFO ] [c.internal.ModelRepositoryImpl] - Loading model 'default.sitemap'
2016-11-16 14:01:05.080 [INFO ] [c.internal.ModelRepositoryImpl] - Loading model 'experiment.items'
2016-11-16 14:01:09.671 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Available engines:
2016-11-16 14:01:09.677 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Oracle Nashorn
2016-11-16 14:01:09.677 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Groovy Scripting Engine
2016-11-16 14:01:09.679 [INFO ] [o.c.j.i.e.scriptmanager.Script] - Loading Script kebacurrentlimittest.groovy
2016-11-16 14:01:09.705 [INFO ] [o.c.j.i.e.scriptmanager.Script] - EngineName: Groovy Scripting Engine
2016-11-16 14:01:10.750 [INFO ] [o.o.c.j.i.e.s.ScriptManager ] - Engine found for File: kebacurrentlimittest.groovy
2016-11-16 14:01:10.825 [WARN ] [k.internal.KeContactPActivator] - KeContactP binding has been started.
2016-11-16 14:01:10.873 [WARN ] [ContactPGenericBindingProvider] - getBindingType
2016-11-16 14:01:10.873 [WARN ] [ContactPGenericBindingProvider] - getBindingType
2016-11-16 14:01:10.874 [WARN ] [ContactPGenericBindingProvider] - getBindingType
2016-11-16 14:01:10.874 [WARN ] [ContactPGenericBindingProvider] - getBindingType
2016-11-16 14:01:10.874 [WARN ] [ContactPGenericBindingProvider] - validateItemType ladestrom (Type=NumberItem, State=Uninitialized)10.128.3.131
2016-11-16 14:01:10.875 [WARN ] [ContactPGenericBindingProvider] - processBindingConfiguration experiment.itemsladestrom (Type=NumberItem, State=Uninitialized)10.128.3.131
2016-11-16 14:01:10.975 [INFO ] [.o.u.w.i.servlet.WebAppServlet] - Started Classic UI at /classicui/openhab.app
2016-11-16 14:02:00.032 [INFO ] [.o.c.j.i.engine.TimeTriggerJob] - TimeTrigger for rule: KebaCurrentLimitTest@2ee540bd, scriptName: kebacurrentlimittest.groovy
2016-11-16 14:02:00.034 [WARN ] [.m.jsr223.KebaCurrentLimitTest] - About to set current limit
2016-11-16 14:02:00.050 [INFO ] [runtime.busevents ] - ladestrom received command 33333
osgi> exit
Really want to stop Equinox? (y/n; default=y) y
2016-11-16 14:02:11.019 [INFO ] [penhab.io.rest.RESTApplication] - Stopped REST API
Here are the important parts:
Groovy rule to send a command to the binding
import org.openhab.core.jsr223.internal.shared.*
import groovy.transform.CompileStatic
import org.slf4j.Logger;
import org.openhab.core.items.Item
import org.openhab.core.items.ItemRegistry
Global.itemRegistry = this.ItemRegistry
Global.pe = this.pe
class Global {
static ItemRegistry itemRegistry
static Class pe
}
@CompileStatic
class KebaCurrentLimitTest implements Rule {
protected static Logger log = Openhab.getLogger("KebaCurrentLimitTest")
public KebaCurrentLimitTest() { }
java.util.List<?> getEventTrigger() {
return [
new TimerTrigger("0 * * * * ?")
]
}
void execute(Event event) {
log.warn("About to set current limit")
Item ladestrom = Global.itemRegistry.getItem("ladestrom");
Openhab.sendCommand(ladestrom, "33333")
}
}
@CompileStatic
RuleSet getRules() {
return new RuleSet(new KebaCurrentLimitTest())
}
experiment.items
Number ladestrom "Ladestrom [%d]" (gemischt) {kecontactp="10.128.3.131"}
default.sitemap
sitemap default label="Demo House"
{
Frame label="gemischt" {
Text item=Date
Number item=ladestrom
}
}
MANIFEST.MF
Manifest-Version: 1.0
Private-Package: org.openhab.binding.kecontactp.internal
Ignore-Package: org.openhab.binding.kecontactp.internal
Bundle-License: http://www.eclipse.org/legal/epl-v10.html
Bundle-Name: openHAB KeContactP Binding
Bundle-SymbolicName: org.openhab.binding.kecontactp
Bundle-Vendor: openHAB.org
Bundle-Version: 1.8.3.qualifier
Bundle-Activator: org.openhab.binding.kecontactp.internal.KeContactPActivator
Bundle-ManifestVersion: 2
Bundle-Description: This is the KeContactP binding of the open Home Aut
omation Bus (openHAB)
Import-Package: org.apache.commons.lang,
org.openhab.core.binding,
org.openhab.core.events,
org.openhab.core.items,
org.openhab.core.library.items,
org.openhab.core.library.types,
org.openhab.core.types,
org.openhab.model.item.binding,
org.osgi.framework,
org.osgi.service.component,
org.osgi.service.event,
org.slf4j
Export-Package: org.openhab.binding.kecontactp
Bundle-DocURL: http://www.openhab.org
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Service-Component: OSGI-INF/binding.xml, OSGI-INF/genericbindingprovider.xml
Bundle-ClassPath: .
build.properties
source.. = src/main/java/,\
src/main/resources/
bin.includes = META-INF/,\
.,\
OSGI-INF/
output.. = target/classes/
binding.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.2.0" activate="activate" modified="modified" deactivate="deactivate" name="org.openhab.binding.kecontactp.binding" factory="org.openhab.kecontactp" immediate="false" configuration-pid="org.openhab.kecontactp" configuration-policy="optional">
<implementation class="org.openhab.binding.kecontactp.internal.KeContactPBinding" />
<service>
<provide interface="org.osgi.service.cm.ManagedService" />
<provide interface="org.osgi.service.event.EventHandler" />
</service>
<property name="service.pid" type="String" value="org.openhab.kecontactp" />
<property name="event.topics" type="String" value="openhab/*" />
<reference bind="setEventPublisher" cardinality="1..1"
interface="org.openhab.core.events.EventPublisher" name="EventPublisher" policy="dynamic" unbind="unsetEventPublisher" />
<reference bind="addBindingProvider" cardinality="1..n"
interface="org.openhab.binding.kecontactp.KeContactPBindingProvider" name="KeContactPBindingProvider" policy="dynamic" unbind="removeBindingProvider" />
</scr:component>
genericbindingprovider.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.openhab.binding.kecontactp.genericbindingprovider">
<implementation class="org.openhab.binding.kecontactp.internal.KeContactPGenericBindingProvider"/>
<service>
<provide interface="org.openhab.model.item.binding.BindingConfigReader"/>
<provide interface="org.openhab.binding.kecontactp.KeContactPBindingProvider"/>
</service>
</scr:component>
KeContactPBindingProvider
package org.openhab.binding.kecontactp;
import java.net.InetAddress;
import org.openhab.core.binding.BindingProvider;
public interface KeContactPBindingProvider extends BindingProvider {
InetAddress getAddress(String itemName);
int getPort(String itemName);
}
KeContactPActivator.java
package org.openhab.binding.kecontactp.internal;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class KeContactPActivator implements BundleActivator {
private static Logger logger = LoggerFactory.getLogger(KeContactPActivator.class);
private static BundleContext context;
public void start(BundleContext bc) throws Exception {
context = bc;
logger.warn("KeContactP binding has been started.");
}
public void stop(BundleContext bc) throws Exception {
context = null;
logger.warn("KeContactP binding has been stopped.");
}
public static BundleContext getContext() {
logger.warn("getContext");
return context;
}
}
KeContactPBinding.java
package org.openhab.binding.kecontactp.internal;
import java.util.Map;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import org.openhab.binding.kecontactp.KeContactPBindingProvider;
import org.apache.commons.lang.StringUtils;
import org.openhab.core.binding.AbstractActiveBinding;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.json.JSONObject;
public class KeContactPBinding extends AbstractActiveBinding<KeContactPBindingProvider> {
private static final Logger logger = LoggerFactory.getLogger(KeContactPBinding.class);
private BundleContext bundleContext;
private int timeout = 1;
public KeContactPBinding() {}
public void activate(final BundleContext bundleContext, final Map<String, Object> configuration) {
logger.warn("activate");
this.bundleContext = bundleContext;
modified(configuration);
setProperlyConfigured(true);
}
public void modified(final Map<String, Object> configuration) {
logger.warn("modified");
// PARSE CONFIG HERE
}
public void deactivate(final int reason) {
logger.warn("deactivate");
this.bundleContext = null;
}
@Override
protected long getRefreshInterval() {
return 0;
}
@Override
protected String getName() {
return "KeContactP UDP receiver";
}
@Override
protected void execute() {
logger.warn("execute() method is called!");
for (KeContactPBindingProvider provider : providers) {
for (String itemName : provider.getItemNames()) {
InetAddress address = provider.getAddress(itemName);
int port = provider.getPort(itemName);
logger.warn("execute address: " + address + " port: " + port);
}
}
}
@Override
protected void internalReceiveCommand(String itemName, Command command) {
logger.warn("internalReceiveCommand() method is called!", itemName, command);
for (KeContactPBindingProvider provider : this.providers) {
InetAddress address = provider.getAddress(itemName);
int port = provider.getPort(itemName);
// DO SOMETHING HERE
logger.warn("internalReceiveCommand address: " + address + " port: " + port);
}
}
@Override
protected void internalReceiveUpdate(String itemName, State newState) {
logger.error("internalReceiveUpdate({},{}) is called but not intended to be implemented!", itemName, newState);
}
}
KeContactPGenericBindingProvider.java
package org.openhab.binding.kecontactp.internal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.openhab.binding.kecontactp.KeContactPBindingProvider;
import org.openhab.core.binding.BindingConfig;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.NumberItem;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeContactPGenericBindingProvider extends AbstractGenericBindingProvider implements KeContactPBindingProvider {
private static final Logger logger = LoggerFactory.getLogger(KeContactPGenericBindingProvider.class);
public String getBindingType() {
logger.warn("getBindingType");
return "kecontactp";
}
@Override
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
logger.warn("validateItemType " + item + bindingConfig);
if (!(item instanceof NumberItem)) {
throw new BindingConfigParseException("item '" + item.getName()
+ "' is of type '" + item.getClass().getSimpleName()
+ "', only NumberItems are allowed - please check your *.items configuration");
}
}
@Override
public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException {
super.processBindingConfiguration(context, item, bindingConfig);
logger.warn("processBindingConfiguration " + context + item + bindingConfig);
KeContactPBindingConfig config = new KeContactPBindingConfig();
// PARSE CONFIG HERE
addBindingConfig(item, config);
}
public InetAddress getAddress(String itemName) {
logger.warn("getAddress " + itemName);
KeContactPBindingConfig config = (KeContactPBindingConfig) bindingConfigs.get(itemName);
return config.address;
}
public int getPort(String itemName) {
logger.warn("getPort " + itemName);
KeContactPBindingConfig config = (KeContactPBindingConfig) bindingConfigs.get(itemName);
return config.port;
}
static private class KeContactPBindingConfig implements BindingConfig {
public InetAddress address;
public int port = 7090;
}
}