mirror of
https://github.com/evopro-ag/Sharp7Reactive.git
synced 2025-12-16 19:52:53 +00:00
Cache S7 variable names
This commit is contained in:
20
Sharp7.Rx/CacheVariableNameParser.cs
Normal file
20
Sharp7.Rx/CacheVariableNameParser.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Sharp7.Rx.Interfaces;
|
||||||
|
|
||||||
|
namespace Sharp7.Rx
|
||||||
|
{
|
||||||
|
internal class CacheVariableNameParser : IS7VariableNameParser
|
||||||
|
{
|
||||||
|
private static readonly ConcurrentDictionary<string, S7VariableAddress> addressCache = new ConcurrentDictionary<string, S7VariableAddress>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private readonly IS7VariableNameParser inner;
|
||||||
|
|
||||||
|
public CacheVariableNameParser(IS7VariableNameParser inner)
|
||||||
|
{
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public S7VariableAddress Parse(string input) => addressCache.GetOrAdd(input, inner.Parse);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,6 @@ namespace Sharp7.Rx.Interfaces
|
|||||||
Task<bool> WriteBit(Operand operand, ushort startByteAddress, byte bitAdress, bool value, ushort dbNr, CancellationToken token);
|
Task<bool> WriteBit(Operand operand, ushort startByteAddress, byte bitAdress, bool value, ushort dbNr, CancellationToken token);
|
||||||
Task<ushort> WriteBytes(Operand operand, ushort startByteAdress, byte[] data, ushort dBNr, CancellationToken token);
|
Task<ushort> WriteBytes(Operand operand, ushort startByteAdress, byte[] data, ushort dBNr, CancellationToken token);
|
||||||
ILogger Logger { get; }
|
ILogger Logger { get; }
|
||||||
Task<Dictionary<string, byte[]>> ExecuteMultiVarRequest(IEnumerable<string> variableNames);
|
Task<Dictionary<string, byte[]>> ExecuteMultiVarRequest(IReadOnlyList<string> variableNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ namespace Sharp7.Rx
|
|||||||
{
|
{
|
||||||
private static readonly Regex regex = new Regex(@"^(?<operand>db{1})(?<dbNr>\d{1,4})\.?(?<type>dbx|x|s|string|b|dbb|d|int|dbw|w|dint|dul|dulint|dulong|){1}(?<start>\d+)(\.(?<bitOrLength>\d+))?$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
private static readonly Regex regex = new Regex(@"^(?<operand>db{1})(?<dbNr>\d{1,4})\.?(?<type>dbx|x|s|string|b|dbb|d|int|dbw|w|dint|dul|dulint|dulong|){1}(?<start>\d+)(\.(?<bitOrLength>\d+))?$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
private static readonly IReadOnlyDictionary<string, DbType> types = new Dictionary<string, DbType>(StringComparer.InvariantCultureIgnoreCase)
|
private static readonly IReadOnlyDictionary<string, DbType> types = new Dictionary<string, DbType>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
{"x", DbType.Bit},
|
{"x", DbType.Bit},
|
||||||
{"dbx", DbType.Bit},
|
{"dbx", DbType.Bit},
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace Sharp7.Rx
|
|||||||
{
|
{
|
||||||
private readonly IS7VariableNameParser variableNameParser;
|
private readonly IS7VariableNameParser variableNameParser;
|
||||||
private readonly BehaviorSubject<ConnectionState> connectionStateSubject = new BehaviorSubject<ConnectionState>(Enums.ConnectionState.Initial);
|
private readonly BehaviorSubject<ConnectionState> connectionStateSubject = new BehaviorSubject<ConnectionState>(Enums.ConnectionState.Initial);
|
||||||
private ConcurrentDictionary<string, S7VariableAddress> s7VariableAddresses = new ConcurrentDictionary<string, S7VariableAddress>();
|
|
||||||
|
|
||||||
private readonly CompositeDisposable disposables = new CompositeDisposable();
|
private readonly CompositeDisposable disposables = new CompositeDisposable();
|
||||||
private readonly LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(maxDegreeOfParallelism:1);
|
private readonly LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(maxDegreeOfParallelism:1);
|
||||||
@@ -34,16 +33,15 @@ namespace Sharp7.Rx
|
|||||||
private bool disposed;
|
private bool disposed;
|
||||||
|
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
public async Task<Dictionary<string, byte[]>> ExecuteMultiVarRequest(IEnumerable<string> variableNames)
|
public async Task<Dictionary<string, byte[]>> ExecuteMultiVarRequest(IReadOnlyList<string> variableNames)
|
||||||
{
|
{
|
||||||
var enumerable = variableNames as string[] ?? variableNames.ToArray();
|
if (variableNames.IsEmpty())
|
||||||
|
|
||||||
if (enumerable.IsEmpty())
|
|
||||||
return new Dictionary<string, byte[]>();
|
return new Dictionary<string, byte[]>();
|
||||||
|
|
||||||
var s7MultiVar = new S7MultiVar(sharp7);
|
var s7MultiVar = new S7MultiVar(sharp7);
|
||||||
|
|
||||||
var buffers = enumerable.Select(key => new {VariableName = key, Address = s7VariableAddresses.GetOrAdd(key, s => variableNameParser.Parse(s))})
|
var buffers = variableNames
|
||||||
|
.Select(key => new {VariableName = key, Address = variableNameParser.Parse(key)})
|
||||||
.Select(x =>
|
.Select(x =>
|
||||||
{
|
{
|
||||||
var buffer = new byte[x.Address.Length];
|
var buffer = new byte[x.Address.Length];
|
||||||
@@ -67,10 +65,10 @@ namespace Sharp7.Rx
|
|||||||
public Sharp7Connector(PlcConnectionSettings settings, IS7VariableNameParser variableNameParser)
|
public Sharp7Connector(PlcConnectionSettings settings, IS7VariableNameParser variableNameParser)
|
||||||
{
|
{
|
||||||
this.variableNameParser = variableNameParser;
|
this.variableNameParser = variableNameParser;
|
||||||
this.ipAddress = settings.IpAddress;
|
ipAddress = settings.IpAddress;
|
||||||
this.cpuSlotNr = settings.CpuMpiAddress;
|
cpuSlotNr = settings.CpuMpiAddress;
|
||||||
this.port = settings.Port;
|
port = settings.Port;
|
||||||
this.rackNr = settings.RackNumber;
|
rackNr = settings.RackNumber;
|
||||||
|
|
||||||
ReconnectDelay = TimeSpan.FromSeconds(5);
|
ReconnectDelay = TimeSpan.FromSeconds(5);
|
||||||
}
|
}
|
||||||
@@ -120,7 +118,7 @@ namespace Sharp7.Rx
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
sharp7 = new S7Client();
|
sharp7 = new S7Client();
|
||||||
sharp7.PLCPort = this.port;
|
sharp7.PLCPort = port;
|
||||||
|
|
||||||
var subscription =
|
var subscription =
|
||||||
ConnectionState
|
ConnectionState
|
||||||
@@ -223,7 +221,7 @@ namespace Sharp7.Rx
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
await EvaluateErrorCode(result);
|
await EvaluateErrorCode(result);
|
||||||
var errorText = this.sharp7.ErrorText(result);
|
var errorText = sharp7.ErrorText(result);
|
||||||
throw new InvalidOperationException($"Error reading {operand}{dBNr}:{startByteAddress}->{bytesToRead} ({errorText})");
|
throw new InvalidOperationException($"Error reading {operand}{dBNr}:{startByteAddress}->{bytesToRead} ({errorText})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,7 @@ namespace Sharp7.Rx
|
|||||||
{
|
{
|
||||||
public class Sharp7Plc : IPlc
|
public class Sharp7Plc : IPlc
|
||||||
{
|
{
|
||||||
private readonly string ipAddress;
|
private readonly IS7VariableNameParser varaibleNameParser = new CacheVariableNameParser(new S7VariableNameParser());
|
||||||
private readonly int rackNumber;
|
|
||||||
private readonly int cpuMpiAddress;
|
|
||||||
private readonly int port;
|
|
||||||
private readonly IS7VariableNameParser varaibleNameParser;
|
|
||||||
private bool disposed;
|
private bool disposed;
|
||||||
private ISubject<Unit> disposingSubject = new Subject<Unit>();
|
private ISubject<Unit> disposingSubject = new Subject<Unit>();
|
||||||
private IS7Connector s7Connector;
|
private IS7Connector s7Connector;
|
||||||
@@ -37,14 +33,7 @@ namespace Sharp7.Rx
|
|||||||
|
|
||||||
public Sharp7Plc(string ipAddress, int rackNumber, int cpuMpiAddress, int port = 102)
|
public Sharp7Plc(string ipAddress, int rackNumber, int cpuMpiAddress, int port = 102)
|
||||||
{
|
{
|
||||||
this.ipAddress = ipAddress;
|
|
||||||
this.rackNumber = rackNumber;
|
|
||||||
this.cpuMpiAddress = cpuMpiAddress;
|
|
||||||
this.port = port;
|
|
||||||
|
|
||||||
plcConnectionSettings = new PlcConnectionSettings(){IpAddress = ipAddress, RackNumber = rackNumber, CpuMpiAddress = cpuMpiAddress, Port = port};
|
plcConnectionSettings = new PlcConnectionSettings(){IpAddress = ipAddress, RackNumber = rackNumber, CpuMpiAddress = cpuMpiAddress, Port = port};
|
||||||
|
|
||||||
varaibleNameParser = new S7VariableNameParser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IObservable<ConnectionState> ConnectionState { get; private set; }
|
public IObservable<ConnectionState> ConnectionState { get; private set; }
|
||||||
@@ -403,7 +392,7 @@ namespace Sharp7.Rx
|
|||||||
var stopWatch = Stopwatch.StartNew();
|
var stopWatch = Stopwatch.StartNew();
|
||||||
foreach (var partsOfMultiVarRequest in multiVariableSubscriptions.ExistingKeys.Buffer(MultiVarRequestMaxItems))
|
foreach (var partsOfMultiVarRequest in multiVariableSubscriptions.ExistingKeys.Buffer(MultiVarRequestMaxItems))
|
||||||
{
|
{
|
||||||
var multiVarRequest = await connector.ExecuteMultiVarRequest(partsOfMultiVarRequest);
|
var multiVarRequest = await connector.ExecuteMultiVarRequest(partsOfMultiVarRequest as IReadOnlyList<string>??partsOfMultiVarRequest.ToList());
|
||||||
|
|
||||||
foreach (var pair in multiVarRequest)
|
foreach (var pair in multiVarRequest)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user