Search in sources :

Example 1 with ChannelType

use of org.openhab.core.thing.type.ChannelType in project openhab-addons by openhab.

the class HarmonyDeviceHandler method updateButtonPressChannel.

/**
 * Updates the buttonPress channel with the available buttons as option states.
 */
private void updateButtonPressChannel(@Nullable HarmonyConfig harmonyConfig) {
    ChannelTypeUID channelTypeUID = new ChannelTypeUID(getThing().getUID().getAsString() + ":" + CHANNEL_BUTTON_PRESS);
    if (harmonyConfig == null) {
        logger.debug("Cannot update {} when HarmonyConfig is null", channelTypeUID);
        return;
    }
    logger.debug("Updating {}", channelTypeUID);
    List<StateOption> states = getButtonStateOptions(harmonyConfig);
    ChannelType channelType = ChannelTypeBuilder.state(channelTypeUID, "Send Button Press", "String").withDescription("Send a button press to device " + getThing().getLabel()).withStateDescriptionFragment(StateDescriptionFragmentBuilder.create().withOptions(states).build()).build();
    factory.addChannelType(channelType);
    Channel channel = ChannelBuilder.create(new ChannelUID(getThing().getUID(), CHANNEL_BUTTON_PRESS), "String").withType(channelTypeUID).build();
    // replace existing buttonPress with updated one
    List<Channel> newChannels = new ArrayList<>();
    for (Channel c : getThing().getChannels()) {
        if (!c.getUID().equals(channel.getUID())) {
            newChannels.add(c);
        }
    }
    newChannels.add(channel);
    ThingBuilder thingBuilder = editThing();
    thingBuilder.withChannels(newChannels);
    updateThing(thingBuilder.build());
}
Also used : ThingBuilder(org.openhab.core.thing.binding.builder.ThingBuilder) ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) ChannelUID(org.openhab.core.thing.ChannelUID) Channel(org.openhab.core.thing.Channel) ArrayList(java.util.ArrayList) ChannelType(org.openhab.core.thing.type.ChannelType) StateOption(org.openhab.core.types.StateOption)

Example 2 with ChannelType

use of org.openhab.core.thing.type.ChannelType in project openhab-addons by openhab.

the class HarmonyHubHandler method updateCurrentActivityChannel.

/**
 * Updates the current activity channel with the available activities as option states.
 */
private void updateCurrentActivityChannel(@Nullable HarmonyConfig config) {
    ChannelTypeUID channelTypeUID = new ChannelTypeUID(getThing().getUID() + ":" + CHANNEL_CURRENT_ACTIVITY);
    if (config == null) {
        logger.debug("Cannot update {} when HarmonyConfig is null", channelTypeUID);
        return;
    }
    logger.debug("Updating {}", channelTypeUID);
    List<Activity> activities = config.getActivities();
    // sort our activities in order
    Collections.sort(activities, ACTIVITY_COMPERATOR);
    // add our activities as channel state options
    List<StateOption> states = new LinkedList<>();
    for (Activity activity : activities) {
        states.add(new StateOption(activity.getLabel(), activity.getLabel()));
    }
    ChannelType channelType = ChannelTypeBuilder.state(channelTypeUID, "Current Activity", "String").withDescription("Current activity for " + getThing().getLabel()).withStateDescriptionFragment(StateDescriptionFragmentBuilder.create().withPattern("%s").withReadOnly(false).withOptions(states).build()).build();
    factory.addChannelType(channelType);
    Channel channel = ChannelBuilder.create(new ChannelUID(getThing().getUID(), CHANNEL_CURRENT_ACTIVITY), "String").withType(channelTypeUID).build();
    // replace existing currentActivity with updated one
    List<Channel> newChannels = new ArrayList<>();
    for (Channel c : getThing().getChannels()) {
        if (!c.getUID().equals(channel.getUID())) {
            newChannels.add(c);
        }
    }
    newChannels.add(channel);
    BridgeBuilder thingBuilder = editThing();
    thingBuilder.withChannels(newChannels);
    updateThing(thingBuilder.build());
}
Also used : ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) ChannelUID(org.openhab.core.thing.ChannelUID) Channel(org.openhab.core.thing.Channel) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Activity(com.digitaldan.harmony.config.Activity) ChannelType(org.openhab.core.thing.type.ChannelType) StateOption(org.openhab.core.types.StateOption) LinkedList(java.util.LinkedList) BridgeBuilder(org.openhab.core.thing.binding.builder.BridgeBuilder)

Example 3 with ChannelType

use of org.openhab.core.thing.type.ChannelType in project openhab-addons by openhab.

the class KM200ThingHandler method createChannel.

/**
 * Creates a new channel
 */
