当前位置: 首页 > news >正文

使用java通过modbus读取前端设备数据

背景

中频炉改造项目,因现场没有一级plc、点位采集设备支撑,故采用modbus485协议进行采集。项目中使用到了redis,主要是对数据采集的临时存储,用于业务触发。点位数据存储到iotdb时序数据库,用于过程质量的追溯和展示。

点位数据管理

使用modbus485读取点位数据,需要配置点位的以下参数。
在这里插入图片描述
1、IP地址:设备所在ip段;
2、端口:每款设备需要在集线器分配端口;
3、从机地址:Modbus协议中,每个从设备都有一个唯一的地址,范围通常是1到247;
4、寄存器读取开始位置:寄存器的起始地址;
5、读取寄存器的数量:需要读取的寄存器数量;
6、功能码:根据设备不同,所选功能码不同。
7、点位名称:业务自己命名,便于管理;
8、点位编码:触发系统业务模块使用,与读取数据无关;

引入modbus依赖

<dependency><groupId>com.intelligt.modbus</groupId><artifactId>jlibmodbus</artifactId><version>1.2.9.7</version></dependency>

读取数据

@Component
public class ModbusTcpListener {@Resourceprivate RedisTemplate redisTemplate;@Resourceprivate IotDbServer iotDbServer;@Resourceprivate ModbusApiService modbusApiService;private static final ObjectMapper objectMapper = new ObjectMapper();public static void main(String[] args) {}
//    @Scheduled(cron = "0/30 * * * * ?")public void getData() throws UnknownHostException, JsonProcessingException {String json = (String) redisTemplate.opsForValue().get("modbus");List<ModBusRequest> lis2t = objectMapper.readValue(json, new TypeReference<List<ModBusRequest>>() {});for (ModBusRequest request : lis2t) {int slaveId = request.getSlaveId();//从机地址int offset = request.getOffset();//寄存器读取开始地址int quantity = request.getQuantity();//读取的寄存器数量String pointCode=request.getPointCode();//设备codeint port=request.getPort();//端口List<JSONObject> jsonObjectList = new ArrayList<>();// 设置主机TCP参数TcpParameters tcpParameters = new TcpParameters();// 设置TCP的ip地址InetAddress adress = InetAddress.getByName(request.getIp());// TCP参数设置ip地址tcpParameters.setHost(adress);// TCP设置长连接tcpParameters.setKeepAlive(true);// TCP设置端口,这里设置是默认端口502tcpParameters.setPort(request.getPort());// 创建一个主机ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);Modbus.setAutoIncrementTransactionId(true);try {// 读取对应从机的数据,readInputRegisters读取的写寄存器,功能码04// 读取对应从机的数据,readHoldingRegisters,功能码03if (!master.isConnected()) {master.connect();// 开启连接}System.out.printf("=========>"+request);//根据寄存器的功能码判断switch (request.getDeviceId()) {case "1":getBooleanData(master.readCoils(slaveId, offset, quantity), offset,pointCode,request.getIp(),port);break;case "2":getBooleanData(master.readDiscreteInputs(slaveId, offset, quantity), offset,pointCode,request.getIp(),port);break;case "3":getIntData(master.readHoldingRegisters(slaveId, offset, quantity), offset,pointCode,request.getIp(),port);break;case "4":getIntData(master.readInputRegisters(slaveId, offset, quantity), offset,pointCode,request.getIp(),port);break;default:getIntData(master.readHoldingRegisters(slaveId, offset, quantity), offset,pointCode,request.getIp(),port);break;}
//                    Thread.sleep(1000); // 每隔1000毫秒读取一次数据 getIntData(registerValues,offset);} catch (ModbusProtocolException | ModbusIOException | ModbusNumberException e) {e.printStackTrace();} finally {try {master.disconnect();} catch (ModbusIOException e) {e.printStackTrace();}}}}/*** int类型数据方法** @param registerValues* @param offset*/public void getIntData(int[] registerValues, int offset,String pointCode,String ip,int port) {for (int value : registerValues) {System.out.println(" offset: " + offset);System.out.println(" Value: " + value);IotDbParam iotDbParam=new IotDbParam();iotDbParam.setPk(pointCode);iotDbParam.setTime(System.currentTimeMillis());iotDbParam.setBreath(String.valueOf(value));iotDbParam.setHeart(String.valueOf(offset));try {iotDbServer.insertData(iotDbParam);redisTemplate.opsForValue().set(pointCode+"-"+offset,String.valueOf(value));ModbusApiDto modbusApiDto = new ModbusApiDto();modbusApiDto.setPointCode(pointCode);modbusApiDto.setTriggerTime(new Date());modbusApiDto.setValue(String.valueOf(value));modbusApiDto.setOffset(offset);//192.168.0.7 炉后天车称| 192.168.0.233 三项电表| 192.168.0.7 炉后小车位置激光测距| 192.168.0.7 炉后大车位置激光测距if (("192.168.0.7").equals(ip) && port == 23 && offset == 6 ||("192.168.0.233").equals(ip) && port == 502 && offset == 11 ||("192.168.0.7").equals(ip) && port == 35 && offset == 3 ||("192.168.0.7").equals(ip) && port == 35 && offset == 4) {modbusApiService.dealModbusData(JSON.toJSONString(modbusApiDto));}} catch (StatementExecutionException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();} catch (IoTDBConnectionException e) {e.printStackTrace();}offset++;}}/*** boolean类型数据方法** @param readDataBoolean* @param offset*/public void getBooleanData(boolean[] readDataBoolean, int offset,String pointCode,String ip,int port) {for (boolean value : readDataBoolean) {System.out.println(" offset: " + offset);System.out.println(" Value: " + value);IotDbParam iotDbParam=new IotDbParam();iotDbParam.setPk(pointCode);iotDbParam.setTime(System.currentTimeMillis());iotDbParam.setBreath(value==true?"1":"0");iotDbParam.setHeart(String.valueOf(offset));try {iotDbServer.insertData(iotDbParam);redisTemplate.opsForValue().set(pointCode+"-"+offset,String.valueOf(value));ModbusApiDto modbusApiDto=new ModbusApiDto();//小车振动信号if(("192.168.0.7").equals(ip) && port==29 &&(offset==200 || offset==201)){modbusApiDto.setPointCode(pointCode);modbusApiDto.setTriggerTime(new Date());modbusApiDto.setValue(iotDbParam.getBreath());modbusApiDto.setOffset(offset);modbusApiService.dealModbusData(JSON.toJSONString(modbusApiDto));}} catch (StatementExecutionException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();} catch (IoTDBConnectionException e) {e.printStackTrace();}offset++;}}}

补充说明

在这里插入图片描述
读取offset,是因为设备寄存器读取数量是固定的(可能是多个),里面有无效值,判断offset是为了读取有效值进行存储,可根据前端设备说明书进行相应取值。

相关文章:

