All Downloads are FREE. Search and download functionalities are using the official Maven repository.

HslCommunication.Profinet.Siemens.SiemensFetchWriteNet Maven / Gradle / Ivy

Go to download

一个工业物联网的底层架构框架,专注于底层的技术通信及跨平台,跨语言通信功能,实现各种主流的PLC数据读写,实现modbus的各种协议读写等等

There is a newer version: 3.7.0
Show newest version
package HslCommunication.Profinet.Siemens;

import HslCommunication.BasicFramework.SoftBasic;
import HslCommunication.Core.IMessage.FetchWriteMessage;
import HslCommunication.Core.IMessage.INetMessage;
import HslCommunication.Core.Net.NetworkBase.NetworkDeviceBase;
import HslCommunication.Core.Transfer.ByteTransformHelper;
import HslCommunication.Core.Transfer.ReverseBytesTransform;
import HslCommunication.Core.Types.FunctionOperateExOne;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Core.Types.OperateResultExThree;
import HslCommunication.StringResources;

/**
 * 使用了Fetch/Write协议来和西门子进行通讯,该种方法需要在PLC侧进行一些配置
 */
public class SiemensFetchWriteNet extends NetworkDeviceBase {

    /**
     * 实例化一个西门子的Fetch/Write协议的通讯对象
     */
    public SiemensFetchWriteNet() {
        WordLength = 2;
        setByteTransform(new ReverseBytesTransform( ));
    }


    /**
     * 实例化一个西门子的Fetch/Write协议的通讯对象
     *
     * @param ipAddress PLC的Ip地址
     * @param port      PLC的端口
     */
    public SiemensFetchWriteNet(String ipAddress, int port) {
        WordLength = 2;
        setIpAddress(ipAddress);
        setPort(port);
        setByteTransform(new ReverseBytesTransform( ));
    }

    @Override
    protected INetMessage GetNewNetMessage() {
        return new FetchWriteMessage( );
    }

    /**
     * 从PLC读取数据,地址格式为I100,Q100,DB20.100,M100,T100,C100,以字节为单位
     *
     * @param address 起始地址,格式为I100,M100,Q100,DB20.100,T100,C100
     * @param length  读取的数量,以字节为单位
     * @return 带有成功标志的字节信息
     */
    @Override
    public OperateResultExOne Read(String address, short length) {
        OperateResultExOne result = new OperateResultExOne();
        OperateResultExOne command = BuildReadCommand(address, length);
        if (!command.IsSuccess) {
            result.CopyErrorFromOther(command);
            return result;
        }

        OperateResultExOne read = ReadFromCoreServer(command.Content);
        if (read.IsSuccess) {
            if (read.Content[8] == 0x00) {
                // 分析结果
                byte[] buffer = new byte[read.Content.length - 16];
                System.arraycopy(read.Content, 16, buffer, 0, buffer.length);

                result.Content = buffer;
                result.IsSuccess = true;
            } else {
                result.ErrorCode = read.Content[8];
                result.Message = "发生了异常,具体信息查找Fetch/Write协议文档";
            }
        } else {
            result.ErrorCode = read.ErrorCode;
            result.Message = read.Message;
        }

        return result;
    }


    /**
     * 读取指定地址的byte数据
     *
     * @param address 起始地址,格式为I100,M100,Q100,DB20.100
     * @return 返回写入结果
     */
    public OperateResultExOne ReadByte(String address) {
        return ByteTransformHelper.GetResultFromBytes(Read(address, (short) 1), new FunctionOperateExOne() {
            public Byte Action(byte[] content) {
                return content[0];
            }
        });
    }


