Search in sources :

Example 21 with ThingHandlerFactory

use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.

the class ThingManagerImpl method doRegisterHandler.

private void doRegisterHandler(final Thing thing, final ThingHandlerFactory thingHandlerFactory) {
    logger.debug("Calling '{}.registerHandler()' for thing '{}'.", thingHandlerFactory.getClass().getSimpleName(), thing.getUID());
    try {
        ThingHandler thingHandler = thingHandlerFactory.registerHandler(thing);
        thingHandler.setCallback(ThingManagerImpl.this.thingHandlerCallback);
        thing.setHandler(thingHandler);
        thingHandlers.put(thing.getUID(), thingHandler);
        synchronized (thingHandlersByFactory) {
            thingHandlersByFactory.computeIfAbsent(thingHandlerFactory, unused -> new HashSet<>()).add(thingHandler);
        }
    } catch (Exception ex) {
        ThingStatusInfo statusInfo = buildStatusInfo(ThingStatus.UNINITIALIZED, ThingStatusDetail.HANDLER_REGISTERING_ERROR, ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
        setThingStatus(thing, statusInfo);
        logger.error("Exception occurred while calling thing handler factory '{}': {}", thingHandlerFactory, ex.getMessage(), ex);
    }
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) LoggerFactory(org.slf4j.LoggerFactory) SafeCaller(org.openhab.core.common.SafeCaller) ReadyTracker(org.openhab.core.service.ReadyService.ReadyTracker) StorageService(org.openhab.core.storage.StorageService) ConfigDescriptionRegistry(org.openhab.core.config.core.ConfigDescriptionRegistry) ChannelTypeRegistry(org.openhab.core.thing.type.ChannelTypeRegistry) Nullable(org.eclipse.jdt.annotation.Nullable) Configuration(org.openhab.core.config.core.Configuration) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) Map(java.util.Map) UID(org.openhab.core.thing.UID) URI(java.net.URI) ChannelGroupUID(org.openhab.core.thing.ChannelGroupUID) EventPublisher(org.openhab.core.events.EventPublisher) ConfigDescription(org.openhab.core.config.core.ConfigDescription) BundleResolver(org.openhab.core.util.BundleResolver) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Storage(org.openhab.core.storage.Storage) ChannelBuilder(org.openhab.core.thing.binding.builder.ChannelBuilder) ItemChannelLinkRegistry(org.openhab.core.thing.link.ItemChannelLinkRegistry) Deactivate(org.osgi.service.component.annotations.Deactivate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BridgeHandler(org.openhab.core.thing.binding.BridgeHandler) ReferencePolicy(org.osgi.service.component.annotations.ReferencePolicy) PrivilegedAction(java.security.PrivilegedAction) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) ThingTypeRegistry(org.openhab.core.thing.type.ThingTypeRegistry) ReadyMarkerUtils(org.openhab.core.service.ReadyMarkerUtils) Channel(org.openhab.core.thing.Channel) ThingTypeMigrationService(org.openhab.core.thing.ThingTypeMigrationService) ThingEventFactory(org.openhab.core.thing.events.ThingEventFactory) List(java.util.List) ThingRegistry(org.openhab.core.thing.ThingRegistry) Provider(org.openhab.core.common.registry.Provider) ChannelGroupTypeRegistry(org.openhab.core.thing.type.ChannelGroupTypeRegistry) Entry(java.util.Map.Entry) AccessController(java.security.AccessController) ConfigValidationException(org.openhab.core.config.core.validation.ConfigValidationException) ThingManager(org.openhab.core.thing.ThingManager) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) StartLevelService(org.openhab.core.service.StartLevelService) ChannelGroupType(org.openhab.core.thing.type.ChannelGroupType) ThingType(org.openhab.core.thing.type.ThingType) ThingStatusInfoBuilder(org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder) ChannelDefinition(org.openhab.core.thing.type.ChannelDefinition) ComponentContext(org.osgi.service.component.ComponentContext) HashMap(java.util.HashMap) Function(java.util.function.Function) MessageFormat(java.text.MessageFormat) ArrayList(java.util.ArrayList) ConfigDescriptionValidator(org.openhab.core.config.core.validation.ConfigDescriptionValidator) ThingStatusInfoI18nLocalizationService(org.openhab.core.thing.i18n.ThingStatusInfoI18nLocalizationService) HashSet(java.util.HashSet) Thing(org.openhab.core.thing.Thing) Component(org.osgi.service.component.annotations.Component) ChannelGroupTypeUID(org.openhab.core.thing.type.ChannelGroupTypeUID) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ChannelUID(org.openhab.core.thing.ChannelUID) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) Activate(org.osgi.service.component.annotations.Activate) ThingTypeUID(org.openhab.core.thing.ThingTypeUID) ThreadPoolManager(org.openhab.core.common.ThreadPoolManager) ThingStatus(org.openhab.core.thing.ThingStatus) ThingHandlerHelper(org.openhab.core.thing.util.ThingHandlerHelper) Command(org.openhab.core.types.Command) Logger(org.slf4j.Logger) ReentrantLock(java.util.concurrent.locks.ReentrantLock) ThingUID(org.openhab.core.thing.ThingUID) ReadyMarkerFilter(org.openhab.core.service.ReadyMarkerFilter) ThingHandler(org.openhab.core.thing.binding.ThingHandler) State(org.openhab.core.types.State) ThingStatusDetail(org.openhab.core.thing.ThingStatusDetail) ReadyMarker(org.openhab.core.service.ReadyMarker) ChannelType(org.openhab.core.thing.type.ChannelType) TimeUnit(java.util.concurrent.TimeUnit) ReferenceCardinality(org.osgi.service.component.annotations.ReferenceCardinality) Lock(java.util.concurrent.locks.Lock) ReadyService(org.openhab.core.service.ReadyService) ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) Identifiable(org.openhab.core.common.registry.Identifiable) Reference(org.osgi.service.component.annotations.Reference) ManagedProvider(org.openhab.core.common.registry.ManagedProvider) Bridge(org.openhab.core.thing.Bridge) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) ConfigValidationException(org.openhab.core.config.core.validation.ConfigValidationException) HashSet(java.util.HashSet)

