123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- package com.jg.service.impl;
- import com.alibaba.fastjson2.JSON;
- import com.alibaba.fastjson2.JSONArray;
- import com.jg.common.ValueType;
- import com.jg.service.ModBusService;
- import com.jg.util.ModBusUtil;
- import com.jg.util.WebSocketServer;
- import com.jg.vo.ShowVo;
- import com.jg.vo.TagVo;
- 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.locator.BaseLocator;
- import jdk.nashorn.internal.ir.annotations.Reference;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.context.event.ApplicationReadyEvent;
- import org.springframework.context.event.EventListener;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Service;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.math.BigDecimal;
- import java.net.URISyntaxException;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.nio.file.Paths;
- import java.util.*;
- @Slf4j
- @Service
- public class ModBusServiceImpl implements ModBusService {
- private static final Map<Long, ModbusMaster> MASTER_MAP = new HashMap<>(64);
- private String show;
- @Value("${modbus.host}")
- private String host;
- @Value("${modbus.port}")
- private Integer port;
- @Reference
- private WebSocketServer webSocketServer;
- /**
- * 创建ModBusTCP连接
- */
- // @EventListener(ApplicationReadyEvent.class)
- private void createConn() {
- // 创建ModBus连接, 存入MASTER_MAP
- // List<CollectModuleInfo> collectModuleInfoList = collectModuleInfoService.findCurrent();
- // log.info("[查询采集模块列表]: {}", collectModuleInfoList);
- // if (!CollectionUtils.isEmpty(collectModuleInfoList)) {
- // for (CollectModuleInfo collectModuleInfo : collectModuleInfoList) {
- // Long collectModuleInfoId = collectModuleInfo.getId();
- // MODULE_INFO_MAP.put(collectModuleInfoId, collectModuleInfo);
- // // 循环创建ModBus连接
- // ModbusMaster modbusMaster = MASTER_MAP.get(collectModuleInfoId);
- // if (null == modbusMaster) {
- // // 创建ModBus连接, 存入Map, key: 采集模块id, value: ModBus连接
- // modbusMaster = ModBusUtil.createMaster(collectModuleInfo);
- // MASTER_MAP.put(collectModuleInfoId, modbusMaster);
- // }
- // }
- // } else {
- //// throw new BizException("连接失败! 没有查询到ModBus模块信息!");
- // }
- // log.warn("[开始连接采集模块]: {}", JSON.toJSONString(collectModuleInfoList));
- // ModbusMaster master = ModBusUtil.createMaster(host, port);
- // MASTER_MAP.put(1l, master);
- InputStream inputStream = getClass().getClassLoader().getResourceAsStream("tag.json");
- try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()){
- byte[] buffer = new byte[1024];
- int length;
- while ((length = inputStream.read(buffer)) != -1) {
- byteArrayOutputStream.write(buffer, 0, length);
- }
- show = byteArrayOutputStream.toString(StandardCharsets.UTF_8.name());
- // 使用 show 字符串
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- // @Scheduled(fixedRate = 1000)
- private void readTagsValue(){
- List<TagVo> tagVos = JSON.parseArray(show, TagVo.class);
- BatchRead<String> batch = new BatchRead<>();
- JSONArray array = new JSONArray();
- for (TagVo tagVo: tagVos){
- Integer slaveId = tagVo.getSlaveId();
- Integer functionCode = tagVo.getFunctionCode();
- int offset = tagVo.getOffset();
- String tag = tagVo.getTag();
- String dataType = tagVo.getDataType();
- switch (functionCode) {
- case 1:
- batch.addLocator(tag, BaseLocator.coilStatus(slaveId, offset));
- break;
- case 2:
- batch.addLocator(tag, BaseLocator.inputStatus(slaveId, offset));
- break;
- case 3:
- batch.addLocator(tag, BaseLocator.holdingRegister(slaveId, offset, getValueType(dataType)));
- break;
- case 4:
- batch.addLocator(tag, BaseLocator.inputRegister(slaveId, offset, getValueType(dataType)));
- break;
- default:
- break;
- }
- }
- batch.setContiguousRequests(false);
- ModbusMaster modbusMaster = MASTER_MAP.get(1l);
- try {
- if (!modbusMaster.isInitialized()) {
- modbusMaster.init();
- }
- modbusMaster.setTimeout(500);
- BatchResults<String> results = modbusMaster.send(batch);
- for (TagVo tagVo: tagVos){
- // log.info("采集中文: {}, 值: {}", tagVo.getDesc(), results.getValue(tagVo.getTag()));
- Object value = results.getValue(tagVo.getTag());
- BigDecimal bigDecimalValue = convertToBigDecimal(value);
- ShowVo showVo = new ShowVo();
- showVo.setName(tagVo.getDesc());
- showVo.setValue(bigDecimalValue);
- showVo.setUnit(tagVo.getUnit());
- // showVos.add(showVo);
- array.add(showVo);
- }
- log.info(array.toString());
- webSocketServer.sendInfo(array.toString(), "push");
- modbusMaster.destroy();
- } catch (Exception e) {
- log.error("采集模块Id: {}, 读取失败: {}", 1l, e.getMessage());
- }
- }
- /**
- * 获取数据类型
- * 说明:此处可根据实际项目情况进行拓展
- * 1.swap 交换
- * 2.大端/小端,默认是大端
- * 3.拓展其他数据类型
- *
- * @param type Value Type
- * @return Modbus Data Type
- */
- public static int getValueType(String type) {
- switch (type.toLowerCase()) {
- case ValueType.LONG:
- return DataType.FOUR_BYTE_INT_SIGNED;
- case ValueType.FLOAT:
- return DataType.FOUR_BYTE_FLOAT;
- case ValueType.DOUBLE:
- return DataType.EIGHT_BYTE_FLOAT;
- default:
- return DataType.TWO_BYTE_INT_UNSIGNED;
- }
- }
- /**
- * 将 Object 转换为 BigDecimal
- **/
- private static BigDecimal convertToBigDecimal(Object obj) {
- // 处理 obj 为 null 的情况,返回 -1
- if (obj == null) {
- return BigDecimal.valueOf(-1);
- }
- if (obj instanceof BigDecimal) {
- return (BigDecimal) obj;
- } else if (obj instanceof Integer) {
- return BigDecimal.valueOf((Integer) obj);
- } else if (obj instanceof Double) {
- return BigDecimal.valueOf((Double) obj);
- } else if (obj instanceof String) {
- return new BigDecimal((String) obj);
- } else if (obj instanceof Float){
- return BigDecimal.valueOf(((Float) obj).doubleValue());
- } else if (obj instanceof Boolean) {
- return BigDecimal.valueOf((Boolean) obj ? 1 : 0);
- } else {
- throw new IllegalArgumentException("Unsupported object type: " + obj.getClass());
- }
- }
- @Override
- public void startCollect() {
- createConn();
- readTagsValue();
- }
- }
|