    /**
     * 将数据写入到PLC数据,地址格式为I100,Q100,DB20.100,M100,以字节为单位
     *
     * @param address 起始地址,格式为I100,M100,Q100,DB20.100
     * @param value   写入的数据,长度根据data的长度来指示
     * @return 返回写入结果
     */
    @Override
    public OperateResult Write(String address, byte[] value) {
        OperateResult result = new OperateResult();

        OperateResultExOne command = BuildWriteCommand(address, value);
        if (!command.IsSuccess) {
            result.CopyErrorFromOther(command);
            return result;
        }


        OperateResultExOne write = ReadFromCoreServer(command.Content);
        if (write.IsSuccess) {
            if (write.Content[8] != 0x00) {
                // 写入异常
                result.Message = "写入数据异常,代号为:" + String.valueOf(write.Content[8]);
            } else {
                result.IsSuccess = true;  // 写入成功
            }
        } else {
            result.ErrorCode = write.ErrorCode;
            result.Message = write.Message;
        }
        return result;
    }

    /**
     * 向PLC中写入bool数组,返回值说明,比如你写入M100,那么data[0]对应M100.0
     *
     * @param address 要写入的数据地址
     * @param values  要写入的实际数据,长度为8的倍数
     * @return 返回写入结果
     */
    public OperateResult Write(String address, boolean[] values) {
        return Write(address, SoftBasic.BoolArrayToByte(values));
    }


    /**
     * 向PLC中写入byte数据,返回值说明
     *
     * @param address 要写入的数据地址
     * @param value   要写入的实际数据
     * @return 返回写入结果
     */
    public OperateResult Write(String address, byte value) {
        return Write(address, new byte[]{value});
    }


    /**
     * 返回表示当前对象的字符串
     *
     * @return 字符串
     */
    @Override
    public String toString() {
        return "SiemensFetchWriteNet";
    }




    /**
     * 计算特殊的地址信息
     *
     * @param address 字符串信息
     * @return 实际值
     */
    public static int CalculateAddressStarted(String address) {
        if (address.indexOf('.') < 0) {
            return Integer.parseInt(address);
        } else {
            String[] temp = address.split("\\.");
            return Integer.parseInt(temp[0]);
        }
    }


    /**
     * 解析数据地址,解析出地址类型,起始地址,DB块的地址
     *
     * @param address 数据地址
     * @return 解析出地址类型,起始地址,DB块的地址
     */
    public static OperateResultExThree AnalysisAddress(String address) {
        OperateResultExThree result = new OperateResultExThree();
        try {
            result.Content3 = 0;
            if (address.indexOf(0) == 'I') {
                result.Content1 = 0x03;
                result.Content2 = CalculateAddressStarted(address.substring(1));
            } else if (address.indexOf(0) == 'Q') {
                result.Content1 = 0x04;
                result.Content2 = CalculateAddressStarted(address.substring(1));
            } else if (address.indexOf(0) == 'M') {
                result.Content1 = 0x02;
                result.Content2 = CalculateAddressStarted(address.substring(1));
            } else if (address.indexOf(0) == 'D' || address.substring(0, 2).equals("DB")) {
                result.Content1 = 0x01;
                String[] adds = address.split("\\.");
                if (address.indexOf(1) == 'B') {
                    result.Content3 = Integer.parseInt(adds[0].substring(2));
                } else {
                    result.Content3 = Integer.parseInt(adds[0].substring(1));
                }

                if (result.Content3 > 255) {
                    result.Message = StringResources.Language.SiemensDBAddressNotAllowedLargerThan255();
                    return result;
                }

                result.Content2 = CalculateAddressStarted(address.substring(address.indexOf('.') + 1));
            } else if (address.indexOf(0) == 'T') {
                result.Content1 = 0x07;
                result.Content2 = CalculateAddressStarted(address.substring(1));
            } else if (address.indexOf(0) == 'C') {
                result.Content1 = 0x06;
                result.Content2 = CalculateAddressStarted(address.substring(1));
            } else {
                return new OperateResultExThree(StringResources.Language.NotSupportedDataType());
            }
        } catch (Exception ex) {
            result.Message = ex.getMessage();
            return result;
        }

        result.IsSuccess = true;
        return result;
    }


