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