Search in sources :

Example 1 with ChannelBuilder

use of org.openhab.core.thing.binding.builder.ChannelBuilder 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 2 with ChannelBuilder

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

the class EventFilterHandler method updateChannelSet.

/**
 * Checks existing channels, adds missing and removes extraneous channels from the Thing.
 *
 * @param config The validated Configuration of the Thing.
 */
private void updateChannelSet(EventFilterConfiguration config) {
    final ThingHandlerCallback handlerCallback = getCallback();
    if (handlerCallback == null) {
        return;
    }
    final List<Channel> currentChannels = getThing().getChannels();
    final ThingBuilder thingBuilder = editThing();
    BigDecimal maxEvents = config.maxEvents;
    if (maxEvents == null || maxEvents.compareTo(BigDecimal.ZERO) < 1) {
        thingBuilder.withoutChannels(currentChannels);
        updateThing(thingBuilder.build());
        return;
    }
    generateExpectedChannelList(maxEvents.intValue());
    synchronized (resultChannels) {
        currentChannels.stream().filter((Channel current) -> {
            String currentGroupId = current.getUID().getGroupId();
            if (currentGroupId == null) {
                return true;
            }
            for (ResultChannelSet channelSet : resultChannels) {
                if (channelSet.resultGroup.getId().contentEquals(currentGroupId)) {
                    return false;
                }
            }
            return true;
        }).forEach((Channel toDelete) -> {
            thingBuilder.withoutChannel(toDelete.getUID());
        });
        resultChannels.stream().filter((ResultChannelSet current) -> {
            return (getThing().getChannelsOfGroup(current.resultGroup.toString()).size() == 0);
        }).forEach((ResultChannelSet current) -> {
            for (ChannelBuilder builder : handlerCallback.createChannelBuilders(current.resultGroup, GROUP_TYPE_UID)) {
                Channel currentChannel = builder.build();
                Channel existingChannel = getThing().getChannel(currentChannel.getUID());
                if (existingChannel == null) {
                    thingBuilder.withChannel(currentChannel);
                }
            }
        });
    }
    updateThing(thingBuilder.build());
}
Also used : ThingBuilder(org.openhab.core.thing.binding.builder.ThingBuilder) Channel(org.openhab.core.thing.Channel) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ChannelBuilder(org.openhab.core.thing.binding.builder.ChannelBuilder) BigDecimal(java.math.BigDecimal)

Example 3 with ChannelBuilder

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

the class TrackerHandler method createBasicDistanceChannel.

/**
 * Create distance channel for measuring the distance between the tracker and the szstem.
 */
private void createBasicDistanceChannel() {
    @Nullable ThingHandlerCallback callback = getCallback();
    if (callback != null) {
        // find the system distance channel
        ChannelUID systemDistanceChannelUID = new ChannelUID(thing.getUID(), CHANNEL_DISTANCE_SYSTEM_ID);
        Channel systemDistance = thing.getChannel(CHANNEL_DISTANCE_SYSTEM_ID);
        ChannelBuilder channelBuilder = null;
        if (systemDistance != null) {
            if (!systemDistance.getConfiguration().get(CONFIG_REGION_CENTER_LOCATION).equals(sysLocation.toFullString())) {
                logger.trace("Existing distance channel for system. Changing system location config parameter: {}", sysLocation.toFullString());
                channelBuilder = callback.editChannel(thing, systemDistanceChannelUID);
                Configuration configToUpdate = systemDistance.getConfiguration();
                configToUpdate.put(CONFIG_REGION_CENTER_LOCATION, sysLocation.toFullString());
                channelBuilder.withConfiguration(configToUpdate);
            } else {
                logger.trace("Existing distance channel for system. No change.");
            }
        } else {
            logger.trace("Creating missing distance channel for system.");
            Configuration config = new Configuration();
            config.put(ConfigHelper.CONFIG_REGION_NAME, CHANNEL_DISTANCE_SYSTEM_NAME);
            config.put(CONFIG_REGION_CENTER_LOCATION, sysLocation.toFullString());
            config.put(ConfigHelper.CONFIG_REGION_RADIUS, CHANNEL_DISTANCE_SYSTEM_RADIUS);
            config.put(ConfigHelper.CONFIG_ACCURACY_THRESHOLD, 0);
            channelBuilder = callback.createChannelBuilder(systemDistanceChannelUID, CHANNEL_TYPE_DISTANCE).withLabel("System Distance").withConfiguration(config);
        }
        // update the thing with system distance channel
        if (channelBuilder != null) {
            List<Channel> channels = new ArrayList<>(thing.getChannels());
            if (systemDistance != null) {
                channels.remove(systemDistance);
            }
            channels.add(channelBuilder.build());
            ThingBuilder thingBuilder = editThing();
            thingBuilder.withChannels(channels);
            updateThing(thingBuilder.build());
            logger.debug("Distance channel created for system: {}", systemDistanceChannelUID);
        }
    }
}
Also used : ThingBuilder(org.openhab.core.thing.binding.builder.ThingBuilder) Configuration(org.openhab.core.config.core.Configuration) ChannelUID(org.openhab.core.thing.ChannelUID) 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) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 4 with ChannelBuilder

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

