This seems to work, I can get all item updates.
The problem I have i how do I reference this osgi-service in my binding?
For instance I have a factory like this:
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.mybinding")
@NonNullByDefault
public class MyBindingThingHandlerFactory extends BaseThingHandlerFactory {
@Reference
private @NonNullByDefault({}) MyBindingEventSubscriber eventSubscriber;
public MyBindingThingHandlerFactory() {
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return MyBindingMachineThingHandler.supportsThingType(thingTypeUID);
}
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (MyBindingThingHandler.supportsThingType(thingTypeUID)) {
return new MyBindingThingHandler(thing, eventSubscriber);
}
return null;
}
}
This @Reference doesn’t work. And at the same time I cannot reference the Factory inside the event listener.
The error I get is:
Feature resolution failed for [openhab-binding-mybinding/3.0.0.SNAPSHOT]
[ERROR] Message: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity
I’ve also tried getting hold of the reference via FramWorkUtil.getBundle and bundleContext.
Hi!
Still can’t get it to work.
Adding the class in the component annotation removes the compilation error. The reference is still null. I removed the xml-file as well.
This is what I currently have:
@Component(service = {EventSubscriber.class, MySubscriber.class}, property = { "service.pid=org.openhab.binding.mybinding.MySubscriber",
"service.config.description.uri=binding:mybinding", "service.config.label=MyBidning Integration",
"service.config.category=binding" })
public class MySubscriber implements EventSubscriber {
private final Logger logger = LoggerFactory.getLogger(MySubscriber.class);
private final Set<String> subscribedEventTypes = new HashSet<String>();
public MySubscriber() {
subscribedEventTypes.add(ItemStateEvent.TYPE);
subscribedEventTypes.add(ItemCommandEvent.TYPE);
}
@Override
public Set<String> getSubscribedEventTypes() {
return subscribedEventTypes;
}
@Override
public EventFilter getEventFilter() {
return null;
}
@Override
public void receive(Event event) {
logger.debug("Got Event event: topic {} payload: {}", event.getTopic(), event.getPayload());
}
Below the @Reference object is always null.
@Component(service = {ThingHandlerFactory.class, MyBindingThingHandlerFactory.class} , configurationPid = "binding.mybinding")
@NonNullByDefault
public class MyBindingThingHandlerFactory extends BaseThingHandlerFactory {
@Reference
private @NonNullByDefault({}) MySubscriber eventSubscriber;
public MyBindingThingHandlerFactory() {
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return MyBindingMachineThingHandler.supportsThingType(thingTypeUID);
}
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (MyBindingThingHandler.supportsThingType(thingTypeUID)) {
return new MyBindingThingHandler(thing, eventSubscriber);
}
return null;
}
}
I’ve experimented with adding immidate=true, and passing the reference in the constructor with @Reference and annotated constructor with @Activate, but doing so the binding silently fail (or the Eventsubscriber is at least not working.
I don’t know if it makes a difference, but can you try setting only service on the MySubscriber class in @Component and add a configurationPid = "binding.mybinding.eventsubscriber
Preferred initialization in Factory class would be:
private final MySubscriber eventSubscriber;
@Activate
public MyBindingThingHandlerFactory(@Reference MySubscriber eventSubscriber) {
this.eventSubscriber = eventSubscriber;
...
Also I would not expect MyBindingThingHandlerFactory.class to be in the service in the @Component in that class.