mirror of
https://github.com/evopro-ag/Sharp7Reactive.git
synced 2025-12-16 19:52:53 +00:00
Make .TriggerConnection void and extend xml docs
This commit is contained in:
@@ -116,12 +116,11 @@ internal class Sharp7Connector : IDisposable
|
|||||||
return buffers.ToDictionary(arg => arg.VariableName, arg => arg.Buffer);
|
return buffers.ToDictionary(arg => arg.VariableName, arg => arg.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task InitializeAsync()
|
public void InitializeAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sharp7 = new S7Client();
|
sharp7 = new S7Client {PLCPort = port};
|
||||||
sharp7.PLCPort = port;
|
|
||||||
|
|
||||||
var subscription =
|
var subscription =
|
||||||
ConnectionState
|
ConnectionState
|
||||||
@@ -138,8 +137,6 @@ internal class Sharp7Connector : IDisposable
|
|||||||
{
|
{
|
||||||
Logger?.LogError(ex, "S7 driver for {Connection} could not be initialized", ConnectionIdentifier);
|
Logger?.LogError(ex, "S7 driver for {Connection} could not be initialized", ConnectionIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte[]> ReadBytes(Operand operand, ushort startByteAddress, ushort bytesToRead, ushort dbNo, CancellationToken token)
|
public async Task<byte[]> ReadBytes(Operand operand, ushort startByteAddress, ushort bytesToRead, ushort dbNo, CancellationToken token)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class Sharp7Plc : IPlc
|
|||||||
private readonly ConcurrentSubjectDictionary<string, byte[]> multiVariableSubscriptions = new(StringComparer.InvariantCultureIgnoreCase);
|
private readonly ConcurrentSubjectDictionary<string, byte[]> multiVariableSubscriptions = new(StringComparer.InvariantCultureIgnoreCase);
|
||||||
private readonly List<long> performanceCounter = new(1000);
|
private readonly List<long> performanceCounter = new(1000);
|
||||||
private readonly PlcConnectionSettings plcConnectionSettings;
|
private readonly PlcConnectionSettings plcConnectionSettings;
|
||||||
private readonly CacheVariableNameParser variableNameParser = new CacheVariableNameParser(new VariableNameParser());
|
private readonly CacheVariableNameParser variableNameParser = new(new VariableNameParser());
|
||||||
private bool disposed;
|
private bool disposed;
|
||||||
private int initialized;
|
private int initialized;
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ public class Sharp7Plc : IPlc
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ipAddress"></param>
|
/// <param name="ipAddress">IP address of S7.</param>
|
||||||
/// <param name="rackNumber"></param>
|
/// <param name="rackNumber">See <see href="https://github.com/fbarresi/Sharp7/wiki/Connection#rack-and-slot">Sharp7 wiki</see></param>
|
||||||
/// <param name="cpuMpiAddress"></param>
|
/// <param name="cpuMpiAddress">See <see href="https://github.com/fbarresi/Sharp7/wiki/Connection#rack-and-slot">Sharp7 wiki</see></param>
|
||||||
/// <param name="port"></param>
|
/// <param name="port">TCP port for communication</param>
|
||||||
/// <param name="multiVarRequestCycleTime">
|
/// <param name="multiVarRequestCycleTime">
|
||||||
/// <para>
|
/// <para>
|
||||||
/// Polling interval for multi variable read from PLC.
|
/// Polling interval for multi variable read from PLC.
|
||||||
@@ -90,10 +90,6 @@ public class Sharp7Plc : IPlc
|
|||||||
/// Create an Observable for a given variable. Multiple notifications are automatically combined into a multi-variable subscription to
|
/// Create an Observable for a given variable. Multiple notifications are automatically combined into a multi-variable subscription to
|
||||||
/// reduce network trafic and PLC workload.
|
/// reduce network trafic and PLC workload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TValue"></typeparam>
|
|
||||||
/// <param name="variableName"></param>
|
|
||||||
/// <param name="transmissionMode"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IObservable<TValue> CreateNotification<TValue>(string variableName, TransmissionMode transmissionMode)
|
public IObservable<TValue> CreateNotification<TValue>(string variableName, TransmissionMode transmissionMode)
|
||||||
{
|
{
|
||||||
return Observable.Create<TValue>(observer =>
|
return Observable.Create<TValue>(observer =>
|
||||||
@@ -128,12 +124,28 @@ public class Sharp7Plc : IPlc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read PLC variable as generic variable.
|
/// Creates an observable of object for a variable.
|
||||||
|
/// The return type is automatically infered from the variable name.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The return type is infered from the variable name.</returns>
|
||||||
|
public IObservable<object> CreateNotification(string variableName, TransmissionMode transmissionMode)
|
||||||
|
{
|
||||||
|
var address = variableNameParser.Parse(variableName);
|
||||||
|
var clrType = address.GetClrType();
|
||||||
|
|
||||||
|
var genericCreateNotification = createNotificationMethod!.MakeGenericMethod(clrType);
|
||||||
|
|
||||||
|
var genericNotification = genericCreateNotification.Invoke(this, [variableName, transmissionMode]);
|
||||||
|
|
||||||
|
return SignatureConverter.ConvertToObjectObservable(genericNotification, clrType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read PLC variable as generic variable.
|
||||||
|
/// <para>
|
||||||
|
/// The method will fail with a <see cref="InvalidOperationException" />, if <see cref="ConnectionState" /> is not <see cref="ConnectionState.Connected" />.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TValue"></typeparam>
|
|
||||||
/// <param name="variableName"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<TValue> GetValue<TValue>(string variableName, CancellationToken token = default)
|
public async Task<TValue> GetValue<TValue>(string variableName, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var address = ParseAndVerify(variableName, typeof(TValue));
|
var address = ParseAndVerify(variableName, typeof(TValue));
|
||||||
@@ -145,9 +157,10 @@ public class Sharp7Plc : IPlc
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read PLC variable as object.
|
/// Read PLC variable as object.
|
||||||
/// The return type is automatically infered from the variable name.
|
/// The return type is automatically infered from the variable name.
|
||||||
|
/// <para>
|
||||||
|
/// The method will fail with a <see cref="InvalidOperationException" />, if <see cref="ConnectionState" /> is not <see cref="ConnectionState.Connected" />.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="variableName"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns>The actual return type is infered from the variable name.</returns>
|
/// <returns>The actual return type is infered from the variable name.</returns>
|
||||||
public async Task<object> GetValue(string variableName, CancellationToken token = default)
|
public async Task<object> GetValue(string variableName, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -168,12 +181,10 @@ public class Sharp7Plc : IPlc
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write value to the PLC.
|
/// Write value to the PLC.
|
||||||
|
/// <para>
|
||||||
|
/// The method will fail with a <see cref="InvalidOperationException" />, if <see cref="ConnectionState" /> is not <see cref="ConnectionState.Connected" />.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TValue"></typeparam>
|
|
||||||
/// <param name="variableName"></param>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task SetValue<TValue>(string variableName, TValue value, CancellationToken token = default)
|
public async Task SetValue<TValue>(string variableName, TValue value, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var address = ParseAndVerify(variableName, typeof(TValue));
|
var address = ParseAndVerify(variableName, typeof(TValue));
|
||||||
@@ -201,25 +212,6 @@ public class Sharp7Plc : IPlc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an observable of object for a variable.
|
|
||||||
/// The return type is automatically infered from the variable name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variableName"></param>
|
|
||||||
/// <param name="transmissionMode"></param>
|
|
||||||
/// <returns>The return type is infered from the variable name.</returns>
|
|
||||||
public IObservable<object> CreateNotification(string variableName, TransmissionMode transmissionMode)
|
|
||||||
{
|
|
||||||
var address = variableNameParser.Parse(variableName);
|
|
||||||
var clrType = address.GetClrType();
|
|
||||||
|
|
||||||
var genericCreateNotification = createNotificationMethod!.MakeGenericMethod(clrType);
|
|
||||||
|
|
||||||
var genericNotification = genericCreateNotification.Invoke(this, [variableName, transmissionMode]);
|
|
||||||
|
|
||||||
return SignatureConverter.ConvertToObjectObservable(genericNotification, clrType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trigger PLC connection and start notification loop.
|
/// Trigger PLC connection and start notification loop.
|
||||||
/// <para>
|
/// <para>
|
||||||
@@ -228,26 +220,35 @@ public class Sharp7Plc : IPlc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Always true</returns>
|
/// <returns>Always true</returns>
|
||||||
[Obsolete($"Use {nameof(InitializeConnection)} or {nameof(TriggerConnection)}.")]
|
[Obsolete($"Use {nameof(InitializeConnection)} or {nameof(TriggerConnection)}.")]
|
||||||
public async Task<bool> InitializeAsync()
|
public Task<bool> InitializeAsync()
|
||||||
{
|
{
|
||||||
await TriggerConnection();
|
TriggerConnection();
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize PLC connection and wait for connection to be established.
|
/// Initialize PLC connection and wait for connection to be established (<see cref="ConnectionState" /> is <see cref="ConnectionState.Connected" />).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task InitializeConnection(CancellationToken token = default) => await DoInitializeConnection(true, token);
|
public async Task InitializeConnection(CancellationToken token = default)
|
||||||
|
{
|
||||||
|
DoInitializeConnection();
|
||||||
|
await s7Connector.ConnectionState
|
||||||
|
.FirstAsync(c => c == Enums.ConnectionState.Connected)
|
||||||
|
.ToTask(token);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize PLC and trigger connection. This method will not wait for the connection to be established.
|
/// Initialize PLC and trigger connection. This method will not wait for the connection to be established.
|
||||||
|
/// <para>
|
||||||
|
/// Without an established connection, it is safe to call <see cref="CreateNotification" />, but <see cref="GetValue{TValue}" />
|
||||||
|
/// and <see cref="SetValue{TValue}" /> will fail.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task TriggerConnection(CancellationToken token = default) => await DoInitializeConnection(false, token);
|
public void TriggerConnection() => DoInitializeConnection();
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
@@ -270,11 +271,12 @@ public class Sharp7Plc : IPlc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DoInitializeConnection(bool waitForConnection, CancellationToken token)
|
private void DoInitializeConnection()
|
||||||
{
|
{
|
||||||
if (Interlocked.Exchange(ref initialized, 1) == 1) return;
|
if (Interlocked.Exchange(ref initialized, 1) == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
await s7Connector.InitializeAsync();
|
s7Connector.InitializeAsync();
|
||||||
|
|
||||||
// Triger connection.
|
// Triger connection.
|
||||||
// The initial connection might fail. In this case a reconnect is initiated.
|
// The initial connection might fail. In this case a reconnect is initiated.
|
||||||
@@ -285,16 +287,11 @@ public class Sharp7Plc : IPlc
|
|||||||
{
|
{
|
||||||
await s7Connector.Connect();
|
await s7Connector.Connect();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// Ignore. Exception is logged in the connector
|
// Ignore. Exception is logged in the connector
|
||||||
}
|
}
|
||||||
}, token);
|
});
|
||||||
|
|
||||||
if (waitForConnection)
|
|
||||||
await s7Connector.ConnectionState
|
|
||||||
.FirstAsync(c => c == Enums.ConnectionState.Connected)
|
|
||||||
.ToTask(token);
|
|
||||||
|
|
||||||
StartNotificationLoop();
|
StartNotificationLoop();
|
||||||
}
|
}
|
||||||
@@ -370,9 +367,4 @@ public class Sharp7Plc : IPlc
|
|||||||
// Subscription has already been created (race condition). Dispose new subscription.
|
// Subscription has already been created (race condition). Dispose new subscription.
|
||||||
subscription.Dispose();
|
subscription.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
~Sharp7Plc()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user