/** * 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.maxcube.internal.message; import java.util.ArrayList; import org.apache.commons.codec.binary.Base64; import org.openhab.binding.maxcube.internal.MaxCubeBinding; import org.openhab.binding.maxcube.internal.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The M message contains metadata about the MAX!Cube setup. * * @author Andreas Heil (info@aheil.de) * @since 1.4.0 */ public final class M_Message extends Message { public ArrayList<RoomInformation> rooms; public ArrayList<DeviceInformation> devices; private Boolean hasConfiguration; Logger logger = LoggerFactory.getLogger(MaxCubeBinding.class); public M_Message(String raw) { super(raw); hasConfiguration = false; String[] tokens = this.getPayload().split(Message.DELIMETER); if (tokens.length > 1) { try { byte[] bytes = Base64.decodeBase64(tokens[2].getBytes()); hasConfiguration = true; logger.trace("*** M_Message trace**** "); logger.trace("\tMagic? (expect 86) : {}", (int) bytes[0]); logger.trace("\tVersion? (expect 2): {}", (int) bytes[1]); logger.trace("\t#defined rooms in M: {}", (int) bytes[2]); rooms = new ArrayList<RoomInformation>(); devices = new ArrayList<DeviceInformation>(); int roomCount = bytes[2]; int byteOffset = 3; // start of rooms /* process room */ for (int i = 0; i < roomCount; i++) { int position = bytes[byteOffset++]; int nameLength = bytes[byteOffset++] & 0xff; byte[] data = new byte[nameLength]; System.arraycopy(bytes, byteOffset, data, 0, nameLength); byteOffset += nameLength; String name = new String(data, "UTF-8"); String rfAddress = Utils.toHex((bytes[byteOffset] & 0xff), (bytes[byteOffset + 1] & 0xff), (bytes[byteOffset + 2] & 0xff)); byteOffset += 3; rooms.add(new RoomInformation(position, name, rfAddress)); } /* process devices */ int deviceCount = bytes[byteOffset++]; for (int deviceId = 0; deviceId < deviceCount; deviceId++) { DeviceType deviceType = DeviceType.create(bytes[byteOffset++]); String rfAddress = Utils.toHex((bytes[byteOffset] & 0xff), (bytes[byteOffset + 1] & 0xff), (bytes[byteOffset + 2] & 0xff)); byteOffset += 3; String serialNumber = ""; for (int i = 0; i < 10; i++) { serialNumber += (char) bytes[byteOffset++]; } int nameLength = bytes[byteOffset++] & 0xff; byte[] data = new byte[nameLength]; System.arraycopy(bytes, byteOffset, data, 0, nameLength); byteOffset += nameLength; String deviceName = new String(data, "UTF-8"); int roomId = bytes[byteOffset++] & 0xff; devices.add(new DeviceInformation(deviceType, serialNumber, rfAddress, deviceName, roomId)); } } catch (Exception e) { logger.info("Unknown error parsing the M Message"); logger.info(e.getMessage()); logger.debug(Utils.getStackTrace(e)); logger.debug("\tRAW : {}", this.getPayload()); } } else { logger.info("No rooms defined. Configure your Max!Cube"); hasConfiguration = false; } } @Override public void debug(Logger logger) { logger.debug("=== M_Message === "); if (hasConfiguration) { logger.trace("\tRAW : {}", this.getPayload()); for (RoomInformation room : rooms) { logger.debug("\t=== Rooms ==="); logger.debug("\tRoom Pos : {}", room.getPosition()); logger.debug("\tRoom Name : {}", room.getName()); logger.debug("\tRoom RF Adr: {}", room.getRFAddress()); for (DeviceInformation device : devices) { if (room.getPosition() == device.getRoomId()) { logger.debug("\t=== Devices ==="); logger.debug("\tDevice Type : {}", device.getDeviceType()); logger.debug("\tDevice Name : {}", device.getName()); logger.debug("\tDevice Serialnr: {}", device.getSerialNumber()); logger.debug("\tDevice RF Adr : {}", device.getRFAddress()); logger.debug("\tRoom Id : {}", device.getRoomId()); } } } } else { logger.debug("M-Message empty. No Configuration"); } } @Override public MessageType getType() { return MessageType.M; } }