whyclj
2020-09-24 2b64a566f77f90fe47f62863b7a185b6e1c514b7
WaterSystem_MonitorServer/src/com/modbus/data/MyModbusUtils.java
@@ -1,286 +1,416 @@
package com.modbus.data;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;
public class MyModbusUtils {
   /**
    * 读取[01 Coil Status 0x]类型 开关数据
    *
    * @param slaveId
    *            slaveId
    * @param offset
    *            位置
    * @return 读取值
    */
   public static Boolean readCoilStatus(int offset,MyModbusMaster master){
      // 01 Coil Status
      BaseLocator<Boolean> loc = BaseLocator.coilStatus(master.getSlaveId(), offset);
      Boolean value = null;;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         master.addErrorCount();
         //e.printStackTrace();
      }
      return value;
   }
   /**
    * 读取[02 Input Status 1x]类型 开关数据
    *
    * @param slaveId
    * @param offset
    * @return
    */
   public static Boolean readInputStatus(int offset,MyModbusMaster master){
      // 02 Input Status
      BaseLocator<Boolean> loc = BaseLocator.inputStatus(master.getSlaveId(), offset);
      Boolean value = null;;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         master.addErrorCount();
         //e.printStackTrace();
      }
      return value;
   }
   /**
    * 读取[03 Holding Register类型 2x]模拟量数据
    *
    * @param slaveId
    *            slave Id
    * @param offset
    *            位置
    * @param dataType
    *            数据类型,来自com.serotonin.modbus4j.code.DataType
    * @return
    */
   public static Number readHoldingRegister(int offset, int dataType,MyModbusMaster master){
      // 03 Holding Register类型数据读取
      BaseLocator<Number> loc = BaseLocator.holdingRegister(master.getSlaveId(), offset, dataType);
      Number value = null;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         master.addErrorCount();
      }
      return value;
   }
   /**
    * 读取[04 Input Registers 3x]类型 模拟量数据
    *
    * @param slaveId
    *            slaveId
    * @param offset
    *            位置
    * @param dataType
    *            数据类型,来自com.serotonin.modbus4j.code.DataType
    * @return 返回结果
    * @throws ModbusTransportException
    *             异常
    * @throws ErrorResponseException
    *             异常
    * @throws ModbusInitException
    *             异常
    */
   public static Number readInputRegisters(int offset, int dataType,MyModbusMaster master){
      // 04 Input Registers类型数据读取
      BaseLocator<Number> loc = BaseLocator.inputRegister(master.getSlaveId(), offset, dataType);
      Number value = null;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         master.addErrorCount();
      }
      return value;
   }
   /**
    * 批量读取使用方法
    *
    * @throws ModbusTransportException
    * @throws ErrorResponseException
    * @throws ModbusInitException
    */
   public static void batchRead() {
//      BatchRead<Integer> batch = new BatchRead<Integer>();
//
//      batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
//      batch.addLocator(1, BaseLocator.inputStatus(1, 0));
//
//      ModbusMaster master = getMaster();
//
//      batch.setContiguousRequests(false);
//      BatchResults<Integer> results = master.send(batch);
//      System.out.println(results.getValue(0));
//      System.out.println(results.getValue(1));
   }
   /**
    * 写 [01 Coil Status(0x)]写一个 function ID = 5
    *
    * @param slaveId
    *            slave的ID
    * @param writeOffset
    *            位置
    * @param writeValue
    *            ֵ
    * @return 是否写入成功
    */
   public static boolean writeCoil(int writeOffset, boolean writeValue,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求
      // 发送请求并获取响应对象
      WriteCoilResponse response = null;
      try {
         WriteCoilRequest request = new WriteCoilRequest(master.getSlaveId(), writeOffset, writeValue);
         response = (WriteCoilResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         return true;
      }
   }
   /**
    * 写[01 Coil Status(0x)] 写多个 function ID = 15
    *
    * @param slaveId
    *            slaveId
    * @param startOffset
    *            开始位置
    * @param bdata
    *            写入的数据
    * @return 是否写入成功
    */
   public static boolean writeCoils(int startOffset, boolean[] bdata,MyModbusMaster master) {
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求
      WriteCoilsRequest request;
      WriteCoilsResponse response = null;
      try {
         request = new WriteCoilsRequest(master.getSlaveId(), startOffset, bdata);
         response = (WriteCoilsResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      // 发送请求并获取响应对象
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         return true;
      }
   }
   /***
    * 写[03 Holding Register(4x)] 写一个 function ID = 6
    *
    * @param slaveId
    * @param writeOffset
    * @param writeValue
    * @return
    */
   public static boolean writeRegister(int writeOffset, short writeValue,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求对象
      WriteRegisterRequest request;
      WriteRegisterResponse response = null;
      try {
         request = new WriteRegisterRequest(master.getSlaveId(), writeOffset, writeValue);
         response = (WriteRegisterResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         return true;
      }
   }
   /**
    *
    * 写入[03 Holding Register(4x)]写多个 function ID=16
    *
    * @param slaveId
    *            modbus的slaveID
    * @param startOffset
    *            起始位置偏移量值
    * @param sdata
    *            写入的数据
    * @return 返回是否写入成功
    */
   public static boolean writeRegisters(int startOffset, short[] sdata,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求对象
      WriteRegistersRequest request;
      // 发送请求并获取响应对象
      ModbusResponse response = null;
      try {
         request = new WriteRegistersRequest(master.getSlaveId(), startOffset, sdata);
         response = tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response.isException()) {
         //log.error(response.getExceptionMessage());
         master.addErrorCount();
         return false;
      } else {
         return true;
      }
   }
   /**
    * 写入数字类型的模拟量(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)
    *
    * @param slaveId
    * @param offset
    * @param value
    *            写入值,Number的子类,例如写入Float浮点类型,Double双精度类型,以及整型short,int,long
    * @param registerCount
    *            ,com.serotonin.modbus4j.code.DataType
    */
   public static void writeHoldingRegister(int offset, Number value, int dataType,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 类型
      BaseLocator<Number> locator = BaseLocator.holdingRegister(master.getSlaveId(), offset, dataType);
      try {
         tcpMaster.setValue(locator, value);
      } catch (ModbusTransportException | ErrorResponseException e) {
         e.printStackTrace();
      }
   }
}
package com.modbus.data;
import java.util.Date;
import com.base.ComBase;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;
public class MyModbusUtils {
   /**
    * 读取[01 Coil Status 0x]类型 开关数据
    *
    * @param slaveId
    *            slaveId
    * @param offset
    *            位置
    * @return 读取值
    */
   public static Boolean readCoilStatus(int offset,MyModbusMaster master){
      // 01 Coil Status
      BaseLocator<Boolean> loc = BaseLocator.coilStatus(master.getSlaveId(), offset);
      Boolean value = null;
      boolean isSuccess = true;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = false;
      } finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
      return value;
   }
   /**
    * 读取[02 Input Status 1x]类型 开关数据
    *
    * @param slaveId
    * @param offset
    * @return
    */
   public static Boolean readInputStatus(int offset,MyModbusMaster master){
      // 02 Input Status
      BaseLocator<Boolean> loc = BaseLocator.inputStatus(master.getSlaveId(), offset);
      Boolean value = null;;
      boolean isSuccess = true;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = false;
      } finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
      return value;
   }
   /**
    * 读取[03 Holding Register类型 2x]模拟量数据
    *
    * @param slaveId
    *            slave Id
    * @param offset
    *            位置
    * @param dataType
    *            数据类型,来自com.serotonin.modbus4j.code.DataType
    * @return
    */
   public static Number readHoldingRegister(int offset, int dataType,MyModbusMaster master){
      // 03 Holding Register类型数据读取
      BaseLocator<Number> loc = BaseLocator.holdingRegister(master.getSlaveId(), offset, dataType);
      Number value = null;
      boolean isSuccess = true;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = false;
      }  finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
      return value;
   }
   /**
    * 读取[04 Input Registers 3x]类型 模拟量数据
    *
    * @param slaveId
    *            slaveId
    * @param offset
    *            位置
    * @param dataType
    *            数据类型,来自com.serotonin.modbus4j.code.DataType
    * @return 返回结果
    * @throws ModbusTransportException
    *             异常
    * @throws ErrorResponseException
    *             异常
    * @throws ModbusInitException
    *             异常
    */
   public static Number readInputRegisters(int offset, int dataType,MyModbusMaster master){
      // 04 Input Registers类型数据读取
      BaseLocator<Number> loc = BaseLocator.inputRegister(master.getSlaveId(), offset, dataType);
      Number value = null;
      boolean isSuccess = true;
      try {
         value = master.getMaster().getValue(loc);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = false;
      } finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
      return value;
   }
   public static BatchResults<Integer> readMutilRegisters(BatchRead<Integer> batch,MyModbusMaster master){
      batch.setContiguousRequests(false);
      boolean isSuccess = true;
      try {
         return master.getMaster().send(batch);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = false;
      } finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
      return null;
   }
   /**
    * 批量读取使用方法
    *
    * @throws ModbusTransportException
    * @throws ErrorResponseException
    * @throws ModbusInitException
    */
   public static void batchRead() {
//      BatchRead<Integer> batch = new BatchRead<Integer>();
//
//      batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
//      batch.addLocator(1, BaseLocator.inputStatus(1, 0));
//
//      ModbusMaster master = getMaster();
//
//      batch.setContiguousRequests(false);
//      BatchResults<Integer> results = master.send(batch);
//      System.out.println(results.getValue(0));
//      System.out.println(results.getValue(1));
   }
   /**
    *    构造线圈读取节点
    * @param offset
    * @param master
    * @return
    */
   public static BaseLocator<?> createBaseLocator(int offset,MyModbusMaster master) {
      return BaseLocator.coilStatus(master.getSlaveId(), offset);
   }
   /**
    *    构造读取节点
    * @param offset
    * @param master
    * @return
    */
   public static BaseLocator<?> createBaseLocator(int offset,int datatype,MyModbusMaster master) {
      return BaseLocator.holdingRegister(master.getSlaveId(), offset, datatype);
   }
   /**
    * 写 [01 Coil Status(0x)]写一个 function ID = 5
    *
    * @param slaveId
    *            slave的ID
    * @param writeOffset
    *            位置
    * @param writeValue
    *            ֵ
    * @return 是否写入成功
    */
   public static boolean writeCoil(int writeOffset, boolean writeValue,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求
      // 发送请求并获取响应对象
      WriteCoilResponse response = null;
      try {
         WriteCoilRequest request = new WriteCoilRequest(master.getSlaveId(), writeOffset, writeValue);
         response = (WriteCoilResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         master.clearError();
         return true;
      }
   }
   /**
    * 写[01 Coil Status(0x)] 写多个 function ID = 15
    *
    * @param slaveId
    *            slaveId
    * @param startOffset
    *            开始位置
    * @param bdata
    *            写入的数据
    * @return 是否写入成功
    */
   public static boolean writeCoils(int startOffset, boolean[] bdata,MyModbusMaster master) {
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求
      WriteCoilsRequest request;
      WriteCoilsResponse response = null;
      try {
         request = new WriteCoilsRequest(master.getSlaveId(), startOffset, bdata);
         response = (WriteCoilsResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      // 发送请求并获取响应对象
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         master.clearError();
         return true;
      }
   }
   /***
    * 写[03 Holding Register(4x)] 写一个 function ID = 6
    *
    * @param slaveId
    * @param writeOffset
    * @param writeValue
    * @return
    */
   public static boolean writeRegister(int writeOffset, short writeValue,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求对象
      WriteRegisterRequest request;
      WriteRegisterResponse response = null;
      try {
         request = new WriteRegisterRequest(master.getSlaveId(), writeOffset, writeValue);
         response = (WriteRegisterResponse) tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response == null || response.isException()) {
         master.addErrorCount();
         return false;
      } else {
         master.clearError();
         return true;
      }
   }
   /**
    *
    * 写入[03 Holding Register(4x)]写多个 function ID=16
    *
    * @param slaveId
    *            modbus的slaveID
    * @param startOffset
    *            起始位置偏移量值
    * @param sdata
    *            写入的数据
    * @return 返回是否写入成功
    */
   public static boolean writeRegisters(int startOffset, short[] sdata,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 创建请求对象
      WriteRegistersRequest request;
      // 发送请求并获取响应对象
      ModbusResponse response = null;
      try {
         request = new WriteRegistersRequest(master.getSlaveId(), startOffset, sdata);
         response = tcpMaster.send(request);
      } catch (ModbusTransportException e) {
         e.printStackTrace();
      }
      if (response.isException()) {
         //log.error(response.getExceptionMessage());
         master.addErrorCount();
         return false;
      } else {
         master.clearError();
         return true;
      }
   }
   /**
    * 写入数字类型的模拟量(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)
    *
    * @param slaveId
    * @param offset
    * @param value
    *            写入值,Number的子类,例如写入Float浮点类型,Double双精度类型,以及整型short,int,long
    * @param registerCount
    *            ,com.serotonin.modbus4j.code.DataType
    */
   public static void writeHoldingRegister(int offset, Number value, int dataType,MyModbusMaster master){
      // 获取master
      ModbusMaster tcpMaster = master.getMaster();
      // 类型
      BaseLocator<Number> locator = BaseLocator.holdingRegister(master.getSlaveId(), offset, dataType);
      boolean isSuccess = true;
      try {
         tcpMaster.setValue(locator, value);
      } catch (ModbusTransportException | ErrorResponseException e) {
         //e.printStackTrace();
         isSuccess = true;
      } finally {
         if(isSuccess) {
            master.clearError();
         }else {
            master.addErrorCount();
         }
      }
   }
   public static void main(String[] args) {
      BatchRead<Integer> batch = new BatchRead<Integer>();
      batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));
        batch.addLocator(1, BaseLocator.coilStatus(1, 1));
        batch.setContiguousRequests(true);
      MyModbusMaster m = new MyModbusMaster("192.168.10.221", 2);
      ModbusMaster master = m.getMaster();
      BatchResults<Integer> results = new BatchResults<>();
      try {
         results = master.send(batch);
      } catch (ModbusTransportException | ErrorResponseException e) {
         e.printStackTrace();
      }
      System.out.println(results.getValue(0));
      //System.out.println(results.getValue(1));
   }
   /**
    *    读取float类型数据
    * @param obj   Short类型
    * @return
    */
   public static float readShortToFloat(Object obj) {
      return (float)ComBase.changeShortToInt((Short)obj);
   }
   /**
    *    读取int类型数据
    * @param obj   Short类型
    * @return
    */
   public static int readShortToInt(Object obj) {
      return ComBase.changeShortToInt((Short)obj);
   }
   /**
    *    读取Boolean类型数据
    * @param obj   Boolean类型
    * @return
    */
   public static int readBooleanToInt(Object obj) {
      return ((Boolean)obj?1:0);
   }
}