]> git.basschouten.com Git - openhab-addons.git/blob
122e616530bd719150931fbb200d351d0a23e196
[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.Entry;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20
21 /**
22  * This class has utilities related to the X10 protocol.
23  *
24  * @author Bernd Pfrommer - Initial contribution
25  * @author Rob Nielsen - Port to openHAB 2 insteon binding
26  */
27 @NonNullByDefault
28 @SuppressWarnings("null")
29 public class X10 {
30     /**
31      * Enumerates the X10 command codes.
32      *
33      * @author Bernd Pfrommer - openHAB 1 insteonplm binding
34      *
35      */
36     public enum Command {
37         ALL_LIGHTS_OFF(0x6),
38         STATUS_OFF(0xE),
39         ON(0x2),
40         PRESET_DIM_1(0xA),
41         ALL_LIGHTS_ON(0x1),
42         HAIL_ACKNOWLEDGE(0x9),
43         BRIGHT(0x5),
44         STATUS_ON(0xD),
45         EXTENDED_CODE(0x9),
46         STATUS_REQUEST(0xF),
47         OFF(0x3),
48         PRESET_DIM_2(0xB),
49         ALL_UNITS_OFF(0x0),
50         HAIL_REQUEST(0x8),
51         DIM(0x4),
52         EXTENDED_DATA(0xC);
53
54         private final byte code;
55
56         Command(int b) {
57             code = (byte) b;
58         }
59
60         public byte code() {
61             return code;
62         }
63     }
64
65     /**
66      * converts house code to clear text
67      *
68      * @param c house code as per X10 spec
69      * @return clear text house code, i.e letter A-P
70      */
71     public static String houseToString(byte c) {
72         String s = houseCodeToString.get(c & 0xff);
73         return (s == null) ? "X" : s;
74     }
75
76     /**
77      * converts unit code to regular integer
78      *
79      * @param c unit code per X10 spec
80      * @return decoded integer, i.e. number 0-16
81      */
82     public static int unitToInt(byte c) {
83         Integer i = unitCodeToInt.get(c & 0xff);
84         return (i == null) ? -1 : i;
85     }
86
87     /**
88      * Test if string has valid X10 address of form "H.U", e.g. A.10
89      *
90      * @param s string to test
91      * @return true if is valid X10 address
92      */
93     public static boolean isValidAddress(String s) {
94         String[] parts = s.split("\\.");
95         if (parts.length != 2) {
96             return false;
97         }
98         return parts[0].matches("[A-P]") && parts[1].matches("\\d{1,2}");
99     }
100
101     /**
102      * Turn clear text address ("A.10") to byte code
103      *
104      * @param addr clear text address
105      * @return byte that encodes house + unit code
106      */
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);
113     }
114
115     /**
116      * converts String to house byte code
117      *
118      * @param s clear text house string
119      * @return coded house byte
120      */
121     public static int houseStringToCode(String s) {
122         Integer i = findKey(houseCodeToString, s);
123         return (i == null) ? 0xf : i;
124     }
125
126     /**
127      * converts unit string to unit code
128      *
129      * @param s string with clear text integer inside
130      * @return encoded unit byte
131      */
132     public static int unitStringToCode(String s) {
133         try {
134             Integer key = Integer.parseInt(s);
135             Integer i = findKey(unitCodeToInt, key);
136             return i;
137         } catch (NumberFormatException e) {
138         }
139         return 0xf;
140     }
141
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();
146             }
147         }
148         return null;
149     }
150
151     /**
152      * Map between 4-bit X10 code and the house code.
153      */
154     private static HashMap<Integer, @Nullable String> houseCodeToString = new HashMap<>();
155     /**
156      * Map between 4-bit X10 code and the unit code.
157      */
158     private static HashMap<Integer, @Nullable Integer> unitCodeToInt = new HashMap<>();
159
160     static {
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);
193     }
194 }