Java tutorial
/** * Copyright (c) 2010-2017 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 de.csdev.ebus.utils; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import de.csdev.ebus.command.EBusCommandRegistry; import de.csdev.ebus.command.EBusCommandUtils; import de.csdev.ebus.command.IEBusCommandCollection; import de.csdev.ebus.command.IEBusCommandMethod; import de.csdev.ebus.command.datatypes.EBusTypeException; import de.csdev.ebus.core.EBusConsts; import de.csdev.ebus.core.EBusDataException; import de.csdev.ebus.service.device.EBusDevice; import de.csdev.ebus.service.device.EBusDeviceTable; import de.csdev.ebus.service.metrics.EBusMetricsService; /** * * @author Christian Sowada - Initial contribution * */ public class EBusConsoleUtils { private static final Logger logger = LoggerFactory.getLogger(EBusConsoleUtils.class); /** * Returns metrics information * * @param service * @return */ public static String getMetricsInformation(EBusMetricsService service) { StringBuilder sb = new StringBuilder(); sb.append(String.format("%-25s | %-10s\n", "Successful received", service.getReceived())); sb.append(String.format("%-25s | %-10s\n", "Failed received", service.getFailed())); sb.append(String.format("%-25s | %-10s\n", "Successful/Failed ratio", service.getFailureRatio())); sb.append("\n"); sb.append(String.format("%-25s | %-10s\n", "Resolved telegrams", service.getResolved())); sb.append(String.format("%-25s | %-10s\n", "Unresolved telegrams", service.getUnresolved())); sb.append(String.format("%-25s | %-10s\n", "Resolved/Unresolved ratio", service.getUnresolvedRatio())); return sb.toString(); } /** * Returns device table information * * @return */ public static String getDeviceTableInformation(Collection<IEBusCommandCollection> collections, EBusDeviceTable deviceTable) { StringBuilder sb = new StringBuilder(); Map<String, String> mapping = new HashMap<String, String>(); for (IEBusCommandCollection collection : collections) { for (String identification : collection.getIdentification()) { mapping.put(identification, collection.getId()); } } EBusDevice ownDevice = deviceTable.getOwnDevice(); sb.append(String.format("%-2s | %-2s | %-14s | %-14s | %-25s | %-2s | %-10s | %-10s | %-20s\n", "MA", "SA", "Identifier", "Device", "Manufacture", "ID", "Firmware", "Hardware", "Last Activity")); sb.append(String.format("%-2s-+-%-2s-+-%-14s-+-%-14s-+-%-20s-+-%-2s-+-%-10s-+-%-10s-+-%-20s\n", StringUtils.repeat("-", 2), StringUtils.repeat("-", 2), StringUtils.repeat("-", 14), StringUtils.repeat("-", 14), StringUtils.repeat("-", 20), StringUtils.repeat("-", 2), StringUtils.repeat("-", 10), StringUtils.repeat("-", 10), StringUtils.repeat("-", 20))); for (EBusDevice device : deviceTable.getDeviceTable()) { boolean isBridge = device.equals(ownDevice); String masterAddress = EBusUtils.toHexDumpString(device.getMasterAddress()); String slaveAddress = EBusUtils.toHexDumpString(device.getSlaveAddress()); String activity = device.getLastActivity() == 0 ? "---" : new Date(device.getLastActivity()).toString(); String id = EBusUtils.toHexDumpString(device.getDeviceId()).toString(); String deviceName = isBridge ? "<interface>" : mapping.getOrDefault(id, "---"); String manufacture = isBridge ? "eBUS Library" : device.getManufacturerName(); sb.append(String.format("%-2s | %-2s | %-14s | %-14s | %-25s | %-2s | %-10s | %-10s | %-20s\n", masterAddress, slaveAddress, id, deviceName, manufacture, EBusUtils.toHexDumpString(device.getManufacturer()), device.getSoftwareVersion(), device.getHardwareVersion(), activity)); } sb.append(StringUtils.repeat("-", 118) + "\n"); sb.append("MA = Master Address / SA = Slave Address / ID = Manufacture ID\n"); return sb.toString(); } /** * Returns telegram analyze data * * @param registry * @param data * @return */ public static String analyzeTelegram(EBusCommandRegistry registry, byte[] data) { StringBuilder sb = new StringBuilder(); try { byte[] edata = null; sb.append("\n"); try { edata = EBusCommandUtils.checkRawTelegram(data); } catch (EBusDataException e) { String msg = String.format("** Error on checking telegram: %s **", e.getMessage()); int len = msg.length(); sb.append("\n"); sb.append(StringUtils.repeat("*", len) + "\n"); sb.append(msg + "\n"); msg = "** !!! Warning: All following results are wrong and only displayed for information purpose !!!"; msg += StringUtils.repeat(" ", len - msg.length() - 2) + "**"; sb.append(msg + "\n"); sb.append(StringUtils.repeat("*", len) + "\n"); sb.append("\n"); return sb.toString(); } sb.append("\n"); sb.append("Check and unescape telegram\n"); sb.append("***************************\n"); sb.append("\n"); sb.append(String.format("Original data : %s\n", EBusUtils.toHexDumpString(data))); sb.append(String.format("Unescaped data: %s\n", EBusUtils.toHexDumpString(edata))); byte[] command = Arrays.copyOfRange(edata, 2, 4); boolean isMasterMaster = EBusUtils.isMasterAddress(edata[1]); boolean isBroadcast = edata[1] == EBusConsts.BROADCAST_ADDRESS; boolean isMasterSlave = !isMasterMaster && !isBroadcast; int masterDataLenPos = 4; int masterDataLen = edata[masterDataLenPos]; byte[] masterData = Arrays.copyOfRange(edata, 5, 5 + masterDataLen); int masterCrcPos = 5 + masterDataLen; int slaveACKPos = masterCrcPos + 1; String dataString = EBusUtils.toHexDumpString(edata).toString(); int dataLen = dataString.length(); sb.append("\n"); sb.append("Analyse the telegram\n"); sb.append("********************\n"); sb.append("\n"); sb.append(dataString + "\n"); final String FORMAT = "%-20s | %-20s | %s"; sb.append(createTelegramResoverRow(0, 1, dataLen, String.format(FORMAT, "Source address", "Type: " + addressType(edata[0]), hex(edata[0])))); sb.append(createTelegramResoverRow(1, 1, dataLen, String.format(FORMAT, "Destination address", "Type: " + addressType(edata[1]), hex(edata[1])))); sb.append(createTelegramResoverRow(2, 2, dataLen, String.format(FORMAT, "Command", "", hex(command)))); sb.append(createTelegramResoverRow(4, 1, dataLen, String.format(FORMAT, "Master Data Length", "Length: " + edata[4], hex(edata[4])))); sb.append(createTelegramResoverRow(5, masterDataLen, dataLen, String.format(FORMAT, "Master Data", "", hex(masterData)))); sb.append(createTelegramResoverRow(masterCrcPos, 1, dataLen, String.format(FORMAT, "Master CRC", "", hex(edata[masterCrcPos])))); if (isMasterMaster) { sb.append( createTelegramResoverRow(slaveACKPos, 1, dataLen, hex(edata[slaveACKPos]) + " Slave ACK")); // SYN } else if (isBroadcast) { // SYN } else if (isMasterSlave) { int slaveDataLenPos = slaveACKPos + 1; int slaveDataLen = edata[slaveDataLenPos]; int slaveDataPos = slaveDataLenPos + 1; int slaveCRCPos = slaveDataPos + slaveDataLen; int masterACKPos = slaveCRCPos + 1; byte[] slaveData = Arrays.copyOfRange(edata, slaveDataPos, slaveDataPos + slaveDataLen); sb.append(createTelegramResoverRow(slaveACKPos, 1, dataLen, String.format(FORMAT, "Slave ACK", "", hex(edata[slaveACKPos])))); sb.append(createTelegramResoverRow(slaveDataLenPos, 1, dataLen, String.format(FORMAT, "Slave Data Length", "Length: " + edata[slaveDataLenPos], hex(edata[slaveDataLenPos])))); sb.append(createTelegramResoverRow(slaveDataPos, slaveDataLen, dataLen, String.format(FORMAT, "Slave Data", "", hex(slaveData)))); sb.append(createTelegramResoverRow(slaveCRCPos, 1, dataLen, String.format(FORMAT, "Slave CRC", "", hex(edata[slaveCRCPos])))); sb.append(createTelegramResoverRow(masterACKPos, 1, dataLen, String.format(FORMAT, "Master ACK", "", hex(edata[masterACKPos])))); } List<IEBusCommandMethod> methods = registry.find(edata); sb.append("\n"); sb.append("Resolve the telegram\n"); sb.append("********************\n"); sb.append("\n"); sb.append(String.format("Found %s command method(s) for this telegram.\n", methods.size())); sb.append("\n"); for (IEBusCommandMethod method : methods) { try { Map<String, Object> result = EBusCommandUtils.decodeTelegram(method, data); sb.append(String.format("Values from command '%s' with method '%s' from collection '%s'\n", method.getParent().getId(), method.getMethod(), method.getParent().getParentCollection().getId())); for (Entry<String, Object> entry : result.entrySet()) { Object value = entry.getValue(); if (value instanceof byte[]) { value = EBusUtils.toHexDumpString((byte[]) value); } sb.append(String.format(" %-20s = %s\n", entry.getKey(), value != null ? value.toString() : "NULL")); } } catch (EBusTypeException e) { logger.error("error!", e); } } sb.append("\n"); } catch (Exception e) { logger.error("error!", e); } return sb.toString(); } private static String addressType(byte b) { if (EBusUtils.isMasterAddress(b)) { return "Master"; } else if (b == EBusConsts.BROADCAST_ADDRESS) { return "Broadcast"; } return "Slave"; } private static String hex(byte[] b) { return EBusUtils.toHexDumpString(b).toString(); } private static String hex(byte b) { return EBusUtils.toHexDumpString(b); } private static String createTelegramResoverRow(int pos, int length, int textStart, String text) { StringBuilder sb = new StringBuilder(); String repeat = StringUtils.repeat("^^ ", length); if (repeat.length() > 0) { repeat = repeat.substring(0, repeat.length() - 1); } sb.append(StringUtils.repeat(" ", pos * 3)); sb.append(repeat); sb.append(StringUtils.repeat("-", textStart - sb.length())); sb.append(" "); sb.append(text); sb.append("\n"); return sb.toString(); } }