1using Dreamine.PLC.Abstractions.Clients;
2using Dreamine.PLC.Abstractions.Connections;
3using Dreamine.PLC.Abstractions.Devices;
4using Dreamine.PLC.Abstractions.Results;
56 public PlcConnectionState
State {
get;
private set; } = PlcConnectionState.Disconnected;
108 public async Task<PlcResult>
ConnectAsync(CancellationToken cancellationToken =
default)
110 using (await
_syncLock.LockAsync(cancellationToken).ConfigureAwait(
false))
114 if (
State == PlcConnectionState.Connected)
116 return PlcResult.Success();
119 SetState(PlcConnectionState.Connecting);
123 var result = await
ConnectCoreAsync(cancellationToken).ConfigureAwait(
false);
126 ? PlcConnectionState.Connected
127 : PlcConnectionState.Faulted);
131 catch (OperationCanceledException ex)
133 SetState(PlcConnectionState.Disconnected);
134 return PlcResult.Failure(ex.Message);
138 SetState(PlcConnectionState.Faulted);
139 return PlcResult.Failure(ex.Message);
176 public async Task<PlcResult>
DisconnectAsync(CancellationToken cancellationToken =
default)
178 using (await
_syncLock.LockAsync(cancellationToken).ConfigureAwait(
false))
182 return PlcResult.Success();
185 var previousState =
State;
186 SetState(PlcConnectionState.Disconnecting);
192 SetState(PlcConnectionState.Disconnected);
195 catch (OperationCanceledException ex)
198 return PlcResult.Failure(ex.Message);
202 SetState(PlcConnectionState.Faulted);
203 return PlcResult.Failure(ex.Message);
257 CancellationToken cancellationToken =
default)
262 if (!validationResult.IsSuccess)
264 return PlcResult<bool[]>.Failure(validationResult.Message ??
"Invalid PLC bit read request.", validationResult.ErrorCode);
267 if (
State != PlcConnectionState.Connected)
269 return PlcResult<bool[]>.Failure(
"The PLC client is not connected.");
274 return await
ReadBitsCoreAsync(address, count, cancellationToken).ConfigureAwait(
false);
276 catch (OperationCanceledException ex)
278 return PlcResult<bool[]>.Failure(ex.Message);
282 SetState(PlcConnectionState.Faulted);
283 return PlcResult<bool[]>.Failure(ex.Message);
336 CancellationToken cancellationToken =
default)
341 if (!validationResult.IsSuccess)
343 return PlcResult<short[]>.Failure(validationResult.Message ??
"Invalid PLC word read request.", validationResult.ErrorCode);
346 if (
State != PlcConnectionState.Connected)
348 return PlcResult<short[]>.Failure(
"The PLC client is not connected.");
353 return await
ReadWordsCoreAsync(address, count, cancellationToken).ConfigureAwait(
false);
355 catch (OperationCanceledException ex)
357 return PlcResult<short[]>.Failure(ex.Message);
361 SetState(PlcConnectionState.Faulted);
362 return PlcResult<short[]>.Failure(ex.Message);
414 IReadOnlyList<bool> values,
415 CancellationToken cancellationToken =
default)
420 if (!validationResult.IsSuccess)
422 return validationResult;
425 if (
State != PlcConnectionState.Connected)
427 return PlcResult.Failure(
"The PLC client is not connected.");
432 return await
WriteBitsCoreAsync(address, values, cancellationToken).ConfigureAwait(
false);
434 catch (OperationCanceledException ex)
436 return PlcResult.Failure(ex.Message);
440 SetState(PlcConnectionState.Faulted);
441 return PlcResult.Failure(ex.Message);
493 IReadOnlyList<short> values,
494 CancellationToken cancellationToken =
default)
499 if (!validationResult.IsSuccess)
501 return validationResult;
504 if (
State != PlcConnectionState.Connected)
506 return PlcResult.Failure(
"The PLC client is not connected.");
511 return await
WriteWordsCoreAsync(address, values, cancellationToken).ConfigureAwait(
false);
513 catch (OperationCanceledException ex)
515 return PlcResult.Failure(ex.Message);
519 SetState(PlcConnectionState.Faulted);
520 return PlcResult.Failure(ex.Message);
542 if (Interlocked.CompareExchange(ref
_disposeGuard, 1, 0) != 0)
553 using (await
_syncLock.LockAsync(CancellationToken.None).ConfigureAwait(
false))
555 if (
State is not (PlcConnectionState.Disconnected or PlcConnectionState.Disconnecting))
557 SetState(PlcConnectionState.Disconnecting);
568 SetState(PlcConnectionState.Disconnected);
577 GC.SuppressFinalize(
this);
670 CancellationToken cancellationToken);
712 CancellationToken cancellationToken);
753 IReadOnlyList<bool> values,
754 CancellationToken cancellationToken);
795 IReadOnlyList<short> values,
796 CancellationToken cancellationToken);
857 if (!addressResult.IsSuccess)
859 return addressResult;
897 if (!addressResult.IsSuccess)
899 return addressResult;
937 if (!addressResult.IsSuccess)
939 return addressResult;
963 ObjectDisposedException.ThrowIf(
_disposed, GetType().Name);
async Task< PlcResult > DisconnectAsync(CancellationToken cancellationToken=default)
Task< PlcResult > WriteBitsCoreAsync(PlcAddress address, IReadOnlyList< bool > values, CancellationToken cancellationToken)
readonly AsyncLock _syncLock
async Task< PlcResult > WriteBitsAsync(PlcAddress address, IReadOnlyList< bool > values, CancellationToken cancellationToken=default)
Task< PlcResult > ConnectCoreAsync(CancellationToken cancellationToken)
Task< PlcResult< short[]> > ReadWordsCoreAsync(PlcAddress address, int count, CancellationToken cancellationToken)
async Task< PlcResult< short[]> > ReadWordsAsync(PlcAddress address, int count, CancellationToken cancellationToken=default)
static PlcResult ValidateReadRequest(PlcAddress address, int count)
async Task< PlcResult< bool[]> > ReadBitsAsync(PlcAddress address, int count, CancellationToken cancellationToken=default)
async Task< PlcResult > WriteWordsAsync(PlcAddress address, IReadOnlyList< short > values, CancellationToken cancellationToken=default)
Task< PlcResult< bool[]> > ReadBitsCoreAsync(PlcAddress address, int count, CancellationToken cancellationToken)
virtual async ValueTask DisposeAsync()
async Task< PlcResult > ConnectAsync(CancellationToken cancellationToken=default)
void SetState(PlcConnectionState state)
EventHandler< PlcConnectionState >? StateChanged
Task< PlcResult > WriteWordsCoreAsync(PlcAddress address, IReadOnlyList< short > values, CancellationToken cancellationToken)
static PlcResult ValidateWriteWordRequest(PlcAddress address, IReadOnlyList< short > values)
Task< PlcResult > DisconnectCoreAsync(CancellationToken cancellationToken)
static PlcResult ValidateWriteBitRequest(PlcAddress address, IReadOnlyList< bool > values)
static PlcResult ValidateAddress(PlcAddress address)
static PlcResult ValidateBitValues(IReadOnlyList< bool > values)
static PlcResult ValidateCount(int count)
static PlcResult ValidateWordValues(IReadOnlyList< short > values)