Search in sources :

Example 6 with ThingHandlerCallback

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

the class InsteonDeviceHandler method initialize.

@Override
public void initialize() {
    config = getConfigAs(InsteonDeviceConfiguration.class);
    scheduler.execute(() -> {
        if (getBridge() == null) {
            String msg = "An Insteon network bridge has not been selected for this device.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        InsteonDeviceConfiguration config = this.config;
        if (config == null) {
            String msg = "Insteon device configuration is null.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        String address = config.getAddress();
        if (!InsteonAddress.isValid(address)) {
            String msg = "Unable to start Insteon device, the insteon or X10 address '" + address + "' is invalid. It must be in the format 'AB.CD.EF' or 'H.U' (X10).";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        DeviceTypeLoader instance = DeviceTypeLoader.instance();
        if (instance == null) {
            String msg = "Device type loader is null.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        String productKey = config.getProductKey();
        if (instance.getDeviceType(productKey) == null) {
            String msg = "Unable to start Insteon device, invalid product key '" + productKey + "'.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        String deviceConfig = config.getDeviceConfig();
        Map<String, Object> deviceConfigMap;
        if (deviceConfig != null) {
            Type mapType = new TypeToken<Map<String, Object>>() {
            }.getType();
            try {
                deviceConfigMap = Objects.requireNonNull(new Gson().fromJson(deviceConfig, mapType));
            } catch (JsonParseException e) {
                String msg = "The device configuration parameter is not valid JSON.";
                logger.warn("{} {}", thing.getUID().getAsString(), msg);
                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
                return;
            }
        } else {
            deviceConfigMap = Collections.emptyMap();
        }
        InsteonBinding insteonBinding = getInsteonBinding();
        InsteonAddress insteonAddress = new InsteonAddress(address);
        if (insteonBinding.getDevice(insteonAddress) != null) {
            String msg = "A device already exists with the address '" + address + "'.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        InsteonDevice device = insteonBinding.makeNewDevice(insteonAddress, productKey, deviceConfigMap);
        if (device == null) {
            String msg = "Unable to create a device with the product key '" + productKey + "' with the address'" + address + "'.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        ThingHandlerCallback callback = getCallback();
        if (callback == null) {
            String msg = "Unable to get thing handler callback.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
            return;
        }
        Map<String, Channel> channelMap = new HashMap<>();
        String thingId = getThing().getUID().getAsString();
        for (String channelId : ALL_CHANNEL_IDS) {
            String feature = channelId.toLowerCase();
            if (productKey.equals(HIDDEN_DOOR_SENSOR_PRODUCT_KEY)) {
                if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL) || feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_WATERMARK_LEVEL)) {
                    feature = DATA;
                }
            } else if (productKey.equals(MOTION_SENSOR_PRODUCT_KEY)) {
                if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL) || feature.equalsIgnoreCase(InsteonBindingConstants.LIGHT_LEVEL)) {
                    feature = DATA;
                }
            } else if (productKey.equals(MOTION_SENSOR_II_PRODUCT_KEY)) {
                if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL) || feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_PERCENT) || feature.equalsIgnoreCase(InsteonBindingConstants.LIGHT_LEVEL) || feature.equalsIgnoreCase(InsteonBindingConstants.TEMPERATURE_LEVEL)) {
                    feature = DATA;
                }
            } else if (productKey.equals(PLM_PRODUCT_KEY)) {
                String[] parts = feature.split("#");
                if (parts.length == 2 && parts[0].equalsIgnoreCase(InsteonBindingConstants.BROADCAST_ON_OFF) && parts[1].matches("^\\d+$")) {
                    feature = BROADCAST_ON_OFF;
                }
            } else if (productKey.equals(POWER_METER_PRODUCT_KEY)) {
                if (feature.equalsIgnoreCase(InsteonBindingConstants.KWH) || feature.equalsIgnoreCase(InsteonBindingConstants.RESET) || feature.equalsIgnoreCase(InsteonBindingConstants.UPDATE) || feature.equalsIgnoreCase(InsteonBindingConstants.WATTS)) {
                    feature = METER;
                }
            }
            DeviceFeature f = device.getFeature(feature);
            if (f != null) {
                if (!f.isFeatureGroup()) {
                    if (channelId.equals(InsteonBindingConstants.BROADCAST_ON_OFF)) {
                        Set<String> broadcastChannels = new HashSet<>();
                        for (Channel channel : thing.getChannels()) {
                            String id = channel.getUID().getId();
                            if (id.startsWith(InsteonBindingConstants.BROADCAST_ON_OFF)) {
                                channelMap.put(id, channel);
                                broadcastChannels.add(id);
                            }
                        }
                        Object groups = deviceConfigMap.get(BROADCAST_GROUPS);
                        if (groups != null) {
                            boolean valid = false;
                            if (groups instanceof List<?>) {
                                valid = true;
                                for (Object o : (List<?>) groups) {
                                    if (o instanceof Double && (Double) o % 1 == 0) {
                                        String id = InsteonBindingConstants.BROADCAST_ON_OFF + "#" + ((Double) o).intValue();
                                        if (!broadcastChannels.contains(id)) {
                                            ChannelUID channelUID = new ChannelUID(thing.getUID(), id);
                                            ChannelTypeUID channelTypeUID = new ChannelTypeUID(InsteonBindingConstants.BINDING_ID, InsteonBindingConstants.SWITCH);
                                            Channel channel = callback.createChannelBuilder(channelUID, channelTypeUID).withLabel(id).build();
                                            channelMap.put(id, channel);
                                            broadcastChannels.add(id);
                                        }
                                    } else {
                                        valid = false;
                                        break;
                                    }
                                }
                            }
                            if (!valid) {
                                String msg = "The value for key " + BROADCAST_GROUPS + " must be an array of integers in the device configuration parameter.";
                                logger.warn("{} {}", thing.getUID().getAsString(), msg);
                                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
                                return;
                            }
                        }
                    } else {
                        ChannelUID channelUID = new ChannelUID(thing.getUID(), channelId);
                        ChannelTypeUID channelTypeUID = new ChannelTypeUID(InsteonBindingConstants.BINDING_ID, channelId);
                        Channel channel = thing.getChannel(channelUID);
                        if (channel == null) {
                            channel = callback.createChannelBuilder(channelUID, channelTypeUID).build();
                        }
                        channelMap.put(channelId, channel);
                    }
                } else {
                    logger.debug("{} is a feature group for {}. It will not be added as a channel.", feature, productKey);
                }
            }
        }
        if (!channelMap.isEmpty() || device.isModem()) {
            List<Channel> channels = new ArrayList<>();
            StringBuilder channelList = new StringBuilder();
            if (!channelMap.isEmpty()) {
                List<String> channelIds = new ArrayList<>(channelMap.keySet());
                Collections.sort(channelIds);
                channelIds.forEach(channelId -> {
                    Channel channel = channelMap.get(channelId);
                    if (channel != null) {
                        channels.add(channel);
                        if (channelList.length() > 0) {
                            channelList.append(", ");
                        }
                        channelList.append(channelId);
                    }
                });
                updateThing(editThing().withChannels(channels).build());
            }
            StringBuilder builder = new StringBuilder(thingId);
            builder.append(" address = ");
            builder.append(address);
            builder.append(" productKey = ");
            builder.append(productKey);
            builder.append(" channels = ");
            builder.append(channelList.toString());
            String msg = builder.toString();
            logger.debug("{}", msg);
            getInsteonNetworkHandler().initialized(getThing().getUID(), msg);
            channels.forEach(channel -> {
                if (isLinked(channel.getUID())) {
                    channelLinked(channel.getUID());
                }
            });
            updateStatus(ThingStatus.ONLINE);
        } else {
            String msg = "Product key '" + productKey + "' does not have any features that match existing channels.";
            logger.warn("{} {}", thing.getUID().getAsString(), msg);
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
        }
    });
}
Also used : InsteonDevice(org.openhab.binding.insteon.internal.device.InsteonDevice) HashMap(java.util.HashMap) InsteonAddress(org.openhab.binding.insteon.internal.device.InsteonAddress) ArrayList(java.util.ArrayList) Gson(com.google.gson.Gson) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) JsonParseException(com.google.gson.JsonParseException) ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) ChannelUID(org.openhab.core.thing.ChannelUID) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) InsteonDeviceConfiguration(org.openhab.binding.insteon.internal.config.InsteonDeviceConfiguration) InsteonBinding(org.openhab.binding.insteon.internal.InsteonBinding) Channel(org.openhab.core.thing.Channel) Type(java.lang.reflect.Type) DeviceFeature(org.openhab.binding.insteon.internal.device.DeviceFeature) DeviceTypeLoader(org.openhab.binding.insteon.internal.device.DeviceTypeLoader) HashMap(java.util.HashMap) Map(java.util.Map)

