/** * 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 java.util.HashMap; import java.util.Map.Entry; /* * This class has utilities related to the X10 protocol. * * @author Bernd Pfrommer * @since 1.7.0 */ public class X10 { /** * Enumerates the X10 command codes. * * @author Bernd Pfrommer * */ public enum Command { ALL_LIGHTS_OFF(0x6), STATUS_OFF(0xE), ON(0x2), PRESET_DIM_1(0xA), ALL_LIGHTS_ON(0x1), HAIL_ACKNOWLEDGE(0x9), BRIGHT(0x5), STATUS_ON(0xD), EXTENDED_CODE(0x9), STATUS_REQUEST(0xF), OFF(0x3), PRESET_DIM_2(0xB), ALL_UNITS_OFF(0x0), HAIL_REQUEST(0x8), DIM(0x4), EXTENDED_DATA(0xC); private final byte m_code; Command(int b) { m_code = (byte) b; } public byte code() { return m_code; } } /** * converts house code to clear text * * @param c house code as per X10 spec * @return clear text house code, i.e letter A-P */ public static String s_houseToString(byte c) { String s = s_houseCodeToString.get(new Integer(c & 0xff)); return (s == null) ? "X" : s; } /** * converts unit code to regular integer * * @param c unit code per X10 spec * @return decoded integer, i.e. number 0-16 */ public static int s_unitToInt(byte c) { Integer i = s_unitCodeToInt.get(new Integer(c & 0xff)); return (i == null) ? -1 : i; } /** * Test if string has valid X10 address of form "H.U", e.g. A.10 * * @param s string to test * @return true if is valid X10 address */ public static boolean s_isValidAddress(String s) { String[] parts = s.split("\\."); if (parts.length != 2) { return false; } return parts[0].matches("[A-P]") && parts[1].matches("\\d{1,2}"); } /** * Turn clear text address ("A.10") to byte code * * @param addr clear text address * @return byte that encodes house + unit code */ public static byte s_addressToByte(String addr) { String[] parts = addr.split("\\."); int ih = s_houseStringToCode(parts[0]); int iu = s_unitStringToCode(parts[1]); int itot = ih << 4 | iu; return (byte) (itot & 0xff); } /** * converts String to house byte code * * @param s clear text house string * @return coded house byte */ public static int s_houseStringToCode(String s) { Integer i = s_findKey(s_houseCodeToString, s); return (i == null) ? 0xf : i; } /** * converts unit string to unit code * * @param s string with clear text integer inside * @return encoded unit byte */ public static int s_unitStringToCode(String s) { try { Integer key = Integer.parseInt(s); Integer i = s_findKey(s_unitCodeToInt, key); return i; } catch (NumberFormatException e) { } return 0xf; } private static <T, E> T s_findKey(HashMap<T, E> map, E value) { for (Entry<T, E> entry : map.entrySet()) { if (value.equals(entry.getValue())) { return entry.getKey(); } } return null; } /** * Map between 4-bit X10 code and the house code. */ private static HashMap<Integer, String> s_houseCodeToString = new HashMap<Integer, String>(); /** * Map between 4-bit X10 code and the unit code. */ private static HashMap<Integer, Integer> s_unitCodeToInt = new HashMap<Integer, Integer>(); static { s_houseCodeToString.put(0x6, "A"); s_unitCodeToInt.put(0x6, 1); s_houseCodeToString.put(0xe, "B"); s_unitCodeToInt.put(0xe, 2); s_houseCodeToString.put(0x2, "C"); s_unitCodeToInt.put(0x2, 3); s_houseCodeToString.put(0xa, "D"); s_unitCodeToInt.put(0xa, 4); s_houseCodeToString.put(0x1, "E"); s_unitCodeToInt.put(0x1, 5); s_houseCodeToString.put(0x9, "F"); s_unitCodeToInt.put(0x9, 6); s_houseCodeToString.put(0x5, "G"); s_unitCodeToInt.put(0x5, 7); s_houseCodeToString.put(0xd, "H"); s_unitCodeToInt.put(0xd, 8); s_houseCodeToString.put(0x7, "I"); s_unitCodeToInt.put(0x7, 9); s_houseCodeToString.put(0xf, "J"); s_unitCodeToInt.put(0xf, 10); s_houseCodeToString.put(0x3, "K"); s_unitCodeToInt.put(0x3, 11); s_houseCodeToString.put(0xb, "L"); s_unitCodeToInt.put(0xb, 12); s_houseCodeToString.put(0x0, "M"); s_unitCodeToInt.put(0x0, 13); s_houseCodeToString.put(0x8, "N"); s_unitCodeToInt.put(0x8, 14); s_houseCodeToString.put(0x4, "O"); s_unitCodeToInt.put(0x4, 15); s_houseCodeToString.put(0xc, "P"); s_unitCodeToInt.put(0xc, 16); } }