]> git.basschouten.com Git - openhab-addons.git/blob
90b8317fb015458630379ec76bf5fc8c6a021e51
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.insteon.internal.device;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.Map.Entry;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21
22 /**
23  * This class has utilities related to the X10 protocol.
24  *
25  * @author Bernd Pfrommer - Initial contribution
26  * @author Rob Nielsen - Port to openHAB 2 insteon binding
27  */
28 @NonNullByDefault
29 @SuppressWarnings("null")
30 public class X10 {
31     /**
32      * Enumerates the X10 command codes.
33      *
34      * @author Bernd Pfrommer - openHAB 1 insteonplm binding
35      *
36      */
37     public enum Command {
38         ALL_LIGHTS_OFF(0x6),
39         STATUS_OFF(0xE),
40         ON(0x2),
41         PRESET_DIM_1(0xA),
42         ALL_LIGHTS_ON(0x1),
43         HAIL_ACKNOWLEDGE(0x9),
44         BRIGHT(0x5),
45         STATUS_ON(0xD),
46         EXTENDED_CODE(0x9),
47         STATUS_REQUEST(0xF),
48         OFF(0x3),
49         PRESET_DIM_2(0xB),
50         ALL_UNITS_OFF(0x0),
51         HAIL_REQUEST(0x8),
52         DIM(0x4),
53         EXTENDED_DATA(0xC);
54
55         private final byte code;
56
57         Command(int b) {
58             code = (byte) b;
59         }
60
61         public byte code() {
62             return code;
63         }
64     }
65
66     /**
67      * converts house code to clear text
68      *
69      * @param c house code as per X10 spec
70      * @return clear text house code, i.e letter A-P
71      */
72     public static String houseToString(byte c) {
73         String s = houseCodeToString.get(c & 0xff);
74         return (s == null) ? "X" : s;
75     }
76
77     /**
78      * converts unit code to regular integer
79      *
80      * @param c unit code per X10 spec
81      * @return decoded integer, i.e. number 0-16
82      */
83     public static int unitToInt(byte c) {
84         Integer i = unitCodeToInt.get(c & 0xff);
85         return (i == null) ? -1 : i;
86     }
87
88     /**
89      * Test if string has valid X10 address of form "H.U", e.g. A.10
90      *
91      * @param s string to test
92      * @return true if is valid X10 address
93      */
94     public static boolean isValidAddress(String s) {
95         String[] parts = s.split("\\.");
96         if (parts.length != 2) {
97             return false;
98         }
99         return parts[0].matches("[A-P]") && parts[1].matches("\\d{1,2}");
100     }
101
102     /**
103      * Turn clear text address ("A.10") to byte code
104      *
105      * @param addr clear text address
106      * @return byte that encodes house + unit code
107      */
108     public static byte addressToByte(String addr) {
109         String[] parts = addr.split("\\.");
110         int ih = houseStringToCode(parts[0]);
111         int iu = unitStringToCode(parts[1]);
112         int itot = ih << 4 | iu;
113         return (byte) (itot & 0xff);
114     }
115
116     /**
117      * converts String to house byte code
118      *
119      * @param s clear text house string
120      * @return coded house byte
121      */
122     public static int houseStringToCode(String s) {
123         Integer i = findKey(houseCodeToString, s);
124         return (i == null) ? 0xf : i;
125     }
126
127     /**
128      * converts unit string to unit code
129      *
130      * @param s string with clear text integer inside
131      * @return encoded unit byte
132      */
133     public static int unitStringToCode(String s) {
134         try {
135             Integer key = Integer.parseInt(s);
136             Integer i = findKey(unitCodeToInt, key);
137             return i;
138         } catch (NumberFormatException e) {
139         }
140         return 0xf;
141     }
142
143     private static @Nullable <T, E> T findKey(Map<T, E> map, E value) {
144         for (Entry<T, E> entry : map.entrySet()) {
145             if (value.equals(entry.getValue())) {
146                 return entry.getKey();
147             }
148         }
149         return null;
150     }
151
152     /**
153      * Map between 4-bit X10 code and the house code.
154      */
155     private static Map<Integer, String> houseCodeToString = new HashMap<>();
156     /**
157      * Map between 4-bit X10 code and the unit code.
158      */
159     private static Map<Integer, Integer> unitCodeToInt = new HashMap<>();
160
161     static {
162         houseCodeToString.put(0x6, "A");
163         unitCodeToInt.put(0x6, 1);
164         houseCodeToString.put(0xe, "B");
165         unitCodeToInt.put(0xe, 2);
166         houseCodeToString.put(0x2, "C");
167         unitCodeToInt.put(0x2, 3);
168         houseCodeToString.put(0xa, "D");
169         unitCodeToInt.put(0xa, 4);
170         houseCodeToString.put(0x1, "E");
171         unitCodeToInt.put(0x1, 5);
172         houseCodeToString.put(0x9, "F");
173         unitCodeToInt.put(0x9, 6);
174         houseCodeToString.put(0x5, "G");
175         unitCodeToInt.put(0x5, 7);
176         houseCodeToString.put(0xd, "H");
177         unitCodeToInt.put(0xd, 8);
178         houseCodeToString.put(0x7, "I");
179         unitCodeToInt.put(0x7, 9);
180         houseCodeToString.put(0xf, "J");
181         unitCodeToInt.put(0xf, 10);
182         houseCodeToString.put(0x3, "K");
183         unitCodeToInt.put(0x3, 11);
184         houseCodeToString.put(0xb, "L");
185         unitCodeToInt.put(0xb, 12);
186         houseCodeToString.put(0x0, "M");
187         unitCodeToInt.put(0x0, 13);
188         houseCodeToString.put(0x8, "N");
189         unitCodeToInt.put(0x8, 14);
190         houseCodeToString.put(0x4, "O");
191         unitCodeToInt.put(0x4, 15);
192         houseCodeToString.put(0xc, "P");
193         unitCodeToInt.put(0xc, 16);
194     }
195 }