the class ApiPageParser method getApiPageEntry.

private void getApiPageEntry(@Nullable String id2, int line, int col, String shortName, String description, Object value) {
    if (logger.isTraceEnabled()) {
        logger.trace("Found parameter {}:{}:{} [{}] : {} \"{}\" = {}", id, line, col, this.fieldType, shortName, description, value);
    }
    if (!this.seenNames.add(shortName)) {
        logger.warn("Found duplicate parameter '{}' in {}:{}:{} [{}] : {} \"{}\" = {}", shortName, id, line, col, this.fieldType, shortName, description, value);
        return;
    }
    if (value instanceof String && ((String) value).contains("can_busy")) {
        // special state to indicate value currently cannot be retrieved..
        return;
    }
    ApiPageEntry.Type type;
    State state;
    String channelType;
    ChannelTypeUID ctuid;
    switch(this.fieldType) {
        case BUTTON:
            type = Type.SWITCH_BUTTON;
            state = this.buttonValue == ButtonValue.ON ? OnOffType.ON : OnOffType.OFF;
            ctuid = TACmiBindingConstants.CHANNEL_TYPE_SCHEME_SWITCH_RW_UID;
            channelType = "Switch";
            break;
        case READ_ONLY:
        case FORM_VALUE:
            String vs = (String) value;
            // C.M.I. mixes up languages...
            boolean isOn = "ON".equals(vs) || "EIN".equals(vs);
            if (isOn || "OFF".equals(vs) || "AUS".equals(vs)) {
                channelType = "Switch";
                state = isOn ? OnOffType.ON : OnOffType.OFF;
                if (this.fieldType == FieldType.READ_ONLY || this.address == null) {
                    ctuid = TACmiBindingConstants.CHANNEL_TYPE_SCHEME_SWITCH_RO_UID;
                    type = Type.READ_ONLY_SWITCH;
                } else {
                    ctuid = TACmiBindingConstants.CHANNEL_TYPE_SCHEME_SWITCH_RW_UID;
                    type = Type.SWITCH_FORM;
                }
            } else {
                try {
                    // check if we have a numeric value (either with or without unit)
                    String[] valParts = vs.split(" ");
                    // It seems for some wired cases the C.M.I. uses different decimal separators for
                    // different device types. It seems all 'new' X2-Devices use a dot as separator,
                    // for the older pre-X2 devices (i.e. the UVR 1611) we get a comma. So we
                    // we replace all ',' with '.' to check if it's a valid number...
                    String val = valParts[0].replace(',', '.');
                    BigDecimal bd = new BigDecimal(val);
                    if (valParts.length == 2) {
                        if ("°C".equals(valParts[1])) {
                            channelType = "Number:Temperature";
                            state = new QuantityType<>(bd, SIUnits.CELSIUS);
                        } else if ("%".equals(valParts[1])) {
                            // channelType = "Number:Percent"; Number:Percent is currently not handled...
                            channelType = "Number:Dimensionless";
                            state = new QuantityType<>(bd, Units.PERCENT);
                        } else if ("Imp".equals(valParts[1])) {
                            // impulses - no idea how to map this to something useful here?
                            channelType = "Number";
                            state = new DecimalType(bd);
                        } else if ("V".equals(valParts[1])) {
                            channelType = "Number:Voltage";
                            state = new QuantityType<>(bd, Units.VOLT);
                        } else if ("A".equals(valParts[1])) {
                            channelType = "Number:Current";
                            state = new QuantityType<>(bd, Units.AMPERE);
                        } else if ("Hz".equals(valParts[1])) {
                            channelType = "Number:Frequency";
                            state = new QuantityType<>(bd, Units.HERTZ);
                        } else if ("kW".equals(valParts[1])) {
                            channelType = "Number:Power";
                            bd = bd.multiply(new BigDecimal(1000));
                            state = new QuantityType<>(bd, Units.WATT);
                        } else if ("kWh".equals(valParts[1])) {
                            channelType = "Number:Power";
                            bd = bd.multiply(new BigDecimal(1000));
                            state = new QuantityType<>(bd, Units.KILOWATT_HOUR);
                        } else if ("l/h".equals(valParts[1])) {
                            channelType = "Number:Volume";
                            bd = bd.divide(new BigDecimal(60));
                            state = new QuantityType<>(bd, Units.LITRE_PER_MINUTE);
                        } else {
                            channelType = "Number";
                            state = new DecimalType(bd);
                            logger.debug("Unhandled UoM for channel {} of type {} for '{}': {}", shortName, channelType, description, valParts[1]);
                        }
                    } else {
                        channelType = "Number";
                        state = new DecimalType(bd);
                    }
                    if (this.fieldType == FieldType.READ_ONLY || this.address == null) {
                        ctuid = TACmiBindingConstants.CHANNEL_TYPE_SCHEME_NUMERIC_RO_UID;
                        type = Type.READ_ONLY_NUMERIC;
                    } else {
                        ctuid = null;
                        type = Type.NUMERIC_FORM;
                    }
                } catch (NumberFormatException nfe) {
                    // not a number...
                    channelType = "String";
                    if (this.fieldType == FieldType.READ_ONLY || this.address == null) {
                        ctuid = TACmiBindingConstants.CHANNEL_TYPE_SCHEME_STATE_RO_UID;
                        type = Type.READ_ONLY_STATE;
                    } else {
                        ctuid = null;
                        type = Type.STATE_FORM;
                    }
                    state = new StringType(vs);
                }
            }
            break;
        case UNKNOWN:
        case IGNORE:
            return;
        default:
            // should't happen but we have to add default for the compiler...
            return;
    }
    ApiPageEntry e = this.entries.get(shortName);
    boolean isNewEntry;
    if (e == null || e.type != type || !channelType.equals(e.channel.getAcceptedItemType())) {
        @Nullable Channel channel = this.taCmiSchemaHandler.getThing().getChannel(shortName);
        @Nullable ChangerX2Entry cx2e = null;
        if (this.fieldType == FieldType.FORM_VALUE) {
            try {
                URI uri = this.taCmiSchemaHandler.buildUri("INCLUDE/changerx2.cgi?sadrx2=" + address);
                final ChangerX2Parser pp = this.taCmiSchemaHandler.parsePage(uri, new ChangerX2Parser(shortName));
                cx2e = pp.getParsedEntry();
            } catch (final ParseException | RuntimeException ex) {
                logger.warn("Error parsing API Scheme: {} ", ex.getMessage(), ex);
            } catch (final TimeoutException | InterruptedException | ExecutionException ex) {
                logger.warn("Error loading API Scheme: {} ", ex.getMessage());
            }
        }
        if (channel == null || !Objects.equals(ctuid, channel.getChannelTypeUID())) {
            logger.debug("Creating / updating channel {} of type {} for '{}'", shortName, channelType, description);
            this.configChanged = true;
            ChannelUID channelUID = new ChannelUID(this.taCmiSchemaHandler.getThing().getUID(), shortName);
            ChannelBuilder channelBuilder = ChannelBuilder.create(channelUID, channelType);
            channelBuilder.withLabel(description);
            if (ctuid != null) {
                channelBuilder.withType(ctuid);
            } else if (cx2e != null) {
                ChannelType ct = buildAndRegisterChannelType(shortName, type, cx2e);
                channelBuilder.withType(ct.getUID());
            } else {
                logger.warn("Error configurating channel for {}: channeltype cannot be determined!", shortName);
            }
            // add configuration property...
            channel = channelBuilder.build();
        } else if (ctuid == null && cx2e != null) {
            // custom channel type - check if it already exists and recreate when needed...
            ChannelTypeUID curCtuid = channel.getChannelTypeUID();
            if (curCtuid != null) {
                ChannelType ct = channelTypeProvider.getChannelType(curCtuid, null);
                if (ct == null) {
                    buildAndRegisterChannelType(shortName, type, cx2e);
                }
            }
        }
        this.configChanged = true;
        e = new ApiPageEntry(type, channel, address, cx2e, state);
        this.entries.put(shortName, e);
        isNewEntry = true;
    } else {
        isNewEntry = false;
    }
    this.channels.add(e.channel);
    // polling the state. It might deliver the previous / old state.
    if (e.getLastCommandTS() < this.statusRequestStartTS) {
        Number updatePolicyI = (Number) e.channel.getConfiguration().get("updatePolicy");
        int updatePolicy = updatePolicyI == null ? 0 : updatePolicyI.intValue();
        switch(updatePolicy) {
            // 'default'
            case 0:
            default:
                // we do 'On-Fetch' update when channel is changeable, otherwise 'On-Change'
                switch(e.type) {
                    case NUMERIC_FORM:
                    case STATE_FORM:
                    case SWITCH_BUTTON:
                    case SWITCH_FORM:
                        if (isNewEntry || !state.equals(e.getLastState())) {
                            e.setLastState(state);
                            this.taCmiSchemaHandler.updateState(e.channel.getUID(), state);
                        }
                        break;
                    case READ_ONLY_NUMERIC:
                    case READ_ONLY_STATE:
                    case READ_ONLY_SWITCH:
                        e.setLastState(state);
                        this.taCmiSchemaHandler.updateState(e.channel.getUID(), state);
                        break;
                }
                break;
            case // On-Fetch
            1:
                e.setLastState(state);
                this.taCmiSchemaHandler.updateState(e.channel.getUID(), state);
                break;
            case // On-Change
            2:
                if (isNewEntry || !state.equals(e.getLastState())) {
                    e.setLastState(state);
                    this.taCmiSchemaHandler.updateState(e.channel.getUID(), state);
                }
                break;
        }
    }
}
Also used : StringType(org.openhab.core.library.types.StringType) URI(java.net.URI) ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) ChannelUID(org.openhab.core.thing.ChannelUID) Type(org.openhab.binding.tacmi.internal.schema.ApiPageEntry.Type) ExecutionException(java.util.concurrent.ExecutionException) ChannelBuilder(org.openhab.core.thing.binding.builder.ChannelBuilder) TimeoutException(java.util.concurrent.TimeoutException) Channel(org.openhab.core.thing.Channel) BigDecimal(java.math.BigDecimal) QuantityType(org.openhab.core.library.types.QuantityType) State(org.openhab.core.types.State) DecimalType(org.openhab.core.library.types.DecimalType) ParseException(org.attoparser.ParseException) ChannelType(org.openhab.core.thing.type.ChannelType) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 5 with ChannelBuilder

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

