Skip to content

Commit

Permalink
[rfxcom] Repaired support for RFXThermostat3 messages (openhab#5765)
Browse files Browse the repository at this point in the history
Also-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
Signed-off-by: Martin van Wingerden <martin@martinvw.nl>
Signed-off-by: Tim Roberts <timmarkroberts@gmail.com>
  • Loading branch information
martinvw authored and tmrobert8 committed Jan 21, 2020
1 parent dd96d55 commit 7cebf11
Show file tree
Hide file tree
Showing 20 changed files with 381 additions and 65 deletions.
35 changes: 30 additions & 5 deletions bundles/org.openhab.binding.rfxcom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,13 @@ This binding currently supports following channel types:
|-----------------|---------------|------------------------------------------------------------------------------------|
| chimesound | Number | Id of the chime sound |
| command | Switch | Command channel. |
| commandId | String | Id of the command. |
| commandId | Number | Id of the command (between 0 and 255). |
| commandString | String | Id of the command. |
| contact | Contact | Contact channel. |
| datetime | DateTime | DateTime channel. |
| dimminglevel | Dimmer | Dimming level channel. |
| forecast | String | Weather forecast from device: NO\_INFO\_AVAILABLE/SUNNY/PARTLY\_CLOUDY/CLOUDY/RAIN |
| tempcontrol | Rollershutter | Global control for temperature also setting ON, OFF, UP, DOWN |
| humidity | Number | Relative humidity level in percentages. |
| humiditystatus | String | Current humidity status: NORMAL/COMFORT/DRY/WET |
| instantamp | Number | Instant current in Amperes. |
Expand Down Expand Up @@ -964,10 +966,31 @@ A Thermostat3 device.

#### Channels

| Name | Channel Type | Item Type | Remarks |
|-------------|-------------------------------------|-----------|----------|
| command | [command](#channels) | Switch | |
| signalLevel | [system.signal-strength](#channels) | Number | |
| Name | Channel Type | Item Type | Remarks |
|-------------------|-------------------------------------|---------------|----------|
| command | [command](#channels) | Switch | |
| command2nd | [command](#channels) | Switch | |
| control\* | [tempcontrol](#channels) | Rollershutter | |
| commandString\*\* | [commandString](#channels) | String | |
| signalLevel | [system.signal-strength](#channels) | Number | |

\* `control` supports:

* UP
* DOWN
* STOP

\*\* `commandString` supports:

* OFF
* ON
* UP
* DOWN
* RUN_UP
* RUN_DOWN
* SECOND_ON
* SECOND_OFF
* STOP

#### Configuration Options

Expand All @@ -982,6 +1005,8 @@ A Thermostat3 device.
* MERTIK\_\_G6R\_H4TD\_\_G6R\_H4T16 - Mertik (G6R H4TD or G6R H4T16)
* MERTIK\_\_G6R\_H4S\_TRANSMIT\_ONLY - Mertik (G6R H4S \- transmit only)

#### Examples


### undecoded - RFXCOM Undecoded RF Messages

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public interface DeviceMessageListener {
* This method is called whenever the message is received from the bridge.
*
* @param bridge
* The RFXCom bridge where message is received.
* The RFXCom bridge where message is received.
* @param message
* The message which received.
* The message which received.
*/
void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message) throws RFXComException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ public class RFXComBindingConstants {
public static final String CHANNEL_VENETIAN_BLIND = "venetianBlind";
public static final String CHANNEL_SUN_WIND_DETECTOR = "sunWindDetector";
public static final String CHANNEL_COMMAND = "command";
public static final String CHANNEL_COMMAND_SECOND = "command2nd";
public static final String CHANNEL_CONTROL = "control";
public static final String CHANNEL_PROGRAM = "program";
public static final String CHANNEL_COMMAND_ID = "commandId";
public static final String CHANNEL_COMMAND_STRING = "commandString";
public static final String CHANNEL_MOOD = "mood";
public static final String CHANNEL_SIGNAL_LEVEL = "signalLevel";
public static final String CHANNEL_DIMMING_LEVEL = "dimmingLevel";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public interface RFXComConnectorInterface {
* Procedure for connecting to RFXCOM controller.
*
* @param device
* Controller connection parameters (e.g. serial port name or IP
* address).
* Controller connection parameters (e.g. serial port name or IP
* address).
*/
public void connect(RFXComBridgeConfiguration device) throws Exception;

Expand All @@ -42,23 +42,23 @@ public interface RFXComConnectorInterface {
* Procedure for send raw data to RFXCOM controller.
*
* @param data
* raw bytes.
* raw bytes.
*/
public void sendMessage(byte[] data) throws IOException;

/**
* Procedure for register event listener.
*
* @param listener
* Event listener instance to handle events.
* Event listener instance to handle events.
*/
public void addEventListener(RFXComEventListener listener);

/**
* Procedure for remove event listener.
*
* @param listener
* Event listener instance to remove.
* Event listener instance to remove.
*/
public void removeEventListener(RFXComEventListener listener);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ public interface RFXComEventListener {
* Procedure for receive raw data from RFXCOM controller.
*
* @param data
* Received raw data.
* Received raw data.
*/
void packetReceived(byte[] data);

/**
* Procedure for receiving information fatal error.
*
* @param error
* Error occurred.
* Error occurred.
*/
void errorOccurred(String error);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,17 @@ public void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message
updateStatus(ThingStatus.ONLINE);

for (Channel channel : getThing().getChannels()) {
String channelId = channel.getUID().getId();
ChannelUID uid = channel.getUID();
String channelId = uid.getId();

try {
if (channelId.equals(CHANNEL_LOW_BATTERY)) {
updateState(channelId, isLowBattery(message.convertToState(CHANNEL_BATTERY_LEVEL)));
updateState(uid, isLowBattery(message.convertToState(CHANNEL_BATTERY_LEVEL)));
} else {
updateState(channelId, message.convertToState(channelId));
State state = message.convertToState(channelId);
if (state != null) {
updateState(uid, state);
}
}
} catch (RFXComException e) {
logger.trace("{} does not handle {}", channelId, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public String getDeviceId() {
* Convert a 0-15 scale value to a percent type.
*
* @param pt
* percent type to convert
* percent type to convert
* @return converted value 0-15
*/
public static int getDimLevelFromPercentType(PercentType pt) {
Expand All @@ -164,7 +164,7 @@ public static int getDimLevelFromPercentType(PercentType pt) {
* Convert a 0-15 scale value to a percent type.
*
* @param value
* percent type to convert
* percent type to convert
* @return converted value 0-15
*/
public static PercentType getPercentTypeFromDimLevel(int value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ public byte toByte() {
/**
* Note: for the lighting5 commands, some command are only supported for certain sub types and
* command-bytes might even have a different meaning for another sub type.
* <p>
*
* If no sub types are specified for a command, its supported by all sub types.
* An example is the command OFF which is represented by the byte 0x00 for all subtypes.
* <p>
*
* Otherwise the list of sub types after the command-bytes indicates the sub types
* which support this command with this byte.
* Example byte value 0x03 means GROUP_ON for IT and some others while it means MOOD1 for LIGHTWAVERF
Expand Down Expand Up @@ -206,7 +206,7 @@ public String getDeviceId() {
* Convert a 0-31 scale value to a percent type.
*
* @param pt
* percent type to convert
* percent type to convert
* @return converted value 0-31
*/
public static int getDimLevelFromPercentType(PercentType pt) {
Expand All @@ -218,7 +218,7 @@ public static int getDimLevelFromPercentType(PercentType pt) {
* Convert a 0-31 scale value to a percent type.
*
* @param value
* percent type to convert
* percent type to convert
* @return converted value 0-31
*/
public static PercentType getPercentTypeFromDimLevel(int value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface RFXComMessage {
* Procedure for encode raw data.
*
* @param data
* Raw data.
* Raw data.
*/
void encodeMessage(byte[] data) throws RFXComException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@
*/
package org.openhab.binding.rfxcom.internal.messages;

import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_COMMAND;
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
import static org.openhab.binding.rfxcom.internal.messages.RFXComThermostat3Message.SubType.*;

import java.util.Arrays;
import java.util.List;

import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.OpenClosedType;
import org.eclipse.smarthome.core.library.types.PercentType;
import org.eclipse.smarthome.core.library.types.StopMoveType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.library.types.UpDownType;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.Type;
import org.eclipse.smarthome.core.types.UnDefType;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
Expand Down Expand Up @@ -98,7 +101,6 @@ public static Commands fromByte(int input, SubType subType) throws RFXComUnsuppo
public SubType subType;
private int unitId;
public Commands command;
private byte commandId;

public RFXComThermostat3Message() {
super(PacketType.THERMOSTAT3);
Expand All @@ -115,7 +117,7 @@ public String toString() {
str += super.toString();
str += ", Sub type = " + subType;
str += ", Device Id = " + getDeviceId();
str += ", Command = " + command + "(" + commandId + ")";
str += ", Command = " + command;
str += ", Signal level = " + signalLevel;

return str;
Expand All @@ -132,8 +134,7 @@ public void encodeMessage(byte[] data) throws RFXComException {

subType = fromByte(SubType.class, super.subType);
unitId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
commandId = data[7];
command = Commands.fromByte(commandId, subType);
command = Commands.fromByte(data[7], subType);
signalLevel = (byte) ((data[8] & 0xF0) >> 4);
}

Expand All @@ -159,19 +160,51 @@ public State convertToState(String channelId) throws RFXComUnsupportedChannelExc
switch (channelId) {
case CHANNEL_COMMAND:
switch (command) {
case RUN_DOWN:
case OFF:
case SECOND_OFF:
return OnOffType.OFF;
case ON:
case RUN_UP:
case UP:
return OnOffType.ON;
case SECOND_ON:
case SECOND_OFF:
return null;
default:
return UnDefType.UNDEF;

}
case CHANNEL_CONTROL:
switch (command) {
case ON:
return OnOffType.ON;
case UP:
case RUN_UP:
return UpDownType.UP;
case OFF:
return OnOffType.OFF;
case DOWN:
case RUN_DOWN:
return UpDownType.DOWN;
case SECOND_ON:
case SECOND_OFF:
case STOP:
return null;
default:
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
}
case CHANNEL_COMMAND_SECOND:
switch (command) {
case SECOND_OFF:
return OnOffType.OFF;
case SECOND_ON:
return OnOffType.ON;
default:
return null;
}
case CHANNEL_COMMAND_STRING:
return command == null ? UnDefType.UNDEF : StringType.valueOf(command.toString());

default:
return super.convertToState(channelId);
}
Expand All @@ -183,15 +216,35 @@ public void convertFromState(String channelId, Type type) throws RFXComUnsupport
case CHANNEL_COMMAND:
if (type instanceof OnOffType) {
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
} else if (type instanceof UpDownType) {
} else {
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
}
break;

case CHANNEL_COMMAND_SECOND:
if (type instanceof OnOffType) {
command = (type == OnOffType.ON ? Commands.SECOND_ON : Commands.SECOND_OFF);
} else {
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
}
break;

case CHANNEL_CONTROL:
if (type instanceof UpDownType) {
command = (type == UpDownType.UP ? Commands.UP : Commands.DOWN);
} else if (type instanceof OpenClosedType) {
command = (type == OpenClosedType.CLOSED ? Commands.ON : Commands.OFF);
} else if (type == StopMoveType.STOP) {
command = Commands.STOP;
} else if (type instanceof PercentType) {
command = ((PercentType) type).as(UpDownType.class) == UpDownType.UP ? Commands.UP : Commands.DOWN;
} else {
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
}
break;

case CHANNEL_COMMAND_STRING:
command = Commands.valueOf(type.toString().toUpperCase());
break;

default:
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@
<channel-type id="commandId">
<item-type>Number</item-type>
<label>Command ID</label>
<description>Command channel, ID of the channel</description>
<description>Command channel, ID of the command</description>
<state min="0" max="255" step="1" pattern="%d" readOnly="false"></state>
</channel-type>

<channel-type id="commandString">
<item-type>String</item-type>
<label>Command String</label>
<description>Command channel, Name of the command</description>
</channel-type>

<channel-type id="contact">
<item-type>Contact</item-type>
<label>Contact</label>
Expand Down Expand Up @@ -70,6 +76,12 @@
<state min="0" max="255" step="1" pattern="%d °C" readOnly="false"></state>
</channel-type>

<channel-type id="tempcontrol">
<item-type>Rollershutter</item-type>
<label>Global Temperature Control</label>
<description>Requested temperature setting, UP, DOWN, STOP</description>
</channel-type>

<channel-type id="motion">
<item-type>Switch</item-type>
<label>Motion</label>
Expand Down
Loading

0 comments on commit 7cebf11

Please sign in to comment.