在C# 和Java中,利用反射处理S7协议读取西门子PLC的变量

在C#和java中,有开源通信库NetS7Plus和S7Connector提供后台与PLC的通信。由于这两个库都提供了连续读取的方法。

以java为例,按偏移量读取Db块中的数值:

package com.zg.mymes.myConnPLC.myS7.myS7entities;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.s7connector.api.annotation.S7Variable;
import com.github.s7connector.impl.utils.S7Type;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.format.annotation.DateTimeFormat;
import org.yaml.snakeyaml.scanner.Constant;

import java.util.Date;

/**
 * @Auther: Zg
 * @Date: 2022/11/23 - 11 - 23 - 17:13
 * @Description: com.zg.mymes.myConnPLC.myS7.myS7entities
 * @version: 1.0
 * 可定制化的PLC值
 */
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
//@PropertySource("classpath:myS7Db.properties")
public class MyS7Entity {

//    @TableId(type = IdType.AUTO)
//    private Integer id;
//
//    public static final Integer dbNum = 30;
//    //@Value("${myS7Db.offSet}")
//    public static final Integer offSet = 42;
//
//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
//    private Date createTime;
//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
//    private Date insertTime;

    //必须为public 否则报错
    @S7Variable(byteOffset = 0, type = S7Type.REAL)
    public Double aBLineVoltage_PLC;
    @S7Variable(byteOffset = 4, type = S7Type.REAL)
    public Double bCLineVoltage_PLC;
    @S7Variable(byteOffset = 8, type = S7Type.REAL)
    public Double aCLineVoltage_PLC;
    @S7Variable(byteOffset = 12, type = S7Type.REAL)
    public Double aPhaseVoltage_PLC;
    @S7Variable(byteOffset = 16, type = S7Type.REAL)
    public Double bPhaseVoltage_PLC;
    @S7Variable(byteOffset = 20, type = S7Type.REAL)
    public Double cPhaseVoltage_PLC;
    @S7Variable(byteOffset = 24, type = S7Type.REAL)
    public Double aPhaseCurrent_PLC;
    @S7Variable(byteOffset = 28, type = S7Type.REAL)
    public Double bPhaseCurrent_PLC;
    @S7Variable(byteOffset = 32, type = S7Type.REAL)
    public Double cPhaseCurrent_PLC;
    @S7Variable(byteOffset = 36, type = S7Type.REAL)
    public Double allActivePower_PLC;
    @S7Variable(byteOffset = 40, type = S7Type.REAL)
    public Double aActivePower_PLC;
    @S7Variable(byteOffset = 44, type = S7Type.REAL)
    public Double bActivePower_PLC;
    @S7Variable(byteOffset = 48, type = S7Type.REAL)
    public Double cActivePower_PLC;
    @S7Variable(byteOffset = 52, type = S7Type.REAL)
    public Double allReactivePower_PLC;
    @S7Variable(byteOffset = 56, type = S7Type.REAL)
    public Double aReactivePower_PLC;
    @S7Variable(byteOffset = 60, type = S7Type.REAL)
    public Double bReactivePower_PLC;
    @S7Variable(byteOffset = 64, type = S7Type.REAL)
    public Double cReactivePower_PLC;
    @S7Variable(byteOffset = 68, type = S7Type.REAL)
    public Double allPowerFactor_PLC;
    @S7Variable(byteOffset = 72, type = S7Type.REAL)
    public Double aPowerFactor_PLC;
    @S7Variable(byteOffset = 76, type = S7Type.REAL)
    public Double bPowerFactor_PLC;
    @S7Variable(byteOffset = 80, type = S7Type.REAL)
    public Double cPowerFactor_PLC;
    @S7Variable(byteOffset = 84, type = S7Type.REAL)
    public Double aBLineVoltage_Power;
    @S7Variable(byteOffset = 88, type = S7Type.REAL)
    public Double bCLineVoltage_Power;
    @S7Variable(byteOffset = 92, type = S7Type.REAL)
    public Double aCLineVoltage_Power;
    @S7Variable(byteOffset = 96, type = S7Type.REAL)
    public Double aPhaseVoltage_Power;
    @S7Variable(byteOffset = 100, type = S7Type.REAL)
    public Double bPhaseVoltage_Power;
    @S7Variable(byteOffset = 104, type = S7Type.REAL)
    public Double cPhaseVoltage_Power;
    @S7Variable(byteOffset = 108, type = S7Type.REAL)
    public Double aPhaseCurrent_Power;
    @S7Variable(byteOffset = 112, type = S7Type.REAL)
    public Double bPhaseCurrent_Power;
    @S7Variable(byteOffset = 116, type = S7Type.REAL)
    public Double cPhaseCurrent_Power;
    @S7Variable(byteOffset = 120, type = S7Type.REAL)
    public Double allActivePower_Power;
    @S7Variable(byteOffset = 124, type = S7Type.REAL)
    public Double aActivePower_Power;
    @S7Variable(byteOffset = 128, type = S7Type.REAL)
    public Double bActivePower_Power;
    @S7Variable(byteOffset = 132, type = S7Type.REAL)
    public Double cActivePower_Power;
    @S7Variable(byteOffset = 136, type = S7Type.REAL)
    public Double allReactivePower_Power;
    @S7Variable(byteOffset = 140, type = S7Type.REAL)
    public Double aReactivePower_Power;
    @S7Variable(byteOffset = 144, type = S7Type.REAL)
    public Double bReactivePower_Power;
    @S7Variable(byteOffset = 148, type = S7Type.REAL)
    public Double cReactivePower_Power;
    @S7Variable(byteOffset = 152, type = S7Type.REAL)
    public Double allPowerFactor_Power;
    @S7Variable(byteOffset = 156, type = S7Type.REAL)
    public Double aPowerFactor_Power;
    @S7Variable(byteOffset = 160, type = S7Type.REAL)
    public Double bPowerFactor_Power;
    @S7Variable(byteOffset = 164, type = S7Type.REAL)
    public Double cPowerFactor_Power;
    @S7Variable(byteOffset = 168, type = S7Type.REAL)
    public Double testAlarm;
    @S7Variable(byteOffset = 404, type = S7Type.WORD)
    public Integer heartBeat;