@Nullable
Channel createChannel(ChannelTypeUID channelTypeUID, ChannelUID channelUID, String root, String type, @Nullable String currentPathName, String description, String label, boolean addProperties, boolean switchProgram, StateDescriptionFragment state, String unitOfMeasure) {
    URI configDescriptionUriChannel = null;
    Channel newChannel = null;
    ChannelType channelType = null;
    Map<String, String> chProperties = new HashMap<>();
    String itemType = "";
    String category = null;
    if (CoreItemFactory.NUMBER.equals(type)) {
        itemType = "NumberType";
        category = "Number";
    } else if (CoreItemFactory.STRING.equals(type)) {
        itemType = "StringType";
        category = "Text";
    } else {
        logger.info("Channeltype {} not supported", type);
        return null;
    }
    try {
        configDescriptionUriChannel = new URI(CONFIG_DESCRIPTION_URI_CHANNEL);
        channelType = // 
        ChannelTypeBuilder.state(channelTypeUID, label, itemType).withDescription(// 
        description).withCategory(// 
        checkCategory(unitOfMeasure, category, state.isReadOnly())).withTags(// 
        checkTags(unitOfMeasure, state.isReadOnly())).withStateDescriptionFragment(// 
        state).withConfigDescriptionURI(configDescriptionUriChannel).build();
    } catch (URISyntaxException ex) {
        logger.warn("Can't create ConfigDescription URI '{}', ConfigDescription for channels not avilable!", CONFIG_DESCRIPTION_URI_CHANNEL);
        channelType = // 
        ChannelTypeBuilder.state(channelTypeUID, label, itemType).withDescription(// 
        description).withCategory(// 
        checkCategory(unitOfMeasure, category, state.isReadOnly())).withTags(checkTags(unitOfMeasure, state.isReadOnly())).build();
    }
    channelTypeProvider.addChannelType(channelType);
    chProperties.put("root", KM200Utils.translatesPathToName(root));
    if (null != currentPathName && switchProgram) {
        chProperties.put(SWITCH_PROGRAM_CURRENT_PATH_NAME, currentPathName);
    }
    if (addProperties) {
        newChannel = ChannelBuilder.create(channelUID, type).withType(channelTypeUID).withDescription(description).withLabel(label).withKind(ChannelKind.STATE).withProperties(chProperties).build();
    } else {
        newChannel = ChannelBuilder.create(channelUID, type).withType(channelTypeUID).withDescription(description).withLabel(label).withKind(ChannelKind.STATE).build();
    }
    return newChannel;
}
Also used : HashMap(java.util.HashMap) Channel(org.openhab.core.thing.Channel) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) ChannelType(org.openhab.core.thing.type.ChannelType) Nullable(org.eclipse.jdt.annotation.Nullable)

Example 4 with ChannelType

use of org.openhab.core.thing.type.ChannelType 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 ChannelType

use of org.openhab.core.thing.type.ChannelType in project openhab-addons by openhab.

the class ApiPageParser method buildAndRegisterChannelType.

private ChannelType buildAndRegisterChannelType(String shortName, Type type, ChangerX2Entry cx2e) {
    StateDescriptionFragmentBuilder sdb = StateDescriptionFragmentBuilder.create().withReadOnly(type.readOnly);
    String itemType;
    switch(cx2e.optionType) {
        case NUMBER:
            itemType = "Number";
            String min = cx2e.options.get(ChangerX2Entry.NUMBER_MIN);
            if (min != null && !min.trim().isEmpty()) {
                sdb.withMinimum(new BigDecimal(min));
            }
            String max = cx2e.options.get(ChangerX2Entry.NUMBER_MAX);
            if (max != null && !max.trim().isEmpty()) {
                sdb.withMaximum(new BigDecimal(max));
            }
            String step = cx2e.options.get(ChangerX2Entry.NUMBER_STEP);
            if (step != null && !step.trim().isEmpty()) {
                sdb.withStep(new BigDecimal(step));
            }
            break;
        case SELECT:
            itemType = "String";
            for (Entry<String, @Nullable String> entry : cx2e.options.entrySet()) {
                String val = entry.getValue();
                if (val != null) {
                    sdb.withOption(new StateOption(val, entry.getKey()));
                }
            }
            break;
        default:
            throw new IllegalStateException();
    }
    ChannelTypeBuilder<?> ctb = ChannelTypeBuilder.state(new ChannelTypeUID(TACmiBindingConstants.BINDING_ID, shortName), shortName, itemType).withDescription("Auto-created for " + shortName).withStateDescriptionFragment(sdb.build());
    // add config description URI
    URI cdu = configDescriptionUriAPISchemaDefaults;
    if (cdu != null) {
        ctb = ctb.withConfigDescriptionURI(cdu);
    }
    ChannelType ct = ctb.build();
    channelTypeProvider.addChannelType(ct);
    return ct;
}
Also used : ChannelTypeUID(org.openhab.core.thing.type.ChannelTypeUID) StateDescriptionFragmentBuilder(org.openhab.core.types.StateDescriptionFragmentBuilder) URI(java.net.URI) ChannelType(org.openhab.core.thing.type.ChannelType) BigDecimal(java.math.BigDecimal) StateOption(org.openhab.core.types.StateOption)

Aggregations

ChannelType (org.openhab.core.thing.type.ChannelType)57 ChannelTypeUID (org.openhab.core.thing.type.ChannelTypeUID)27 Channel (org.openhab.core.thing.Channel)21 ArrayList (java.util.ArrayList)20 Nullable (org.eclipse.jdt.annotation.Nullable)17 ChannelUID (org.openhab.core.thing.ChannelUID)16 ChannelDefinition (org.openhab.core.thing.type.ChannelDefinition)14 Test (org.junit.jupiter.api.Test)11 URI (java.net.URI)10 JavaOSGiTest (org.openhab.core.test.java.JavaOSGiTest)10 Thing (org.openhab.core.thing.Thing)9 ThingType (org.openhab.core.thing.type.ThingType)9 StateOption (org.openhab.core.types.StateOption)9 BigDecimal (java.math.BigDecimal)8 Collection (java.util.Collection)8 ChannelDefinitionBuilder (org.openhab.core.thing.type.ChannelDefinitionBuilder)8 ChannelTypeProvider (org.openhab.core.thing.type.ChannelTypeProvider)8 Locale (java.util.Locale)7 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)7 Configuration (org.openhab.core.config.core.Configuration)7