]> git.basschouten.com Git - openhab-addons.git/blob
bcbb3a64b9c0ea962c6c5e634220186e44899150
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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 org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.binding.insteon.internal.utils.Utils;
18
19 /**
20  * This class wraps an Insteon Address 'xx.xx.xx'
21  *
22  * @author Daniel Pfrommer - Initial contribution
23  * @author Rob Nielsen - Port to openHAB 2 insteon binding
24  */
25 @NonNullByDefault
26 public class InsteonAddress {
27     private byte highByte;
28     private byte middleByte;
29     private byte lowByte;
30     private boolean x10;
31
32     public InsteonAddress() {
33         highByte = 0x00;
34         middleByte = 0x00;
35         lowByte = 0x00;
36         x10 = false;
37     }
38
39     public InsteonAddress(InsteonAddress a) {
40         highByte = a.highByte;
41         middleByte = a.middleByte;
42         lowByte = a.lowByte;
43         x10 = a.x10;
44     }
45
46     public InsteonAddress(byte high, byte middle, byte low) {
47         highByte = high;
48         middleByte = middle;
49         lowByte = low;
50         x10 = false;
51     }
52
53     /**
54      * Constructor
55      *
56      * @param address string must have format of e.g. '2a.3c.40' or (for X10) 'H.UU'
57      */
58     public InsteonAddress(String address) throws IllegalArgumentException {
59         if (X10.isValidAddress(address)) {
60             highByte = 0;
61             middleByte = 0;
62             lowByte = X10.addressToByte(address);
63             x10 = true;
64         } else {
65             String[] parts = address.split("\\.");
66             if (parts.length != 3) {
67                 throw new IllegalArgumentException("Address string must have 3 bytes, has: " + parts.length);
68             }
69             highByte = (byte) Utils.fromHexString(parts[0]);
70             middleByte = (byte) Utils.fromHexString(parts[1]);
71             lowByte = (byte) Utils.fromHexString(parts[2]);
72             x10 = false;
73         }
74     }
75
76     /**
77      * Constructor for an InsteonAddress that wraps an X10 address.
78      * Simply stuff the X10 address into the lowest byte.
79      *
80      * @param aX10HouseUnit the house & unit number as encoded by the X10 protocol
81      */
82     public InsteonAddress(byte aX10HouseUnit) {
83         highByte = 0;
84         middleByte = 0;
85         lowByte = aX10HouseUnit;
86         x10 = true;
87     }
88
89     public void setHighByte(byte h) {
90         highByte = h;
91     }
92
93     public void setMiddleByte(byte m) {
94         middleByte = m;
95     }
96
97     public void setLowByte(byte l) {
98         lowByte = l;
99     }
100
101     public byte getHighByte() {
102         return highByte;
103     }
104
105     public byte getMiddleByte() {
106         return middleByte;
107     }
108
109     public byte getLowByte() {
110         return lowByte;
111     }
112
113     public byte getX10HouseCode() {
114         return (byte) ((lowByte & 0xf0) >> 4);
115     }
116
117     public byte getX10UnitCode() {
118         return (byte) ((lowByte & 0x0f));
119     }
120
121     public boolean isX10() {
122         return x10;
123     }
124
125     public void storeBytes(byte[] bytes, int offset) {
126         bytes[offset] = getHighByte();
127         bytes[offset + 1] = getMiddleByte();
128         bytes[offset + 2] = getLowByte();
129     }
130
131     public void loadBytes(byte[] bytes, int offset) {
132         setHighByte(bytes[offset]);
133         setMiddleByte(bytes[offset + 1]);
134         setLowByte(bytes[offset + 2]);
135     }
136
137     @Override
138     public String toString() {
139         String s = null;
140         if (isX10()) {
141             byte house = (byte) (((getLowByte() & 0xf0) >> 4) & 0xff);
142             byte unit = (byte) ((getLowByte() & 0x0f) & 0xff);
143             s = X10.houseToString(house) + "." + X10.unitToInt(unit);
144             // s = Utils.getHexString(lowByte);
145         } else {
146             s = Utils.getHexString(highByte) + "." + Utils.getHexString(middleByte) + "." + Utils.getHexString(lowByte);
147         }
148         return s;
149     }
150
151     @Override
152     public boolean equals(@Nullable Object obj) {
153         if (this == obj) {
154             return true;
155         }
156         if (obj == null) {
157             return false;
158         }
159         if (getClass() != obj.getClass()) {
160             return false;
161         }
162         InsteonAddress other = (InsteonAddress) obj;
163         if (highByte != other.highByte) {
164             return false;
165         }
166         if (lowByte != other.lowByte) {
167             return false;
168         }
169         if (middleByte != other.middleByte) {
170             return false;
171         }
172         if (x10 != other.x10) {
173             return false;
174         }
175         return true;
176     }
177
178     @Override
179     public int hashCode() {
180         final int prime = 31;
181         int result = 1;
182         result = prime * result + highByte;
183         result = prime * result + lowByte;
184         result = prime * result + middleByte;
185         result = prime * result + (x10 ? 1231 : 1237);
186         return result;
187     }
188
189     /**
190      * Test if Insteon address is valid
191      *
192      * @return true if address is in valid AB.CD.EF or (for X10) H.UU format
193      */
194     public static boolean isValid(@Nullable String addr) {
195         if (addr == null) {
196             return false;
197         }
198         if (X10.isValidAddress(addr)) {
199             return true;
200         }
201         String[] fields = addr.split("\\.");
202         if (fields.length != 3) {
203             return false;
204         }
205         try {
206             // convert the insteon xx.xx.xx address to integer to test
207             @SuppressWarnings("unused")
208             int test = Integer.parseInt(fields[2], 16) * 65536 + Integer.parseInt(fields[1], 16) * 256
209                     + +Integer.parseInt(fields[0], 16);
210         } catch (NumberFormatException e) {
211             return false;
212         }
213         return true;
214     }
215
216     /**
217      * Turn string into address
218      *
219      * @param val the string to convert
220      * @return the corresponding insteon address
221      */
222     public static InsteonAddress parseAddress(String val) {
223         return new InsteonAddress(val);
224     }
225 }