Skip to content

Commit

Permalink
Add humidity and pressure converters (#149)
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <chris@cd-jackson.com>
  • Loading branch information
cdjackson committed Feb 11, 2018
1 parent 8036727 commit ac176d7
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 7 deletions.
10 changes: 10 additions & 0 deletions ESH-INF/thing/_channels.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@
<state pattern="%.1f" readOnly="true">
</state>
</channel-type>

<!-- Atmospheric Pressure Channel -->
<channel-type id="measurement_pressure">
<item-type>Number</item-type>
<label>Atmospheric Pressure</label>
<description>Indicates the current pressure</description>
<category>Pressure</category>
<state pattern="%.1f" readOnly="true">
</state>
</channel-type>

<!-- Humidity Channel -->
<channel-type id="measurement_relativehumidity">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class ZigBeeBindingConstants {
public static final String CHANNEL_ILLUMINANCE_VALUE = "zigbee:measurement_illuminance";
public static final String CHANNEL_TEMPERATURE_VALUE = "zigbee:measurement_temperature";
public static final String CHANNEL_HUMIDITY_VALUE = "zigbee:measurement_relativehumidity";
public static final String CHANNEL_PRESSURE_VALUE = "zigbee:measurement_pressure";

public static final String CHANNEL_OCCUPANCY_SENSOR = "zigbee:sensor_occupancy";

Expand Down Expand Up @@ -86,7 +87,6 @@ public class ZigBeeBindingConstants {
public static final String THING_PROPERTY_ROUTES = "zigbee_routes";
public static final String THING_PROPERTY_NEIGHBORS = "zigbee_neighbors";
public static final String THING_PROPERTY_LASTUPDATE = "zigbee_lastupdate";
public static final String THING_PROPERTY_PERMITJOINING = "zigbee_permitjoining";
public static final String THING_PROPERTY_ASSOCIATEDDEVICES = "zigbee_devices";

// List of all configuration parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ public ZigBeeChannelConverterFactory() {
channelMap.put(ZigBeeBindingConstants.CHANNEL_COLOR_COLOR, ZigBeeConverterColorColor.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_COLOR_TEMPERATURE, ZigBeeConverterColorTemperature.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_ELECTRICAL_ACTIVEPOWER, ZigBeeConverterMeasurementPower.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_HUMIDITY_VALUE, ZigBeeConverterRelativeHumidity.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_IAS_CONTACT_PORTAL1, ZigBeeConverterIasContactPortal1.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_IAS_MOTION_INTRUSION, ZigBeeConverterIasMotionIntrusion.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_IAS_MOTION_PRESENCE, ZigBeeConverterIasMotionPresence.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_IAS_STANDARDCIE_SYSTEM, ZigBeeConverterIasCieSystem.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_ILLUMINANCE_VALUE, ZigBeeConverterIlluminance.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_OCCUPANCY_SENSOR, ZigBeeConverterOccupancy.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_POWER_BATTERYPERCENT, ZigBeeConverterBatteryPercent.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_PRESSURE_VALUE, ZigBeeConverterAtmosphericPressure.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_SWITCH_ONOFF, ZigBeeConverterSwitchOnoff.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_SWITCH_LEVEL, ZigBeeConverterSwitchLevel.class);
channelMap.put(ZigBeeBindingConstants.CHANNEL_TEMPERATURE_VALUE, ZigBeeConverterTemperature.class);
Expand Down Expand Up @@ -111,7 +113,7 @@ public Collection<Channel> getChannels(ThingUID thingUID, ZigBeeEndpoint endpoin

// Perform a channel consolidation at endpoint level to remove unnecessary channels.
// This removes channels that are covered through inheritance.
for (Map.Entry<String,String> consolidationChannel : channelConsolidation.entrySet()) {
for (Map.Entry<String, String> consolidationChannel : channelConsolidation.entrySet()) {
if (channels.containsKey(consolidationChannel.getKey())
&& channels.containsKey(consolidationChannel.getValue())) {
logger.debug("{}: Removing channel {} in favor of {}", endpoint.getIeeeAddress(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.zigbee.internal.converter;

import java.math.BigDecimal;

import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.openhab.binding.zigbee.ZigBeeBindingConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zsmartsystems.zigbee.ZigBeeEndpoint;
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
import com.zsmartsystems.zigbee.zcl.ZclAttributeListener;
import com.zsmartsystems.zigbee.zcl.clusters.ZclPressureMeasurementCluster;
import com.zsmartsystems.zigbee.zcl.protocol.ZclClusterType;

/**
* Converter for the atmospheric pressure channel.
* This channel will attempt to detect if the device is supporting the enhanced (scaled) value reports and use them if
* they are available.
*
* @author Chris Jackson - Initial Contribution
*
*/
public class ZigBeeConverterAtmosphericPressure extends ZigBeeBaseChannelConverter implements ZclAttributeListener {
private Logger logger = LoggerFactory.getLogger(ZigBeeConverterAtmosphericPressure.class);

private ZclPressureMeasurementCluster cluster;

/**
* If enhancedScale is null, then the binding will use the MeasuredValue report,
* otherwise it will use the ScaledValue report
*/
private Integer enhancedScale = null;

@Override
public boolean initializeConverter() {
cluster = (ZclPressureMeasurementCluster) endpoint.getInputCluster(ZclPressureMeasurementCluster.CLUSTER_ID);
if (cluster == null) {
logger.error("{}: Error opening device pressure measurement cluster", endpoint.getIeeeAddress());
return false;
}

// Check if the enhanced attributes are supported
if (cluster.getScaledValue(Long.MAX_VALUE) != null) {
enhancedScale = cluster.getScale(Long.MAX_VALUE);
if (enhancedScale != null) {
enhancedScale *= -1;
}
}

cluster.bind();

// Add a listener, then request the status
cluster.addAttributeListener(this);

// Configure reporting - no faster than once per second - no slower than 10 minutes.
if (enhancedScale != null) {
cluster.setScaledValueReporting(1, REPORTING_PERIOD_DEFAULT_MAX, 0.1);
} else {
cluster.setMeasuredValueReporting(1, REPORTING_PERIOD_DEFAULT_MAX, 0.1);
}
return true;
}

@Override
public void disposeConverter() {
cluster.removeAttributeListener(this);
}

@Override
public void handleRefresh() {
if (enhancedScale != null) {
cluster.getScaledValue(0);
} else {
cluster.getMeasuredValue(0);
}
}

@Override
public Channel getChannel(ThingUID thingUID, ZigBeeEndpoint endpoint) {
if (endpoint.getInputCluster(ZclPressureMeasurementCluster.CLUSTER_ID) == null) {
return null;
}
return createChannel(thingUID, endpoint, ZigBeeBindingConstants.CHANNEL_PRESSURE_VALUE,
ZigBeeBindingConstants.ITEM_TYPE_NUMBER, "Atmospheric Pressure");
}

@Override
public void attributeUpdated(ZclAttribute attribute) {
logger.debug("{}: ZigBee attribute reports {}", endpoint.getIeeeAddress(), attribute);
if (attribute.getCluster() == ZclClusterType.PRESSURE_MEASUREMENT) {
// Handle automatic reporting of the enhanced attribute configuration
if (attribute.getId() == ZclPressureMeasurementCluster.ATTR_SCALE) {
enhancedScale = (Integer) attribute.getLastValue();
if (enhancedScale != null) {
enhancedScale *= -1;
}
return;
}

if (attribute.getId() == ZclPressureMeasurementCluster.ATTR_SCALEDVALUE && enhancedScale != null) {
Integer value = (Integer) attribute.getLastValue();
if (value != null) {
updateChannelState(new DecimalType(BigDecimal.valueOf(value, enhancedScale)));
}
return;
}

if (attribute.getId() == ZclPressureMeasurementCluster.ATTR_MEASUREDVALUE && enhancedScale == null) {
Integer value = (Integer) attribute.getLastValue();
if (value != null) {
updateChannelState(new DecimalType(BigDecimal.valueOf(value, 0)));
}
return;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public boolean initializeConverter() {
return false;
}

Integer kMin = clusterColorControl.getColorTemperatureMin(Integer.MAX_VALUE);
Integer kMax = clusterColorControl.getColorTemperatureMax(Integer.MAX_VALUE);
Integer kMin = clusterColorControl.getColorTemperatureMin(Long.MAX_VALUE);
Integer kMax = clusterColorControl.getColorTemperatureMax(Long.MAX_VALUE);

if (kMin == null) {
kelvinMin = CT_DEFAULT_MIN;
Expand Down Expand Up @@ -118,15 +118,16 @@ public void handleCommand(final Command command) {

@Override
public Channel getChannel(ThingUID thingUID, ZigBeeEndpoint endpoint) {
clusterColorControl = (ZclColorControlCluster) endpoint.getInputCluster(ZclColorControlCluster.CLUSTER_ID);
ZclColorControlCluster clusterColorControl = (ZclColorControlCluster) endpoint
.getInputCluster(ZclColorControlCluster.CLUSTER_ID);
if (clusterColorControl == null) {
return null;
}

try {
if (!clusterColorControl.discoverAttributes(false).get()) {
// Device is not supporting attribute reporting - instead, just read the attributes
Integer capabilities = clusterColorControl.getColorCapabilities(Integer.MAX_VALUE);
Integer capabilities = clusterColorControl.getColorCapabilities(Long.MAX_VALUE);
if (capabilities != null && (capabilities & ColorCapabilitiesEnum.COLOR_TEMPERATURE.getKey()) == 0) {
// No support for color temperature
return null;
Expand All @@ -136,7 +137,7 @@ public Channel getChannel(ThingUID thingUID, ZigBeeEndpoint endpoint) {
}
} else if (clusterColorControl.isAttributeSupported(ZclColorControlCluster.ATTR_COLORCAPABILITIES)) {
// If the device is reporting is capabilities, then use this over attribute detection
Integer capabilities = clusterColorControl.getColorCapabilities(Integer.MAX_VALUE);
Integer capabilities = clusterColorControl.getColorCapabilities(Long.MAX_VALUE);
if (capabilities != null && (capabilities & ColorCapabilitiesEnum.COLOR_TEMPERATURE.getKey()) == 0) {
// No support for color temperature
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.zigbee.internal.converter;

import java.math.BigDecimal;

import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.openhab.binding.zigbee.ZigBeeBindingConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zsmartsystems.zigbee.ZigBeeEndpoint;
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
import com.zsmartsystems.zigbee.zcl.ZclAttributeListener;
import com.zsmartsystems.zigbee.zcl.clusters.ZclRelativeHumidityMeasurementCluster;
import com.zsmartsystems.zigbee.zcl.protocol.ZclClusterType;

/**
* Converter for the relative humidity channel
*
* @author Chris Jackson - Initial Contribution
*
*/
public class ZigBeeConverterRelativeHumidity extends ZigBeeBaseChannelConverter implements ZclAttributeListener {
private Logger logger = LoggerFactory.getLogger(ZigBeeConverterRelativeHumidity.class);

private ZclRelativeHumidityMeasurementCluster cluster;

@Override
public boolean initializeConverter() {
cluster = (ZclRelativeHumidityMeasurementCluster) endpoint
.getInputCluster(ZclRelativeHumidityMeasurementCluster.CLUSTER_ID);
if (cluster == null) {
logger.error("{}: Error opening device relative humidity measurement cluster", endpoint.getIeeeAddress());
return false;
}

cluster.bind();

// Add a listener, then request the status
cluster.addAttributeListener(this);

// Configure reporting - no faster than once per second - no slower than 10 minutes.
cluster.setMeasuredValueReporting(1, REPORTING_PERIOD_DEFAULT_MAX, 0.1);
return true;
}

@Override
public void disposeConverter() {
cluster.removeAttributeListener(this);
}

@Override
public void handleRefresh() {
cluster.getMeasuredValue(0);
}

@Override
public Channel getChannel(ThingUID thingUID, ZigBeeEndpoint endpoint) {
if (endpoint.getInputCluster(ZclRelativeHumidityMeasurementCluster.CLUSTER_ID) == null) {
return null;
}
return createChannel(thingUID, endpoint, ZigBeeBindingConstants.CHANNEL_HUMIDITY_VALUE,
ZigBeeBindingConstants.ITEM_TYPE_NUMBER, "Relative Humidity");
}

@Override
public void attributeUpdated(ZclAttribute attribute) {
logger.debug("{}: ZigBee attribute reports {}", endpoint.getIeeeAddress(), attribute);
if (attribute.getCluster() == ZclClusterType.RELATIVE_HUMIDITY_MEASUREMENT
&& attribute.getId() == ZclRelativeHumidityMeasurementCluster.ATTR_MEASUREDVALUE) {
Integer value = (Integer) attribute.getLastValue();
if (value != null) {
updateChannelState(new DecimalType(BigDecimal.valueOf(value, 2)));
}
}
}
}

0 comments on commit ac176d7

Please sign in to comment.