MelsecMcHelp.cs 7.75 KB
using HslCommunication;
using HslCommunication.Profinet.Melsec;

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

namespace HH_WCS_Standard
{
    public class MelsecMcHelp : I_OpcHelp
    {
        private MelsecMcNet melsecMcNet;

        public MelsecMcHelp(MelsecMcNet siemens)
        {
            melsecMcNet = siemens;
        }

        /// <summary>
        /// 打开S7 Net长连接
        /// </summary>
        /// <returns></returns>
        public override BllResult OpenConn()
        {
            try
            {
                OperateResult connect = melsecMcNet.ConnectServer();
                if (connect.IsSuccess)
                {
                    return BllResult.Sucess();
                }
                else
                {
                    return BllResult.Error(connect.Message);
                }
            }
            catch (Exception ex)
            {
                return BllResult.Error(ex);
            }
        }

        /// <summary>
        /// 关闭S7 Net长连接
        /// </summary>
        /// <returns></returns>
        public override BllResult CloseConn()
        {
            try
            {
                OperateResult connect = melsecMcNet.ConnectClose();
                if (connect.IsSuccess)
                {
                    return BllResult.Sucess();
                }
                else
                {
                    return BllResult.Error(connect.Message);
                }
            }
            catch (Exception ex)
            {
                return BllResult.Error(ex);
            }
        }

        //获取各数据类型长度
        public override ushort GetTypeLength(string addresstype)
        {
            switch (addresstype)
            {
                case "BOOL": return 1;
                case "INT": return 1;
                case "STRING": return 12;
                default: return 0;
            }
        }

        public override BllResult ReadAddress(List<I_Device_Address> address)
        {
            address = address.OrderBy(a => a.Address).ToList();
            OperateResult<byte[]> read;
            if (address.Count == 1)
            {
                string startaddress = address[0].Db;
                read = melsecMcNet.Read(startaddress, GetTypeLength(address[0].AddressType));
            }
            else
            {
                double admax = address.Select(a => a.Address).Max();
                double admin = address.Select(a => a.Address).Min();
                ushort length = (ushort)(Math.Floor(admax - admin) + GetTypeLength(address.Last().AddressType));
                string startaddress = address[0].Db;
                read = melsecMcNet.Read(startaddress, length);
            }
            if (read.IsSuccess)
            {
                if (TransforWCSDataToAddressData(address, read).Success)
                {
                    return BllResult.Sucess(address, "成功");
                }
                else
                {
                    return BllResult.Sucess(address, "成功");
                }
            }
            else
            {
                return BllResult.Error(read.Message);
            }
        }

        public override BllResult WriteAddress(List<I_Device_Address> address)
        {
            address = address.OrderBy(a => a.Address).ToList();
            string startaddress = address[0].Db;
            BllResult bllResult = TransforAddressDataToWCSData(address);
            if (bllResult.Success)
            {
                OperateResult operate = melsecMcNet.Write(startaddress, (byte[])bllResult.Data);
                if (operate.IsSuccess)
                {
                    return BllResult.Sucess();
                }
                else
                {
                    return BllResult.Error(operate.Message);
                }
            }
            else
            {
                return BllResult.Error(bllResult.Msg);
            }
        }

        public override BllResult TransforWCSDataToAddressData(List<I_Device_Address> address, OperateResult<byte[]> read)
        {
            try
            {
                //按偏移量排序
                address = address.OrderBy(a => a.Address).ToList();
                int startindex = address[0].Address;
                for (int i = 0; i < address.Count; i++)
                {
                    int index = (address[i].Address - startindex) * 2;
                    switch (address[i].AddressType)
                    {
                        case "BOOL":
                            address[i].value = melsecMcNet.ByteTransform.TransBool(read.Content, index, 1)[address[i].Address_decimal].ToString();
                            break;

                        case "INT":
                            address[i].value = melsecMcNet.ByteTransform.TransInt16(read.Content, index).ToString();
                            break;

                        case "DINT":
                            address[i].value = Convert.ToString(melsecMcNet.ByteTransform.TransInt32(read.Content, index), 10);
                            break;

                        case "STRING":
                            address[i].value = melsecMcNet.ByteTransform.TransString(read.Content, index, 12, Encoding.ASCII).Replace(" ", "").Replace("\0", "").Replace("\u0003", "");
                            break;

                        default:
                            return BllResult.Error("找不到未知的数据类型");
                    }
                }
                return BllResult.Sucess(address);
            }
            catch (Exception ex)
            {
                return BllResult.Error($"转换WCS数据失败{ex.Message}");
            }
        }

        public override BllResult TransforAddressDataToWCSData(List<I_Device_Address> address)
        {
            try
            {
                //address = new ObservableCollection<I_Device_Address>(address.OrderBy(item => item.Address));
                double admax = address.Select(a => a.Address).Max();
                double admin = address.Select(a => a.Address).Min();
                ushort length = (ushort)(Math.Floor(admax - admin) + GetTypeLength(address.Last().AddressType));
                int startindex = address[0].Address;
                byte[] writebyte = new byte[length * 2];
                for (int i = 0; i < address.Count; i++)
                {
                    int index = (address[i].Address - startindex) * 2;
                    object value = address[i].value;
                    switch (address[i].AddressType)
                    {
                        case "BOOL":
                            bool[] tobool = melsecMcNet.ByteTransform.TransBool(writebyte, index, 1);
                            tobool[address[i].Address_decimal] = bool.Parse(address[i].value);
                            melsecMcNet.ByteTransform.TransByte(tobool).CopyTo(writebyte, index);
                            break;

                        case "INT":
                            short toint = Convert.ToInt16(value);
                            melsecMcNet.ByteTransform.TransByte(toint).CopyTo(writebyte, index);
                            break;

                        case "STRING":
                            byte[] tochar = Encoding.ASCII.GetBytes(((string)value).PadRight(12, ' '));
                            tochar.CopyTo(writebyte, index);
                            break;

                        default:
                            return BllResult.Error("找不到未知的数据类型");
                    }
                }
                return BllResult.Sucess(writebyte);
            }
            catch (Exception ex)
            {
                return BllResult.Error($"转换WCS数据失败{ex.Message}");
            }
        }
    }
}