| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using HslCommunication.Core;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using TeamAAS.Communication.Interfaces;
- namespace TeamAAS.Communication.Base
- {
- public abstract class PlcCommunicationBase : BindableCommunicationBase
- {
- [Browsable(false)]
- public override string TypeKey => GetType().FullName;
- public abstract string PlcVendor { get; }
- [JsonIgnore, Browsable(false)]
- protected IReadWriteNet Driver;
- private byte _station = 1;
- [Category("II.PLC配置"), DisplayName("从站号"), Description("Modbus 等多从站协议用")]
- public byte Station
- {
- get => _station;
- set => SetProperty(ref _station, value);
- }
- private ByteOrderType _byteOrder = ByteOrderType.ABCD;
- [Category("II.PLC配置"), DisplayName("字节序"), Description("多字节数据字节排列顺序")]
- public ByteOrderType ByteOrder
- {
- get => _byteOrder;
- set => SetProperty(ref _byteOrder, value);
- }
- protected virtual string ResolveAddress(string address) => address;
- public override object ReadValue(string address) => ReadValue(address, DebugDataType.Int, 1);
- public override Task<object> ReadValueAsync(string address) => Task.Run(() => ReadValue(address));
- public override void WriteValue(string address, object value)
- {
- if (value == null) throw new ArgumentNullException(nameof(value));
- WriteValue(address, value, InferDataType(value), 1);
- }
- public override Task WriteValueAsync(string address, object value) => Task.Run(() => WriteValue(address, value));
- private static DebugDataType InferDataType(object value)
- {
- if (value is bool) return DebugDataType.Bool;
- if (value is byte) return DebugDataType.Byte;
- if (value is short) return DebugDataType.Short;
- if (value is ushort) return DebugDataType.Ushort;
- if (value is int) return DebugDataType.Int;
- if (value is uint) return DebugDataType.Uint;
- if (value is long) return DebugDataType.Long;
- if (value is ulong) return DebugDataType.Ulong;
- if (value is float) return DebugDataType.Float;
- if (value is double) return DebugDataType.Double;
- return DebugDataType.String;
- }
- public virtual object ReadValue(string address, DebugDataType type, ushort length = 1)
- {
- if (Driver == null) throw new InvalidOperationException($"{PlcVendor} 底层驱动未初始化,请先连接。");
- var addr = ResolveAddress(address);
- ushort len = Math.Max(length, (ushort)1);
- switch (type)
- {
- case DebugDataType.Bool:
- if (len == 1) { var r = Driver.ReadBool(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadBool(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Byte:
- { var r = Driver.Read(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Short:
- if (len == 1) { var r = Driver.ReadInt16(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadInt16(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Ushort:
- if (len == 1) { var r = Driver.ReadUInt16(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadUInt16(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Int:
- if (len == 1) { var r = Driver.ReadInt32(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadInt32(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Uint:
- if (len == 1) { var r = Driver.ReadUInt32(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadUInt32(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Long:
- if (len == 1) { var r = Driver.ReadInt64(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadInt64(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Ulong:
- if (len == 1) { var r = Driver.ReadUInt64(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadUInt64(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Float:
- if (len == 1) { var r = Driver.ReadFloat(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadFloat(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.Double:
- if (len == 1) { var r = Driver.ReadDouble(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- { var r = Driver.ReadDouble(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- case DebugDataType.String:
- { var r = Driver.ReadString(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
- default:
- throw new ArgumentOutOfRangeException(nameof(type));
- }
- }
- public virtual void WriteValue(string address, object value, DebugDataType type, ushort length = 1)
- {
- if (Driver == null) throw new InvalidOperationException($"{PlcVendor} 底层驱动未初始化,请先连接。");
- var addr = ResolveAddress(address);
- HslCommunication.OperateResult result;
- switch (type)
- {
- case DebugDataType.Bool:
- result = value is bool[] bArr ? Driver.Write(addr, bArr) : Driver.Write(addr, Convert.ToBoolean(value));
- break;
- case DebugDataType.Byte:
- result = value is byte[] byArr ? Driver.Write(addr, byArr) : Driver.Write(addr, new[] { Convert.ToByte(value) });
- break;
- case DebugDataType.Short:
- result = value is short[] sArr ? Driver.Write(addr, sArr) : Driver.Write(addr, Convert.ToInt16(value));
- break;
- case DebugDataType.Ushort:
- result = value is ushort[] usArr ? Driver.Write(addr, usArr) : Driver.Write(addr, Convert.ToUInt16(value));
- break;
- case DebugDataType.Int:
- result = value is int[] iArr ? Driver.Write(addr, iArr) : Driver.Write(addr, Convert.ToInt32(value));
- break;
- case DebugDataType.Uint:
- result = value is uint[] uiArr ? Driver.Write(addr, uiArr) : Driver.Write(addr, Convert.ToUInt32(value));
- break;
- case DebugDataType.Long:
- result = value is long[] lArr ? Driver.Write(addr, lArr) : Driver.Write(addr, Convert.ToInt64(value));
- break;
- case DebugDataType.Ulong:
- result = value is ulong[] ulArr ? Driver.Write(addr, ulArr) : Driver.Write(addr, Convert.ToUInt64(value));
- break;
- case DebugDataType.Float:
- result = value is float[] fArr ? Driver.Write(addr, fArr) : Driver.Write(addr, Convert.ToSingle(value));
- break;
- case DebugDataType.Double:
- result = value is double[] dArr ? Driver.Write(addr, dArr) : Driver.Write(addr, Convert.ToDouble(value));
- break;
- case DebugDataType.String: result = Driver.Write(addr, value?.ToString() ?? ""); break;
- default: throw new ArgumentOutOfRangeException(nameof(type));
- }
- if (!result.IsSuccess) throw new InvalidOperationException(result.Message);
- }
- public Task<object> ReadValueAsync(string address, DebugDataType type, ushort length = 1)
- => Task.Run(() => ReadValue(address, type, length));
- public Task WriteValueAsync(string address, object value, DebugDataType type, ushort length = 1)
- => Task.Run(() => WriteValue(address, value, type, length));
- }
- }
|