/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.insteonplm.internal.device; import org.openhab.binding.insteonplm.internal.utils.Utils; /** * This class wraps an Insteon Address 'xx.xx.xx' * * @author Daniel Pfrommer * @since 1.5.0 */ public class InsteonAddress { private byte highByte; private byte middleByte; private byte lowByte; private boolean x10; public InsteonAddress() { highByte = 0x00; middleByte = 0x00; lowByte = 0x00; x10 = false; } public InsteonAddress(InsteonAddress a) { highByte = a.highByte; middleByte = a.middleByte; lowByte = a.lowByte; x10 = a.x10; } public InsteonAddress(byte high, byte middle, byte low) { highByte = high; middleByte = middle; lowByte = low; x10 = false; } /** * Constructor * * @param address string must have format of e.g. '2a.3c.40' or (for X10) 'H.UU' */ public InsteonAddress(String address) throws IllegalArgumentException { if (X10.s_isValidAddress(address)) { highByte = 0; middleByte = 0; lowByte = X10.s_addressToByte(address); x10 = true; } else { String[] parts = address.split("\\."); if (parts.length != 3) { throw new IllegalArgumentException("Address string must have 3 bytes, has: " + parts.length); } highByte = (byte) Utils.fromHexString(parts[0]); middleByte = (byte) Utils.fromHexString(parts[1]); lowByte = (byte) Utils.fromHexString(parts[2]); x10 = false; } } /** * Constructor for an InsteonAddress that wraps an X10 address. * Simply stuff the X10 address into the lowest byte. * * @param aX10HouseUnit the house & unit number as encoded by the X10 protocol */ public InsteonAddress(byte aX10HouseUnit) { highByte = 0; middleByte = 0; lowByte = aX10HouseUnit; x10 = true; } public void setHighByte(byte h) { highByte = h; } public void setMiddleByte(byte m) { middleByte = m; } public void setLowByte(byte l) { lowByte = l; } public byte getHighByte() { return highByte; } public byte getMiddleByte() { return middleByte; } public byte getLowByte() { return lowByte; } public byte getX10HouseCode() { return (byte) ((lowByte & 0xf0) >> 4); } public byte getX10UnitCode() { return (byte) ((lowByte & 0x0f)); } public boolean isX10() { return x10; } public void storeBytes(byte[] bytes, int offset) { bytes[offset] = getHighByte(); bytes[offset + 1] = getMiddleByte(); bytes[offset + 2] = getLowByte(); } public void loadBytes(byte[] bytes, int offset) { setHighByte(bytes[offset]); setMiddleByte(bytes[offset + 1]); setLowByte(bytes[offset + 2]); } @Override public String toString() { String s = null; if (isX10()) { byte house = (byte) (((getLowByte() & 0xf0) >> 4) & 0xff); byte unit = (byte) ((getLowByte() & 0x0f) & 0xff); s = X10.s_houseToString(house) + "." + X10.s_unitToInt(unit); // s = Utils.getHexString(lowByte); } else { s = Utils.getHexString(highByte) + "." + Utils.getHexString(middleByte) + "." + Utils.getHexString(lowByte); } return s; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } InsteonAddress other = (InsteonAddress) obj; if (highByte != other.highByte) { return false; } if (lowByte != other.lowByte) { return false; } if (middleByte != other.middleByte) { return false; } if (x10 != other.x10) { return false; } return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + highByte; result = prime * result + lowByte; result = prime * result + middleByte; result = prime * result + (x10 ? 1231 : 1237); return result; } /** * Test if Insteon address is valid * * @return true if address is in valid AB.CD.EF or (for X10) H.UU format */ public static boolean s_isValid(String addr) { if (addr == null) { return false; } if (X10.s_isValidAddress(addr)) { return true; } String[] fields = addr.split("\\."); if (fields.length != 3) { return false; } try { // convert the insteon xx.xx.xx address to integer to test @SuppressWarnings("unused") int test = Integer.parseInt(fields[2], 16) * 65536 + Integer.parseInt(fields[1], 16) * 256 + +Integer.parseInt(fields[0], 16); } catch (Exception e) { return false; } return true; } /** * Turn string into address * * @param val the string to convert * @return the corresponding insteon address */ public static InsteonAddress s_parseAddress(String val) { return new InsteonAddress(val); } /** * Function for unit testing * * @param args ignored */ public static void main(String[] args) { // debug/test code InsteonAddress a1 = new InsteonAddress(); InsteonAddress a2 = new InsteonAddress(); System.out.println(a1.equals(a2)); System.out.println(new InsteonAddress("0f.0f.0a")); } }