diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/RFXComDataConverter.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/RFXComDataConverter.java index 90021b7cab0..56b3aebe3fb 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/RFXComDataConverter.java +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/RFXComDataConverter.java @@ -109,6 +109,10 @@ public static State convertRFXCOMValueToOpenHABValue(Object obj, else if (obj instanceof RFXComLighting2Message) return convertLighting2ToState((RFXComLighting2Message) obj, valueSelector); + + else if (obj instanceof RFXComLighting5Message) + return convertLighting5ToState((RFXComLighting5Message) obj, + valueSelector); else if (obj instanceof RFXComSecurity1Message) return convertSecurity1ToState((RFXComSecurity1Message) obj, @@ -318,6 +322,106 @@ private static State convertLighting2ToState(RFXComLighting2Message obj, return state; } + private static State convertLighting5ToState(RFXComLighting5Message obj, + RFXComValueSelector valueSelector) { + + org.openhab.core.types.State state = UnDefType.UNDEF; + + if (valueSelector.getItemClass() == NumberItem.class) { + + if (valueSelector == RFXComValueSelector.SIGNAL_LEVEL) { + + state = new DecimalType(obj.signalLevel); + + } else { + throw new NumberFormatException("Can't convert " + + valueSelector + " to NumberItem"); + } + + } else if (valueSelector.getItemClass() == DimmerItem.class + || valueSelector.getItemClass() == RollershutterItem.class) { + + if (valueSelector == RFXComValueSelector.DIMMING_LEVEL) { + state = RFXComLighting5Message.getPercentTypeFromDimLevel(obj.dimmingLevel); + + } else { + throw new NumberFormatException("Can't convert " + + valueSelector + " to DimmerItem/RollershutterItem"); + } + + } else if (valueSelector.getItemClass() == SwitchItem.class) { + + if (valueSelector == RFXComValueSelector.COMMAND) { + + switch (obj.command) { + case OFF: + case GROUP_OFF: + state = OnOffType.OFF; + break; + + case ON: + state = OnOffType.ON; + break; + + case SET_LEVEL: + default: + throw new NumberFormatException("Can't convert " + + obj.command + " to SwitchItem"); + + } + + } else { + throw new NumberFormatException("Can't convert " + + valueSelector + " to SwitchItem"); + } + + } else if (valueSelector.getItemClass() == ContactItem.class) { + + if (valueSelector == RFXComValueSelector.COMMAND) { + + switch (obj.command) { + case OFF: + case GROUP_OFF: + state = OpenClosedType.OPEN; + break; + + case ON: + state = OpenClosedType.CLOSED; + break; + + case SET_LEVEL: + default: + throw new NumberFormatException("Can't convert " + + obj.command + " to ContactItem"); + } + + } else { + throw new NumberFormatException("Can't convert " + + valueSelector + " to ContactItem"); + } + + } else if (valueSelector.getItemClass() == StringItem.class) { + + if (valueSelector == RFXComValueSelector.RAW_DATA) { + + state = new StringType( + DatatypeConverter.printHexBinary(obj.rawMessage)); + + } else { + throw new NumberFormatException("Can't convert " + + valueSelector + " to StringItem"); + } + + } else { + + throw new NumberFormatException("Can't convert " + valueSelector + + " to " + valueSelector.getItemClass()); + + } + + return state; + } + private static State convertSecurity1ToState(RFXComSecurity1Message obj, RFXComValueSelector valueSelector) { @@ -731,13 +835,76 @@ public static Object convertOpenHABValueToRFXCOMValue(String id, + " to Command"); } break; + + default: + break; + + } + break; + + case LIGHTING5: + RFXComLighting5Message d5 = new RFXComLighting5Message(); + d5.subType = (RFXComLighting5Message.SubType) subType; + d5.seqNbr = seqNumber; + String[] ids5 = id.split("\\."); + d5.sensorId = Integer.parseInt(ids5[0]); + d5.unitcode = Byte.parseByte(ids5[1]); + + logger.debug( + "convertOpenHABValueToRFXCOMValue 5 (command='{}', type='{}')", + new Object[] { valueSelector.toString(), type.toString()}); + + + switch (valueSelector) { + case COMMAND: + if (type instanceof OnOffType) { + d5.command = (type == OnOffType.ON ? RFXComLighting5Message.Commands.ON + : RFXComLighting5Message.Commands.OFF); + d5.dimmingLevel = 0; + obj = d5; + } else { + throw new NumberFormatException("Can't convert " + type + + " to Command"); + } + break; + case DIMMING_LEVEL: + if (type instanceof OnOffType) { + d5.command = (type == OnOffType.ON ? RFXComLighting5Message.Commands.ON + : RFXComLighting5Message.Commands.OFF); + d5.dimmingLevel = 0; + obj = d5; + } else if (type instanceof PercentType) { + d5.command = RFXComLighting5Message.Commands.SET_LEVEL; + d5.dimmingLevel = (byte) RFXComLighting5Message.getDimLevelFromPercentType((PercentType) type); + + if ( d5.dimmingLevel == 0) { + d5.command = RFXComLighting5Message.Commands.OFF; + } + + logger.debug( + "dim level = '{}')", + new Object[] {d5.dimmingLevel}); + + obj = d5; + } else if (type instanceof IncreaseDecreaseType) { + d5.command = RFXComLighting5Message.Commands.SET_LEVEL; + //Evert: I do not know how to get previous object state... + d5.dimmingLevel = 5; + + obj = d5; + + } else { + throw new NumberFormatException("Can't convert " + type + + " to Command"); + } + break; + default: break; } break; - case CURTAIN1: RFXComCurtain1Message d3 = new RFXComCurtain1Message(); diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBaseMessage.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBaseMessage.java index b20bf061d83..4413ed27d90 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBaseMessage.java +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComBaseMessage.java @@ -44,6 +44,7 @@ public enum PacketType { TRANSMITTER_MESSAGE(2), LIGHTING1(16), LIGHTING2(17), + LIGHTING5(20), CURTAIN1(18), SECURITY1(32), TEMPERATURE(80), diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComLighting5Message.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComLighting5Message.java new file mode 100644 index 00000000000..0f9bf0024cf --- /dev/null +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComLighting5Message.java @@ -0,0 +1,207 @@ +/** + * openHAB, the open Home Automation Bus. + * Copyright (C) 2010-2013, openHAB.org + * + * See the contributors.txt file in the distribution for a + * full listing of individual contributors. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or + * combining it with Eclipse (or a modified version of that library), + * containing parts covered by the terms of the Eclipse Public License + * (EPL), the licensors of this Program grant you additional permission + * to convey the resulting work. + */ +package org.openhab.binding.rfxcom.internal.messages; + +import java.math.BigDecimal; + +import org.openhab.core.library.types.PercentType; + +/** + * RFXCOM data class for lighting5 message. + * + * @author Paul Hampson + * @since 1.3.0 + */ +public class RFXComLighting5Message extends RFXComBaseMessage { + + public enum Commands { + OFF(0), + ON(1), + GROUP_OFF(2), + MOOD1(3), + MOOD2(4), + MOOD3(5), + MOOD4(6), + MOOD5(7), + RESERVED1(8), + RESERVED2(9), + UNLOCK(10), + LOCK(11), + ALL_LOCK(12), + CLOSE_RELAY(13), + STOP_RELAY(14), + OPEN_RELAY(15), + SET_LEVEL(16); + + private final int command; + + Commands(int command) { + this.command = command; + } + + Commands(byte command) { + this.command = command; + } + + public byte toByte() { + return (byte) command; + } + } + + + public enum SubType { + LIGHTWAVERF(0), + EMW100(1), + BBSB_NEW(2), + MDREMOTE(3), + CONRAD_RSL2(4); + + private final int subType; + + SubType(int subType) { + this.subType = subType; + } + + SubType(byte subType) { + this.subType = subType; + } + + public byte toByte() { + return (byte) subType; + } + } + + public SubType subType = SubType.LIGHTWAVERF; + public int sensorId = 0; + public byte unitcode = 0; + public Commands command = Commands.OFF; + public byte dimmingLevel = 0; + public byte signalLevel = 0; + + public RFXComLighting5Message() { + packetType = PacketType.LIGHTING5; + + } + + public RFXComLighting5Message(byte[] data) { + + encodeMessage(data); + } + + @Override + public String toString() { + String str = ""; + + str += super.toString(); + str += "\n - Sub type = " + subType; + str += "\n - Id = " + sensorId; + str += "\n - Unit code = " + unitcode; + str += "\n - Command = " + command; + str += "\n - Dim level = " + dimmingLevel; + str += "\n - Signal level = " + signalLevel; + + return str; + } + + @Override + public void encodeMessage(byte[] data) { + + super.encodeMessage(data); + + subType = SubType.values()[super.subType]; + sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 + | (data[6] & 0xFF) << 0; + unitcode = data[7]; + command = Commands.values()[data[8]]; + dimmingLevel = data[9]; + signalLevel = (byte) ((data[10] & 0xF0) >> 4); + } + + @Override + public byte[] decodeMessage() { + + byte[] data = new byte[11]; + + data[0] = 0x0A; + data[1] = RFXComBaseMessage.PacketType.LIGHTING5.toByte(); + data[2] = subType.toByte(); + data[3] = seqNbr; + data[4] = (byte) ((sensorId >> 16) & 0xFF); + data[5] = (byte) ((sensorId >> 8) & 0xFF); + data[6] = (byte) (sensorId & 0xFF); + + data[7] = unitcode; + data[8] = command.toByte(); + data[9] = dimmingLevel; + data[10] = (byte) ((signalLevel & 0x0F) << 4); + + return data; + } + + @Override + public String generateDeviceId() { + return sensorId + "." + unitcode; + } + + + + /** + * Convert a 0-31 scale value to a percent type. + * + * @param pt + * percent type to convert + * @return converted value 0-31 + */ + public static int getDimLevelFromPercentType(PercentType pt) { + return pt + .toBigDecimal() + .multiply(BigDecimal.valueOf(31)) + .divide(PercentType.HUNDRED.toBigDecimal(), 0, + BigDecimal.ROUND_UP).intValue(); + } + + /** + * Convert a 0-31 scale value to a percent type. + * + * @param pt + * percent type to convert + * @return converted value 0-31 + */ + public static PercentType getPercentTypeFromDimLevel(int value) { + value = Math.min(value, 31); + + return new PercentType(BigDecimal + .valueOf(value) + .multiply(BigDecimal.valueOf(100)) + .divide(BigDecimal.valueOf(31), 0, + BigDecimal.ROUND_UP).intValue()); + } + + +} diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComMessageUtils.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComMessageUtils.java index b36e50a8ddd..da7642992ae 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComMessageUtils.java +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComMessageUtils.java @@ -81,6 +81,9 @@ public static Object decodePacket(byte[] data) throws IllegalArgumentException { case (byte) 0x11: obj = new RFXComLighting2Message(data); break; + case (byte) 0x14: + obj = new RFXComLighting5Message(data); + break; case (byte) 0x18: obj = new RFXComCurtain1Message(data); break; @@ -115,7 +118,7 @@ public static byte[] encodePacket(Object obj) throws IllegalArgumentException { if( data == null ) { throw new IllegalArgumentException("No valid encoder implemented!"); } - + return data; } @@ -151,6 +154,14 @@ public static Object convertSubType(PacketType packetType, String subType) { } break; + case LIGHTING5: + for (RFXComLighting5Message.SubType s : RFXComLighting5Message.SubType.values()) { + if (s.toString().equals(subType)) { + return s; + } + } + break; + case CURTAIN1: for (RFXComCurtain1Message.SubType s : RFXComCurtain1Message.SubType.values()) { if (s.toString().equals(subType)) { diff --git a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComTemperatureHumidityMessage.java b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComTemperatureHumidityMessage.java index 73bec918ace..8483448e198 100644 --- a/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComTemperatureHumidityMessage.java +++ b/bundles/binding/org.openhab.binding.rfxcom/src/main/java/org/openhab/binding/rfxcom/internal/messages/RFXComTemperatureHumidityMessage.java @@ -46,6 +46,7 @@ public enum SubType { TFA_TS34C__CRESTA(7), WT260_WT260H_WT440H_WT450_WT450H(8), VIKING_02035_02038(9), + RUBICSON(10), UNKNOWN(255); @@ -65,9 +66,9 @@ public byte toByte() { } public enum HumidityStatus { - DRY(0), + NORMAL(0), COMFORT(1), - NORMAL(2), + DRY(2), WET(3), UNKNOWN(255);