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