/* * Copyright 2011-16 Fraunhofer ISE * * This file is part of OpenMUC. * For more information visit http://www.openmuc.org * * OpenMUC is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenMUC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenMUC. If not, see <http://www.gnu.org/licenses/>. * */ package org.openmuc.framework.driver.modbus; import org.openmuc.framework.data.BooleanValue; import org.openmuc.framework.data.ByteArrayValue; import org.openmuc.framework.data.DoubleValue; import org.openmuc.framework.data.FloatValue; import org.openmuc.framework.data.IntValue; import org.openmuc.framework.data.LongValue; import org.openmuc.framework.data.ShortValue; import org.openmuc.framework.data.Value; import net.wimpi.modbus.procimg.InputRegister; import net.wimpi.modbus.procimg.Register; import net.wimpi.modbus.procimg.SimpleRegister; import net.wimpi.modbus.util.BitVector; import net.wimpi.modbus.util.ModbusUtil; public class ModbusDriverUtil { public Value getBitVectorsValue(BitVector bitVector) { Value readValue; if (bitVector.size() == 1) { readValue = new BooleanValue(bitVector.getBit(0)); // read single bit } else { readValue = new ByteArrayValue(bitVector.getBytes()); // read multiple bits } return readValue; } public BitVector getBitVectorFromByteArray(Value value) { BitVector bv = new BitVector(value.asByteArray().length * 8); bv.setBytes(value.asByteArray()); return bv; } /** * Converts the registers into the datatyp of the channel * * @param registers * input register array * @param datatype * Edatatype * @return the corresponding Value Object */ public Value getRegistersValue(InputRegister[] registers, EDatatype datatype) { Value registerValue = null; byte[] registerAsByteArray = inputRegisterToByteArray(registers); switch (datatype) { case SHORT: registerValue = new ShortValue(ModbusUtil.registerToShort(registerAsByteArray)); break; case INT: registerValue = new IntValue(ModbusUtil.registersToInt(registerAsByteArray)); break; case FLOAT: registerValue = new FloatValue(ModbusUtil.registersToFloat(registerAsByteArray)); break; case DOUBLE: registerValue = new DoubleValue(ModbusUtil.registersToDouble(registerAsByteArray)); break; case LONG: registerValue = new LongValue(ModbusUtil.registersToLong(registerAsByteArray)); break; case BYTEARRAY: registerValue = new ByteArrayValue(registerAsByteArray); break; case BYTE_HIGH: registerValue = new IntValue(registerAsByteArray[1] & 0xFF); break; case BYTE_LOW: registerValue = new IntValue(registerAsByteArray[0] & 0xFF); break; default: throw new RuntimeException("Datatype " + datatype.toString() + " not supported yet"); } return registerValue; } public Register[] valueToRegisters(Value value, EDatatype datatype) { Register[] registers; switch (datatype) { case SHORT: registers = byteArrayToRegister(ModbusUtil.shortToRegister(value.asShort())); break; case INT: registers = byteArrayToRegister(ModbusUtil.intToRegisters(value.asInt())); break; case DOUBLE: registers = byteArrayToRegister(ModbusUtil.doubleToRegisters(value.asDouble())); break; case FLOAT: registers = byteArrayToRegister(ModbusUtil.floatToRegisters(value.asFloat())); break; case LONG: registers = byteArrayToRegister(ModbusUtil.longToRegisters(value.asLong())); break; case BYTEARRAY: registers = byteArrayToRegister(value.asByteArray()); break; case BYTE_HIGH: case BYTE_LOW: default: throw new RuntimeException("Datatype " + datatype.toString() + " not supported yet"); } return registers; } /** * Converts an array of input registers into a byte array * * @param inputRegister * inputRegister array * @return the InputRegister[] as byte[] */ private byte[] inputRegisterToByteArray(InputRegister[] inputRegister) { byte[] registerAsBytes = new byte[inputRegister.length * 2]; // one register = 2 bytes for (int i = 0; i < inputRegister.length; i++) { System.arraycopy(inputRegister[i].toBytes(), 0, registerAsBytes, i * inputRegister[0].toBytes().length, inputRegister[i].toBytes().length); } return registerAsBytes; } // TODO check byte order e.g. is an Integer! // TODO only works for even byteArray.length! private Register[] byteArrayToRegister(byte[] byteArray) throws RuntimeException { // TODO byteArray might has a odd number of bytes... SimpleRegister[] register; if (byteArray.length % 2 == 0) { register = new SimpleRegister[byteArray.length / 2]; int j = 0; // for (int i = 0; i < byteArray.length; i++) { for (int i = 0; i < byteArray.length / 2; i++) { register[i] = new SimpleRegister(byteArray[j], byteArray[j + 1]); j = j + 2; } } else { throw new RuntimeException("conversion vom byteArray to Register is not working for odd number of bytes"); } return register; } }