]> git.basschouten.com Git - openhab-addons.git/blob
fed14815b46e15ac89e8b49007d33b4d62487596
[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 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 and 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     @SuppressWarnings("PMD.SimplifyBooleanReturns")
152     @Override
153     public boolean equals(@Nullable Object obj) {
154         if (this == obj) {
155             return true;
156         }
157         if (obj == null) {
158             return false;
159         }
160         if (getClass() != obj.getClass()) {
161             return false;
162         }
163         InsteonAddress other = (InsteonAddress) obj;
164         if (highByte != other.highByte) {
165             return false;
166         }
167         if (lowByte != other.lowByte) {
168             return false;
169         }
170         if (middleByte != other.middleByte) {
171             return false;
172         }
173         if (x10 != other.x10) {
174             return false;
175         }
176         return true;
177     }
178
179     @Override
180     public int hashCode() {
181         final int prime = 31;
182         int result = 1;
183         result = prime * result + highByte;
184         result = prime * result + lowByte;
185         result = prime * result + middleByte;
186         result = prime * result + (x10 ? 1231 : 1237);
187         return result;
188     }
189
190     /**
191      * Test if Insteon address is valid
192      *
193      * @return true if address is in valid AB.CD.EF or (for X10) H.UU format
194      */
195     public static boolean isValid(@Nullable String addr) {
196         if (addr == null) {
197             return false;
198         }
199         if (X10.isValidAddress(addr)) {
200             return true;
201         }
202         String[] fields = addr.split("\\.");
203         if (fields.length != 3) {
204             return false;
205         }
206         try {
207             // convert the insteon xx.xx.xx address to integer to test
208             @SuppressWarnings("unused")
209             int test = Integer.parseInt(fields[2], 16) * 65536 + Integer.parseInt(fields[1], 16) * 256
210                     + +Integer.parseInt(fields[0], 16);
211         } catch (NumberFormatException e) {
212             return false;
213         }
214         return true;
215     }
216
217     /**
218      * Turn string into address
219      *
220      * @param val the string to convert
221      * @return the corresponding insteon address
222      */
223     public static InsteonAddress parseAddress(String val) {
224         return new InsteonAddress(val);
225     }
226 }