    @S7Variable(byteOffset = 606,size = 130, type = S7Type.STRING)
    public String var100;
    @S7Variable(byteOffset = 738,size = 130, type = S7Type.STRING)
    public String var101;

    /**
     @S7Variable(byteOffset=0, type= S7Type.REAL) public double var1;
     @S7Variable(byteOffset=4, type= S7Type.REAL) public double var2;
     @S7Variable(byteOffset=8, type= S7Type.REAL) public double var3;
     @S7Variable(byteOffset=144, type= S7Type.BOOL) public boolean STATE_P1;
     @S7Variable(byteOffset=144, type= S7Type.BOOL,bitOffset = 1) public boolean STATE_P1;
     */
}

读取的变量为类中的字段,但是实际情况中,我们往往需要各个变量的采集时间,报警值,缩放比例,中文名等,例如

package com.zg.mymes.entities;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * @Auther: Zg
 * @Date: 2022/11/23 - 11 - 23 - 14:26
 * @Description: com.zg.mymes.entities
 * @version: 1.0
 */

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class ActualData {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String name;
    private String description;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createTime;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date insertTime;
    private String varAddress;
    private String varType;
    private String scale;
    private String highAlarm;
    private String highHighAlarm;
    private String lowAlarm;
    private String lowLowAlarm;
    private String alarmDescription;
    private String value;
}

