PLC4J库读取西门子plc s7-1500的数据

1.添加依赖

点击查看代码
 <dependency>
            <groupId>org.apache.plc4x</groupId>
            <artifactId>plc4j-api</artifactId>
            <version>0.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.plc4x</groupId>
            <artifactId>plc4j-driver-s7</artifactId>
            <version>0.12.0</version>
        </dependency>
2.创建工具类
点击查看代码
package com.pangus.ims.custom.client.lannRay.util;

import org.apache.plc4x.java.api.PlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;


import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.*;

public class Plc4xUtil {
    private static PlcConnection plcConnection=null;

    private static final String PLC_URL = "s7://172.17.16.251"; // PLC 的地址

    public static PlcConnection createConnection() {
//        try {
//            //return new PlcDriverManager().getConnection(PLC_URL);
//        } catch (PlcConnectionException e) {
//            e.printStackTrace(); // 打印异常信息
//            return null; // 或者抛出自定义异常
//        }
        return null;
    }


    public static Map<String, Object> readPlcDataBatch(PlcConnection plcConnection, String[] itemAddresses) throws IOException {
        Map<String, Object> resultMap = new HashMap<>();

        try {
            PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
            for (int i = 0; i < itemAddresses.length; i++) {
                builder.addTagAddress("value-" + i, itemAddresses[i]);
            }
            PlcReadRequest readRequest = builder.build();
            PlcReadResponse response = readRequest.execute().get(5000, TimeUnit.MILLISECONDS);
//            for (String tagName : response.getTagNames()) {
//                if(response.getResponseCode(tagName) == PlcResponseCode.OK) {
//                    int numValues = response.getNumberOfValues(tagName);
//                    // If it's just one element, output just one single line.
//                    if(numValues == 1) {
//                        // logger.info("Value[" + tagName + "]: " + response.getObject(tagName));
//                        System.out.println("Value[" + tagName + "]: " + response.getObject(tagName));
//                    }
//                    // If it's more than one element, output each in a single row.
//                    else {
//                        // logger.info("Value[" + tagName + "]:");
//                        for(int i = 0; i < numValues; i++) {
//                            System.out.println(" - " + response.getObject(tagName, i));
//                        }
//                    }
//                }
//                // Something went wrong, to output an error message instead.
//                else {
//                    System.out.println("Error[" + tagName + "]: " + response.getResponseCode(tagName).name());
//                }
//            }
            // 处理响应结果并将其存储到结果映射中
            for (int i = 0; i < itemAddresses.length; i++) {
                String itemName = "value-" + i;
                String address = itemAddresses[i];
                if (response.getResponseCode(itemName) == PlcResponseCode.OK) {
                    Object value = null;
                    // 根据地址的类型选择相应的获取方法
                    if (address.contains(":BOOL")) {
                        value = response.getBoolean(itemName); // 布尔类型
                    } else if (address.contains(":BYTE")) {
                        value = response.getByte(itemName); // 字节类型
                    } else if (address.contains(":WORD")) {
                        value = response.getShort(itemName); // 16位整数 (WORD)
                    } else if (address.contains(":DWORD")) {
                        value = response.getInteger(itemName); // 32位整数 (DWORD)
                    } else if (address.contains(":REAL")) {
                        value = response.getFloat(itemName); // 实数 (REAL)
                    } else if (address.contains(":STRING")) {
                        value = response.getString(itemName); // 字符串类型
                    } else if (address.contains(":DINT")) {
                        value = response.getInteger(itemName); // 32位整数 (DINT)
                    } else {
                        // 你可以在这里扩展更多类型支持
                        System.err.println("Unknown type for address: " + address);
                    }

                    // 将读取的值存储到结果映射中
                    resultMap.put(address, value);
                } else {
                    System.err.println("Error reading value for address: " + address + " - " + response.getResponseCode(itemName));
                    resultMap.put(address, null);  // 如果读取失败,存储 null
                }
            }


        } catch  ( TimeoutException | InterruptedException | ExecutionException e)  {
            e.printStackTrace();
        }
        return resultMap;  // 返回包含所有读取结果的 Map
    }


    // 主方法示例