Example 7 with ThingHandlerCallback

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

the class DarkSkyWeatherAndForecastHandler method createChannelsForGroup.

/**
 * Creates all {@link Channel}s for the given {@link ChannelGroupTypeUID}.
 *
 * @param channelGroupId the channel group id
 * @param channelGroupTypeUID the {@link ChannelGroupTypeUID}
 * @return a list of all {@link Channel}s for the channel group
 */
private List<Channel> createChannelsForGroup(String channelGroupId, ChannelGroupTypeUID channelGroupTypeUID) {
    logger.debug("Building channel group '{}' for thing '{}'.", channelGroupId, getThing().getUID());
    List<Channel> channels = new ArrayList<>();
    ThingHandlerCallback callback = getCallback();
    if (callback != null) {
        for (ChannelBuilder channelBuilder : callback.createChannelBuilders(new ChannelGroupUID(getThing().getUID(), channelGroupId), channelGroupTypeUID)) {
            Channel newChannel = channelBuilder.build(), existingChannel = getThing().getChannel(newChannel.getUID().getId());
            if (existingChannel != null) {
                logger.trace("Thing '{}' already has an existing channel '{}'. Omit adding new channel '{}'.", getThing().getUID(), existingChannel.getUID(), newChannel.getUID());
                continue;
            }
            channels.add(newChannel);
        }
    }
    return channels;
}
Also used : ChannelGroupUID(org.openhab.core.thing.ChannelGroupUID) Channel(org.openhab.core.thing.Channel) ArrayList(java.util.ArrayList) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ChannelBuilder(org.openhab.core.thing.binding.builder.ChannelBuilder)

