Dreamine.PLC.Omron.CxComponent 1.0.1
Dreamine.PLC.Omron.CxComponent 산업 자동화 및 I/O 기능을 제공합니다.
로딩중...
검색중...
일치하는것 없음
OmronCxComponentPlcClient.cs
이 파일의 문서화 페이지로 가기
1using System.Globalization;
2using System.Runtime.InteropServices;
3using Dreamine.PLC.Abstractions.Devices;
4using Dreamine.PLC.Abstractions.Results;
5using Dreamine.PLC.Core.Clients;
9
11
20public sealed class OmronCxComponentPlcClient : PlcClientBase
21{
39 private readonly IComObjectFactory _factory;
48 private object? _component;
49
75 : this(options, new DefaultComObjectFactory())
76 {
77 }
78
112 {
113 _options = options ?? throw new ArgumentNullException(nameof(options));
114 _factory = factory ?? throw new ArgumentNullException(nameof(factory));
115 }
116
126
175 protected override Task<PlcResult> ConnectCoreAsync(CancellationToken cancellationToken)
176 {
177 cancellationToken.ThrowIfCancellationRequested();
178
179 _component = _factory.Create(_options.ProgId);
180 TrySetProperty(_component, _options.PeerAddressPropertyName, _options.PeerAddress);
181 ComInvoker.SetProperty(_component, _options.ActivePropertyName, true);
182
183 return Task.FromResult(PlcResult.Success());
184 }
185
226 protected override Task<PlcResult> DisconnectCoreAsync(CancellationToken cancellationToken)
227 {
228 cancellationToken.ThrowIfCancellationRequested();
229
230 if (_component is null)
231 {
232 return Task.FromResult(PlcResult.Success());
233 }
234
235 TrySetProperty(_component, _options.ActivePropertyName, false);
237 return Task.FromResult(PlcResult.Success());
238 }
239
296 protected override Task<PlcResult<bool[]>> ReadBitsCoreAsync(
297 PlcAddress address,
298 int count,
299 CancellationToken cancellationToken)
300 {
301 var component = RequireComponent();
302 var values = new bool[count];
303
304 try
305 {
306 for (var index = 0; index < count; index++)
307 {
308 cancellationToken.ThrowIfCancellationRequested();
309
310 var raw = ComInvoker.Invoke(
311 component,
312 _options.ReadVariableMethodName,
314
315 values[index] = Convert.ToInt32(raw, CultureInfo.InvariantCulture) != 0;
316 }
317 }
318 catch (Exception ex) when (ex is not OperationCanceledException)
319 {
320 return Task.FromResult(PlcResult<bool[]>.Failure($"CX-Compolet bit read failed. {ex.Message}"));
321 }
322
323 return Task.FromResult(PlcResult<bool[]>.Success(values));
324 }
325
382 protected override Task<PlcResult<short[]>> ReadWordsCoreAsync(
383 PlcAddress address,
384 int count,
385 CancellationToken cancellationToken)
386 {
387 var component = RequireComponent();
388 var values = new short[count];
389
390 try
391 {
392 for (var index = 0; index < count; index++)
393 {
394 cancellationToken.ThrowIfCancellationRequested();
395
396 var raw = ComInvoker.Invoke(
397 component,
398 _options.ReadVariableMethodName,
400
401 values[index] = Convert.ToInt16(raw, CultureInfo.InvariantCulture);
402 }
403 }
404 catch (Exception ex) when (ex is not OperationCanceledException)
405 {
406 return Task.FromResult(PlcResult<short[]>.Failure($"CX-Compolet word read failed. {ex.Message}"));
407 }
408
409 return Task.FromResult(PlcResult<short[]>.Success(values));
410 }
411
468 protected override Task<PlcResult> WriteBitsCoreAsync(
469 PlcAddress address,
470 IReadOnlyList<bool> values,
471 CancellationToken cancellationToken)
472 {
473 var component = RequireComponent();
474
475 try
476 {
477 for (var index = 0; index < values.Count; index++)
478 {
479 cancellationToken.ThrowIfCancellationRequested();
480
481 ComInvoker.Invoke(
482 component,
483 _options.WriteVariableMethodName,
485 values[index] ? 1 : 0);
486 }
487 }
488 catch (Exception ex) when (ex is not OperationCanceledException)
489 {
490 return Task.FromResult(PlcResult.Failure($"CX-Compolet bit write failed. {ex.Message}"));
491 }
492
493 return Task.FromResult(PlcResult.Success());
494 }
495
552 protected override Task<PlcResult> WriteWordsCoreAsync(
553 PlcAddress address,
554 IReadOnlyList<short> values,
555 CancellationToken cancellationToken)
556 {
557 var component = RequireComponent();
558
559 try
560 {
561 for (var index = 0; index < values.Count; index++)
562 {
563 cancellationToken.ThrowIfCancellationRequested();
564
565 ComInvoker.Invoke(
566 component,
567 _options.WriteVariableMethodName,
569 values[index]);
570 }
571 }
572 catch (Exception ex) when (ex is not OperationCanceledException)
573 {
574 return Task.FromResult(PlcResult.Failure($"CX-Compolet word write failed. {ex.Message}"));
575 }
576
577 return Task.FromResult(PlcResult.Success());
578 }
579
596 public override async ValueTask DisposeAsync()
597 {
598 await base.DisposeAsync().ConfigureAwait(false);
600 }
601
642 private static void TrySetProperty(object target, string name, object? value)
643 {
644 try
645 {
646 ComInvoker.SetProperty(target, name, value);
647 }
648 catch (MissingMethodException)
649 {
650 // CX-Compolet controls vary by PLC family; optional properties are intentionally ignored.
651 }
652 }
653
678 private object RequireComponent()
679 {
680 return _component ?? throw new InvalidOperationException("CX-Compolet is not connected.");
681 }
682
691 private void ReleaseComponent()
692 {
693 if (_component is null)
694 {
695 return;
696 }
697
698 if (OperatingSystem.IsWindows() && Marshal.IsComObject(_component))
699 {
700 Marshal.FinalReleaseComObject(_component);
701 }
702
703 _component = null;
704 }
705}
OmronCxComponentPlcClient(OmronCxComponentOptions options, IComObjectFactory factory)
override Task< PlcResult > WriteWordsCoreAsync(PlcAddress address, IReadOnlyList< short > values, CancellationToken cancellationToken)
override Task< PlcResult< bool[]> > ReadBitsCoreAsync(PlcAddress address, int count, CancellationToken cancellationToken)
static void TrySetProperty(object target, string name, object? value)
override Task< PlcResult > ConnectCoreAsync(CancellationToken cancellationToken)
override Task< PlcResult< short[]> > ReadWordsCoreAsync(PlcAddress address, int count, CancellationToken cancellationToken)
override Task< PlcResult > WriteBitsCoreAsync(PlcAddress address, IReadOnlyList< bool > values, CancellationToken cancellationToken)
override Task< PlcResult > DisconnectCoreAsync(CancellationToken cancellationToken)