|
@@ -0,0 +1,200 @@
|
|
|
+package com.syjy.tunnelworker.gathers.iml;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.syjy.DataExchangeException;
|
|
|
+import com.syjy.container.ProtocolDataContainer;
|
|
|
+import com.syjy.tunnelinfo.BaseTunnelInfo;
|
|
|
+import com.syjy.tunnelinfo.DataPoint;
|
|
|
+import com.syjy.tunnelworker.BaseProtocolTunnel;
|
|
|
+import com.syjy.tunnelworker.gathers.DataGatherInterface;
|
|
|
+import lombok.Getter;
|
|
|
+import lombok.Setter;
|
|
|
+import wei.yigulu.modbus.domain.FunctionCode;
|
|
|
+import wei.yigulu.modbus.domain.Obj4RequestCoil;
|
|
|
+import wei.yigulu.modbus.domain.Obj4RequestRegister;
|
|
|
+import wei.yigulu.modbus.domain.datatype.BooleanModbusDataInRegister;
|
|
|
+import wei.yigulu.modbus.domain.datatype.IModbusDataType;
|
|
|
+import wei.yigulu.modbus.domain.datatype.ModbusDataTypeEnum;
|
|
|
+import wei.yigulu.modbus.domain.datatype.NumericModbusData;
|
|
|
+import wei.yigulu.modbus.exceptiom.ModbusException;
|
|
|
+import wei.yigulu.modbus.utils.ModbusRequestDataUtils;
|
|
|
+import wei.yigulu.netty.BaseProtocolBuilder;
|
|
|
+import wei.yigulu.netty.MasterInterface;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 抽象的modbus数据获取
|
|
|
+ *
|
|
|
+ * @author: xiuwei
|
|
|
+ * @version:
|
|
|
+ */
|
|
|
+@Setter
|
|
|
+@Getter
|
|
|
+public abstract class AbstractModbusDataGather<T extends BaseTunnelInfo, E extends BaseProtocolBuilder> extends BaseProtocolTunnel<T, E> implements DataGatherInterface {
|
|
|
+
|
|
|
+ int slaveId;
|
|
|
+
|
|
|
+ FunctionCode functionCode;
|
|
|
+ /**
|
|
|
+ * 通道点位 ---- 点位对象
|
|
|
+ */
|
|
|
+ Map<Integer, Map<Integer, DataPoint>> dataPointMap = new HashMap<>();
|
|
|
+ /**
|
|
|
+ * 0: 线圈 1:寄存器
|
|
|
+ */
|
|
|
+ private int functionFlag;
|
|
|
+ /**
|
|
|
+ * 向modbus slave端发送的请求
|
|
|
+ */
|
|
|
+ private Map<Integer, List<Obj4RequestRegister>> requestRegisterListMap = new HashMap<>();
|
|
|
+ /**
|
|
|
+ * 向modbus slave端发送线圈的请求
|
|
|
+ */
|
|
|
+ private Map<Integer, List<Obj4RequestCoil>> requestCoilListMap = new HashMap<>();
|
|
|
+
|
|
|
+ protected E protocolBuilder;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 连续异常的次数
|
|
|
+ */
|
|
|
+ protected int consecutiveExceptions;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 顶层的构造方法
|
|
|
+ *
|
|
|
+ * @param tunnelInfo 通道信息
|
|
|
+ */
|
|
|
+ public AbstractModbusDataGather(T tunnelInfo) {
|
|
|
+ super(tunnelInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void parseGatherDataPoint() throws DataExchangeException {
|
|
|
+ log.info("解析该通道下所管理的点位");
|
|
|
+ List<DataPoint> dataPoints = tunnelInfo.getDataPoints();
|
|
|
+ if (dataPoints == null || dataPoints.size() == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dataPoints.removeIf((o) -> o.getProtocolPoint() == null);
|
|
|
+ if (getFunctionCode().getCode() == 1 || getFunctionCode().getCode() == 2) {
|
|
|
+ setFunctionFlag(0);
|
|
|
+ } else {
|
|
|
+ setFunctionFlag(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Integer, Map<Integer, ModbusDataTypeEnum>> points = new HashMap<>();
|
|
|
+ Map<Integer, List<Integer>> coilPoints = new HashMap<>();
|
|
|
+ List<Integer> coilList;
|
|
|
+ Map<Integer, ModbusDataTypeEnum> registerMap;
|
|
|
+ setDataPointMap(new HashMap<>());
|
|
|
+ if (getFunctionFlag() == 0) {
|
|
|
+ for (DataPoint d : dataPoints) {
|
|
|
+ add2DataPointMap(d);
|
|
|
+ if (d.getSlaveId() == null) {
|
|
|
+ d.setSlaveId(getSlaveId());
|
|
|
+ }
|
|
|
+ if (coilPoints.containsKey(d.getSlaveId())) {
|
|
|
+ coilPoints.get(d.getSlaveId()).add(d.getProtocolPoint());
|
|
|
+ } else {
|
|
|
+ coilList = new ArrayList<>();
|
|
|
+ coilList.add((d.getProtocolPoint()));
|
|
|
+ coilPoints.put(d.getSlaveId(), coilList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ for (Map.Entry<Integer, List<Integer>> e : coilPoints.entrySet()) {
|
|
|
+ getRequestCoilListMap().put(e.getKey(), ModbusRequestDataUtils.splitModbusRequest(e.getValue(), e.getKey(), getFunctionCode()));
|
|
|
+ }
|
|
|
+ } catch (ModbusException e) {
|
|
|
+ throw new DataExchangeException(e.getCode(), e.getMsg());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (DataPoint d : dataPoints) {
|
|
|
+ add2DataPointMap(d);
|
|
|
+ if (d.getSlaveId() == null) {
|
|
|
+ d.setSlaveId(getSlaveId());
|
|
|
+ }
|
|
|
+ if (points.containsKey(d.getSlaveId())) {
|
|
|
+ points.get(d.getSlaveId()).put(d.getProtocolPoint(), d.getDataType());
|
|
|
+ } else {
|
|
|
+ registerMap = new HashMap<>();
|
|
|
+ registerMap.put(d.getProtocolPoint(), d.getDataType());
|
|
|
+ points.put(d.getSlaveId(), registerMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ for (Map.Entry<Integer, Map<Integer, ModbusDataTypeEnum>> e : points.entrySet()) {
|
|
|
+ getRequestRegisterListMap().put(e.getKey(), ModbusRequestDataUtils.splitModbusRequest(e.getValue(), e.getKey(), getFunctionCode()));
|
|
|
+ }
|
|
|
+ } catch (ModbusException e) {
|
|
|
+ throw new DataExchangeException(e.getCode(), e.getMsg());
|
|
|
+ }
|
|
|
+ log.info("解析该通道下所管理的点位完成");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 向点表和数据池id的映射map添加值
|
|
|
+ *
|
|
|
+ * @param d d
|
|
|
+ */
|
|
|
+ public void add2DataPointMap(DataPoint d) {
|
|
|
+ if (d.getSlaveId() == null) {
|
|
|
+ d.setSlaveId(getSlaveId());
|
|
|
+ }
|
|
|
+ if (dataPointMap.containsKey(d.getSlaveId())) {
|
|
|
+ dataPointMap.get(d.getSlaveId()).put(d.getProtocolPoint(), d);
|
|
|
+ } else {
|
|
|
+ Map<Integer, DataPoint> map = new HashMap<>();
|
|
|
+ map.put(d.getProtocolPoint(), d);
|
|
|
+ dataPointMap.put(d.getSlaveId(), map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void getDataFromProtocol() throws DataExchangeException {
|
|
|
+ log.info("获取到从通道中获取的点位");
|
|
|
+ try {
|
|
|
+ if (getFunctionFlag() == 1 && getRequestRegisterListMap() != null) {
|
|
|
+ Map<Integer, IModbusDataType> map = null;
|
|
|
+ for (Map.Entry<Integer, List<Obj4RequestRegister>> e : getRequestRegisterListMap().entrySet()) {
|
|
|
+ map = ModbusRequestDataUtils.getRegisterData((MasterInterface) protocolBuilder, e.getValue());
|
|
|
+ log.info(JSON.toJSONString(map));
|
|
|
+ for (Integer i : map.keySet()) {
|
|
|
+ if (map.get(i) instanceof NumericModbusData) {
|
|
|
+ ProtocolDataContainer.getInstance().putNumber(getDataPointMap().get(e.getKey()).get(i).getId(), ((NumericModbusData) map.get(i)).getValue().multiply(BigDecimal.valueOf(getDataPointMap().get(e.getKey()).get(i).getMag())));
|
|
|
+ } else {
|
|
|
+ ProtocolDataContainer.getInstance().putBoolean(getDataPointMap().get(e.getKey()).get(i).getId(), ((BooleanModbusDataInRegister) map.get(i)).getValue(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (getFunctionFlag() == 0 && getRequestRegisterListMap() != null) {
|
|
|
+ Map<Integer, Boolean> map = null;
|
|
|
+ for (Map.Entry<Integer, List<Obj4RequestCoil>> e : getRequestCoilListMap().entrySet()) {
|
|
|
+ map = ModbusRequestDataUtils.getCoilData((MasterInterface) protocolBuilder, e.getValue());
|
|
|
+ log.info(JSON.toJSONString(map));
|
|
|
+ for (Integer i : map.keySet()) {
|
|
|
+ ProtocolDataContainer.getInstance().putBoolean(getDataPointMap().get(e.getKey()).get(i).getId(), map.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (ModbusException e) {
|
|
|
+ throw new DataExchangeException(e.getCode(), e.getMsg());
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|