Example 8 with ThingHandlerCallback

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

the class DwdUnwetterHandler method createChannels.

/**
 * Creates the Channels for each warning.
 *
 * @return The List of Channels to be added
 */
private List<Channel> createChannels(int warningNumber) {
    logger.debug("Building channels for thing '{}'.", getThing().getUID());
    List<Channel> channels = new ArrayList<>();
    ThingHandlerCallback callback = getCallback();
    if (callback != null) {
        createChannelIfNotExist(callback, channels, CHANNEL_UPDATED, "Updated", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_WARNING, "Warning", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_SEVERITY, "Severity", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_DESCRIPTION, "Description", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_EFFECTIVE, "Issued", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_ONSET, "Valid From", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_EXPIRES, "Valid To", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_EVENT, "Type", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_HEADLINE, "Headline", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_ALTITUDE, "Height (from)", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_CEILING, "Height (to)", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_INSTRUCTION, "Instruction", warningNumber);
        createChannelIfNotExist(callback, channels, CHANNEL_URGENCY, "Urgency", warningNumber);
    }
    return channels;
}
Also used : Channel(org.openhab.core.thing.Channel) ArrayList(java.util.ArrayList) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback)

Example 9 with ThingHandlerCallback

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

the class DeutscheBahnTimetableHandlerTest method testStopsAreOrderedByDeparture.

