houzhongjian
2024-07-23 a6de490948278991e47952e90671ddba4555e9a2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.iailab.module.data.channel.modbus.collector;
 
import com.iailab.module.data.common.enums.CommonConstant;
import com.iailab.module.data.common.enums.DataSourceType;
import com.iailab.framework.common.util.object.ConvertUtils;
import com.iailab.module.data.common.utils.TagUtils;
import com.iailab.module.data.channel.modbus.dto.ChannelModBusDeviceDTO;
import com.iailab.module.data.channel.modbus.entity.ChannelModBusDeviceEntity;
import com.iailab.module.data.channel.modbus.service.ChannelModbusDeviceService;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年05月12日
 */
@Slf4j
@Component
public class ModBusCollector {
 
    @Resource
    private ChannelModbusDeviceService channelModbusDeviceService;
 
    private Map<String, ModbusMaster> clientMap = new ConcurrentHashMap<>();
 
    private Map<String, ChannelModBusDeviceEntity> deviceMap = new HashMap<>();
 
    private synchronized ModbusMaster getMaster(String sourceId) throws Exception {
        log.info("=========Modbus============");
        try {
            if (!clientMap.containsKey(sourceId)) {
                ChannelModBusDeviceEntity entity = channelModbusDeviceService.info(sourceId);
                ChannelModBusDeviceDTO tModbusDTO = ConvertUtils.sourceToTarget(entity, ChannelModBusDeviceDTO.class);
                ModbusMaster modbusMaster = ModbusUtils.getMaster(tModbusDTO);
                if (modbusMaster != null) {
                    clientMap.put(sourceId, modbusMaster);
                }
            }
        } catch (Exception ex) {
            log.error("=========Modbus Exception============");
            log.error("ex.message+" + ex.getMessage());
            throw new Exception(ex.getMessage());
        }
        return clientMap.get(sourceId);
    }
 
    public Double getTagValue(String sourceId, String tagNo) {
        Double result = CommonConstant.BAD_VALUE.doubleValue();
        try {
            ModbusMaster modbusMaster = this.getMaster(sourceId);
            // 获取寄存器类型
            String type = tagNo.substring(0, 1);
            int slaveId = 1;
            int offset = Integer.parseInt(tagNo.substring(1)) - 1;
            switch (type) {
                case "0":
                    // 读线圈寄存器
                    result = ModbusUtils.readCoilStatus(modbusMaster, slaveId, offset) ? 1d : 0;
                    break;
                case "1":
                    // 读离散输入寄存器
                    result = ModbusUtils.inputStatus(modbusMaster, slaveId, offset)  ? 1d : 0;
                    break;
                case "3":
                    // 读输入寄存器
                    result = ModbusUtils.inputRegister(modbusMaster, slaveId, offset, DataType.TWO_BYTE_INT_SIGNED)
                            .doubleValue();
                    break;
                case "4":
                    // 读输入寄存器数据
                    result = ModbusUtils.holdingRegister(modbusMaster, slaveId, offset, DataType.TWO_BYTE_INT_SIGNED)
                            .doubleValue();
                    break;
                default:
                    break;
            }
            return result;
        } catch (Exception ex) {
            log.error("TagNo========" + tagNo);
            ex.printStackTrace();
        }
        return result;
    }
 
    public void setTagValue(String sourceId, String tagNo, String newValue) {
        try {
            ModbusMaster modbusMaster = this.getMaster(sourceId);
            // 获取寄存器类型
            String type = tagNo.substring(0, 1);
            int slaveId = 1;
            int offset = Integer.parseInt(tagNo.substring(1)) - 1;
            switch (type) {
                case "0":
                    // 写单个线圈寄存器
                    ModbusUtils.writeCoilStatus(modbusMaster, slaveId, offset, Integer.parseInt(newValue) > 0 );
                    break;
                case "4":
                    // 写单个保持寄存器
                    ModbusUtils.writeRegister(modbusMaster, slaveId, offset, Integer.parseInt(newValue));
                    break;
                default:
                    break;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
    public Map<String, Object> getTagValues(List<String[]> params) {
        if (CollectionUtils.isEmpty(params)) {
            return new HashMap<>();
        }
        Map<String, Object> result = new HashMap<>(params.size());
        params.forEach(item -> {
            try {
                Double value = this.getTagValue(item[0], item[1]);
                result.put(TagUtils.genTagId(DataSourceType.ModBus.getCode(), deviceMap.get(item[0]).getName(), item[1]), value);
            } catch (Exception ex) {
                ex.printStackTrace();
                result.put(TagUtils.genTagId(DataSourceType.ModBus.getCode(), deviceMap.get(item[0]).getName(), item[1]), CommonConstant.BAD_VALUE);
            }
        });
        return result;
    }
}