using MCProtocol; namespace Seyounth.Hyosung.Core.Plc; public class McPlc(string host, int port, Mitsubishi.McFrame type) { private readonly Mitsubishi.McProtocolTcp _mc = new(); public async Task ConnectAsync() { _mc.HostName = host; _mc.PortNumber = port; _mc.CommandFrame = type; using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)); var openTask = Task.Run(()=>_mc.Open(), cts.Token) ; var completedTask = await Task.WhenAny( openTask, Task.Delay(Timeout.Infinite, cts.Token) ); if (completedTask != openTask) { throw new TimeoutException("PLC 连接超时 (1 秒未响应)"); } return await openTask; } public Task CloseAsync() { var code = _mc.Close(); _mc.Dispose(); return Task.FromResult(code); } public async Task ReadBytesAsync(int address, int length) { var code = await _mc.ReadDeviceBlock(Mitsubishi.PlcDeviceType.D, address, length / 2); return code; } public async Task ReadShortsAsync(int address, int length) { var code = await _mc.ReadDeviceBlock(Mitsubishi.PlcDeviceType.D, address, length); if (code is null || code.Length < length * 2) throw new Exception("read short error"); var shorts = new short[length]; Buffer.BlockCopy(code, 0, shorts, 0, code.Length); return shorts; } public async Task WriteShortsAsync(int address, params short[] values) { var code = await _mc.WriteDeviceBlock(Mitsubishi.PlcDeviceType.D, address, values.Length, values.SelectMany(BitConverter.GetBytes).ToArray()); } public async Task WriteBytesAsync(int address, byte[] data) { var code = await _mc.WriteDeviceBlock(Mitsubishi.PlcDeviceType.D, address, data.Length / 2, data); } public async Task ReadStringAsync(int address) { const int fixedLength = 20; // 调用 ReadBytesAsync 方法读取字节数据,固定长度为 10 byte[] bytes = await ReadBytesAsync(address, fixedLength); // 将字节数组使用 ASCII 编码转换为字符串 string result = System.Text.Encoding.ASCII.GetString(bytes); // 去除字符串末尾可能存在的空字符 return result.TrimEnd('\0'); } public async Task WriteStringAsync(int address, string value) { const int fixedLength = 10; // 将字符串使用 ASCII 编码转换为字节数组 byte[] bytes = System.Text.Encoding.ASCII.GetBytes(value); // 确保字节数组长度为 10 byte[] fixedLengthBytes = new byte[fixedLength*2]; Array.Copy(bytes, fixedLengthBytes, Math.Min(bytes.Length, fixedLength*2)); // 调用 WriteBytesAsync 方法写入字节数组 await WriteBytesAsync(address, fixedLengthBytes); } }