@Test
public void testStopsAreOrderedByDeparture() throws Exception {
    final Bridge bridge = mockBridge("departures");
    final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
    final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge, "/timetablesDataDifferentOrder");
    try {
        verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
        verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
        verifyThingUpdated(bridge, 0, "-5296516961807204721-2108160906-5");
        verifyThingUpdated(bridge, 1, "-8364795265993682073-2108160911-6");
    } finally {
        handler.dispose();
    }
}
Also used : ArgumentMatchers(org.mockito.ArgumentMatchers) TimetablesV1ApiStub(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiStub) ArrayList(java.util.ArrayList) TimetableStop(org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Thing(org.openhab.core.thing.Thing) Calendar(java.util.Calendar) Configuration(org.openhab.core.config.core.Configuration) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) ThingStatus(org.openhab.core.thing.ThingStatus) GregorianCalendar(java.util.GregorianCalendar) ThingUID(org.openhab.core.thing.ThingUID) UnDefType(org.openhab.core.types.UnDefType) TimetablesV1ImplTestHelper(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ImplTestHelper) Test(org.junit.jupiter.api.Test) TimeproviderStub(org.openhab.binding.deutschebahn.internal.timetable.TimeproviderStub) Mockito(org.mockito.Mockito) Channel(org.openhab.core.thing.Channel) List(java.util.List) Event(org.openhab.binding.deutschebahn.internal.timetable.dto.Event) HttpCallable(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable) TimetablesV1ApiFactory(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiFactory) Timetable(org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable) Bridge(org.openhab.core.thing.Bridge) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) Bridge(org.openhab.core.thing.Bridge) Test(org.junit.jupiter.api.Test)

Example 10 with ThingHandlerCallback

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

the class DeutscheBahnTimetableHandlerTest method testStopsAreOrderedByArrival.

@Test
public void testStopsAreOrderedByArrival() throws Exception {
    final Bridge bridge = mockBridge("arrivals");
    final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
    final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge, "/timetablesDataDifferentOrder");
    try {
        verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
        verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
        verifyThingUpdated(bridge, 0, "-8364795265993682073-2108160911-6");
        verifyThingUpdated(bridge, 1, "-5296516961807204721-2108160906-5");
    } finally {
        handler.dispose();
    }
}
Also used : ArgumentMatchers(org.mockito.ArgumentMatchers) TimetablesV1ApiStub(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiStub) ArrayList(java.util.ArrayList) TimetableStop(org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Thing(org.openhab.core.thing.Thing) Calendar(java.util.Calendar) Configuration(org.openhab.core.config.core.Configuration) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) ThingStatus(org.openhab.core.thing.ThingStatus) GregorianCalendar(java.util.GregorianCalendar) ThingUID(org.openhab.core.thing.ThingUID) UnDefType(org.openhab.core.types.UnDefType) TimetablesV1ImplTestHelper(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ImplTestHelper) Test(org.junit.jupiter.api.Test) TimeproviderStub(org.openhab.binding.deutschebahn.internal.timetable.TimeproviderStub) Mockito(org.mockito.Mockito) Channel(org.openhab.core.thing.Channel) List(java.util.List) Event(org.openhab.binding.deutschebahn.internal.timetable.dto.Event) HttpCallable(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable) TimetablesV1ApiFactory(org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiFactory) Timetable(org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable) Bridge(org.openhab.core.thing.Bridge) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) Bridge(org.openhab.core.thing.Bridge) Test(org.junit.jupiter.api.Test)

Aggregations

ThingHandlerCallback (org.openhab.core.thing.binding.ThingHandlerCallback)79 Thing (org.openhab.core.thing.Thing)48 Test (org.junit.jupiter.api.Test)39 Configuration (org.openhab.core.config.core.Configuration)30 Channel (org.openhab.core.thing.Channel)30 JavaOSGiTest (org.openhab.core.test.java.JavaOSGiTest)28 ThingHandler (org.openhab.core.thing.binding.ThingHandler)26 ChannelUID (org.openhab.core.thing.ChannelUID)25 Nullable (org.eclipse.jdt.annotation.Nullable)23 InvocationOnMock (org.mockito.invocation.InvocationOnMock)23 ArrayList (java.util.ArrayList)19 ThingTypeUID (org.openhab.core.thing.ThingTypeUID)19 ThingHandlerFactory (org.openhab.core.thing.binding.ThingHandlerFactory)19 ThingStatusInfo (org.openhab.core.thing.ThingStatusInfo)18 ThingUID (org.openhab.core.thing.ThingUID)18 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)16 Bridge (org.openhab.core.thing.Bridge)12 ThingStatus (org.openhab.core.thing.ThingStatus)11 ChannelTypeUID (org.openhab.core.thing.type.ChannelTypeUID)11 List (java.util.List)10