Example 22 with ThingHandlerFactory

use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.

the class ThingManagerImpl method thingRemoved.

@Override
public void thingRemoved(final Thing thing, ThingTrackerEvent thingTrackerEvent) {
    logger.debug("Thing '{}' is no longer tracked by ThingManager.", thing.getUID());
    ThingHandler thingHandler = thingHandlers.get(thing.getUID());
    if (thingHandler != null) {
        final ThingHandlerFactory thingHandlerFactory = findThingHandlerFactory(thing.getThingTypeUID());
        if (thingHandlerFactory != null) {
            unregisterAndDisposeHandler(thingHandlerFactory, thing, thingHandler);
            if (thingTrackerEvent == ThingTrackerEvent.THING_REMOVED) {
                safeCaller.create(thingHandlerFactory, ThingHandlerFactory.class).build().removeThing(thing.getUID());
            }
        } else {
            logger.warn("Cannot unregister handler. No handler factory for thing '{}' found.", thing.getUID());
        }
    }
    this.things.remove(thing);
}
Also used : ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory)

Example 23 with ThingHandlerFactory

use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.

the class ThingManagerImpl method migrateThingType.

@Override
public void migrateThingType(final Thing thing, final ThingTypeUID thingTypeUID, @Nullable final Configuration configuration) {
    final ThingType thingType = thingTypeRegistry.getThingType(thingTypeUID);
    if (thingType == null) {
        throw new IllegalStateException(MessageFormat.format("No thing type {0} registered, cannot change thing type for thing {1}", thingTypeUID.getAsString(), thing.getUID().getAsString()));
    }
    scheduler.schedule(new Runnable() {

        @Override
        public void run() {
            ThingUID thingUID = thing.getUID();
            Lock lock = getLockForThing(thingUID);
            try {
                lock.lock();
                // Remove the ThingHandler, if any
                final ThingHandlerFactory oldThingHandlerFactory = findThingHandlerFactory(thing.getThingTypeUID());
                if (oldThingHandlerFactory != null) {
                    ThingHandler thingHandler = thing.getHandler();
                    if (thingHandler != null) {
                        unregisterAndDisposeHandler(oldThingHandlerFactory, thing, thingHandler);
                        waitUntilHandlerUnregistered(thing, 60 * 1000);
                    } else {
                        logger.debug("No ThingHandler to dispose for {}", thing.getUID());
                    }
                } else {
                    logger.debug("No ThingHandlerFactory available that can handle {}", thing.getThingTypeUID());
                }
                // Set the new channels
                List<Channel> channels = ThingFactoryHelper.createChannels(thingType, thingUID, configDescriptionRegistry);
                ((ThingImpl) thing).setChannels(channels);
                // Set the given configuration
                Configuration editConfiguration = configuration != null ? configuration : new Configuration();
                ThingFactoryHelper.applyDefaultConfiguration(editConfiguration, thingType, configDescriptionRegistry);
                ((ThingImpl) thing).setConfiguration(editConfiguration);
                // Set the new properties (keeping old properties, unless they have the same name as a new property)
                for (Entry<String, String> entry : thingType.getProperties().entrySet()) {
                    ((ThingImpl) thing).setProperty(entry.getKey(), entry.getValue());
                }
                // Change the ThingType
                ((ThingImpl) thing).setThingTypeUID(thingTypeUID);
                // Register the new Handler - ThingManager.updateThing() is going to take care of that
                thingRegistry.update(thing);
                ThingHandler handler = thing.getHandler();
                logger.debug("Changed ThingType of Thing {} to {}. New ThingHandler is {}.", thingUID, thing.getThingTypeUID(), handler == null ? "NO HANDLER" : handler);
            } finally {
                lock.unlock();
            }
        }

        private void waitUntilHandlerUnregistered(final Thing thing, int timeout) {
            for (int i = 0; i < timeout / 100; i++) {
                if (thing.getHandler() == null && thingHandlers.get(thing.getUID()) == null) {
                    return;
                }
                try {
                    Thread.sleep(100);
                    logger.debug("Waiting for handler deregistration to complete for thing {}. Took already {}ms.", thing.getUID().getAsString(), (i + 1) * 100);
                } catch (InterruptedException e) {
                    return;
                }
            }
            String message = MessageFormat.format("Thing type migration failed for {0}. The handler deregistration did not complete within {1}ms.", thing.getUID().getAsString(), timeout);
            logger.error(message);
            throw new IllegalStateException(message);
        }
    }, 0, TimeUnit.MILLISECONDS);
}
Also used : Configuration(org.openhab.core.config.core.Configuration) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingType(org.openhab.core.thing.type.ThingType) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock) Entry(java.util.Map.Entry) ThingUID(org.openhab.core.thing.ThingUID) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Thing(org.openhab.core.thing.Thing)

Example 24 with ThingHandlerFactory

use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.

the class ThingManagerImplTest method thingHandlerFactoryLifecycle.

@Test
public void thingHandlerFactoryLifecycle() {
    ThingHandlerFactory mockFactory1 = mock(ThingHandlerFactory.class);
    ThingHandlerFactory mockFactory2 = mock(ThingHandlerFactory.class);
    when(storageServiceMock.getStorage(any(), any())).thenReturn(storageMock);
    when(storageMock.get(any())).thenReturn(null);
    ThingManagerImpl thingManager = createThingManager();
    thingManager.thingAdded(thingMock, ThingTrackerEvent.THING_ADDED);
    thingManager.addThingHandlerFactory(mockFactory1);
    verify(mockFactory1, atLeastOnce()).supportsThingType(any());
    thingManager.removeThingHandlerFactory(mockFactory1);
    thingManager.addThingHandlerFactory(mockFactory2);
    verify(mockFactory2, atLeastOnce()).supportsThingType(any());
    thingManager.removeThingHandlerFactory(mockFactory2);
}
Also used : ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) Test(org.junit.jupiter.api.Test)

Example 25 with ThingHandlerFactory

use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.

the class ChannelStateDescriptionProviderOSGiTest method beforeEach.

@BeforeEach
public void beforeEach() throws Exception {
    Mockito.when(componentContext.getBundleContext()).thenReturn(bundleContext);
    registerVolatileStorageService();
    itemRegistry = getService(ItemRegistry.class);
    assertNotNull(itemRegistry);
    final TestThingHandlerFactory thingHandlerFactory = new TestThingHandlerFactory();
    thingHandlerFactory.activate(componentContext);
    registerService(thingHandlerFactory, ThingHandlerFactory.class.getName());
    final StateDescriptionFragment state = StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.ZERO).withMaximum(BigDecimal.valueOf(100)).withStep(BigDecimal.TEN).withPattern("%d Peek").withReadOnly(true).withOption(new StateOption("SOUND", "My great sound.")).build();
    final StateDescriptionFragment state2 = StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.ZERO).withMaximum(BigDecimal.valueOf(256)).withStep(BigDecimal.valueOf(8)).build();
    final ChannelType channelType = ChannelTypeBuilder.state(new ChannelTypeUID("hue:alarm"), " ", CoreItemFactory.NUMBER).withStateDescriptionFragment(state).build();
    final ChannelType channelType2 = ChannelTypeBuilder.state(new ChannelTypeUID("hue:num"), " ", CoreItemFactory.NUMBER).withStateDescriptionFragment(state2).build();
    final ChannelType channelType3 = ChannelTypeBuilder.state(new ChannelTypeUID("hue:info"), " ", CoreItemFactory.STRING).isAdvanced(true).build();
    final ChannelType channelType4 = ChannelTypeBuilder.state(new ChannelTypeUID("hue:color"), "Color", CoreItemFactory.COLOR).withCategory("ColorLight").build();
    final ChannelType channelType5 = ChannelTypeBuilder.state(new ChannelTypeUID("hue:brightness"), "Brightness", CoreItemFactory.DIMMER).withCategory("Light").build();
    final ChannelType channelType6 = ChannelTypeBuilder.state(new ChannelTypeUID("hue:switch"), "Switch", CoreItemFactory.SWITCH).withCategory("Light").build();
    final ChannelType channelType7 = ChannelTypeBuilder.state(CHANNEL_TYPE_7_UID, " ", CoreItemFactory.NUMBER).withCategory("Light").withStateDescriptionFragment(state).build();
    List<ChannelType> channelTypes = new ArrayList<>();
    channelTypes.add(channelType);
    channelTypes.add(channelType2);
    channelTypes.add(channelType3);
    channelTypes.add(channelType4);
    channelTypes.add(channelType5);
    channelTypes.add(channelType6);
    channelTypes.add(channelType7);
    registerService(new ChannelTypeProvider() {

        @Override
        public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
            return channelTypes;
        }

        @Override
        @Nullable
        public ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
            for (final ChannelType channelType : channelTypes) {
                if (channelType.getUID().equals(channelTypeUID)) {
                    return channelType;
                }
            }
            return null;
        }
    });
    testBundle = SyntheticBundleInstaller.install(bundleContext, TEST_BUNDLE_NAME);
    assertThat(testBundle, is(notNullValue()));
    thingStatusInfoI18nLocalizationService = getService(ThingStatusInfoI18nLocalizationService.class);
    assertThat(thingStatusInfoI18nLocalizationService, is(notNullValue()));
    thingStatusInfoI18nLocalizationService.setBundleResolver(new BundleResolverImpl());
    List<ChannelDefinition> channelDefinitions = new ArrayList<>();
    channelDefinitions.add(new ChannelDefinitionBuilder("1", channelType.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("2", channelType2.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("3", channelType3.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("4", channelType4.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("5", channelType5.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("6", channelType6.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("7_1", channelType7.getUID()).build());
    channelDefinitions.add(new ChannelDefinitionBuilder("7_2", channelType7.getUID()).build());
    registerService(new SimpleThingTypeProvider(Set.of(ThingTypeBuilder.instance(new ThingTypeUID("hue:lamp"), "label").withChannelDefinitions(channelDefinitions).build())));
    List<Item> items = new ArrayList<>();
    items.add(new NumberItem("TestItem"));
    items.add(new NumberItem("TestItem2"));
    items.add(new StringItem("TestItem3"));
    items.add(new ColorItem("TestItem4"));
    items.add(new DimmerItem("TestItem5"));
    items.add(new SwitchItem("TestItem6"));
    items.add(new NumberItem("TestItem7_1"));
    items.add(new NumberItem("TestItem7_2"));
    registerService(new TestItemProvider(items));
    linkRegistry = getService(ItemChannelLinkRegistry.class);
}
Also used : Locale(java.util.Locale) ChannelDefinitionBuilder(org.openhab.core.thing.type.ChannelDefinitionBuilder) ArrayList(java.util.ArrayList) ColorItem(org.openhab.core.library.items.ColorItem) ItemRegistry(org.openhab.core.items.ItemRegistry) NumberItem(org.openhab.core.library.items.NumberItem) DimmerItem(org.openhab.core.library.items.DimmerItem) SwitchItem(org.openhab.core.library.items.SwitchItem) ColorItem(org.openhab.core.library.items.ColorItem) Item(org.openhab.core.items.Item) StringItem(org.openhab.core.library.items.StringItem) ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) DimmerItem(org.openhab.core.library.items.DimmerItem) ItemChannelLinkRegistry(org.openhab.core.thing.link.ItemChannelLinkRegistry) StateDescriptionFragment(org.openhab.core.types.StateDescriptionFragment) SwitchItem(org.openhab.core.library.items.SwitchItem) ThingStatusInfoI18nLocalizationService(org.openhab.core.thing.i18n.ThingStatusInfoI18nLocalizationService) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) BaseThingHandlerFactory(org.openhab.core.thing.binding.BaseThingHandlerFactory) StringItem(org.openhab.core.library.items.StringItem) StateOption(org.openhab.core.types.StateOption) NumberItem(org.openhab.core.library.items.NumberItem) ChannelDefinition(org.openhab.core.thing.type.ChannelDefinition) ChannelTypeProvider(org.openhab.core.thing.type.ChannelTypeProvider) Collection(java.util.Collection) ThingTypeUID(org.openhab.core.thing.ThingTypeUID) ChannelType(org.openhab.core.thing.type.ChannelType) Nullable(org.eclipse.jdt.annotation.Nullable) BeforeEach(org.junit.jupiter.api.BeforeEach)

Aggregations

ThingHandlerFactory (org.openhab.core.thing.binding.ThingHandlerFactory)40 Thing (org.openhab.core.thing.Thing)32 ThingHandler (org.openhab.core.thing.binding.ThingHandler)31 ThingTypeUID (org.openhab.core.thing.ThingTypeUID)30 Test (org.junit.jupiter.api.Test)27 JavaOSGiTest (org.openhab.core.test.java.JavaOSGiTest)26 Nullable (org.eclipse.jdt.annotation.Nullable)25 ThingHandlerCallback (org.openhab.core.thing.binding.ThingHandlerCallback)20 InvocationOnMock (org.mockito.invocation.InvocationOnMock)19 ThingStatusInfo (org.openhab.core.thing.ThingStatusInfo)15 ArrayList (java.util.ArrayList)8 ThingUID (org.openhab.core.thing.ThingUID)8 Configuration (org.openhab.core.config.core.Configuration)6 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)5 Item (org.openhab.core.items.Item)5 Bridge (org.openhab.core.thing.Bridge)5 ThingRegistry (org.openhab.core.thing.ThingRegistry)5 BaseThingHandlerFactory (org.openhab.core.thing.binding.BaseThingHandlerFactory)5 BeforeEach (org.junit.jupiter.api.BeforeEach)4 StringItem (org.openhab.core.library.items.StringItem)4