    public static void main(String[] args) throws Exception {
        String connectionString = PLC_URL;
        try (PlcConnection plcConnection = PlcDriverManager.getDefault().getConnectionManager().getConnection(connectionString)) {
            if (!plcConnection.getMetadata().isReadSupported()) {
                System.out.println("当前连接不支持读数据");
                return;
            }
            // 定义要批量读取的多个地址
            String[] itemAddresses = {
                    "%IW200:WORD",
                    "%IW202:WORD",
                    "%IW204:WORD",
                    "%IW206:WORD",
                    "%IW208:WORD",
                    "%IW210:WORD",
                    "%IW212:WORD",
                    "%IW416:WORD",
                    "%IW400:WORD",
                    "%IW402:WORD",
                    "%IW404:WORD",
                    "%IW406:WORD",
                    "%IW408:WORD",
                    "%IW410:WORD"
            };
            Map<String, Object> resultMap = readPlcDataBatch(plcConnection, itemAddresses);
            // 输出读取结果
            for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                System.out.println("Address: " + entry.getKey() + " | Value: " + entry.getValue());
            }
        }

    }
}

3.在定时任务中调用
点击查看代码
 public void readPlcDataPlc() throws IOException {
        try {
            String[] itemAddresses = {
                    "%DB18.DBD264:REAL",
                    "%DB18.DBD268:REAL",
                    "%DB80.DBD264:REAL",
                    "%DB80.DBD268:REAL",
                    "%DB20.DBD256:REAL",
                    "%DB20.DBD260:REAL",
                    "%DB18.DBX252.1:BOOL",
                    "%DB18.DBX252.2:BOOL",
                    "%DB80.DBX252.1:BOOL",
                    "%DB80.DBX252.2:BOOL",
                    "%DB20.DBX244.5:BOOL",
                    "%DB20.DBX244.6:BOOL",
                    "%DB3.DBD550:REAL",
                    "%DB18.DBD276:REAL",
                    "%DB3.DBD556:REAL",
                    "%DB80.DBD276:REAL",
                    "%DB3.DBD562:REAL",
                    "%DB20.DBD268:REAL",
                    "%DB18.DBX252.4:BOOL",
                    "%DB18.DBX252.3:BOOL",
                    "%DB80.DBX252.4:BOOL",
                    "%DB80.DBX252.3:BOOL",
                    "%DB20.DBX245.0:BOOL",
                    "%DB20.DBX244.7:BOOL"
            };
            Map<String, Object> map= LannRayPlcDataSend.readPlcDataPlc4(itemAddresses);
            if(map.size()==1||map.size()==0){
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    Object msg=entry.getValue();
                    postMessage(MessageStatusType.ERROR,"程序报错1:"+msg);
                }
            }else{
                ContentBody body=new ContentBody();
                body.setExtendData(map);
                postMessage(MessageStatusType.INFO,"读取到数据:"+map.toString());
                //构建iotBaseMessage
                final ContentMessage<ContentBody> message = new ContentMessage<>();
                message.setBody(body);
                message.setDeviceType(this.getDeviceType());
                //发送数据到上层系统
                sendMessage(message);
                postMessage(MessageStatusType.INFO,"发送iot消息成功,程序等待中...");
            }

        } catch (Exception e) {
            postMessage(MessageStatusType.ERROR,"程序报错2:"+e.getMessage());
            e.printStackTrace();
        }
    }


点击查看代码
    public static Map<String, Object> readPlcDataPlc4(String[] itemAddresses) throws IOException {
        String PLC_URL = "s7://172.17.16.251";
        Map<String, Object> map= new HashMap<>();
        try (PlcConnection plcConnection = PlcDriverManager.getDefault().getConnectionManager().getConnection(PLC_URL)) {
            if (!plcConnection.getMetadata().isReadSupported()) {
                System.out.println("当前连接不支持读数据");
                return null;
            }
            // 批量读取 PLC 地址数据
            Map<String, Object> resultMap = Plc4xUtil.readPlcDataBatch(plcConnection, itemAddresses);
            // 输出读取结果

            for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                String key = entry.getKey()
                        .replace("%", "")
                        .replace(":REAL", "")
                        .replace(":WORD", "")
                        .replace(":BOOL", "")
                        .replace(".0:BOOL", "");
                Object value=entry.getValue();
                map.put(key,value);
            }
            return map;

        } catch (Exception e) {
            map.put("msg",e.getMessage());
            return map;
            //  e.printStackTrace();
        }

    }
posted on 2025-01-02 16:20  呆呆小帅哥  阅读(978)  评论(0)    收藏  举报