这样的格式的变量,这时就需要我们把第一个类class MyS7Entity中的字段映射到class ActualData中,这时就可以利用反射特性快速映射:

    //S7
    @Async
    @Scheduled(cron = "*/1 * * * * *")
    public void Listen(){

        try {
            s7ConnHelper.readPlcData(31, MyS7Entity.class, 0);
            Map<String, Object> myMap = new HashMap<>();
            Field[] fields = s7ConnHelper.getMyDbData().getClass().getFields();
            for (Field f :fields
                 ) {
                //log.info(f.getType().toString());

                if (f.get(s7ConnHelper.getMyDbData()) instanceof Double){
                    String format = String.format("%.3f", f.get(s7ConnHelper.getMyDbData()));
                    myMap.put(f.getName(),format);
                }
                else {
                    myMap.put(f.getName(),f.get(s7ConnHelper.getMyDbData()));
                }

            }
            s7ConnHelper.setMyMap(myMap);


            java.util.Date date = new Date();//获得当前时间
            Timestamp t = new Timestamp(date.getTime());//将时间转换成Timestamp类型,这样便可以存入到Mysql数据库中
            for (ActualData actualData:s7ConnHelper.getActualDatas()
            ) {
                actualData.setCreateTime(t);
                actualData.setValue(myMap.get(actualData.getName()).toString());

                if (
                        actualData.getVarType().equals("Float")&&
                        actualData.getHighHighAlarm()!=null && actualData.getHighHighAlarm().length()!=0&&
                        actualData.getHighAlarm()!=null && actualData.getHighAlarm().length()!=0 &&
                        actualData.getLowLowAlarm()!=null && actualData.getLowLowAlarm().length()!=0 &&
                        actualData.getLowAlarm()!=null && actualData.getLowAlarm().length()!=0
                ){
                    if ((Double.parseDouble(actualData.getValue())>Double.parseDouble(actualData.getHighAlarm()))
                            && (Double.parseDouble(actualData.getValue())<Double.parseDouble(actualData.getHighHighAlarm()))
                    ){
                        actualData.setAlarmDescription("该变量高报警!");
                        actualData.setInsertTime(t);
                        actualDataService.save(actualData);
                    }
                    if (Double.parseDouble(actualData.getValue())>Double.parseDouble(actualData.getHighHighAlarm())){
                        actualData.setAlarmDescription("该变量高高报警!");
                        actualData.setInsertTime(t);
                        actualDataService.save(actualData);
                    }
                    if ((Double.parseDouble(actualData.getValue())<Double.parseDouble(actualData.getLowAlarm()))
                            && (Double.parseDouble(actualData.getValue())>Double.parseDouble(actualData.getLowLowAlarm()))
                    ){
                        actualData.setAlarmDescription("该变量低报警!");
                        actualData.setInsertTime(t);
                        actualDataService.save(actualData);
                    }
                    if (Double.parseDouble(actualData.getValue())<Double.parseDouble(actualData.getLowLowAlarm())){
                        actualData.setAlarmDescription("该变量低低报警!");
                        actualData.setInsertTime(t);
                        actualDataService.save(actualData);
                    }
                }
            }



            s7ConnHelper.getActualDatas().forEach(actualData -> log.info(actualData.toString()));

        catch (Exception ex){
            log.info(ex.getMessage()+"=====");

            s7ConnHelper.s7Connector=null;
            s7ConnHelper.s7Serializer=null;
            try {
                s7ConnHelper.initConnect();
                errorTimes=0;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

通信帮助类:

package com.zg.mymes.myConnPLC.myS7;

import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.S7Serializer;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.github.s7connector.api.factory.S7SerializerFactory;
import com.zg.mymes.entities.ActualData;
import com.zg.mymes.entities.MyConfig;
import com.zg.mymes.helper.MyJsonConfigTool;
import com.zg.mymes.myConnPLC.DataConvert;
import com.zg.mymes.myConnPLC.myS7.myS7entities.MyS7Entity;
import com.zg.mymes.myConnPLC.myS7.myS7entities.MyS7WriteEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
 * @Auther: Zg
 * @Date: 2022/11/23 - 11 - 23 - 17:14
 * @Description: com.zg.mymes.myConnPLC.myS7
 * @version: 1.0
 */
@Component
@Slf4j
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class S7ConnHelper implements IS7ConnHelper {

    private String Ip;
    private Integer Port;
    public S7Connector s7Connector;
    public S7Serializer s7Serializer;
    private List<ActualData> actualDatas = new ArrayList<ActualData>();

    private MyS7Entity myDbData;
    private List<Object> myDbDataList = new ArrayList<>();
    private List<MyS7Entity> myDbDatas = new ArrayList<MyS7Entity>();
    private Map<String,Object> myMap = new HashMap<>();

    private Integer errorTimes = 0;
    private Boolean isConnected = false;

    private Boolean heart = false;

    @Autowired
    private MyJsonConfigTool configTool;

    @Autowired
    private DataConvert dataConvert;

    @Override
    public void initConnect() throws IOException {
        MyConfig myConfig = configTool.ReadJson();
        Ip = myConfig.getIp();
        Port = 102;
        actualDatas = myConfig.getActualDatas();
        if (this.s7Connector==null){
            this.s7Connector = S7ConnectorFactory.buildTCPConnector()
                    .withHost(Ip)
                    .withPort(Port)
                    .withTimeout(10000)
                    .withRack(0)//机架号
                    .withSlot(1)//插槽号
                    .build();
            this.s7Serializer = S7SerializerFactory.buildSerializer(s7Connector);
            this.isConnected = true;
        }
    }


    /**
     *
     * @param dbNum DB号
     * @param clazz 变量
     * @param offSet 偏移量
     */

    @Override
    public MyS7Entity readPlcData(Integer dbNum, Class<?> clazz, int offSet){

        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:数据长度
        //第四个参数:偏移量
        //s7Connector.read(DaveArea.DB,)
//        this.clazz = clazz;
//        this.dbNum = dbNum;
        //S7Serializer s7Serializer = S7SerializerFactory.buildSerializer(s7Connector);
        //db号,偏移量

        if (this.isConnected=true){
//            java.util.Date date = new Date();//获得当前时间
//            Timestamp t = new Timestamp(date.getTime());

            this.myDbData = (MyS7Entity)this.s7Serializer.dispense(clazz, dbNum, offSet);
            //this.myDbData.setCreateTime(t);

            //心跳
            if (heart==false){
                this.myDbData.setHeartBeat(10);
                heart=true;
            }
            else if (heart==true){
                this.myDbData.setHeartBeat(20);
                heart=false;
            }

            try {
                this.s7Serializer.store(this.myDbData,dbNum,offSet);
            }
            //断线重连
            catch (Exception ex){
                log.info(ex.getMessage()+"Inner+=+=");
                this.isConnected=false;

                try {
                    this.s7Connector.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                this.s7Connector=null;
                this.s7Serializer=null;
                try {
                    this.initConnect();
                    errorTimes=0;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            this.myDbData = (MyS7Entity)this.s7Serializer.dispense(clazz, dbNum, offSet);

            if (myDbDatas.size()<30){
                myDbDatas.add(myDbData);
            }
            else {
                myDbDatas.remove(0);
            }

        }

        return myDbData;
    }

    @Override
    public MyS7Entity readTheDbData(Integer dbNum, MyS7Entity clazz, int offSet) {
        MyS7Entity myData = this.s7Serializer.dispense(clazz.getClass(), dbNum, offSet);
        return myData;
    }
    @Override
    public void writePlcData(Integer dbNum, MyS7WriteEntity clazz){

        this.s7Serializer.store(clazz,dbNum,0);
    }

    //DB,DB号,偏移量,Byte数组
    @Override
    public void writePlcByte(byte[] bytes){
        this.s7Connector.write(DaveArea.DB,31,0,bytes);
    }

}

package com.zg.mymes.myConnPLC.myS7;

import com.zg.mymes.myConnPLC.myS7.myS7entities.MyS7Entity;
import com.zg.mymes.myConnPLC.myS7.myS7entities.MyS7WriteEntity;

import java.io.IOException;

/**
 * @Auther: Zg
 * @Date: 2022/11/23 - 11 - 23 - 17:10
 * @Description: com.zg.mymes.myConnPLC.myS7
 * @version: 1.0
 */
public interface IS7ConnHelper {
    void initConnect() throws IOException;
    MyS7Entity readPlcData(Integer dbNum, Class<?> clazz, int offSet);
    MyS7Entity readTheDbData(Integer dbNum, MyS7Entity clazz, int offSet);
    void writePlcData(Integer dbNum, MyS7WriteEntity clazz);
    void writePlcByte(byte[] bytes);
}

package com.zg.mymes.helper;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zg.mymes.entities.MyConfig;
import org.springframework.stereotype.Service;

import java.io.*;

/**
 * @Auther: Zg
 * @Date: 2022/11/23 - 11 - 23 - 14:58
 * @Description: com.zg.mymes.helper
 * @version: 1.0
 */
@Service
public class MyJsonConfigTool {

    public String jsonStr="D:\\s7cfg.json";

    public void CreatJson( MyConfig config) throws IOException {
        // 创建文件对象

        File fileText = new File(jsonStr);
        ObjectMapper mapper = new ObjectMapper();
        // 向文件写入对象写入信息

        FileWriter fileWriter = new FileWriter(fileText);

        // 写文件
        String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(config);
        fileWriter.write(jsonString);

        // 关闭
        fileWriter.close();
    }

    public MyConfig ReadJson() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        File file = new File(jsonStr);
        String str = getStr(file);
        MyConfig myConfig = mapper.readValue(str, MyConfig.class);
        return myConfig;
    }

    public String getStr(File jsonFile){
        String jsonStr = "";
        try {
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

C#的对应代码:

using S7.Net.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ZgCsharp.Entities
{
    public class MyS7Db
    {
        public float aBLineVoltage_PLC { get; set; }
        public float bCLineVoltage_PLC { get; set; }
        public float aCLineVoltage_PLC { get; set; }
        public float aPhaseVoltage_PLC { get; set; }
        public float bPhaseVoltage_PLC { get; set; }
        public float cPhaseVoltage_PLC { get; set; }
        public float aPhaseCurrent_PLC { get; set; }
        public float bPhaseCurrent_PLC { get; set; }
        public float cPhaseCurrent_PLC { get; set; }
        public float allActivePower_PLC { get; set; }
        public float aActivePower_PLC { get; set; }
        public float bActivePower_PLC { get; set; }
        public float cActivePower_PLC { get; set; }
        public float allReactivePower_PLC { get; set; }
        public float aReactivePower_PLC { get; set; }
        public float bReactivePower_PLC { get; set; }
        public float cReactivePower_PLC { get; set; }
        public float allPowerFactor_PLC { get; set; }
        public float aPowerFactor_PLC { get; set; }
        public float bPowerFactor_PLC { get; set; }
        public float cPowerFactor_PLC { get; set; }
        public float aBLineVoltage_Power { get; set; }
        public float bCLineVoltage_Power { get; set; }
        public float aCLineVoltage_Power { get; set; }
        public float aPhaseVoltage_Power { get; set; }
        public float bPhaseVoltage_Power { get; set; }
        public float cPhaseVoltage_Power { get; set; }
        public float aPhaseCurrent_Power { get; set; }
        public float bPhaseCurrent_Power { get; set; }
        public float cPhaseCurrent_Power { get; set; }
        public float allActivePower_Power { get; set; }
        public float aActivePower_Power { get; set; }
        public float bActivePower_Power { get; set; }
        public float cActivePower_Power { get; set; }
        public float allReactivePower_Power { get; set; }
        public float aReactivePower_Power { get; set; }
        public float bReactivePower_Power { get; set; }
        public float cReactivePower_Power { get; set; }
        public float allPowerFactor_Power { get; set; }
        public float aPowerFactor_Power { get; set; }
        public float bPowerFactor_Power { get; set; }
        public float cPowerFactor_Power { get; set; }
        public float testAlarm { get; set; }
        //public ushort heartBeat { get; set; }

        //[S7String(S7StringType.S7String, 130)]
        //public string var100;

        //public string Var100
        //{
        //    get { return var100; }
        //    set { var100 = value; }
        //}
        //[S7String(S7StringType.S7String, 130)]
        //public string var101;

        //public string Var101
        //{
        //    get { return var101; }
        //    set { var101 = value; }
        //}


        //public bool Bool1 { get; set; }
        //public byte Byte1 { get; set; }
        //public double Float1 { get; set; }
        //public uint MD101 { get; set; }

    }
}

using Newtonsoft.Json;
using S7.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZgCsharp.Entities;
using ZgCsharp.SqlSugar.Repository.Impl;

namespace ZgCsharp.S7
{
    /*

    public enum CpuType
    {

        S7200 = 0,
        Logo0BA8 = 1,
        S7200Smart = 2,
        S7300 = 10,
        S7400 = 20,
        S71200 = 30,
        S71500 = 40
    }
     */


    public class MyS7Helper
    {

        public Plc myS7Master = null;




        //配置文件地址
        private string jsonfile = Application.StartupPath + "\\Config\\modbuscfg1.json";
        private string str;
        private CfgJson cfgJson;
        private ModelRepository modelRepository;
        private string ip;
        private int port;
        private string myCpuType;
        private string s7DbNum;
        private string s7StartByte;
        private int strMax;
        private MyS7Db myS7Db = new MyS7Db();

        private List<ActualData> actualDatas = new List<ActualData>();

        public List<ActualData> ActualDatas
        {
            get { return actualDatas; }
            set { actualDatas = value; }
        }

        public MyS7Db MyS7Db
        {
            get { return myS7Db; }
            set { myS7Db = value; }
        }


        private CancellationTokenSource cts = new CancellationTokenSource();


        public MyS7Helper(ModelRepository modelRepository)
        {
            this.modelRepository = modelRepository;
            str = File.ReadAllText(jsonfile);
            cfgJson = JsonConvert.DeserializeObject<CfgJson>(str);
            this.ip = cfgJson.Ip;
            this.port = 102;
            this.myCpuType = cfgJson.CPUType;
            this.s7DbNum = cfgJson.S7DbNum;
            this.s7StartByte = cfgJson.S7StartByte;
            this.strMax = int.Parse(cfgJson.strMax);
            this.actualDatas = cfgJson.ActualDatas;
            this.Conn();
            this.ReadPLCClass();


        }

        public bool Conn()
        {
            myS7Master = new Plc((CpuType)Enum.Parse(typeof(CpuType), this.myCpuType), this.ip, 0, 0);
            try
            {
                myS7Master.Open();
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        public void DisConn()
        {
            myS7Master.Close();
        }

        public void ReadPLCClass()
        {

                Task.Run(async () =>
                {
                    while (!cts.IsCancellationRequested)
                    {
                        if (myS7Master.IsConnected)
                        {
                            //int i = myS7Master.ReadClass(myS7Db, int.Parse(this.s7DbNum), int.Parse(this.s7StartByte));
                            myS7Db = myS7Master.ReadClass<MyS7Db>(int.Parse(this.s7DbNum), int.Parse(this.s7StartByte));
                            await Task.Delay(500);

                            System.Reflection.PropertyInfo[] fields = MyS7Db.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
                            //System.Reflection.FieldInfo[] fields = MyS7Db.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
                            foreach (var item in fields)
                            {
                                foreach (var i in this.actualDatas)
                                {
                                    if (item.Name == i.Name)
                                    {
                                        i.Value = item.GetValue(MyS7Db).ToString();
                                    }
                                }
                            }
                        }
                    }
                }, cts.Token);
        }

        public void WritePLCClass(MyS7Db myS7DbData)
        {
            myS7Master.WriteClass(myS7DbData, int.Parse(this.s7DbNum), int.Parse(this.s7StartByte));
        }

        public void WriteStr(string str)
        {
            byte[] myBytes = Encoding.ASCII.GetBytes(str);

            byte[] byte1 = { (byte)130, (byte)myBytes.Length };

            byte[] b = byte1.Concat(myBytes).ToArray();

            //myS7Master.WriteBytes(DataType.DataBlock, int.Parse(this.s7DbNum), int.Parse(this.s7StartByte), b);
            myS7Master.WriteBytes(DataType.DataBlock, 32, 3696, b);
        }   

        public void WriteBadApple(byte[] bytes)
        {
            myS7Master.WriteBytes(DataType.DataBlock, 32, 0, bytes);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ZgCsharp.Entities
{
    public class CfgJson
    {
        public string Ip { get; set; }
        public string Port { get; set; }
        public string SlaveNo { get; set; }
        public string Address { get; set; }
        public string VarNum { get; set; }
        public string CPUType { get; set; }
        public string S7DbNum { get; set; }
        public string S7StartByte { get; set; }
        public string strMax { get; set; }
        public List<ActualData> ActualDatas { get; set; }
    }
}

使用springboot当后端,layui+thyme leaf当前端:

在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值