2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.insteon.internal.device;
15 import java.util.HashMap;
16 import java.util.Map.Entry;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
22 * This class has utilities related to the X10 protocol.
24 * @author Bernd Pfrommer - Initial contribution
25 * @author Rob Nielsen - Port to openHAB 2 insteon binding
28 @SuppressWarnings("null")
31 * Enumerates the X10 command codes.
33 * @author Bernd Pfrommer - openHAB 1 insteonplm binding
42 HAIL_ACKNOWLEDGE(0x9),
54 private final byte code;
66 * converts house code to clear text
68 * @param c house code as per X10 spec
69 * @return clear text house code, i.e letter A-P
71 public static String houseToString(byte c) {
72 String s = houseCodeToString.get(c & 0xff);
73 return (s == null) ? "X" : s;
77 * converts unit code to regular integer
79 * @param c unit code per X10 spec
80 * @return decoded integer, i.e. number 0-16
82 public static int unitToInt(byte c) {
83 Integer i = unitCodeToInt.get(c & 0xff);
84 return (i == null) ? -1 : i;
88 * Test if string has valid X10 address of form "H.U", e.g. A.10
90 * @param s string to test
91 * @return true if is valid X10 address
93 public static boolean isValidAddress(String s) {
94 String[] parts = s.split("\\.");
95 if (parts.length != 2) {
98 return parts[0].matches("[A-P]") && parts[1].matches("\\d{1,2}");
102 * Turn clear text address ("A.10") to byte code
104 * @param addr clear text address
105 * @return byte that encodes house + unit code
107 public static byte addressToByte(String addr) {
108 String[] parts = addr.split("\\.");
109 int ih = houseStringToCode(parts[0]);
110 int iu = unitStringToCode(parts[1]);
111 int itot = ih << 4 | iu;
112 return (byte) (itot & 0xff);
116 * converts String to house byte code
118 * @param s clear text house string
119 * @return coded house byte
121 public static int houseStringToCode(String s) {
122 Integer i = findKey(houseCodeToString, s);
123 return (i == null) ? 0xf : i;
127 * converts unit string to unit code
129 * @param s string with clear text integer inside
130 * @return encoded unit byte
132 public static int unitStringToCode(String s) {
134 Integer key = Integer.parseInt(s);
135 Integer i = findKey(unitCodeToInt, key);
137 } catch (NumberFormatException e) {
142 private static @Nullable <T, E> T findKey(HashMap<T, E> map, E value) {
143 for (Entry<T, E> entry : map.entrySet()) {
144 if (value.equals(entry.getValue())) {
145 return entry.getKey();
152 * Map between 4-bit X10 code and the house code.
154 private static HashMap<Integer, @Nullable String> houseCodeToString = new HashMap<>();
156 * Map between 4-bit X10 code and the unit code.
158 private static HashMap<Integer, @Nullable Integer> unitCodeToInt = new HashMap<>();
161 houseCodeToString.put(0x6, "A");
162 unitCodeToInt.put(0x6, 1);
163 houseCodeToString.put(0xe, "B");
164 unitCodeToInt.put(0xe, 2);
165 houseCodeToString.put(0x2, "C");
166 unitCodeToInt.put(0x2, 3);
167 houseCodeToString.put(0xa, "D");
168 unitCodeToInt.put(0xa, 4);
169 houseCodeToString.put(0x1, "E");
170 unitCodeToInt.put(0x1, 5);
171 houseCodeToString.put(0x9, "F");
172 unitCodeToInt.put(0x9, 6);
173 houseCodeToString.put(0x5, "G");
174 unitCodeToInt.put(0x5, 7);
175 houseCodeToString.put(0xd, "H");
176 unitCodeToInt.put(0xd, 8);
177 houseCodeToString.put(0x7, "I");
178 unitCodeToInt.put(0x7, 9);
179 houseCodeToString.put(0xf, "J");
180 unitCodeToInt.put(0xf, 10);
181 houseCodeToString.put(0x3, "K");
182 unitCodeToInt.put(0x3, 11);
183 houseCodeToString.put(0xb, "L");
184 unitCodeToInt.put(0xb, 12);
185 houseCodeToString.put(0x0, "M");
186 unitCodeToInt.put(0x0, 13);
187 houseCodeToString.put(0x8, "N");
188 unitCodeToInt.put(0x8, 14);
189 houseCodeToString.put(0x4, "O");
190 unitCodeToInt.put(0x4, 15);
191 houseCodeToString.put(0xc, "P");
192 unitCodeToInt.put(0xc, 16);