sync the state
This commit is contained in:
parent
ac50c18c06
commit
ef8f1cf7cc
@ -155,7 +155,7 @@
|
||||
</site>
|
||||
<site name="MeterProcessState" id="2">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\drabesch_ro\Repo\lab\la_operations\laa_production\Common\Service\MeterProcessState" />
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\SZLATEV\source\repos\laa_production\Common\Service\MeterProcessState" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:56011:localhost" />
|
||||
|
||||
@ -356,6 +356,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaPackages.HttpClient", "L
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stichproben", "Stichproben\Stichproben.csproj", "{F69A79FA-548D-4E21-887E-01FABDAD9E73}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaPackages.Features.Cordonel", "LaaPackages\LaaPackages.Features.Cordonel\LaaPackages.Features.Cordonel.csproj", "{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
Utils\DateTimeServerShared\DateTimeServerShared.projitems*{4806d89a-fbfb-41bc-aaa7-2242444bf55a}*SharedItemsImports = 4
|
||||
@ -5638,6 +5640,70 @@ Global
|
||||
{F69A79FA-548D-4E21-887E-01FABDAD9E73}.XP32bit|x64.Build.0 = Release|Any CPU
|
||||
{F69A79FA-548D-4E21-887E-01FABDAD9E73}.XP32bit|x86.ActiveCfg = Release|Any CPU
|
||||
{F69A79FA-548D-4E21-887E-01FABDAD9E73}.XP32bit|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.COM|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.PerformTest|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.ReleaseTest|x86.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|Any CPU.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|x64.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|x64.Build.0 = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|x86.ActiveCfg = Release|Any CPU
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}.XP32bit|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -5783,6 +5849,7 @@ Global
|
||||
{F90B940C-9A83-496D-AAE0-11CD02CE0A22} = {2E31C385-4FFC-473E-9C00-D7DC48140704}
|
||||
{C9816412-7752-4F7A-8BD2-765DB6D58B3C} = {2E31C385-4FFC-473E-9C00-D7DC48140704}
|
||||
{F69A79FA-548D-4E21-887E-01FABDAD9E73} = {696A94BE-7237-4AE2-9E36-6059DE519971}
|
||||
{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB} = {2E31C385-4FFC-473E-9C00-D7DC48140704}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4BCB7B69-696C-436A-86F7-C91EA5588164}
|
||||
|
||||
@ -57,11 +57,24 @@
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="configuration.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Hardware\WaterMeter\eRegister\Common.Hardware.WaterMeter.eRegister\Common.Hardware.WaterMeter.eRegister.csproj">
|
||||
<Project>{4E8BB839-D40A-488C-88CE-F21811F1F476}</Project>
|
||||
<Name>Common.Hardware.WaterMeter.eRegister</Name>
|
||||
<ProjectReference Include="..\Hardware\WaterMeter\Genesis\GenesisConfig\GenesisConfig.csproj">
|
||||
<Project>{f013a56b-7be6-4852-9cd8-b971cd1add0c}</Project>
|
||||
<Name>GenesisConfig</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Hardware\WaterMeter\Genesis\GenesisCore\GenesisCore.csproj">
|
||||
<Project>{04201e95-90a0-4b73-a72f-379739b2a3ae}</Project>
|
||||
<Name>GenesisCore</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Hardware\WaterMeter\Genesis\Registers\Registers.csproj">
|
||||
<Project>{f4aaf7e6-7333-4284-b735-e32deb076c64}</Project>
|
||||
<Name>Registers</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LaaPackages\LaaPackages.Features.Cordonel\LaaPackages.Features.Cordonel.csproj">
|
||||
<Project>{8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB}</Project>
|
||||
<Name>LaaPackages.Features.Cordonel</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Stichproben\Stichproben.csproj">
|
||||
<Project>{F69A79FA-548D-4E21-887E-01FABDAD9E73}</Project>
|
||||
|
||||
@ -1,197 +1,10 @@
|
||||
namespace CommonConsole
|
||||
{
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
using Common.Hardware.WaterMeter.eRegister.Models;
|
||||
|
||||
using Stichproben.Cordonel;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var stichproben = new Stichproben(typeof(Program).Assembly.Location);
|
||||
|
||||
var result = stichproben.ShouldBePressureTested(20250205);
|
||||
}
|
||||
|
||||
|
||||
public static void ___Main()
|
||||
{
|
||||
var features = new List<EregisterFeature>();
|
||||
|
||||
foreach (var featureInfo in typeof(EregisterFeatures).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
var featurePamAttribute = featureInfo.GetCustomAttribute<PamAttribute>();
|
||||
|
||||
if (featurePamAttribute is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var featureType = featureInfo.PropertyType;
|
||||
|
||||
if (typeof(Pam).IsAssignableFrom(featureType))
|
||||
{
|
||||
var featurePam = Activator.CreateInstance(featureType) as Pam;
|
||||
var feature = new EregisterFeature
|
||||
{
|
||||
FeatureType = featureType,
|
||||
Cmd = featurePam.CmdHex,
|
||||
IsSingleCmd = featurePamAttribute.IsSingleCmd,
|
||||
OnlyProductionMode = featurePamAttribute.OnlyProductionMode,
|
||||
AuthLevel = featurePamAttribute.AuthLevel,
|
||||
};
|
||||
|
||||
foreach (var featurePropertyInfo in feature.FeatureType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (!featurePropertyInfo.CanRead || !featureInfo.CanWrite)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
feature.Add(new EregisterFeatureProperty
|
||||
{
|
||||
Name = featurePropertyInfo.Name,
|
||||
Type = featurePropertyInfo.PropertyType,
|
||||
Getter = featurePropertyInfo.GetValue,
|
||||
Setter = featurePropertyInfo.SetValue,
|
||||
});
|
||||
}
|
||||
|
||||
features.Add(feature);
|
||||
}
|
||||
else if (featureType == typeof(EregisterDebugFeatures))
|
||||
{
|
||||
var feature = new EregisterDebugFeature
|
||||
{
|
||||
AuthLevel = AuthLevel.III,
|
||||
Cmd = "F1",
|
||||
FeatureType = featureType,
|
||||
IsSingleCmd = true
|
||||
};
|
||||
|
||||
foreach (var debugFeatureFeatureInfo in typeof(EregisterDebugFeatures).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
var debugFeaturePamAttribute = debugFeatureFeatureInfo.GetCustomAttribute<PamAttribute>();
|
||||
|
||||
if (debugFeaturePamAttribute is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var debugFeatureType = debugFeatureFeatureInfo.PropertyType;
|
||||
var debugFeaturePam = Activator.CreateInstance(debugFeatureType) as Pam;
|
||||
var debugFeature = new EregisterDebugFeature
|
||||
{
|
||||
FeatureType = featureType,
|
||||
Cmd = debugFeaturePam.CmdHex,
|
||||
IsSingleCmd = featurePamAttribute.IsSingleCmd,
|
||||
OnlyProductionMode = featurePamAttribute.OnlyProductionMode,
|
||||
AuthLevel = featurePamAttribute.AuthLevel,
|
||||
};
|
||||
|
||||
foreach (var debugFeaturePropertyInfo in debugFeatureType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (!debugFeaturePropertyInfo.CanRead || !featureInfo.CanWrite)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
debugFeature.Add(new EregisterFeatureProperty
|
||||
{
|
||||
Name = debugFeaturePropertyInfo.Name,
|
||||
Type = debugFeaturePropertyInfo.PropertyType,
|
||||
Getter = debugFeaturePropertyInfo.GetValue,
|
||||
Setter = debugFeaturePropertyInfo.SetValue,
|
||||
});
|
||||
}
|
||||
|
||||
feature.Add(debugFeature);
|
||||
}
|
||||
|
||||
features.Add(feature);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var feature in features)
|
||||
{
|
||||
foreach (var items in feature.GetItems())
|
||||
{
|
||||
Console.Write($"{items[0],40}");
|
||||
Console.Write($"{items[1],5}");
|
||||
Console.Write($"{items[2],5}");
|
||||
Console.Write($"{items[3],5}");
|
||||
Console.Write($"{items[4],5}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EregisterFeature
|
||||
{
|
||||
private readonly ICollection<EregisterFeatureProperty> properties
|
||||
= new List<EregisterFeatureProperty>();
|
||||
|
||||
public Type FeatureType { get; set; }
|
||||
|
||||
public string Cmd { get; set; }
|
||||
|
||||
public bool IsSingleCmd { get; set; }
|
||||
|
||||
public bool OnlyProductionMode { get; set; }
|
||||
|
||||
public AuthLevel AuthLevel { get; set; }
|
||||
|
||||
public virtual void Add(EregisterFeatureProperty eregisterFeatureProperty)
|
||||
=> this.properties.Add(eregisterFeatureProperty);
|
||||
|
||||
public virtual IEnumerable<string[]> GetItems()
|
||||
{
|
||||
yield return new[]
|
||||
{
|
||||
this.FeatureType.Name,
|
||||
this.Cmd,
|
||||
$"{this.AuthLevel}",
|
||||
this.IsSingleCmd ? "v" : " ",
|
||||
this.OnlyProductionMode ? "v" : " "
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class EregisterDebugFeature : EregisterFeature
|
||||
{
|
||||
private readonly ICollection<EregisterFeature> features
|
||||
= new List<EregisterFeature>();
|
||||
|
||||
public virtual void Add(EregisterFeature feature)
|
||||
=> this.features.Add(feature);
|
||||
|
||||
public override IEnumerable<string[]> GetItems()
|
||||
{
|
||||
foreach (var feature in this.features)
|
||||
{
|
||||
foreach (var items in feature.GetItems())
|
||||
{
|
||||
yield return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EregisterFeatureProperty
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public Type Type { get; set; }
|
||||
|
||||
public Func<object, object> Getter { get; set; }
|
||||
|
||||
public Action<object, object> Setter { get; set; }
|
||||
}
|
||||
}
|
||||
@ -14,10 +14,10 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>\\sla12file\auftrag\Aktuelle Anwendungen\CAL\</PublishUrl>
|
||||
<IsWebBootstrapper>true</IsWebBootstrapper>
|
||||
<PublishUrl>\\SLA12IIS01\LaaProductionWeb\Apps\CordonelAssembly\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Unc</InstallFrom>
|
||||
<InstallFrom>Web</InstallFrom>
|
||||
<UpdateEnabled>true</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
@ -25,12 +25,13 @@
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<InstallUrl>\\sla12file\auftrag\Aktuelle Anwendungen\CAL\</InstallUrl>
|
||||
<InstallUrl>http://sla12iis01.emea.sensus.net/LaaProductionWeb/Apps/CordonelAssembly/</InstallUrl>
|
||||
<ProductName>Cordonel Assembly Line</ProductName>
|
||||
<PublisherName>Xylem Sensus Laatzen</PublisherName>
|
||||
<SuiteName>Cordonel Assembly Line</SuiteName>
|
||||
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
|
||||
<WebPage>publish.htm</WebPage>
|
||||
<ApplicationRevision>6</ApplicationRevision>
|
||||
<ApplicationRevision>8</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<CreateDesktopShortcut>true</CreateDesktopShortcut>
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PamChanel.cs" />
|
||||
<Compile Include="Parameters\BluetoothOperating.cs" />
|
||||
<Compile Include="Parameters\OperatingModes.cs" />
|
||||
<Compile Include="Parameters\P11.cs" />
|
||||
@ -55,21 +56,20 @@
|
||||
<Compile Include="Parameters\RSSI.cs" />
|
||||
<Compile Include="Parameters\SirtOperating.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SerialDataExtensions.cs" />
|
||||
<Compile Include="SerialPort.cs" />
|
||||
<Compile Include="SIRTBroadcaster.Internal.cs" />
|
||||
<Compile Include="SIRTFactory.cs" />
|
||||
<Compile Include="SIRTBroadcaster.Public.cs" />
|
||||
<Compile Include="SIRTKey.cs" />
|
||||
<Compile Include="SIRTMessage.cs" />
|
||||
<Compile Include="SIRTStream.cs" />
|
||||
<Compile Include="SIRTStreamFactory.cs" />
|
||||
<Compile Include="SIRTTask.Public.cs" />
|
||||
<Compile Include="SIRTTaskState.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SIRTTask.Internal.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common.Hardware.Ports\Common.Hardware.Ports.csproj">
|
||||
<Project>{9ae071c0-db12-4e09-a3c7-43f6dcd518d6}</Project>
|
||||
<Name>Common.Hardware.Ports</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
22
Common/Hardware/Common.Hardware.SIRT/PamChanel.cs
Normal file
22
Common/Hardware/Common.Hardware.SIRT/PamChanel.cs
Normal file
@ -0,0 +1,22 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
public class PamChanel
|
||||
{
|
||||
private readonly ConcurrentQueue<SIRTTask> tasks = new ConcurrentQueue<SIRTTask>();
|
||||
|
||||
public uint Address { get; set; }
|
||||
|
||||
public void Push(SIRTMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal void Pop()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
public class BluetoothOperating
|
||||
{
|
||||
private readonly byte[] bits;
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
/// <summary>
|
||||
/// Parameter P81-1 is the first modifier of "Write to PAM Pool" command and is placed at third position,
|
||||
/// if telegram from PC -> SIRT begins with {0x55, 0x81}.
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
public class P821
|
||||
{
|
||||
private readonly byte[] bits;
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System.Text;
|
||||
|
||||
public class PAMStatus
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System;
|
||||
|
||||
public class RFModuleOperating
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
namespace Common.Hardware.SIRT.Parameters
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
public class SirtOperating
|
||||
{
|
||||
private readonly byte[] bits;
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
@ -13,6 +11,8 @@
|
||||
{
|
||||
private readonly ConcurrentDictionary<uint, ConcurrentQueue<SIRTTask>> tasks
|
||||
= new ConcurrentDictionary<uint, ConcurrentQueue<SIRTTask>>();
|
||||
private readonly ManualResetEventSlim tasksAwaiter = new ManualResetEventSlim();
|
||||
private readonly IList<bool> tasksInPampool = new List<bool>();
|
||||
private readonly SerialPort serialPort;
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
@ -165,29 +165,41 @@
|
||||
{
|
||||
this.IsActivated = true;
|
||||
|
||||
this.processingTask = Task.Factory.StartNew(() =>
|
||||
this.processingTask = Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var manualResetEventSlim = new ManualResetEventSlim();
|
||||
|
||||
while (!this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (this.tasksInPampool.Count >= 5)
|
||||
{
|
||||
this.tasksAwaiter.Wait();
|
||||
this.tasksAwaiter.Reset();
|
||||
}
|
||||
|
||||
foreach (var tasksQueue in this.tasks.Values.ToArray())
|
||||
{
|
||||
if (this.tasksInPampool.Count >= 5)
|
||||
{
|
||||
this.tasksAwaiter.Wait();
|
||||
this.tasksAwaiter.Reset();
|
||||
}
|
||||
|
||||
if (tasksQueue.TryPeek(out var task) && task.State == SIRTTaskState.Pending)
|
||||
{
|
||||
this.tasksInPampool.Add(true);
|
||||
this.serialPort.Write(task.Start());
|
||||
this.Logging?.Invoke(task.ToString());
|
||||
}
|
||||
|
||||
manualResetEventSlim.Wait(100);
|
||||
manualResetEventSlim.Reset();
|
||||
await Task.Delay(10);
|
||||
}
|
||||
|
||||
manualResetEventSlim.Wait(100);
|
||||
manualResetEventSlim.Reset();
|
||||
await Task.Delay(10);
|
||||
}
|
||||
|
||||
}, this.cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current)
|
||||
}
|
||||
, this.cancellationToken
|
||||
, TaskCreationOptions.LongRunning
|
||||
, TaskScheduler.Current)
|
||||
.ContinueWith(this.ExceptionLogging);
|
||||
}
|
||||
|
||||
@ -268,6 +280,15 @@
|
||||
task.Cancelled -= this.OnStateChanged;
|
||||
task.Completed -= this.OnStateChanged;
|
||||
task.Timeouted -= this.OnTaskTimeout;
|
||||
|
||||
var lastIX = this.tasksInPampool.Count - 1;
|
||||
|
||||
if (lastIX >= 0)
|
||||
{
|
||||
this.tasksInPampool.RemoveAt(lastIX);
|
||||
}
|
||||
|
||||
this.tasksAwaiter.Set();
|
||||
}
|
||||
|
||||
private bool TryRun<TTask>(TTask task) where TTask : SIRTTask
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
||||
@ -21,15 +21,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseConnections()
|
||||
{
|
||||
foreach (var broadcaster in this.GetConnections())
|
||||
{
|
||||
broadcaster.Logging -= this.NotifyMessage;
|
||||
broadcaster.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void DequeueTasks(uint address)
|
||||
{
|
||||
foreach (var broadcaster in this.GetConnections())
|
||||
@ -38,15 +29,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenConnections()
|
||||
{
|
||||
foreach (var broadcaster in this.GetConnections())
|
||||
{
|
||||
broadcaster.Logging += this.NotifyMessage;
|
||||
broadcaster.Open();
|
||||
}
|
||||
}
|
||||
|
||||
public void ConnectSIRT(string portName, Action<SIRTBroadcaster> callback)
|
||||
{
|
||||
if (!this.broadcasters.TryGetValue(portName, out var broadcaster))
|
||||
@ -60,13 +42,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
callback(broadcaster);
|
||||
|
||||
if (broadcaster?.IsActivated == false)
|
||||
{
|
||||
broadcaster?.Close();
|
||||
broadcaster?.Open();
|
||||
}
|
||||
|
||||
callback(broadcaster);
|
||||
}
|
||||
|
||||
public void EnqueueTask(SIRTTask task)
|
||||
@ -77,9 +58,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetPortNames()
|
||||
=> this.broadcasters.Keys.ToArray();
|
||||
|
||||
public void RemoveConnections()
|
||||
{
|
||||
foreach (var key in this.broadcasters.Keys.ToArray())
|
||||
@ -92,10 +70,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<SIRTBroadcaster> GetConnections()
|
||||
=> this.broadcasters.Values.ToArray();
|
||||
|
||||
private void NotifyMessage(string message)
|
||||
=> this.Logging?.Invoke(message);
|
||||
|
||||
private IEnumerable<SIRTBroadcaster> GetConnections()
|
||||
=> this.broadcasters.Values.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
30
Common/Hardware/Common.Hardware.SIRT/SIRTKey.cs
Normal file
30
Common/Hardware/Common.Hardware.SIRT/SIRTKey.cs
Normal file
@ -0,0 +1,30 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
|
||||
public struct SIRTKey : IEquatable<SIRTKey>
|
||||
{
|
||||
public SIRTKey(string identity, int frecuency) : this()
|
||||
{
|
||||
this.SirtId = identity;
|
||||
this.Frequency = frecuency;
|
||||
}
|
||||
|
||||
public string SirtId { get; set; }
|
||||
|
||||
public int Frequency { get; set; }
|
||||
|
||||
public bool Equals(SIRTKey other)
|
||||
=> other.SirtId == this.SirtId;
|
||||
|
||||
public override bool Equals(object other)
|
||||
=> other is SIRTKey sirtKey
|
||||
&& this.Equals(sirtKey);
|
||||
|
||||
public override int GetHashCode()
|
||||
=> this.ToString().GetHashCode();
|
||||
|
||||
public override string ToString()
|
||||
=> $"{this.SirtId}|{this.Frequency}";
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Newtonsoft.Json;
|
||||
using Common.Hardware.SIRT.Parameters;
|
||||
|
||||
using System;
|
||||
|
||||
public class SIRTMessage
|
||||
@ -26,13 +26,17 @@
|
||||
public SIRTMessage()
|
||||
{
|
||||
this.bytes = new byte[MIN_LEN];
|
||||
this.bytes[0] = PC2SIRT;
|
||||
this.Start = PC2SIRT;
|
||||
this.Stop = STOP;
|
||||
}
|
||||
|
||||
public SIRTMessage(byte[] bytes)
|
||||
public SIRTMessage(byte[] bytes) : this()
|
||||
=> this.bytes = bytes;
|
||||
|
||||
public byte Start
|
||||
{
|
||||
this.bytes = bytes;
|
||||
this.bytes[0] = SIRT2PC;
|
||||
get => this.bytes[0];
|
||||
set => this.bytes[0] = value;
|
||||
}
|
||||
|
||||
public byte Cmd
|
||||
@ -59,9 +63,12 @@
|
||||
set => value.GetBytesBE().CopyTo(this.bytes, 4);
|
||||
}
|
||||
|
||||
public byte Length => this.bytes[8];
|
||||
public byte Length
|
||||
{
|
||||
get => this.bytes[8];
|
||||
set => this.bytes[8] = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
@ -87,24 +94,68 @@
|
||||
}
|
||||
}
|
||||
|
||||
public ushort CRC => this.bytes.ToUInt16BE(this.bytes.Length - 3);
|
||||
|
||||
public string Content => this.ToString();
|
||||
|
||||
public byte[] ToByteArray()
|
||||
public ushort CRC
|
||||
{
|
||||
var length = this.bytes.Length;
|
||||
var crc = this.bytes.CRCCCITT(1, length - 3);
|
||||
var crcBytes = crc.GetBytesBE();
|
||||
get => this.bytes.ToUInt16BE(this.bytes.Length - 3);
|
||||
set => value.GetBytesBE().CopyTo(this.bytes, this.bytes.Length - 3);
|
||||
}
|
||||
|
||||
this.bytes[length - 3] = crcBytes[0];
|
||||
this.bytes[length - 2] = crcBytes[1];
|
||||
this.bytes[length - 1] = STOP;
|
||||
public byte Stop
|
||||
{
|
||||
get => this.bytes[this.bytes.Length - 1];
|
||||
set => this.bytes[this.bytes.Length - 1] = value;
|
||||
}
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
this.CRC = this.bytes.CRCCCITT(1, this.bytes.Length - 3);
|
||||
this.Stop = STOP;
|
||||
|
||||
return this.bytes;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
=> BitConverter.ToString(this.ToByteArray());
|
||||
=> BitConverter.ToString(this.bytes);
|
||||
|
||||
public static implicit operator byte[] (SIRTMessage message)
|
||||
=> message.bytes;
|
||||
|
||||
public static implicit operator SIRTMessage(byte[] bytes)
|
||||
=> new SIRTMessage(bytes);
|
||||
|
||||
internal static SIRTMessage Activate = new SIRTMessage
|
||||
{
|
||||
Cmd = W_REG,
|
||||
Address = 0x20000000,
|
||||
P2 = 0x05,
|
||||
Data = new byte[]
|
||||
{
|
||||
new SirtOperating { /* default */ },
|
||||
new BluetoothOperating { BtOff = true },
|
||||
new RFModuleOperating { RfOff = true },
|
||||
new RFModuleOperating { OpMode = OperatingModes.ReceiveF1TransmitSensusRFF3 },
|
||||
new PamTimeout { Minutes = 1 }
|
||||
}
|
||||
};
|
||||
|
||||
internal static SIRTMessage Identify = new SIRTMessage
|
||||
{
|
||||
Cmd = SIRTMessage.R_REG,
|
||||
Address = 0x11001820,
|
||||
P2 = 0x08
|
||||
};
|
||||
|
||||
internal static readonly SIRTMessage ReadPamPool = new SIRTMessage
|
||||
{
|
||||
Cmd = R_PAM,
|
||||
Address = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
internal static SIRTMessage DeleteFromPamPool(uint address) => new SIRTMessage
|
||||
{
|
||||
Cmd = W_PAM,
|
||||
P1 = new P811 { DelPamAdr = true },
|
||||
Address = address
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
263
Common/Hardware/Common.Hardware.SIRT/SIRTStream.cs
Normal file
263
Common/Hardware/Common.Hardware.SIRT/SIRTStream.cs
Normal file
@ -0,0 +1,263 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using SystemSerialPort = System.IO.Ports.SerialPort;
|
||||
|
||||
public class SIRTStream
|
||||
{
|
||||
private readonly SystemSerialPort serialPort = new SystemSerialPort
|
||||
{
|
||||
BaudRate = 112500,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
StopBits = StopBits.One
|
||||
};
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
public string Identity { get; private set; }
|
||||
|
||||
public int Frecuency { get; private set; }
|
||||
|
||||
public SIRTKey Key { get; private set; }
|
||||
|
||||
public string PortName => this.serialPort.PortName;
|
||||
|
||||
public void Close(int timeout = 3000)
|
||||
{
|
||||
var disposeAwaiter = new ManualResetEventSlim();
|
||||
|
||||
void Disposed(object _, EventArgs _1)
|
||||
{
|
||||
this.serialPort.Disposed -= Disposed;
|
||||
disposeAwaiter.Set();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.serialPort.Disposed += Disposed;
|
||||
this.serialPort.Close();
|
||||
disposeAwaiter.Wait(timeout);
|
||||
}
|
||||
catch // TODO: (Exception e)
|
||||
{
|
||||
this.serialPort.Disposed -= Disposed;
|
||||
disposeAwaiter.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public void Open(string portName, int timeout = 3000)
|
||||
{
|
||||
if (this.serialPort.IsOpen)
|
||||
{
|
||||
this.IsRunning = false;
|
||||
|
||||
this.Close();
|
||||
}
|
||||
|
||||
this.serialPort.PortName = portName;
|
||||
|
||||
try
|
||||
{
|
||||
this.serialPort.Open();
|
||||
}
|
||||
catch // TODO: (Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sirtRequest = default(SIRTMessage);
|
||||
var sirtRequestBytes = default(byte[]);
|
||||
var sirtResponse = default(SIRTMessage);
|
||||
var sirtResponseAwaiter = new ManualResetEventSlim();
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
var cancellationToken = cancellationTokenSource.Token;
|
||||
var cancellationTask = Task.Run(() =>
|
||||
{
|
||||
foreach (var message in this.ReadStream())
|
||||
{
|
||||
var sameAddress = message.Address == sirtRequest?.Address;
|
||||
var isAnswer = message.Cmd == SIRTMessage.ACKNANSW;
|
||||
var withNoErrors = message.P1 == 0;
|
||||
var readOrWrite = message.P2 == SIRTMessage.W_REG || message.P2 == SIRTMessage.R_REG;
|
||||
|
||||
if (sameAddress && isAnswer && withNoErrors && readOrWrite)
|
||||
{
|
||||
sirtResponse = message;
|
||||
sirtResponseAwaiter.Set();
|
||||
}
|
||||
}
|
||||
}, cancellationToken);
|
||||
|
||||
try
|
||||
{
|
||||
sirtResponse = null;
|
||||
sirtRequest = SIRTMessage.Activate;
|
||||
sirtRequestBytes = sirtRequest.GetBytes();
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
this.Write(sirtRequestBytes);
|
||||
sirtResponseAwaiter.Wait(timeout);
|
||||
sirtResponseAwaiter.Reset();
|
||||
|
||||
if (sirtResponse != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sirtResponse = null;
|
||||
sirtRequest = SIRTMessage.Identify;
|
||||
sirtRequestBytes = sirtRequest.GetBytes();
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
this.Write(sirtRequestBytes);
|
||||
sirtResponseAwaiter.Wait(timeout);
|
||||
sirtResponseAwaiter.Reset();
|
||||
|
||||
if (sirtResponse != null)
|
||||
{
|
||||
this.IsRunning = true;
|
||||
this.Identity = BitConverter.ToString(sirtResponse.Data ?? Array.Empty<byte>());
|
||||
this.Frecuency = string.IsNullOrWhiteSpace(this.Identity)
|
||||
? -1
|
||||
: this.Identity[10] == '0'
|
||||
? 868
|
||||
: 433;
|
||||
this.Key = new SIRTKey(this.Identity, this.Frecuency);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cancellationTokenSource.Cancel();
|
||||
}
|
||||
catch // TODO: (Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<SIRTMessage> ReadStream()
|
||||
{
|
||||
var readAwaiter = new ManualResetEventSlim();
|
||||
|
||||
void DataReceived(object _, SerialDataReceivedEventArgs args)
|
||||
{
|
||||
if (args.EventType == SerialData.Chars)
|
||||
{
|
||||
readAwaiter.Set();
|
||||
}
|
||||
}
|
||||
|
||||
this.serialPort.DataReceived += DataReceived;
|
||||
|
||||
var buffer = new List<byte>();
|
||||
var bytes = default(byte[]);
|
||||
var length = default(int);
|
||||
|
||||
while (this.serialPort.IsOpen)
|
||||
{
|
||||
readAwaiter.Wait();
|
||||
readAwaiter.Reset();
|
||||
|
||||
bytes = new byte[this.serialPort.BytesToRead];
|
||||
length = this.serialPort.Read(bytes, 0, bytes.Length);
|
||||
|
||||
if (length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer.AddRange(bytes);
|
||||
|
||||
while (this.TryParseMessage(buffer, out var message))
|
||||
{
|
||||
yield return message;
|
||||
}
|
||||
}
|
||||
|
||||
this.serialPort.DataReceived -= DataReceived;
|
||||
}
|
||||
|
||||
public void Write(byte[] bytes)
|
||||
{
|
||||
if (this.serialPort.IsOpen && bytes?.Length > 0)
|
||||
{
|
||||
this.serialPort.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryParseMessage(List<Byte> buffer, out SIRTMessage message)
|
||||
{
|
||||
message = default(SIRTMessage);
|
||||
|
||||
var bufferLength = buffer.Count;
|
||||
|
||||
if (bufferLength <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var msgLength = 0;
|
||||
var msg = default(byte[]);
|
||||
|
||||
var startIX = buffer.IndexOf(SIRTMessage.SIRT2PC);
|
||||
|
||||
if (startIX < 0)
|
||||
{
|
||||
buffer.Clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var lengthIX = startIX + 8;
|
||||
|
||||
if (lengthIX >= bufferLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var dataLength = buffer[lengthIX];
|
||||
var stopIX = lengthIX + dataLength + 3;
|
||||
|
||||
if (stopIX >= bufferLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffer[stopIX] != SIRTMessage.STOP)
|
||||
{
|
||||
startIX = buffer.IndexOf(SIRTMessage.SIRT2PC, startIX + 1);
|
||||
|
||||
if (startIX >= 0)
|
||||
{
|
||||
buffer.RemoveRange(0, startIX + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Clear();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
msgLength = stopIX - startIX + 1;
|
||||
msg = new byte[msgLength];
|
||||
|
||||
buffer.CopyTo(startIX, msg, 0, msgLength);
|
||||
buffer.RemoveRange(0, startIX + msgLength);
|
||||
|
||||
message = new SIRTMessage(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Common/Hardware/Common.Hardware.SIRT/SIRTStreamFactory.cs
Normal file
81
Common/Hardware/Common.Hardware.SIRT/SIRTStreamFactory.cs
Normal file
@ -0,0 +1,81 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class SIRTStreamFactory
|
||||
{
|
||||
private readonly ConcurrentDictionary<SIRTKey, SIRTStream> streams = new ConcurrentDictionary<SIRTKey, SIRTStream>();
|
||||
private readonly ConcurrentDictionary<SIRTKey, List<bool>> pams = new ConcurrentDictionary<SIRTKey, List<bool>>();
|
||||
private readonly ConcurrentDictionary<SIRTKey, Task> readers = new ConcurrentDictionary<SIRTKey, Task>();
|
||||
private readonly ConcurrentDictionary<uint, PamChanel> chanels
|
||||
= new ConcurrentDictionary<uint, PamChanel>();
|
||||
private readonly ConcurrentDictionary<uint, ConcurrentBag<SIRTKey>> addresses
|
||||
= new ConcurrentDictionary<uint, ConcurrentBag<SIRTKey>>();
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private CancellationToken cancellationToken;
|
||||
private Task cancellationTaks;
|
||||
|
||||
public void ConnectSirts(params string[] portNames)
|
||||
{
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var portName in portNames.Intersect(SerialPort.GetPortNames()))
|
||||
{
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
var sirtStream = new SIRTStream();
|
||||
sirtStream.Open(portName);
|
||||
|
||||
if (sirtStream.IsRunning)
|
||||
{
|
||||
this.streams.GetOrAdd(sirtStream.Key, sirtStream);
|
||||
this.pams.GetOrAdd(sirtStream.Key, new List<bool>());
|
||||
this.readers.GetOrAdd(sirtStream.Key, Task.Run(() =>
|
||||
{
|
||||
var stream = sirtStream;
|
||||
var key = stream.Key;
|
||||
|
||||
foreach (var message in stream.ReadStream())
|
||||
{
|
||||
var address = message.Address;
|
||||
|
||||
this.addresses
|
||||
.GetOrAdd(address, new ConcurrentBag<SIRTKey>())
|
||||
.Add(key);
|
||||
|
||||
this.chanels
|
||||
.GetOrAdd(message.Address, new PamChanel())
|
||||
.Push(message);
|
||||
}
|
||||
}
|
||||
, this.cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
tasks.Add(task);
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
this.cancellationTaks = Task.Run((Action)this.StartSendingPams, this.cancellationToken);
|
||||
}
|
||||
|
||||
private void StartSendingPams()
|
||||
{
|
||||
while (!this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var chanel in this.chanels.Values)
|
||||
{
|
||||
chanel.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,9 +21,9 @@
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
internal class AnswerTask : SIRTTask
|
||||
public class AnswerTask : SIRTTask
|
||||
{
|
||||
public AnswerTask() : base(0, 1000)
|
||||
public AnswerTask() : base(0, 3000)
|
||||
{
|
||||
|
||||
}
|
||||
@ -38,7 +38,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
internal static readonly AnswerTask ActivateSIRT = new AnswerTask
|
||||
public static readonly AnswerTask ActivateSIRT = new AnswerTask
|
||||
{
|
||||
Cmd = SIRTMessage.W_REG,
|
||||
RequestAddress = 0x20000000,
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
public int Frequency { get; }
|
||||
|
||||
public SIRTTaskState State { get; protected set; }
|
||||
public SIRTTaskState State { get; set; }
|
||||
|
||||
public void PushResponse(SIRTMessage response)
|
||||
{
|
||||
@ -84,7 +84,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] ToByteArray() => this.request.ToByteArray();
|
||||
public virtual byte[] ToByteArray() => this.request.GetBytes();
|
||||
|
||||
public override string ToString() => BitConverter.ToString(this.ToByteArray());
|
||||
|
||||
|
||||
584
Common/Hardware/Common.Hardware.SIRT/SerialDataExtensions.cs
Normal file
584
Common/Hardware/Common.Hardware.SIRT/SerialDataExtensions.cs
Normal file
@ -0,0 +1,584 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public static class SerialDataExtensions
|
||||
{
|
||||
private const int ByteSize = 8;
|
||||
private const int SByteSize = 16;
|
||||
private const int Int16Size = 16;
|
||||
private const int UInt16Size = 16;
|
||||
private const int Int32Size = 32;
|
||||
private const int UInt32Size = 32;
|
||||
private const int Int64Size = 64;
|
||||
private const int UInt64Size = 64;
|
||||
|
||||
public static byte[] GetBitsBE(this byte value)
|
||||
{
|
||||
var bits = new byte[ByteSize];
|
||||
|
||||
for (int i = 7, x = 0; i >= 0; i--, x++)
|
||||
{
|
||||
bits[x] = (byte)((value >> i) & 1);
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
public static byte[] GetBitsLE(this byte value)
|
||||
{
|
||||
var bits = new byte[ByteSize];
|
||||
|
||||
for (var i = 0; i < ByteSize; i++)
|
||||
{
|
||||
bits[i] = (byte)((value >> i) & 1);
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
public static byte[] GetBitsLE(this ushort value)
|
||||
{
|
||||
var bits = new byte[UInt16Size];
|
||||
|
||||
for (var i = 0; i < UInt16Size; i++)
|
||||
{
|
||||
bits[i] = (byte)((value >> i) & 1);
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
public static byte GetByteLE(this byte[] bits)
|
||||
{
|
||||
if (bits is null)
|
||||
{
|
||||
return default(byte);
|
||||
}
|
||||
|
||||
var value = default(byte);
|
||||
|
||||
for (var i = 0; i < ByteSize; i++)
|
||||
{
|
||||
value ^= (byte)(bits[i] << i);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static byte GetByteLE(this byte[] bits, int start = 0, int count = 0)
|
||||
{
|
||||
if (bits is null)
|
||||
{
|
||||
return default(byte);
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
count = bits.Length;
|
||||
}
|
||||
|
||||
var length = start + count;
|
||||
var _byte = default(byte);
|
||||
|
||||
for (int i = start, x = 0; i < length; i++, x++)
|
||||
{
|
||||
_byte ^= (byte)(bits[i] << x);
|
||||
}
|
||||
|
||||
return _byte;
|
||||
}
|
||||
|
||||
public static void SetBitsLE(this byte value, byte[] bits, int start = 0, int count = 0)
|
||||
{
|
||||
if (bits is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 0 || count > bits.Length)
|
||||
{
|
||||
count = bits.Length;
|
||||
}
|
||||
|
||||
for (int i = start, x = 0; i < count; i++, x++)
|
||||
{
|
||||
bits[i] = (byte)((value >> x) % 2);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this sbyte value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this short value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this int value)
|
||||
{
|
||||
var bytes = new byte[4];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this long value)
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 56);
|
||||
bytes[index++] = (byte)(value >> 48);
|
||||
bytes[index++] = (byte)(value >> 40);
|
||||
bytes[index++] = (byte)(value >> 32);
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this ushort value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this uint value)
|
||||
{
|
||||
var bytes = new byte[4];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesBE(this ulong value)
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)(value >> 56);
|
||||
bytes[index++] = (byte)(value >> 48);
|
||||
bytes[index++] = (byte)(value >> 40);
|
||||
bytes[index++] = (byte)(value >> 32);
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index] = (byte)value;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this sbyte value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index] = (byte)(value >> 8);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this short value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index] = (byte)(value >> 8);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this int value)
|
||||
{
|
||||
var bytes = new byte[4];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index] = (byte)(value >> 24);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this long value)
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 32);
|
||||
bytes[index++] = (byte)(value >> 40);
|
||||
bytes[index++] = (byte)(value >> 48);
|
||||
bytes[index] = (byte)(value >> 56);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this ushort value)
|
||||
{
|
||||
var bytes = new byte[2];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index] = (byte)(value >> 8);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this uint value)
|
||||
{
|
||||
var bytes = new byte[4];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index] = (byte)(value >> 24);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] GetBytesLE(this ulong value)
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
var index = 0;
|
||||
|
||||
bytes[index++] = (byte)value;
|
||||
bytes[index++] = (byte)(value >> 8);
|
||||
bytes[index++] = (byte)(value >> 16);
|
||||
bytes[index++] = (byte)(value >> 24);
|
||||
bytes[index++] = (byte)(value >> 32);
|
||||
bytes[index++] = (byte)(value >> 40);
|
||||
bytes[index++] = (byte)(value >> 48);
|
||||
bytes[index] = (byte)(value >> 56);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static sbyte ToSByteBE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(sbyte);
|
||||
|
||||
value ^= (sbyte)(bytes[start++] << 8);
|
||||
value ^= (sbyte)bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static short ToInt16BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(short);
|
||||
|
||||
value ^= (short)(bytes[start++] << 8);
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int ToInt32BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(int);
|
||||
|
||||
value ^= bytes[start++] << 24;
|
||||
value ^= bytes[start++] << 16;
|
||||
value ^= bytes[start++] << 8;
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long ToInt64BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(long);
|
||||
|
||||
value ^= bytes[start++] << 56;
|
||||
value ^= bytes[start++] << 48;
|
||||
value ^= bytes[start++] << 40;
|
||||
value ^= bytes[start++] << 32;
|
||||
value ^= bytes[start++] << 24;
|
||||
value ^= bytes[start++] << 16;
|
||||
value ^= bytes[start++] << 8;
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort ToUInt16BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(ushort);
|
||||
|
||||
value ^= (ushort)(bytes[start++] << 8);
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static uint ToUInt32BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(uint);
|
||||
|
||||
value ^= (uint)(bytes[start++] << 24);
|
||||
value ^= (uint)(bytes[start++] << 16);
|
||||
value ^= (uint)(bytes[start++] << 8);
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ulong ToUInt64BE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(ulong);
|
||||
|
||||
value ^= (ulong)(bytes[start++] << 56);
|
||||
value ^= (ulong)(bytes[start++] << 48);
|
||||
value ^= (ulong)(bytes[start++] << 40);
|
||||
value ^= (ulong)(bytes[start++] << 32);
|
||||
value ^= (ulong)(bytes[start++] << 24);
|
||||
value ^= (ulong)(bytes[start++] << 16);
|
||||
value ^= (ulong)(bytes[start++] << 8);
|
||||
value ^= bytes[start];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static sbyte ToSByteLE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(sbyte);
|
||||
|
||||
value ^= (sbyte)bytes[start++];
|
||||
value ^= (sbyte)(bytes[start] << 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static short ToInt16LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(short);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= (short)(bytes[start] << 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int ToInt32LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(int);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= bytes[start++] << 8;
|
||||
value ^= bytes[start++] << 16;
|
||||
value ^= bytes[start] << 24;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long ToInt64LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(long);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= bytes[start++] << 8;
|
||||
value ^= bytes[start++] << 16;
|
||||
value ^= bytes[start++] << 24;
|
||||
value ^= bytes[start++] << 32;
|
||||
value ^= bytes[start++] << 40;
|
||||
value ^= bytes[start++] << 48;
|
||||
value ^= bytes[start] << 56;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort ToUInt16LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(ushort);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= (ushort)(bytes[start] << 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort ToUIint16LEFromBits(this byte[] bits)
|
||||
{
|
||||
const int size = 16;
|
||||
|
||||
if (bits is null)
|
||||
{
|
||||
bits = new byte[size];
|
||||
}
|
||||
|
||||
Array.Resize(ref bits, size);
|
||||
|
||||
ushort value = 0;
|
||||
|
||||
for (var i = 0; i < size; i++)
|
||||
{
|
||||
value ^= (ushort)(bits[i] << i);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static uint ToUInt32LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(uint);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= (uint)(bytes[start++] << 8);
|
||||
value ^= (uint)(bytes[start++] << 16);
|
||||
value ^= (uint)(bytes[start] << 24);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ulong ToUInt64LE(this byte[] bytes, int start = 0)
|
||||
{
|
||||
var value = default(ulong);
|
||||
|
||||
value ^= bytes[start++];
|
||||
value ^= (ulong)(bytes[start++] << 8);
|
||||
value ^= (ulong)(bytes[start++] << 16);
|
||||
value ^= (ulong)(bytes[start++] << 24);
|
||||
value ^= (ulong)(bytes[start++] << 32);
|
||||
value ^= (ulong)(bytes[start++] << 40);
|
||||
value ^= (ulong)(bytes[start++] << 48);
|
||||
value ^= (ulong)(bytes[start] << 56);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort CRCCCITT(this byte[] bytes, int start = 0, int length = 0)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
length = bytes.Length;
|
||||
}
|
||||
|
||||
var crc = (ushort)0xFFFF;
|
||||
|
||||
for (var b = start; b < length; b++)
|
||||
{
|
||||
var _byte = bytes[b];
|
||||
var token = (ushort)((_byte << 8) & 0xFF00);
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
if (0x8000 == ((crc ^ token) & 0x8000))
|
||||
{
|
||||
crc <<= 1;
|
||||
crc ^= 0x1021;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
|
||||
token <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
public static byte[] GetBytes(this string hexString)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(hexString))
|
||||
{
|
||||
hexString = Regex.Replace(hexString, "[^a-fA-F0-9]*", string.Empty);
|
||||
|
||||
var first = true;
|
||||
var x = 0;
|
||||
|
||||
foreach (var hex in hexString)
|
||||
{
|
||||
if ('0' <= hex && hex <= '9')
|
||||
{
|
||||
x += hex - '0';
|
||||
}
|
||||
else if ('A' <= hex && hex <= 'F')
|
||||
{
|
||||
x += hex - 'A' + 10;
|
||||
}
|
||||
else if ('a' <= hex && hex <= 'f')
|
||||
{
|
||||
x = hex - 'a' + 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
x *= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes.Add((byte)x);
|
||||
|
||||
x = 0;
|
||||
}
|
||||
|
||||
first = !first;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] GetEncryptionKey(this string hexString, int requiredLength = 16)
|
||||
{
|
||||
var bytes = hexString.GetBytes();
|
||||
|
||||
if (bytes?.Length != requiredLength)
|
||||
{
|
||||
return default(byte[]);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Common/Hardware/Common.Hardware.SIRT/SerialPort.cs
Normal file
207
Common/Hardware/Common.Hardware.SIRT/SerialPort.cs
Normal file
@ -0,0 +1,207 @@
|
||||
namespace Common.Hardware.SIRT
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
|
||||
using SysSerialPort = System.IO.Ports.SerialPort;
|
||||
|
||||
public sealed class SerialPort
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, SysSerialPort> serialPorts
|
||||
= new ConcurrentDictionary<string, SysSerialPort>();
|
||||
|
||||
private readonly ManualResetEventSlim readAwaiter;
|
||||
private readonly ManualResetEventSlim closeAwaiter;
|
||||
|
||||
public SerialPort(string name, int baudRate, Parity parity, int dataBits, StopBits stopBits)
|
||||
{
|
||||
this.COMPort = name;
|
||||
this.readAwaiter = new ManualResetEventSlim();
|
||||
this.closeAwaiter = new ManualResetEventSlim();
|
||||
var sp = new SysSerialPort(this.COMPort, baudRate, parity, dataBits, stopBits);
|
||||
|
||||
serialPorts.AddOrUpdate(this.COMPort, sp, (key, value) =>
|
||||
{
|
||||
value?.Close();
|
||||
|
||||
return sp;
|
||||
});
|
||||
}
|
||||
|
||||
public event Action Connected;
|
||||
public event Action Disconnected;
|
||||
public event Action<string> Logging;
|
||||
|
||||
public string COMPort { get; }
|
||||
|
||||
public bool IsOpen => serialPorts.TryGetValue(this.COMPort, out var sp) && sp.IsOpen;
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (serialPorts.TryGetValue(this.COMPort, out var sp))
|
||||
{
|
||||
try
|
||||
{
|
||||
sp.Close();
|
||||
this.closeAwaiter.Wait(5000);
|
||||
this.closeAwaiter.Reset();
|
||||
|
||||
sp.DataReceived -= this.SP_DataReceived;
|
||||
sp.Disposed -= this.SP_Disposed;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
if (serialPorts.TryGetValue(this.COMPort, out var sp) && !sp.IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
sp.DataReceived += this.SP_DataReceived;
|
||||
sp.Disposed += this.SP_Disposed;
|
||||
|
||||
sp.Open();
|
||||
|
||||
this.Connected?.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<byte[]> ReadBytes()
|
||||
{
|
||||
var sp = this.GetOpenedSP();
|
||||
var size = sp.ReadBufferSize;
|
||||
var buffer = new byte[size];
|
||||
var length = 0;
|
||||
|
||||
using (sp)
|
||||
{
|
||||
while (sp.IsOpen)
|
||||
{
|
||||
this.readAwaiter.Wait();
|
||||
|
||||
try
|
||||
{
|
||||
buffer = new byte[size];
|
||||
length = sp.Read(buffer, 0, size);
|
||||
|
||||
Array.Resize(ref buffer, length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
|
||||
this.readAwaiter.Reset();
|
||||
|
||||
yield return buffer;
|
||||
}
|
||||
|
||||
sp.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> ReadLines()
|
||||
{
|
||||
var sp = this.GetOpenedSP();
|
||||
var text = default(string);
|
||||
|
||||
using (sp)
|
||||
{
|
||||
while (sp.IsOpen)
|
||||
{
|
||||
this.readAwaiter.Wait();
|
||||
|
||||
try
|
||||
{
|
||||
text = sp.ReadLine();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
|
||||
this.readAwaiter.Reset();
|
||||
|
||||
yield return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
if (serialPorts.TryRemove(this.COMPort, out var sp))
|
||||
{
|
||||
sp.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(byte[] bytes)
|
||||
{
|
||||
var sp = this.GetOpenedSP();
|
||||
|
||||
try
|
||||
{
|
||||
sp.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(string text)
|
||||
{
|
||||
var sp = this.GetOpenedSP();
|
||||
|
||||
try
|
||||
{
|
||||
sp.Write(text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logging?.Invoke(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private SysSerialPort GetOpenedSP()
|
||||
{
|
||||
if (!serialPorts.TryGetValue(this.COMPort, out var sp))
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(SerialPort)} on {this.COMPort} dose not exists!");
|
||||
}
|
||||
|
||||
if (!sp.IsOpen)
|
||||
{
|
||||
this.Close();
|
||||
this.Open();
|
||||
}
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
private void SP_DataReceived(object _, SerialDataReceivedEventArgs args)
|
||||
=> this.readAwaiter.Set();
|
||||
|
||||
private void SP_Disposed(object _, EventArgs _1)
|
||||
{
|
||||
this.closeAwaiter.Set();
|
||||
this.Disconnected?.Invoke();
|
||||
}
|
||||
|
||||
public static string[] GetPortNames()
|
||||
=> SysSerialPort.GetPortNames();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Json
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System;
|
||||
|
||||
public class JsonVersionsConverter : JsonConverter<FwVersion>
|
||||
{
|
||||
public override FwVersion ReadJson(JsonReader reader, Type objectType, FwVersion existingValue, Boolean hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
var jobject = JToken.Load(reader);
|
||||
|
||||
if (jobject.Type != JTokenType.Object)
|
||||
{
|
||||
if (int.TryParse($"{jobject}", out var version))
|
||||
{
|
||||
return new FwVersion
|
||||
{
|
||||
First = version
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return jobject.ToObject<FwVersion>();
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, FwVersion value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Attributes\EregisterFeatureAttribute.cs" />
|
||||
<Compile Include="Eregister.cs" />
|
||||
<Compile Include="EregisterChangeMeterTypeTask.cs" />
|
||||
<Compile Include="EregisterFactory.cs" />
|
||||
<Compile Include="EregisterCheckFinalizationTask.cs" />
|
||||
<Compile Include="EregisterCheckInitializationTask.cs" />
|
||||
@ -157,10 +158,6 @@
|
||||
<Compile Include="Telegrams\SEMI.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Common.Hardware.Ports\Common.Hardware.Ports.csproj">
|
||||
<Project>{9ae071c0-db12-4e09-a3c7-43f6dcd518d6}</Project>
|
||||
<Name>Common.Hardware.Ports</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\Common.Hardware.SIRT\Common.Hardware.SIRT.csproj">
|
||||
<Project>{8de8e742-ee0a-4004-aa49-3d08d748e5ac}</Project>
|
||||
<Name>Common.Hardware.SIRT</Name>
|
||||
|
||||
@ -7,7 +7,9 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
public class Eregister
|
||||
@ -33,6 +35,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<EregisterTask> LoadInspectionInitializationTasks()
|
||||
{
|
||||
var features = parameters.LoadInspectionInitializationFeatures();
|
||||
|
||||
this.LoadProgrammingParameters(features);
|
||||
|
||||
var lastTask = this.runningTasks.LastOrDefault();
|
||||
|
||||
if (lastTask != null)
|
||||
{
|
||||
this.runningTasks.Enqueue(new EregisterChangeMeterTypeTask(lastTask.Frequency, lastTask.Timeout)
|
||||
{
|
||||
SlotNr = features.SlotNr,
|
||||
PoNr = features.PoNr,
|
||||
SerialNr = features.SerialNr,
|
||||
P1 = new P811
|
||||
{
|
||||
DelPamSemi = true,
|
||||
},
|
||||
RequestAddress = features.RequestAddress,
|
||||
ResponseAddress = features.ResponseAddress,
|
||||
EncryptionKey = features.EncryptionKey,
|
||||
Name = "Change Meter Type"
|
||||
});
|
||||
}
|
||||
|
||||
return this.runningTasks.AsEnumerable();
|
||||
}
|
||||
|
||||
internal IEnumerable<EregisterTask> LoadInspectionFinalizationTasks()
|
||||
{
|
||||
var features = parameters.LoadInspectionFinalizationFeatures();
|
||||
@ -56,15 +87,6 @@
|
||||
return this.runningTasks.AsEnumerable();
|
||||
}
|
||||
|
||||
internal IEnumerable<EregisterTask> LoadInspectionInitializationTasks()
|
||||
{
|
||||
var features = parameters.LoadInspectionInitializationFeatures();
|
||||
|
||||
this.LoadProgrammingParameters(features);
|
||||
|
||||
return this.runningTasks.AsEnumerable();
|
||||
}
|
||||
|
||||
internal void StartProgramming()
|
||||
{
|
||||
var manualResetEventSlim = new ManualResetEventSlim();
|
||||
@ -76,6 +98,9 @@
|
||||
|
||||
if (task is EregisterTask _task)
|
||||
{
|
||||
var numberStyles = NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier;
|
||||
var cultureInfo = CultureInfo.InvariantCulture;
|
||||
|
||||
foreach (var etask in this.runningTasks)
|
||||
{
|
||||
if (etask.State != SIRTTaskState.Cancelled && etask.State != SIRTTaskState.Completed)
|
||||
@ -85,6 +110,16 @@
|
||||
etask.RequestAddress = _task.RequestAddress;
|
||||
etask.ResponseAddress = _task.ResponseAddress;
|
||||
}
|
||||
|
||||
if (etask.RadioFWVersion is null)
|
||||
{
|
||||
etask.RadioFWHex = _task.DEBUG?.RadioFWVersion;
|
||||
|
||||
if (int.TryParse($"{etask.RadioFWHex}", numberStyles, cultureInfo, out var radioFWVersion))
|
||||
{
|
||||
etask.RadioFWVersion = radioFWVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +147,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadProgrammingParameters(EregisterFeatures features)
|
||||
private void LoadProgrammingParameters(EregisterFeatures features, [CallerMemberName] string caller = "")
|
||||
{
|
||||
this.Clear();
|
||||
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister
|
||||
{
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
public class EregisterChangeMeterTypeTask : EregisterTask
|
||||
{
|
||||
public EregisterChangeMeterTypeTask(int frequency, int timeout = 5000) : base(frequency, timeout)
|
||||
=> this.Name = "Change meter type";
|
||||
|
||||
public override byte[] ToByteArray()
|
||||
{
|
||||
var numberStyles = NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier;
|
||||
var cultureInfo = CultureInfo.InvariantCulture;
|
||||
|
||||
// from Pruef2000.exe
|
||||
if (int.TryParse($"1108", numberStyles, cultureInfo, out var minFWVersion) && int.TryParse($"110B", numberStyles, cultureInfo, out var exceptFWVersion))
|
||||
{
|
||||
if (this.RadioFWVersion < minFWVersion && this.RadioFWVersion != exceptFWVersion)
|
||||
{
|
||||
// do not change the type
|
||||
this.request.Data = Array.Empty<byte>();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.request.Data.Length > 0)
|
||||
{
|
||||
this.Name = $"FW: {this.RadioFWHex} - C & I";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Name = $"FW: {this.RadioFWHex} - Residential";
|
||||
}
|
||||
|
||||
this.NotifyChanged();
|
||||
|
||||
return base.ToByteArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.WaterMeter.eRegister.Attributes;
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
this.parameters = parameters;
|
||||
this.pendingState = SIRTTaskState.Completed;
|
||||
this.Name = "Initial Check";
|
||||
|
||||
this.Data = new OpticalTelegram
|
||||
{
|
||||
Minutes = 0
|
||||
@ -99,10 +98,7 @@
|
||||
message.AppendLine();
|
||||
message.AppendLine("Möchten Sie mit die Prüfung fortfahren (Yes), oder Abbrechen (No)?");
|
||||
|
||||
var result = MessageBox.Show(
|
||||
message.ToString()
|
||||
, $"Fehler bei der Prüfungsinitialisierung"
|
||||
, MessageBoxButtons.YesNo);
|
||||
var result = MessageBox.Show(message.ToString(), $"Fehler bei der Prüfungsinitialisierung", MessageBoxButtons.YesNo);
|
||||
|
||||
if (result == DialogResult.No)
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
using Common.Hardware.WaterMeter.eRegister.Models;
|
||||
|
||||
|
||||
@ -56,6 +56,10 @@
|
||||
|
||||
public FactoryState Mode { get; set; }
|
||||
|
||||
public int? RadioFWVersion { get; set; }
|
||||
|
||||
public string RadioFWHex { get; set; }
|
||||
|
||||
public override byte[] ToByteArray()
|
||||
{
|
||||
var data = this.request.Data;
|
||||
@ -78,7 +82,7 @@
|
||||
P1 = this.request.P1,
|
||||
P2 = this.request.P2,
|
||||
|
||||
}.ToByteArray();
|
||||
}.GetBytes();
|
||||
}
|
||||
|
||||
protected override void OnTimeout(object sender, ElapsedEventArgs e)
|
||||
@ -149,19 +153,25 @@
|
||||
{
|
||||
this.SEMI = new SEMI(data, this.Frequency, this.P11);
|
||||
this.IsEncrypted = this.SEMI.Crc != 0;
|
||||
this.Label = this.SEMI.PAMStatus.ToString();
|
||||
this.Label = default(string);
|
||||
|
||||
if (this.request.Data.Length > 0 && this.request.Data[0] == Pam.GetDebug && this.DEBUG == null)
|
||||
if (this.SEMI.PAMStatus == PAMStatus.OK)
|
||||
{
|
||||
this.Label = "!DEBUG";
|
||||
}
|
||||
else if (this.SEMI.PAMStatus == PAMStatus.OK)
|
||||
{
|
||||
this.State = SIRTTaskState.Completed;
|
||||
this.EndProcessResponse(response);
|
||||
if (this.request.Data.Length > 0 && this.request.Data[0] == Pam.GetDebug && this.DEBUG == null)
|
||||
{
|
||||
this.Label = "!DEBUG";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = SIRTTaskState.Completed;
|
||||
this.Label = this.SEMI.PAMStatus.ToString();
|
||||
this.EndProcessResponse(response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Label = this.SEMI.PAMStatus.ToString();
|
||||
|
||||
if (this.SEMI.PAMStatus == PAMStatus.EXPIREDAUTH)
|
||||
{
|
||||
this.State = SIRTTaskState.Cancelled;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ActivateMetrologyTestMode : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class AlarmsMask : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeDataLoggerSettings : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeFixedDateReadingSettings : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeMeterId : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeMeterReading : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeRadioId : Pam
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ChangeSensusRFEncryptionKey : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class OpenMeteringTransmitionIntervalWMBus : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class ParameterizeLeakageDetection : SingleBytePam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SendBubbleUpBurst : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetAlarms : AlarmsMask
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetBytterySeconds : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetDateAndTime : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetFrequencyOffset : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetMetrologyParameters : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetPcbId : Pam
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class SetTFXParameters : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Features
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
public class WirelessMBusMode : Pam
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Models
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.WaterMeter.eRegister.Attributes;
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
using Common.Hardware.WaterMeter.eRegister.Telegrams;
|
||||
@ -434,15 +434,6 @@
|
||||
Vpp = this.VolumePerPulse,
|
||||
VppLED = (uint)this.VolumePerLedPulse
|
||||
};
|
||||
|
||||
features.Debug = new EregisterDebugFeatures
|
||||
{
|
||||
SetMeterType = new SetMeterType
|
||||
{
|
||||
Type = (MeterTypes)this.CandIType
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
return features;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Telegrams
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.SIRT.Parameters;
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Telegrams
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.SIRT.Parameters;
|
||||
|
||||
public class DEBUG : Payload
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Telegrams
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.SIRT.Parameters;
|
||||
|
||||
using System;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Common.Hardware.WaterMeter.eRegister.Telegrams
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.Hardware.SIRT.Parameters;
|
||||
using Common.Hardware.WaterMeter.eRegister.Features;
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit fc6d1c60141d1dcce304443fe14f62a94e9dc123
|
||||
Subproject commit 1713caf91ba8771f7331a878005598ef8c47d263
|
||||
@ -6,7 +6,7 @@
|
||||
<appSettings>
|
||||
<add key="ConnectionString" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;" />
|
||||
<add key="EncryptionKeisUrl" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb/api/eregister/radiokey/byserialno/{0}" />
|
||||
<add key="SIRTComPorts" value="COM6, COM8" />
|
||||
<add key="SIRTComPorts" value="COM6,COM8" />
|
||||
<add key="PSNR" value="1" />
|
||||
</appSettings>
|
||||
<runtime>
|
||||
|
||||
@ -151,7 +151,6 @@
|
||||
<Compile Include="Models\Eregister_Shared.cs" />
|
||||
<Compile Include="Models\HttpContext.cs" />
|
||||
<Compile Include="Models\P2000_Shared.cs" />
|
||||
<Compile Include="Models\SIRTFactoryModel.cs" />
|
||||
<Compile Include="Pages\EregisterFinalize.xaml.cs">
|
||||
<DependentUpon>EregisterFinalize.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -279,10 +278,6 @@
|
||||
<Resource Include="ILLink\ILLink.Descriptors.LibraryBuild.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Hardware\Common.Hardware.Ports\Common.Hardware.Ports.csproj">
|
||||
<Project>{9ae071c0-db12-4e09-a3c7-43f6dcd518d6}</Project>
|
||||
<Name>Common.Hardware.Ports</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Hardware\Common.Hardware.SIRT\Common.Hardware.SIRT.csproj">
|
||||
<Project>{8de8e742-ee0a-4004-aa49-3d08d748e5ac}</Project>
|
||||
<Name>Common.Hardware.SIRT</Name>
|
||||
|
||||
@ -5,91 +5,47 @@
|
||||
<Grid.DataContext>
|
||||
<vm:SIRTBroadcasterVM />
|
||||
</Grid.DataContext>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border BorderBrush="Gray"
|
||||
BorderThickness="0, 0, 1, 1"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ComboBox Grid.Row="0"
|
||||
IsEnabled="{Binding ComPortsEnabled}"
|
||||
ItemsSource="{Binding PortNames}"
|
||||
Margin="5, 5, 5, 0"
|
||||
Padding="5, 3, 0, 3"
|
||||
SelectedItem="{Binding PortName}"
|
||||
Width="100"/>
|
||||
<Button Command="{Binding AddSIRTCommand}"
|
||||
Content="Add SIRT"
|
||||
Grid.Row="1"
|
||||
IsEnabled="{Binding AddEnabled}"
|
||||
Margin="5, 5, 5, 0"
|
||||
Padding="20, 3"
|
||||
Width="100" />
|
||||
<Button Command="{Binding ClearAllCommand}"
|
||||
Content="Clear all"
|
||||
Grid.Row="2"
|
||||
IsEnabled="{Binding ClearEnabled}"
|
||||
Margin="5, 5, 5, 5"
|
||||
Padding="20, 3"
|
||||
Width="100" />
|
||||
<Border BorderBrush="Gray" BorderThickness="0, 0, 0, 1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ItemsControl Grid.Column="0" ItemsSource="{Binding Connections}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:SIRTConnectionVM}">
|
||||
<Border BorderBrush="DimGray"
|
||||
BorderThickness="0 0 1 0">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Grid.Column="0" Content="{Binding PortName}" Margin="0 0 0 0" Padding="0 5" FontWeight="Bold" />
|
||||
<Label Grid.Column="1" Content="-" Margin="5 0 0 0" Padding="0 5" />
|
||||
<Label Grid.Column="2" Content="{Binding HexId}" Margin="5 0 0 0" Padding="0 5" FontWeight="Bold" />
|
||||
<Label Grid.Column="3" Content="-" Margin="5 0 0 0" Padding="0 5" />
|
||||
<Label Grid.Column="4" Content="{Binding Frequency}" Margin="5 0 0 0" Padding="0 5" FontWeight="Bold" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<Button Grid.Column="1"
|
||||
Content="Refresh connections"
|
||||
Command="{Binding AddSIRTsCommand}"
|
||||
Padding="20 5"
|
||||
Cursor="Hand"
|
||||
Margin="5"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border BorderBrush="Gray"
|
||||
BorderThickness="0, 0, 0, 1"
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsEnabled="{Binding ComPortsEnabled}"
|
||||
VerticalAlignment="Stretch">
|
||||
<ItemsControl ItemsSource="{Binding Connections}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:SIRTConnectionVM}">
|
||||
<Grid Margin="0, 0, 5, 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="WhiteSmoke" Grid.Column="0" Content="{Binding PortName}" Margin="5, 5, 5, 0" VerticalAlignment="Stretch" />
|
||||
<Label Background="WhiteSmoke" Grid.Column="1" Content="{Binding HexId}" Margin="0, 5, 5, 0" VerticalAlignment="Stretch" />
|
||||
<Label Background="WhiteSmoke" Grid.Column="2" Content="{Binding Frequency}" Margin="0, 5, 5, 0" VerticalAlignment="Stretch" />
|
||||
<Label Background="WhiteSmoke" Grid.Column="3" Content="{Binding IsRunning}" Margin="0, 5, 5, 0" VerticalAlignment="Stretch" />
|
||||
<Button Content="Reconnect"
|
||||
Command="{Binding ReconnectCommand}"
|
||||
Grid.Column="4"
|
||||
IsEnabled="{Binding ReconnectEnabled}"
|
||||
Margin="0, 5, 5, 0"
|
||||
Padding="20, 3" />
|
||||
<Button Content="Disconnect"
|
||||
Command="{Binding DisconnectCommand}"
|
||||
Grid.Column="5"
|
||||
IsEnabled="{Binding DisconnectEnabled}"
|
||||
Margin="0, 5, 5, 0"
|
||||
Padding="10, 3" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
serviceCollection
|
||||
.AddScoped<DeviceManager>()
|
||||
.AddScoped(CreateNLogger)
|
||||
.AddScoped<SIRTFactory>()
|
||||
.AddSingleton<SIRTFactory>()
|
||||
.AddTransient<HomeModel>()
|
||||
.AddTransient<SettingsModel>();
|
||||
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
ShowsNavigationUI="False"
|
||||
Source="Pages/EregisterManualProgramming.xaml"
|
||||
Source="Pages/Home.xaml"
|
||||
Title="TestBench UI">
|
||||
</NavigationWindow>
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
namespace Common.UI.Models
|
||||
{
|
||||
using System;
|
||||
|
||||
using Common.Hardware.SIRT;
|
||||
|
||||
using NLog;
|
||||
|
||||
public class SIRTFactoryModel
|
||||
{
|
||||
private readonly SIRTFactory sirtFactory;
|
||||
private readonly ILogger logger;
|
||||
|
||||
public SIRTFactoryModel(SIRTFactory sirtFactory, ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.sirtFactory = sirtFactory;
|
||||
this.sirtFactory.Logging += this.SirtFactory_Logging;
|
||||
}
|
||||
|
||||
internal Action<SIRTTask> EnqueueAction => this.sirtFactory.EnqueueTask;
|
||||
|
||||
internal void Initialize(string portNamesString, Action<SIRTBroadcaster> connecting)
|
||||
{
|
||||
var portNames = portNamesString
|
||||
?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?? Array.Empty<string>();
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
this.sirtFactory.ConnectSIRT(portName, connecting);
|
||||
}
|
||||
}
|
||||
|
||||
private void SirtFactory_Logging(string content)
|
||||
=> this.logger.Debug(content);
|
||||
|
||||
internal void DisconnectAll() => this.sirtFactory.CloseConnections();
|
||||
|
||||
public static implicit operator SIRTFactory (SIRTFactoryModel model) => model?.sirtFactory;
|
||||
}
|
||||
}
|
||||
@ -3,18 +3,21 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:Controls="clr-namespace:Common.UI.Controls"
|
||||
xmlns:VM="clr-namespace:Common.UI.ViewModels"
|
||||
WindowTitle="TestBench UI / Eregister finalize">
|
||||
WindowTitle="TestBench UI / Eregister finalize"
|
||||
FontFamily="Consolas">
|
||||
<Page.DataContext>
|
||||
<VM:EregisterFinalizeVM />
|
||||
</Page.DataContext>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Controls:SIRTBroadcasters Grid.Row="0" />
|
||||
<ScrollViewer Grid.Row="1"
|
||||
<Controls:MainMenu Background="#FFF0F0F0" Grid.Row="0" />
|
||||
<Controls:SIRTBroadcasters Background="#FFF0F0F0" Grid.Row="1" />
|
||||
<ScrollViewer Grid.Row="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalAlignment="Stretch"
|
||||
@ -23,7 +26,7 @@
|
||||
</ScrollViewer>
|
||||
<Border BorderBrush="#FFF0F0F0"
|
||||
BorderThickness="0, 1, 0, 0"
|
||||
Grid.Row="2" >
|
||||
Grid.Row="3" >
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<Button Content="Start Programming"
|
||||
Command="{Binding StartProgrammingCommand}"
|
||||
|
||||
@ -3,18 +3,21 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:Controls="clr-namespace:Common.UI.Controls"
|
||||
xmlns:VM="clr-namespace:Common.UI.ViewModels"
|
||||
WindowTitle="TestBench UI / Eregister initialize">
|
||||
WindowTitle="TestBench UI / Eregister initialize"
|
||||
FontFamily="Consolas">
|
||||
<Page.DataContext>
|
||||
<VM:EregisterInitializeVM />
|
||||
</Page.DataContext>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Controls:SIRTBroadcasters Background="#FFF0F0F0" Grid.Row="0" />
|
||||
<ScrollViewer Grid.Row="1"
|
||||
<Controls:MainMenu Background="#FFF0F0F0" Grid.Row="0" />
|
||||
<Controls:SIRTBroadcasters Background="#FFF0F0F0" Grid.Row="1" />
|
||||
<ScrollViewer Grid.Row="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalAlignment="Stretch"
|
||||
@ -23,7 +26,7 @@
|
||||
</ScrollViewer>
|
||||
<Border BorderBrush="Gray"
|
||||
BorderThickness="0, 1, 0, 0"
|
||||
Grid.Row="2" >
|
||||
Grid.Row="3" >
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<Button Content="Start Programming"
|
||||
Command="{Binding StartProgrammingCommand}"
|
||||
@ -31,19 +34,19 @@
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{Binding StartEnabled}"
|
||||
Margin="0, 0, 5, 0"
|
||||
Padding="20, 3"/>
|
||||
Padding="20, 5"/>
|
||||
<Button Content="Stop Programming"
|
||||
Command="{Binding StopProgrammingCommand}"
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{Binding StopEnabled}"
|
||||
Margin="0, 0, 5, 0"
|
||||
Padding="20, 3"/>
|
||||
Padding="20, 5"/>
|
||||
<Label FontWeight="Bold"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center"
|
||||
Margin="0"
|
||||
Padding="10, 0"
|
||||
Padding="20, 5"
|
||||
Content="{Binding TimeElapsed}"
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalContentAlignment="Center" />
|
||||
|
||||
@ -46,7 +46,6 @@
|
||||
this.sirtFactory = AppHost.GetService<SIRTFactory>();
|
||||
this.sirtFactory.Logging += x => this.logger.Debug(x);
|
||||
this.eregisterFactory = new EregisterFactory(this.sirtFactory);
|
||||
this.ProgrammingTasks = new ObservableCollection<EregisterTaskVM>();
|
||||
this.StartProgrammingCommand = new Command(this.StartProgrammingCommandHandler);
|
||||
this.StopProgrammingCommand = new Command(this.StopProgrammingCommandHandler);
|
||||
this.StartEnabled = true;
|
||||
@ -76,13 +75,8 @@
|
||||
public ICommand StartProgrammingCommand { get; }
|
||||
|
||||
public ICommand StopProgrammingCommand { get; }
|
||||
|
||||
private IEnumerable<GridItem> programmingTasks;
|
||||
public IEnumerable<GridItem> ProgrammingTasks
|
||||
{
|
||||
get => this.programmingTasks;
|
||||
set => this.Set(vm => vm.programmingTasks = value);
|
||||
}
|
||||
|
||||
public IEnumerable<GridItem> ProgrammingTasks { get; set; }
|
||||
|
||||
internal override void ViewModel_Loaded(object data)
|
||||
{
|
||||
@ -93,8 +87,6 @@
|
||||
this.sharedId = AuftragDbContext.P2000Shared.LoadPendingAction(psnr)?.Id ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
Task.Run(async () => await this.PrepareProgrammingAsync(this.eregisterFactory.LoadInspectionInitializationTasks));
|
||||
}
|
||||
|
||||
private void StartProgrammingCommandHandler()
|
||||
@ -106,20 +98,16 @@
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
this.programmingTask = Task
|
||||
.Run(async () =>
|
||||
.Run(() =>
|
||||
{
|
||||
await this.PrepareProgrammingAsync();
|
||||
await this.eregisterFactory.StartProgrammingAsync(this.cancellationToken);
|
||||
})
|
||||
.ContinueWith(_ =>
|
||||
{
|
||||
this.timer.Stop();
|
||||
|
||||
this.StartEnabled = true;
|
||||
this.StopEnabled = false;
|
||||
this.PrepareProgrammingAsync(this.eregisterFactory.LoadInspectionInitializationTasks)
|
||||
.Wait();
|
||||
this.timer.Start();
|
||||
this.eregisterFactory
|
||||
.StartProgrammingAsync(this.cancellationToken)
|
||||
.Wait();
|
||||
this.StopProgrammingCommandHandler();
|
||||
});
|
||||
|
||||
this.timer.Start();
|
||||
}
|
||||
|
||||
private void StopProgrammingCommandHandler()
|
||||
@ -239,7 +227,11 @@
|
||||
row = 1;
|
||||
}
|
||||
|
||||
this.ProgrammingTasks = tasks;
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.ProgrammingTasks = tasks;
|
||||
this.NotifyPropertyChanged(nameof(this.ProgrammingTasks));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,187 +1,64 @@
|
||||
namespace Common.UI.ViewModels
|
||||
{
|
||||
using Common.Hardware.Ports;
|
||||
using Common.Hardware.SIRT;
|
||||
using Common.UI.Infrastructure;
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
internal class SIRTBroadcasterVM : ViewModel<SIRTBroadcasterVM>
|
||||
{
|
||||
private readonly SIRTFactory broadcaster;
|
||||
private readonly ManagementEventWatcher comWatcher;
|
||||
private readonly SIRTFactory sirtFactory;
|
||||
|
||||
public SIRTBroadcasterVM()
|
||||
{
|
||||
this.broadcaster = AppHost.GetService<SIRTFactory>();
|
||||
this.sirtFactory = AppHost.GetService<SIRTFactory>();
|
||||
this.Connections = new ObservableCollection<SIRTConnectionVM>();
|
||||
this.PortNames = new ObservableCollection<string>();
|
||||
this.AddSIRTCommand = new Command(this.AddSIRTConnectionCommandHandler);
|
||||
this.ClearAllCommand = new Command(this.ClearAllCommandHandler);
|
||||
this.comWatcher = new ManagementEventWatcher("SELECT * FROM Win32_DeviceChangeEvent");
|
||||
this.comWatcher.EventArrived += (_, args) => this.UpdatePortNames();
|
||||
this.comWatcher.Start();
|
||||
this.AddSIRTsCommand = new Command(this.AddSIRTs);
|
||||
|
||||
//TODO: not needed hier
|
||||
//private readonly ManagementEventWatcher comWatcher;
|
||||
//this.comWatcher = new ManagementEventWatcher("SELECT * FROM Win32_DeviceChangeEvent");
|
||||
//this.comWatcher.EventArrived += (_, args) => this.UpdatePortNames();
|
||||
//this.comWatcher.Start();
|
||||
|
||||
this.AddSIRTs();
|
||||
this.UpdatePortNames();
|
||||
}
|
||||
|
||||
private bool comPortsEnabled;
|
||||
public bool ComPortsEnabled
|
||||
{
|
||||
get => this.comPortsEnabled;
|
||||
set => this.Set(vm => vm.comPortsEnabled = value);
|
||||
}
|
||||
|
||||
private bool addEnabled;
|
||||
public bool AddEnabled
|
||||
{
|
||||
get => this.addEnabled;
|
||||
set => this.Set(vm => vm.addEnabled = value);
|
||||
}
|
||||
|
||||
private bool cleanEnabled;
|
||||
public bool ClearEnabled
|
||||
{
|
||||
get => this.cleanEnabled;
|
||||
set => this.Set(vm => vm.cleanEnabled = value);
|
||||
}
|
||||
|
||||
private string portName;
|
||||
public string PortName
|
||||
{
|
||||
get => this.portName;
|
||||
set
|
||||
{
|
||||
this.Set(vm => vm.portName = value);
|
||||
|
||||
this.AddEnabled = !string.IsNullOrWhiteSpace(value);
|
||||
}
|
||||
}
|
||||
|
||||
public Action InvokeWhenReady { get; set; }
|
||||
|
||||
public ICommand AddSIRTCommand { get; }
|
||||
|
||||
public ICommand ClearAllCommand { get; }
|
||||
|
||||
public ObservableCollection<string> PortNames { get; }
|
||||
public ICommand AddSIRTsCommand { get; }
|
||||
|
||||
public ObservableCollection<SIRTConnectionVM> Connections { get; }
|
||||
|
||||
private void AddSIRTConnectionCommandHandler()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(this.PortName))
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
this.broadcaster.ConnectSIRT(this.PortName, broadcaster =>
|
||||
{
|
||||
var broadcasterVM = new SIRTConnectionVM(broadcaster);
|
||||
broadcasterVM.Removed += this.RemoveSIRTConnectionVM;
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.Connections.Add(broadcasterVM);
|
||||
});
|
||||
});
|
||||
|
||||
this.ClearEnabled = true;
|
||||
this.PortName = default(string);
|
||||
this.UpdatePortNames();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearAllCommandHandler()
|
||||
{
|
||||
this.ComPortsEnabled = false;
|
||||
this.ClearEnabled = false;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
this.broadcaster.RemoveConnections();
|
||||
this.InvokeAsync(this.Connections.Clear);
|
||||
this.UpdatePortNames();
|
||||
});
|
||||
}
|
||||
|
||||
private void RemoveSIRTConnectionVM(SIRTConnectionVM connectionVM)
|
||||
{
|
||||
this.ComPortsEnabled = false;
|
||||
this.ClearEnabled = false;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
this.broadcaster.CloseConnection(connectionVM.PortName);
|
||||
})
|
||||
.ContinueWith(_ =>
|
||||
{
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.Connections.Remove(connectionVM);
|
||||
});
|
||||
|
||||
this.UpdatePortNames();
|
||||
});
|
||||
}
|
||||
|
||||
private void AddSIRTs()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
Task.Run(() =>
|
||||
{
|
||||
var portNames = Appsettings
|
||||
.Get("SIRTComPorts")
|
||||
?.Split(new[] { ';', ',', ' ' })
|
||||
?.Select(x => x?.Trim())
|
||||
?.ToArray() ?? new string[0];
|
||||
|
||||
portNames = SerialPort
|
||||
.GetPortNames()
|
||||
.Intersect(portNames)
|
||||
.ToArray();
|
||||
|
||||
foreach (var portName in portNames)
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.broadcaster.ConnectSIRT(portName, broadcaster =>
|
||||
var portNames = Appsettings
|
||||
.Get("SIRTComPorts")
|
||||
?.Split(new[] { ';', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?.Select(x => x?.Trim())
|
||||
?.ToArray() ?? new string[0];
|
||||
|
||||
this.sirtFactory.RemoveConnections();
|
||||
this.Connections.Clear();
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
var broadcasterVM = new SIRTConnectionVM(broadcaster);
|
||||
broadcasterVM.Removed += this.RemoveSIRTConnectionVM;
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
this.sirtFactory.ConnectSIRT(portName, sirt =>
|
||||
{
|
||||
this.Connections.Add(broadcasterVM);
|
||||
this.Connections.Add(new SIRTConnectionVM(sirt));
|
||||
});
|
||||
});
|
||||
|
||||
this.ClearEnabled = true;
|
||||
|
||||
await Task.Delay(500);
|
||||
}
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdatePortNames()
|
||||
=> this.InvokeAsync(() =>
|
||||
{
|
||||
this.PortNames.Clear();
|
||||
|
||||
var portNames = SerialPort
|
||||
.GetPortNames()
|
||||
.Except(this.broadcaster.GetPortNames())
|
||||
.OrderBy(x => x);
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
this.PortNames.Add(portName);
|
||||
}
|
||||
|
||||
this.ComPortsEnabled = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,10 +9,13 @@
|
||||
|
||||
internal class SIRTConnectionVM : ViewModel<SIRTConnectionVM>
|
||||
{
|
||||
private static int count;
|
||||
|
||||
private readonly SIRTBroadcaster connection;
|
||||
|
||||
public SIRTConnectionVM(SIRTBroadcaster connection)
|
||||
{
|
||||
this.Id = ++count;
|
||||
this.connection = connection;
|
||||
this.connection.Activated += this.SIRTBroadcaster_Activated;
|
||||
this.connection.Connected += this.SIRTBroadcaster_Connected;
|
||||
@ -26,6 +29,8 @@
|
||||
|
||||
public event Action<SIRTConnectionVM> Removed;
|
||||
|
||||
public int Id { get; }
|
||||
|
||||
private string portName;
|
||||
public string PortName
|
||||
{
|
||||
@ -81,59 +86,71 @@
|
||||
|
||||
public ICommand RemoveCommand { get; }
|
||||
|
||||
private void RemoveCommand_Handler()
|
||||
{
|
||||
this.Removed?.Invoke(this);
|
||||
}
|
||||
private void RemoveCommand_Handler()
|
||||
=> this.Removed?.Invoke(this);
|
||||
|
||||
private void DisconnectCommand_Handler()
|
||||
{
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = false;
|
||||
this.IsRunning = null;
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = false;
|
||||
this.IsRunning = null;
|
||||
});
|
||||
|
||||
Task.Run((Action)this.connection.Close);
|
||||
}
|
||||
|
||||
private void ReconnectCommand_Handler()
|
||||
{
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = false;
|
||||
this.IsRunning = null;
|
||||
|
||||
Task.Run(() =>
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.connection.Close();
|
||||
this.connection.Open();
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = false;
|
||||
this.IsRunning = null;
|
||||
});
|
||||
|
||||
Task.Run((Action)this.connection.Open);
|
||||
}
|
||||
|
||||
private void SIRTBroadcaster_Activated()
|
||||
{
|
||||
this.DisconnectEnabled = true;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Activated";
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.DisconnectEnabled = true;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Activated";
|
||||
});
|
||||
|
||||
this.UpdateState(this.connection);
|
||||
}
|
||||
|
||||
private void SIRTBroadcaster_Connected()
|
||||
{
|
||||
this.DisconnectEnabled = true;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Connected";
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.DisconnectEnabled = true;
|
||||
this.ReconnectEnabled = false;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Connected";
|
||||
});
|
||||
|
||||
this.UpdateState(this.connection);
|
||||
}
|
||||
|
||||
private void SIRTBroadcaster_Disconnected()
|
||||
{
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = true;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Disconnected";
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.DisconnectEnabled = false;
|
||||
this.ReconnectEnabled = true;
|
||||
this.RemoveEnabled = true;
|
||||
this.IsRunning = "Disconnected";
|
||||
});
|
||||
|
||||
this.UpdateState(this.connection);
|
||||
}
|
||||
|
||||
@ -144,6 +161,10 @@
|
||||
this.PortName = connection.COMPort;
|
||||
this.HexId = connection.HexId;
|
||||
this.Frequency = $"{connection.Frequency}MHz";
|
||||
this.DisconnectEnabled = this.disconnectEnabled;
|
||||
this.ReconnectEnabled = this.reconnectEnabled;
|
||||
this.RemoveEnabled = this.removeEnabled;
|
||||
this.IsRunning = this.running;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user