Add non-generic CreateNotification method

This commit is contained in:
Peter Butzhammer
2024-04-26 10:45:14 +02:00
parent 6917295cf1
commit 57ff276489
4 changed files with 54 additions and 8 deletions

View File

@@ -1,5 +1,4 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Sharp7.Rx.Enums;
namespace Sharp7.Rx.Interfaces;
@@ -7,12 +6,13 @@ namespace Sharp7.Rx.Interfaces;
[NoReorder]
public interface IPlc : IDisposable
{
IObservable<TValue> CreateNotification<TValue>(string variableName, TransmissionMode transmissionMode);
Task SetValue<TValue>(string variableName, TValue value, CancellationToken token = default);
Task<TValue> GetValue<TValue>(string variableName, CancellationToken token = default);
IObservable<ConnectionState> ConnectionState { get; }
Task SetValue<TValue>(string variableName, TValue value, CancellationToken token = default);
Task<TValue> GetValue<TValue>(string variableName, CancellationToken token = default);
Task<object> GetValue(string variableName, CancellationToken token = default);
ILogger Logger { get; }
IObservable<TValue> CreateNotification<TValue>(string variableName, TransmissionMode transmissionMode);
IObservable<object> CreateNotification(string variableName, TransmissionMode transmissionMode);
}

View File

@@ -36,7 +36,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>

View File

@@ -11,6 +11,7 @@ using Sharp7.Rx.Enums;
using Sharp7.Rx.Extensions;
using Sharp7.Rx.Interfaces;
using Sharp7.Rx.Settings;
using Sharp7.Rx.Utils;
namespace Sharp7.Rx;
@@ -21,13 +22,17 @@ public class Sharp7Plc : IPlc
private static readonly MethodInfo getValueMethod = typeof(Sharp7Plc).GetMethods()
.Single(m => m.Name == nameof(GetValue) && m.GetGenericArguments().Length == 1);
private IDisposable notificationSubscription;
private static readonly MethodInfo createNotificationMethod = typeof(Sharp7Plc).GetMethods()
.Single(m => m.Name == nameof(CreateNotification) && m.GetGenericArguments().Length == 1);
private readonly ConcurrentSubjectDictionary<string, byte[]> multiVariableSubscriptions = new(StringComparer.InvariantCultureIgnoreCase);
private readonly List<long> performanceCounter = new(1000);
private readonly PlcConnectionSettings plcConnectionSettings;
private readonly CacheVariableNameParser variableNameParser = new CacheVariableNameParser(new VariableNameParser());
private bool disposed;
private int initialized;
private IDisposable notificationSubscription;
private Sharp7Connector s7Connector;
/// <summary>
@@ -135,10 +140,11 @@ public class Sharp7Plc : IPlc
/// <summary>
/// Read PLC variable as object.
/// The return type is automatically infered from the variable name.
/// </summary>
/// <param name="variableName"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <returns>The actual return type is infered from the variable name.</returns>
public async Task<object> GetValue(string variableName, CancellationToken token = default)
{
var address = variableNameParser.Parse(variableName);
@@ -191,6 +197,25 @@ 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>
/// Trigger PLC connection and start notification loop.
/// <para>

View File

@@ -0,0 +1,21 @@
using System.Reactive.Linq;
using System.Reflection;
namespace Sharp7.Rx.Utils;
internal static class SignatureConverter
{
private static readonly MethodInfo convertToObjectObservableMethod =
typeof(SignatureConverter)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(m => m.Name == nameof(ConvertToObjectObservable) && m.GetGenericArguments().Length == 1);
public static IObservable<object> ConvertToObjectObservable<T>(IObservable<T> obs) => obs.Select(o => (object) o);
public static IObservable<object> ConvertToObjectObservable(object observable, Type sourceType)
{
var convertGeneric = convertToObjectObservableMethod.MakeGenericMethod(sourceType);
return convertGeneric.Invoke(null, [observable]) as IObservable<object>;
}
}