    /**
     * 生成一个读取字数据指令头的通用方法
     *
     * @param address 地址
     * @param count   长度
     * @return 带结果标识的指令
     */
    public static OperateResultExOne BuildReadCommand(String address, int count) {
        OperateResultExThree analysis = AnalysisAddress(address);
        if (!analysis.IsSuccess) return  OperateResultExOne.CreateFailedResult(analysis);

        byte[] _PLCCommand = new byte[16];
        _PLCCommand[0] = 0x53;
        _PLCCommand[1] = 0x35;
        _PLCCommand[2] = 0x10;
        _PLCCommand[3] = 0x01;
        _PLCCommand[4] = 0x03;
        _PLCCommand[5] = 0x05;
        _PLCCommand[6] = 0x03;
        _PLCCommand[7] = 0x08;

        // 指定数据区
        _PLCCommand[8] = analysis.Content1;
        _PLCCommand[9] = analysis.Content3.byteValue();

        // 指定数据地址
        _PLCCommand[10] = (byte) (analysis.Content2 / 256);
        _PLCCommand[11] = (byte) (analysis.Content2 % 256);

        if (analysis.Content1 == 0x01 || analysis.Content1 == 0x06 || analysis.Content1 == 0x07) {
            if (count % 2 != 0) {
                return new OperateResultExOne(StringResources.Language.SiemensReadLengthMustBeEvenNumber());
            } else {
                // 指定数据长度
                _PLCCommand[12] = (byte) (count / 2 / 256);
                _PLCCommand[13] = (byte) (count / 2 % 256);
            }
        } else {
            // 指定数据长度
            _PLCCommand[12] = (byte) (count / 256);
            _PLCCommand[13] = (byte) (count % 256);
        }

        _PLCCommand[14] = (byte) 0xff;
        _PLCCommand[15] = 0x02;

        return OperateResultExOne.CreateSuccessResult(_PLCCommand);
    }


    /**
     * 生成一个写入字节数据的指令
     *
     * @param address 地址
     * @param data    数据
     * @return 带结果标识的指令
     */
    public static OperateResultExOne BuildWriteCommand(String address, byte[] data) {
        if (data == null) data = new byte[0];
        OperateResultExThree analysis = AnalysisAddress(address);
        if (!analysis.IsSuccess) return OperateResultExOne.CreateFailedResult(analysis);


        byte[] _PLCCommand = new byte[16 + data.length];
        _PLCCommand[0] = 0x53;
        _PLCCommand[1] = 0x35;
        _PLCCommand[2] = 0x10;
        _PLCCommand[3] = 0x01;
        _PLCCommand[4] = 0x03;
        _PLCCommand[5] = 0x03;
        _PLCCommand[6] = 0x03;
        _PLCCommand[7] = 0x08;

        // 指定数据区
        _PLCCommand[8] = analysis.Content1;
        _PLCCommand[9] = analysis.Content3.byteValue();

        // 指定数据地址
        _PLCCommand[10] = (byte) (analysis.Content2 / 256);
        _PLCCommand[11] = (byte) (analysis.Content2 % 256);

        if (analysis.Content1 == 0x01 || analysis.Content1 == 0x06 || analysis.Content1 == 0x07) {
            if (data.length % 2 != 0) {
                return new OperateResultExOne(StringResources.Language.SiemensReadLengthMustBeEvenNumber());
            } else {
                // 指定数据长度
                _PLCCommand[12] = (byte) (data.length / 2 / 256);
                _PLCCommand[13] = (byte) (data.length / 2 % 256);
            }
        } else {
            // 指定数据长度
            _PLCCommand[12] = (byte) (data.length / 256);
            _PLCCommand[13] = (byte) (data.length % 256);
        }

        _PLCCommand[14] = (byte) 0xff;
        _PLCCommand[15] = 0x02;

        // 放置数据
        System.arraycopy(data, 0, _PLCCommand, 16, data.length);

        return OperateResultExOne.CreateSuccessResult(_PLCCommand);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy