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);
}
}
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);
}
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);
}
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);
}
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);
}
Aggregations