  • AI Agent开发第65课-DIFY和企业现有系统结合实现高可配置的智能零售AI Agent(下)
  • 【Python爬虫 !!!!!!政府招投标数据爬虫项目--医疗实例项目文档(提供源码!!!)!!!学会Python爬虫轻松赚外快】
  • 现代化QML组件开发教程
  • 支付宝小程序开发指南
  • 在Babylon.js中实现完美截图:包含Canvas和HTML覆盖层
  • Rollup入门与进阶:为现代Web应用构建超小的打包文件
  • Q1财报持续向好,腾讯音乐如何在不确定中寻找确定性?
  • FlashInfer - 安装
  • Spark自定义分区器-基础
  • 订单服务拆分库表迁移实践
  • 杰理-701-手表sdk无法电脑连接经典蓝牙
  • calico.yaml+国内源
  • 《Effective Python》第2章 字符串和切片操作——深入理解Python 中的字符数据类型(bytes 与 str)的差异
  • Day1 时间复杂度
  • 【深度学习-Day 10】机器学习基石:从零入门线性回归与逻辑回归
  • 云共享虚拟主机具体是指什么?
  • “追光”植物背后的故事(二)
  • SpringBoot--springboot简述及快速入门
  • 基于 PLC 的轮式服务机器人研究
  • 医疗实时操作系统方案:手术机器人的微秒级运动控制
  • 郑培凯:汤显祖的“至情”与罗汝芳的“赤子之心”
  • 视频丨美国两名男童持枪与警察对峙,一人还试图扣动扳机
  • 福州千余公共道路泊车位装“智能地锁”续:运营公司被责令改正并罚款
  • 夜读丨取稿费的乐趣
  • 上海能源科技发展有限公司原董事长李海瑜一审获刑13年
  • 美国“贸易战”前线的本土受害者:安静的洛杉矶港和准备关门的小公司