Dreamine.PLC.Mitsubishi.MC 1.0.1
Dreamine.PLC.Mitsubishi.MC 산업 자동화 및 I/O 기능을 제공합니다.
로딩중...
검색중...
일치하는것 없음
MitsubishiMcBinary3EFrameBuilder.cs
이 파일의 문서화 페이지로 가기
1using Dreamine.PLC.Abstractions.Devices;
2using Dreamine.PLC.Abstractions.Results;
5
7
17{
26 private const ushort SubHeader = 0x5000;
36
49
75 {
76 _deviceCodeMapper = deviceCodeMapper ?? throw new ArgumentNullException(nameof(deviceCodeMapper));
77 }
78
145 public PlcResult<byte[]> BuildBatchReadFrame(
147 PlcAddress address,
148 int count,
149 bool isBitAccess)
150 {
151 ArgumentNullException.ThrowIfNull(options);
152
153 if (count <= 0)
154 {
155 return PlcResult<byte[]>.Failure("The read count must be greater than zero.");
156 }
157
158 var deviceCodeResult = _deviceCodeMapper.Map(address.DeviceType);
159 if (!deviceCodeResult.IsSuccess)
160 {
161 return PlcResult<byte[]>.Failure(
162 deviceCodeResult.Message ?? "Unsupported Mitsubishi MC device type.",
163 deviceCodeResult.ErrorCode);
164 }
165
166 var payload = BuildBatchAccessPayload(
167 MitsubishiMcCommand.BatchRead,
168 isBitAccess ? MitsubishiMcSubCommand.Bit : MitsubishiMcSubCommand.Word,
169 address,
170 count,
171 deviceCodeResult.Value);
172
173 return PlcResult<byte[]>.Success(BuildFrame(options, payload));
174 }
175
235 public PlcResult<byte[]> BuildBatchWriteWordsFrame(
237 PlcAddress address,
238 IReadOnlyList<short> values)
239 {
240 ArgumentNullException.ThrowIfNull(options);
241 ArgumentNullException.ThrowIfNull(values);
242
243 if (values.Count == 0)
244 {
245 return PlcResult<byte[]>.Failure("The word value collection must not be empty.");
246 }
247
248 var deviceCodeResult = _deviceCodeMapper.Map(address.DeviceType);
249 if (!deviceCodeResult.IsSuccess)
250 {
251 return PlcResult<byte[]>.Failure(
252 deviceCodeResult.Message ?? "Unsupported Mitsubishi MC device type.",
253 deviceCodeResult.ErrorCode);
254 }
255
256 var payload = BuildBatchAccessPayload(
257 MitsubishiMcCommand.BatchWrite,
259 address,
260 values.Count,
261 deviceCodeResult.Value);
262
263 foreach (var value in values)
264 {
265 MitsubishiMcEndian.WriteUInt16LittleEndian(payload, unchecked((ushort)value));
266 }
267
268 return PlcResult<byte[]>.Success(BuildFrame(options, payload));
269 }
270
330 public PlcResult<byte[]> BuildBatchWriteBitsFrame(
332 PlcAddress address,
333 IReadOnlyList<bool> values)
334 {
335 ArgumentNullException.ThrowIfNull(options);
336 ArgumentNullException.ThrowIfNull(values);
337
338 if (values.Count == 0)
339 {
340 return PlcResult<byte[]>.Failure("The bit value collection must not be empty.");
341 }
342
343 var deviceCodeResult = _deviceCodeMapper.Map(address.DeviceType);
344 if (!deviceCodeResult.IsSuccess)
345 {
346 return PlcResult<byte[]>.Failure(
347 deviceCodeResult.Message ?? "Unsupported Mitsubishi MC device type.",
348 deviceCodeResult.ErrorCode);
349 }
350
351 var payload = BuildBatchAccessPayload(
352 MitsubishiMcCommand.BatchWrite,
354 address,
355 values.Count,
356 deviceCodeResult.Value);
357
358 for (var i = 0; i < values.Count; i += 2)
359 {
360 var high = values[i] ? 0x10 : 0x00;
361 var low = i + 1 < values.Count && values[i + 1] ? 0x01 : 0x00;
362
363 payload.Add((byte)(high | low));
364 }
365
366 return PlcResult<byte[]>.Success(BuildFrame(options, payload));
367 }
368
420 private static List<byte> BuildBatchAccessPayload(
421 MitsubishiMcCommand command,
422 MitsubishiMcSubCommand subCommand,
423 PlcAddress address,
424 int count,
425 MitsubishiMcDeviceCode deviceCode)
426 {
427 const int batchAccessHeaderLength = 10;
428 var payload = new List<byte>(batchAccessHeaderLength);
429
430 MitsubishiMcEndian.WriteUInt16LittleEndian(payload, (ushort)command);
431 MitsubishiMcEndian.WriteUInt16LittleEndian(payload, (ushort)subCommand);
432 MitsubishiMcEndian.WriteUInt24LittleEndian(payload, address.Offset);
433 payload.Add((byte)deviceCode);
434 MitsubishiMcEndian.WriteUInt16LittleEndian(payload, checked((ushort)count));
435
436 return payload;
437 }
438
469 private static byte[] BuildFrame(
471 IReadOnlyCollection<byte> payload)
472 {
473 const int frameHeaderLength = 11;
474 var frame = new List<byte>(frameHeaderLength + payload.Count);
475
477 frame.Add(options.NetworkNumber);
478 frame.Add(options.PlcNumber);
480 frame.Add(options.DestinationModuleStationNumber);
481
482 var requestDataLength = checked((ushort)(payload.Count + 2));
483 MitsubishiMcEndian.WriteUInt16LittleEndian(frame, requestDataLength);
485
486 frame.AddRange(payload);
487
488 return frame.ToArray();
489 }
490}
static List< byte > BuildBatchAccessPayload(MitsubishiMcCommand command, MitsubishiMcSubCommand subCommand, PlcAddress address, int count, MitsubishiMcDeviceCode deviceCode)
static byte[] BuildFrame(MitsubishiMcConnectionOptions options, IReadOnlyCollection< byte > payload)
PlcResult< byte[]> BuildBatchWriteWordsFrame(MitsubishiMcConnectionOptions options, PlcAddress address, IReadOnlyList< short > values)
PlcResult< byte[]> BuildBatchWriteBitsFrame(MitsubishiMcConnectionOptions options, PlcAddress address, IReadOnlyList< bool > values)
PlcResult< byte[]> BuildBatchReadFrame(MitsubishiMcConnectionOptions options, PlcAddress address, int count, bool isBitAccess)
static void WriteUInt16LittleEndian(ICollection< byte > buffer, ushort value)
static void WriteUInt24LittleEndian(ICollection< byte > buffer, int value)