use of org.openhab.core.config.core.Configuration in project org.openhab.binding.zwave by openhab.
the class ZWaveThingHandler method ZWaveIncomingEvent.
@Override
public void ZWaveIncomingEvent(ZWaveEvent incomingEvent) {
// Check if this event is for this device
if (incomingEvent.getNodeId() != nodeId) {
return;
}
logger.debug("NODE {}: Got an event from Z-Wave network: {}", nodeId, incomingEvent.getClass().getSimpleName());
// Handle command class value events.
if (incomingEvent instanceof ZWaveCommandClassValueEvent) {
// Cast to a command class event
ZWaveCommandClassValueEvent event = (ZWaveCommandClassValueEvent) incomingEvent;
String commandClass = event.getCommandClass().toString();
logger.debug("NODE {}: Got a value event from Z-Wave network, endpoint={}, command class={}, value={}", nodeId, event.getEndpoint(), commandClass, event.getValue());
// If this is a configuration parameter update, process it before the channels
Configuration configuration = editConfiguration();
boolean cfgUpdated = false;
switch(event.getCommandClass()) {
case COMMAND_CLASS_CONFIGURATION:
ZWaveConfigurationParameter parameter = ((ZWaveConfigurationParameterEvent) event).getParameter();
if (parameter == null) {
return;
}
logger.debug("NODE {}: Update CONFIGURATION {}/{} to {}", nodeId, parameter.getIndex(), parameter.getSize(), parameter.getValue());
// Check for any sub parameter processing...
// If we have requested the current state of a parameter and t's waiting to be updated, then we
// check this here, update the value and send the request...
// Do this first so we only process the data if we're not waiting to send
ZWaveConfigSubParameter subParameter = subParameters.get(parameter.getIndex());
if (subParameter != null) {
// Get the new value based on the sub-parameter bitmask
int value = subParameter.getValue(parameter.getValue());
logger.debug("NODE {}: Updating sub-parameter {} to {}", nodeId, parameter.getIndex(), value);
// Remove the sub parameter so we don't loop forever!
subParameters.remove(parameter.getIndex());
ZWaveNode node = controllerHandler.getNode(nodeId);
if (node == null) {
logger.warn("NODE {}: Error getting node for config update", nodeId);
return;
}
ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_CONFIGURATION);
if (configurationCommandClass == null) {
logger.debug("NODE {}: Error getting configurationCommandClass", nodeId);
return;
}
ZWaveConfigurationParameter cfgParameter = configurationCommandClass.getParameter(parameter.getIndex());
if (cfgParameter == null) {
cfgParameter = new ZWaveConfigurationParameter(parameter.getIndex(), value, parameter.getSize());
} else {
cfgParameter.setValue(value);
}
logger.debug("NODE {}: Setting parameter {} to {}", nodeId, cfgParameter.getIndex(), cfgParameter.getValue());
node.sendMessage(configurationCommandClass.setConfigMessage(cfgParameter));
node.sendMessage(configurationCommandClass.getConfigMessage(parameter.getIndex()));
// Don't process the data - it hasn't been updated yet!
break;
}
updateConfigurationParameter(configuration, parameter.getIndex(), parameter.getSize(), parameter.getValue());
break;
case COMMAND_CLASS_ASSOCIATION:
case COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION:
int groupId = ((ZWaveAssociationEvent) event).getGroupId();
List<ZWaveAssociation> groupMembers = ((ZWaveAssociationEvent) event).getGroupMembers();
// getAssociationConfigList(ZWaveAssociationGroup newMembers) ;
// if (groupMembers != null) {
// logger.debug("NODE {}: Update ASSOCIATION group_{}", nodeId, groupId);
// List<String> group = new ArrayList<String>();
// Build the configuration value
// for (ZWaveAssociation groupMember : groupMembers) {
// logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding {}", nodeId, groupId,
// groupMember);
// group.add(groupMember.toString());
// }
// logger.debug("NODE {}: Update ASSOCIATION group_{}: {} members", nodeId, groupId, group.size());
// cfgUpdated = true;
configuration.put("group_" + groupId, getAssociationConfigList(groupMembers));
removePendingConfig("group_" + groupId);
// }
break;
case COMMAND_CLASS_SWITCH_ALL:
cfgUpdated = true;
configuration.put(ZWaveBindingConstants.CONFIGURATION_SWITCHALLMODE, event.getValue());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_SWITCHALLMODE);
break;
case COMMAND_CLASS_NODE_NAMING:
switch((ZWaveNodeNamingCommandClass.Type) event.getType()) {
case NODENAME_LOCATION:
cfgUpdated = true;
configuration.put(ZWaveBindingConstants.CONFIGURATION_NODELOCATION, event.getValue());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_NODELOCATION);
break;
case NODENAME_NAME:
cfgUpdated = true;
configuration.put(ZWaveBindingConstants.CONFIGURATION_NODENAME, event.getValue());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_NODENAME);
break;
}
break;
case COMMAND_CLASS_DOOR_LOCK:
switch((ZWaveDoorLockCommandClass.Type) event.getType()) {
case DOOR_LOCK_TIMEOUT:
cfgUpdated = true;
configuration.put(ZWaveBindingConstants.CONFIGURATION_DOORLOCKTIMEOUT, event.getValue());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_DOORLOCKTIMEOUT);
break;
default:
break;
}
break;
case COMMAND_CLASS_USER_CODE:
ZWaveUserCodeValueEvent codeEvent = (ZWaveUserCodeValueEvent) event;
cfgUpdated = true;
String codeParameterName = ZWaveBindingConstants.CONFIGURATION_USERCODE_CODE + codeEvent.getId();
if (codeEvent.getStatus() == UserIdStatusType.OCCUPIED) {
configuration.put(codeParameterName, codeEvent.getCode());
} else {
configuration.put(codeParameterName, "");
}
removePendingConfig(codeParameterName);
break;
default:
break;
}
if (cfgUpdated == true) {
logger.debug("NODE {}: Config updated", nodeId);
updateConfiguration(configuration);
}
if (thingChannelsState == null) {
logger.debug("NODE {}: No state handlers!", nodeId);
return;
}
// Process the channels to see if we're interested
for (ZWaveThingChannel channel : thingChannelsState) {
logger.trace("NODE {}: Checking channel={}, cmdClass={}, endpoint={}", nodeId, channel.getUID(), channel.getCommandClass(), channel.getEndpoint());
if (channel.getEndpoint() != event.getEndpoint()) {
continue;
}
// Is this command class associated with this channel?
if (!channel.getCommandClass().equals(commandClass)) {
continue;
}
if (channel.getConverter() == null) {
logger.warn("NODE {}: No state converter set for channel {}", nodeId, channel.getUID());
return;
}
// logger.debug("NODE {}: Processing event as channel {} {}", nodeId, channel.getUID(),
// channel.dataType);
State state = channel.getConverter().handleEvent(channel, event);
if (state != null) {
logger.debug("NODE {}: Updating channel state {} to {} [{}]", nodeId, channel.getUID(), state, state.getClass().getSimpleName());
updateState(channel.getUID(), state);
}
}
return;
}
// Handle transaction complete events.
if (incomingEvent instanceof ZWaveTransactionCompletedEvent) {
return;
}
// Handle wakeup notification events.
if (incomingEvent instanceof ZWaveWakeUpEvent) {
ZWaveNode node = controllerHandler.getNode(nodeId);
if (node == null) {
return;
}
switch(((ZWaveWakeUpEvent) incomingEvent).getEvent()) {
case ZWaveWakeUpCommandClass.WAKE_UP_INTERVAL_REPORT:
ZWaveWakeUpCommandClass commandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_WAKE_UP);
Configuration configuration = editConfiguration();
configuration.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL, commandClass.getInterval());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL);
configuration.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE, commandClass.getTargetNodeId());
removePendingConfig(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE);
updateConfiguration(configuration);
break;
}
return;
}
// Handle node state change events.
if (incomingEvent instanceof ZWaveNodeStatusEvent) {
// Cast to a command class event
ZWaveNodeStatusEvent event = (ZWaveNodeStatusEvent) incomingEvent;
switch(event.getState()) {
case AWAKE:
Map<String, String> properties = editProperties();
properties.put(ZWaveBindingConstants.PROPERTY_LASTWAKEUP, getISO8601StringForCurrentDate());
updateProperties(properties);
break;
case ASLEEP:
break;
case INITIALIZING:
case ALIVE:
logger.debug("NODE {}: Setting ONLINE", nodeId);
updateStatus(ThingStatus.ONLINE);
break;
case DEAD:
case FAILED:
logger.debug("NODE {}: Setting OFFLINE", nodeId);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, ZWaveBindingConstants.OFFLINE_NODE_DEAD);
break;
}
return;
}
if (incomingEvent instanceof ZWaveInitializationStateEvent) {
ZWaveInitializationStateEvent initEvent = (ZWaveInitializationStateEvent) incomingEvent;
switch(initEvent.getStage()) {
case STATIC_END:
// Update some properties first...
updateNodeProperties();
// Do we need to change type?
if (finalTypeSet == false) {
if (updateThingType() == true) {
// The thing will have already been disposed of so let's get the hell out of here!
return;
}
}
if (finalTypeSet) {
// Now that this node is initialised, we want to re-process all channels
initialiseNode();
}
break;
case HEAL_START:
break;
case HEAL_END:
Map<String, String> properties = editProperties();
properties.put(ZWaveBindingConstants.PROPERTY_LASTHEAL, getISO8601StringForCurrentDate());
updateProperties(properties);
break;
// Don't update the thing state for dynamic updates - this is just polling
case DYNAMIC_VALUES:
case DYNAMIC_END:
break;
// Don't update the thing state when doing a heal
case UPDATE_NEIGHBORS:
case GET_NEIGHBORS:
case DELETE_SUC_ROUTES:
case SUC_ROUTE:
case DELETE_ROUTES:
case RETURN_ROUTES:
break;
case DONE:
updateStatus(ThingStatus.ONLINE);
break;
default:
if (finalTypeSet) {
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "Node initialising: " + initEvent.getStage().toString());
}
break;
}
}
if (incomingEvent instanceof ZWaveNetworkEvent) {
ZWaveNetworkEvent networkEvent = (ZWaveNetworkEvent) incomingEvent;
if (networkEvent.getEvent() == ZWaveNetworkEvent.Type.NodeRoutingInfo) {
updateNodeNeighbours();
}
if (networkEvent.getEvent() == ZWaveNetworkEvent.Type.DeleteNode) {
// TODO: Update to THING_GONE
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE);
}
}
if (incomingEvent instanceof ZWaveDelayedPollEvent) {
long delay = ((ZWaveDelayedPollEvent) incomingEvent).getDelay();
TimeUnit unit = ((ZWaveDelayedPollEvent) incomingEvent).getUnit();
// Don't create a poll beyond our max value
if (unit.toSeconds(delay) > DELAYED_POLLING_PERIOD_MAX) {
delay = DELAYED_POLLING_PERIOD_MAX;
unit = TimeUnit.SECONDS;
}
startPolling(unit.toMillis(delay));
}
// Handle exclusion of this node
if (incomingEvent instanceof ZWaveInclusionEvent) {
ZWaveInclusionEvent incEvent = (ZWaveInclusionEvent) incomingEvent;
if (incEvent.getNodeId() != nodeId) {
return;
}
switch(incEvent.getEvent()) {
case ExcludeDone:
// Let our users know we're gone!
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Node was excluded from the controller");
// Remove the XML file
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.deleteNode(controllerHandler.getHomeId(), nodeId);
// Stop polling
synchronized (pollingSync) {
if (pollingJob != null) {
pollingJob.cancel(true);
pollingJob = null;
}
}
break;
default:
break;
}
}
}
use of org.openhab.core.config.core.Configuration in project org.openhab.binding.zwave by openhab.
the class ZWaveThingHandler method initialiseNode.
void initialiseNode() {
logger.debug("NODE {}: Initialising Thing Node...", nodeId);
// Note that for dynamic channels, it seems that defaults can either be not set, or set with the incorrect
// type. So, we read back as an Object to avoid casting problems.
pollingPeriod = POLLING_PERIOD_DEFAULT;
final Object pollParm = getConfig().get(ZWaveBindingConstants.CONFIGURATION_POLLPERIOD);
if (pollParm instanceof BigDecimal) {
try {
pollingPeriod = ((BigDecimal) pollParm).intValue();
} catch (final NumberFormatException ex) {
logger.debug("NODE {}: pollingPeriod ({}) cannot be parsed - using default", nodeId, pollParm);
}
}
final Object repollParm = getConfig().get(ZWaveBindingConstants.CONFIGURATION_CMDREPOLLPERIOD);
if (repollParm instanceof BigDecimal) {
try {
commandPollDelay = ((BigDecimal) repollParm).intValue();
} catch (final NumberFormatException ex) {
logger.debug("NODE {}: commandPollDelay ({}) cannot be parsed - using default", nodeId, repollParm);
}
}
// Create the channels list to simplify processing incoming events
thingChannelsCmd = new ArrayList<ZWaveThingChannel>();
thingChannelsState = new ArrayList<ZWaveThingChannel>();
for (Channel channel : getThing().getChannels()) {
logger.trace("NODE {}: Processing channel: {} == {}", nodeId, channel.getUID(), channel.getChannelTypeUID());
// Process the channel properties and configuration
Map<String, String> properties = channel.getProperties();
Configuration configuration = channel.getConfiguration();
for (String key : properties.keySet()) {
logger.trace("NODE {}: Processing channel: {} == {}", nodeId, key, properties.get(key));
String[] bindingType = key.split(":");
if (bindingType.length != 3) {
logger.trace("NODE {}: binding string != 3", nodeId);
continue;
}
if (!ZWaveBindingConstants.CHANNEL_CFG_BINDING.equals(bindingType[0])) {
logger.trace("NODE {}: binding string != CFG_BINDING", nodeId);
continue;
}
String[] bindingProperties = properties.get(key).split(";");
// TODO: Check length???
// Get the command classes - comma separated
String[] cmdClasses = bindingProperties[0].split(",");
// Convert the arguments to a map
// - comma separated list of arguments "arg1=val1, arg2=val2"
Map<String, String> argumentMap = new HashMap<String, String>();
if (bindingProperties.length == 2) {
argumentMap = getZWaveProperties(bindingProperties[1]);
}
// Process the user configuration and add it to the argument map
for (String configName : configuration.getProperties().keySet()) {
argumentMap.put(configName, configuration.get(configName).toString());
}
// Add all the command classes...
boolean first = true;
for (String cc : cmdClasses) {
String[] ccSplit = cc.split(":");
int endpoint = 0;
if (ccSplit.length == 2) {
endpoint = Integer.parseInt(ccSplit[1]);
}
// Get the data type
DataType dataType = DataType.DecimalType;
try {
dataType = DataType.valueOf(bindingType[2]);
} catch (IllegalArgumentException e) {
logger.warn("NODE {}: Invalid item type defined {} for {}. Assuming DecimalType.", nodeId, bindingType[2], channel.getUID());
}
ZWaveThingChannel chan = new ZWaveThingChannel(controllerHandler, channel.getChannelTypeUID(), channel.getUID(), dataType, ccSplit[0], endpoint, argumentMap);
// First time round, and this is a command - then add the command
if (first && ("*".equals(bindingType[1]) || "Command".equals(bindingType[1]))) {
thingChannelsCmd.add(chan);
logger.debug("NODE {}: Initialising cmd channel {} for {}", nodeId, channel.getUID(), dataType);
}
// Add the state and polling handlers
if ("*".equals(bindingType[1]) || "State".equals(bindingType[1])) {
logger.debug("NODE {}: Initialising state channel {} for {}", nodeId, channel.getUID(), dataType);
thingChannelsState.add(chan);
}
first = false;
}
}
// if the channel is already linked, add it to our list of channels to poll for
if (isLinked(channel.getUID().getId())) {
thingChannelsPoll.add(channel.getUID());
}
}
startPolling();
}
use of org.openhab.core.config.core.Configuration in project org.openhab.binding.zwave by openhab.
the class ZWaveThingHandlerTest method doConfigurationUpdate.
private ZWaveThingHandler doConfigurationUpdate(String param, Object value) {
ThingType thingType = ThingTypeBuilder.instance("bindingId", "thingTypeId", "label").build();
Thing thing = ThingBuilder.create(thingType.getUID(), new ThingUID(thingType.getUID(), "thingId")).withConfiguration(new Configuration()).build();
ZWaveNode node = Mockito.mock(ZWaveNode.class);
ZWaveController controller = Mockito.mock(ZWaveController.class);
ZWaveControllerHandler controllerHandler = Mockito.mock(ZWaveControllerHandler.class);
Mockito.when(controllerHandler.isControllerMaster()).thenReturn(false);
ThingHandlerCallback thingCallback = Mockito.mock(ThingHandlerCallback.class);
ZWaveThingHandler thingHandler = new ZWaveThingHandlerForTest(thing);
thingHandler.setCallback(thingCallback);
payloadCaptor = ArgumentCaptor.forClass(ZWaveCommandClassTransactionPayload.class);
Field fieldControllerHandler;
try {
ZWaveWakeUpCommandClass wakeupClass = new ZWaveWakeUpCommandClass(node, controller, null);
ZWaveAssociationCommandClass associationClass = new ZWaveAssociationCommandClass(node, controller, null);
ZWaveNodeNamingCommandClass namingClass = new ZWaveNodeNamingCommandClass(node, controller, null);
Mockito.doNothing().when(node).sendMessage(payloadCaptor.capture());
fieldControllerHandler = ZWaveThingHandler.class.getDeclaredField("controllerHandler");
fieldControllerHandler.setAccessible(true);
fieldControllerHandler.set(thingHandler, controllerHandler);
Mockito.when(controller.getOwnNodeId()).thenReturn(1);
Mockito.when(controllerHandler.getOwnNodeId()).thenReturn(1);
Mockito.when(controllerHandler.getNode(ArgumentMatchers.anyInt())).thenReturn(node);
Mockito.when(node.getNodeId()).thenReturn(1);
Mockito.when(node.getAssociationGroup(ArgumentMatchers.anyInt())).thenReturn(new ZWaveAssociationGroup(1));
Mockito.when(node.getCommandClass(ArgumentMatchers.eq(CommandClass.COMMAND_CLASS_WAKE_UP))).thenReturn(wakeupClass);
Mockito.when(node.getCommandClass(ArgumentMatchers.eq(CommandClass.COMMAND_CLASS_ASSOCIATION))).thenReturn(associationClass);
Mockito.when(node.getCommandClass(ArgumentMatchers.eq(CommandClass.COMMAND_CLASS_NODE_NAMING))).thenReturn(namingClass);
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Map<String, Object> config = new HashMap<String, Object>();
config.put(param, value);
thingHandler.handleConfigurationUpdate(config);
configResult = thingHandler.getThing().getConfiguration();
return thingHandler;
}
use of org.openhab.core.config.core.Configuration in project openhab-addons by openhab.
the class AirQualityStationHandler method discoverAttributes.
private void discoverAttributes() {
getAirQualityData().ifPresent(data -> {
// Update thing properties
Map<String, String> properties = new HashMap<>();
properties.put(ATTRIBUTIONS, data.getAttributions());
PointType serverLocation = locationProvider.getLocation();
if (serverLocation != null) {
PointType stationLocation = new PointType(data.getCity().getGeo());
double distance = serverLocation.distanceFrom(stationLocation).doubleValue();
properties.put(DISTANCE, new QuantityType<>(distance / 1000, KILO(SIUnits.METRE)).toString());
}
// Search and remove missing pollutant channels
List<Channel> channels = new ArrayList<>(getThing().getChannels());
Stream.of(Pollutant.values()).forEach(pollutant -> {
String groupName = pollutant.name().toLowerCase();
double value = data.getIaqiValue(pollutant);
channels.removeIf(channel -> value == -1 && groupName.equals(channel.getUID().getGroupId()));
});
// Update thing configuration
Configuration config = editConfiguration();
config.put(AirQualityConfiguration.STATION_ID, data.getStationId());
ThingBuilder thingBuilder = editThing();
thingBuilder.withChannels(channels).withConfiguration(config).withProperties(properties).withLocation(data.getCity().getName());
updateThing(thingBuilder.build());
});
}
use of org.openhab.core.config.core.Configuration in project openhab-addons by openhab.
the class DSCAlarmBaseBridgeHandler method findThing.
/**
* Find a Thing.
*
* @param dscAlarmThingType
* @param partitionId
* @param zoneId
* @return thing
*/
public Thing findThing(DSCAlarmThingType dscAlarmThingType, int partitionId, int zoneId) {
List<Thing> things = getThing().getThings();
Thing thing = null;
for (Thing t : things) {
try {
Configuration config = t.getConfiguration();
DSCAlarmBaseThingHandler handler = (DSCAlarmBaseThingHandler) t.getHandler();
if (handler != null) {
DSCAlarmThingType handlerDSCAlarmThingType = handler.getDSCAlarmThingType();
if (handlerDSCAlarmThingType != null) {
if (handlerDSCAlarmThingType.equals(dscAlarmThingType)) {
switch(handlerDSCAlarmThingType) {
case PANEL:
case KEYPAD:
thing = t;
logger.debug("findThing(): Thing Found - {}, {}, {}", t, handler, handlerDSCAlarmThingType);
return thing;
case PARTITION:
BigDecimal partitionNumber = (BigDecimal) config.get(DSCAlarmPartitionConfiguration.PARTITION_NUMBER);
if (partitionId == partitionNumber.intValue()) {
thing = t;
logger.debug("findThing(): Thing Found - {}, {}, {}", t, handler, handlerDSCAlarmThingType);
return thing;
}
break;
case ZONE:
BigDecimal zoneNumber = (BigDecimal) config.get(DSCAlarmZoneConfiguration.ZONE_NUMBER);
if (zoneId == zoneNumber.intValue()) {
thing = t;
logger.debug("findThing(): Thing Found - {}, {}, {}", t, handler, handlerDSCAlarmThingType);
return thing;
}
break;
default:
break;
}
}
}
}
} catch (Exception e) {
logger.debug("findThing(): Error Seaching Thing - {} ", e.getMessage(), e);
}
}
return thing;
}
Aggregations