the class OwBaseThingHandler method addChannelIfMissingAndEnable.

/**
 * adds (or replaces) a channel and enables it within the sensor (configuration overridden)
 *
 * @param thingBuilder ThingBuilder of the edited thing
 * @param channelConfig a OwChannelConfig for the new channel
 * @param configuration the new Configuration for this channel
 * @param sensorNo number of sensor that provides this channel
 * @return the newly created channel
 */
protected Channel addChannelIfMissingAndEnable(ThingBuilder thingBuilder, OwChannelConfig channelConfig, @Nullable Configuration configuration, int sensorNo) {
    Channel channel = thing.getChannel(channelConfig.channelId);
    Configuration config = configuration;
    String label = channelConfig.label;
    // remove channel if wrong type uid and preserve config if not overridden
    if (channel != null && !channelConfig.channelTypeUID.equals(channel.getChannelTypeUID())) {
        removeChannelIfExisting(thingBuilder, channelConfig.channelId);
        if (config == null) {
            config = channel.getConfiguration();
        }
        channel = null;
    }
    // create channel if missing
    if (channel == null) {
        ChannelBuilder channelBuilder = ChannelBuilder.create(new ChannelUID(thing.getUID(), channelConfig.channelId), ACCEPTED_ITEM_TYPES_MAP.get(channelConfig.channelId)).withType(channelConfig.channelTypeUID);
        if (label != null) {
            channelBuilder.withLabel(label);
        }
        if (config != null) {
            channelBuilder.withConfiguration(config);
        }
        channel = channelBuilder.build();
        thingBuilder.withChannel(channel);
    }
    // enable channel in sensor
    sensors.get(sensorNo).enableChannel(channelConfig.channelId);
    return channel;
}
Also used : BaseHandlerConfiguration(org.openhab.binding.onewire.internal.config.BaseHandlerConfiguration) Configuration(org.openhab.core.config.core.Configuration) ChannelUID(org.openhab.core.thing.ChannelUID) Channel(org.openhab.core.thing.Channel) ChannelBuilder(org.openhab.core.thing.binding.builder.ChannelBuilder)

Aggregations

ChannelBuilder (org.openhab.core.thing.binding.builder.ChannelBuilder)25 ChannelUID (org.openhab.core.thing.ChannelUID)17 ThingBuilder (org.openhab.core.thing.binding.builder.ThingBuilder)10 ChannelTypeUID (org.openhab.core.thing.type.ChannelTypeUID)10 Channel (org.openhab.core.thing.Channel)9 Thing (org.openhab.core.thing.Thing)8 ThingHandlerCallback (org.openhab.core.thing.binding.ThingHandlerCallback)8 Configuration (org.openhab.core.config.core.Configuration)6 Nullable (org.eclipse.jdt.annotation.Nullable)5 Bridge (org.openhab.core.thing.Bridge)5 ArrayList (java.util.ArrayList)4 BigDecimal (java.math.BigDecimal)3 ChannelType (org.openhab.core.thing.type.ChannelType)3 Duration (java.time.Duration)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 Test (org.junit.jupiter.api.Test)2