calibration valkues commitestttt

This commit is contained in:
Roland Drabesch 2024-12-09 15:44:16 +01:00
commit e64fd66d3b
241 changed files with 23144 additions and 20949 deletions

1
.gitignore vendored
View File

@ -398,3 +398,4 @@ FodyWeavers.xsd
![Ww]eb.config
*applicationhost.config
/Common/CommonConsole
/Common/Common.v3.ncrunchsolution

View File

@ -239,7 +239,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "api_doc", "api_doc", "{E608
Hardware\WaterMeter\MagFlux\MagFluxApi\api_doc\SensorInfo.cs = Hardware\WaterMeter\MagFlux\MagFluxApi\api_doc\SensorInfo.cs
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Hardware.Interfaces.Ports.SirtBroadcaster", "Hardware\Interfaces\Ports\Common.Hardware.Interfaces.Ports.SirtBroadcaster\Common.Hardware.Interfaces.Ports.SirtBroadcaster.csproj", "{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Logic", "Logic\Common.Logic\Common.Logic.csproj", "{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@ -5459,70 +5459,70 @@ Global
{F7316525-FF8E-4651-BA67-3C9B948D1E91}.XP32bit|x64.Build.0 = Release|Any CPU
{F7316525-FF8E-4651-BA67-3C9B948D1E91}.XP32bit|x86.ActiveCfg = Release|Any CPU
{F7316525-FF8E-4651-BA67-3C9B948D1E91}.XP32bit|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.COM|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|x64.ActiveCfg = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|x64.Build.0 = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|x86.ActiveCfg = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Debug|x86.Build.0 = Debug|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.PerformTest|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.Release|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.ReleaseTest|x86.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|x64.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|x64.Build.0 = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|x86.ActiveCfg = Release|Any CPU
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}.XP32bit|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.COM|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|x64.Build.0 = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Debug|x86.Build.0 = Debug|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.PerformTest|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.Release|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.ReleaseTest|x86.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|x64.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|x64.Build.0 = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|x86.ActiveCfg = Release|Any CPU
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD}.XP32bit|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -5626,7 +5626,7 @@ Global
{F7316525-FF8E-4651-BA67-3C9B948D1E91} = {03D4F23E-7E4A-4091-BC96-036C996D351A}
{56768A27-D0E4-430E-8E75-AFC7319F189A} = {C9393A97-C0BB-4D59-A879-B572BE04CE15}
{E6081C0A-8452-44B4-8EB4-E0CAE9119830} = {56768A27-D0E4-430E-8E75-AFC7319F189A}
{F408DE9E-01E6-4CFF-AE79-B572B0674FA2} = {B9444AB7-1EB1-484A-8DE6-4EEE03498CD7}
{DB8F04AD-F9F7-413F-B96C-4697FE6512CD} = {57AA2731-BFD9-40A5-820F-E943FBC75D91}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4BCB7B69-696C-436A-86F7-C91EA5588164}

View File

@ -24,6 +24,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<NoWarn>IDE003;IDE0049;</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -39,8 +40,6 @@
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http">
@ -48,60 +47,21 @@
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="WindowsBase" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hardware\Interfaces\Ports\Common.Hardware.Interfaces.Ports.SirtBroadcaster\Common.Hardware.Interfaces.Ports.SirtBroadcaster.csproj">
<Project>{F408DE9E-01E6-4CFF-AE79-B572B0674FA2}</Project>
<Name>Common.Hardware.Interfaces.Ports.SirtBroadcaster</Name>
</ProjectReference>
<ProjectReference Include="..\Hardware\Interfaces\Ports\Common.Hardware.Interfaces.Ports.SIRT\Common.Hardware.Interfaces.Ports.Sirt.csproj">
<ProjectReference Include="..\Hardware\Interfaces\Ports\Common.Hardware.Interfaces.Ports.SIRT\Common.Hardware.Interfaces.Ports.SIRT.csproj">
<Project>{B23BFAF9-08AE-4311-8C08-FB2BB49EA2AD}</Project>
<Name>Common.Hardware.Interfaces.Ports.Sirt</Name>
</ProjectReference>
<ProjectReference Include="..\Hardware\Interfaces\Ports\Common.Hardware.Interfaces.Ports\Common.Hardware.Interfaces.Ports.csproj">
<Project>{9ae071c0-db12-4e09-a3c7-43f6dcd518d6}</Project>
<Name>Common.Hardware.Interfaces.Ports</Name>
</ProjectReference>
<ProjectReference Include="..\Hardware\WaterMeter\eRegister\Common.Hardware.WaterMeter.eRegister.Features\Common.Hardware.WaterMeter.eRegister.Features.csproj">
<Project>{E19C1694-132E-477C-86CB-8E146D5F59B0}</Project>
<Name>Common.Hardware.WaterMeter.eRegister.Features</Name>
</ProjectReference>
<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>
<ProjectReference Include="..\Hardware\WaterMeter\OmniPlus\Common.Hardware.WaterMeter.OmniPlus.Features\Common.Hardware.WaterMeter.OmniPlus.Features.csproj">
<Project>{9D89FA2A-1217-4CE9-B217-E7602B974EA9}</Project>
<Name>Common.Hardware.WaterMeter.OmniPlus.Features</Name>
</ProjectReference>
<ProjectReference Include="..\Hardware\WaterMeter\OmniPlus\Common.Hardware.WaterMeter.OmniPlus\Common.Hardware.WaterMeter.OmniPlus.csproj">
<Project>{6480cc2a-ab54-4a26-8413-d5141431c080}</Project>
<Name>Common.Hardware.WaterMeter.OmniPlus</Name>
</ProjectReference>
<ProjectReference Include="..\Logic\Common.Logic.Extensions.Http\Common.Logic.Extensions.Http.csproj">
<Project>{57ddae1e-fd6b-47e0-ad5e-8ccfad07f1d7}</Project>
<Name>Common.Logic.Extensions.Http</Name>
<Name>Common.Hardware.Interfaces.Ports.SIRT</Name>
</ProjectReference>
<ProjectReference Include="..\Logic\Common.Logic.Extensions.SQL\Common.Logic.Extensions.SQL.csproj">
<Project>{62490923-cd17-45a6-b79f-a027927c75b5}</Project>
<Project>{62490923-CD17-45A6-B79F-A027927C75B5}</Project>
<Name>Common.Logic.Extensions.SQL</Name>
</ProjectReference>
<ProjectReference Include="..\OmniPlus\OmniPlus\OmniPlus.csproj">
<Project>{F8D84B9A-0FCF-4083-B067-8C39B7314152}</Project>
<Name>OmniPlus</Name>
</ProjectReference>
<ProjectReference Include="..\Utils\Common.Utils.Extensions\Common.Utils.Extensions.csproj">
<Project>{05f0ccaf-9f2b-45f9-a7f8-12f29ad182f3}</Project>
<Name>Common.Utils.Extensions</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="configuration.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -1,726 +1,21 @@
namespace CommonConsole
{
using Common.Hardware.WaterMeter.OmniPlus;
using Common.Hardware.Interfaces.Ports.Sirt;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var broadcaster = new SirtBroadcaster("COM6");
broadcaster.Exception += Console.WriteLine;
broadcaster.Start();
Task.Delay(10000).Wait();
broadcaster.Stop();
}
public class Cordonel : Dictionary<String, App>
{
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
foreach (var x in this)
{
x.Value.Name = x.Key;
}
}
}
public class App
{
public Byte Id { get; set; }
public String Name { get; set; }
public V Version { get; set; }
public Registers Registers { get; set; }
public Statuses Status { get; set; }
}
public class V
{
public UInt16? First { get; set; }
public UInt16? Last { get; set; }
}
public class Registers : Dictionary<String, Register>
{
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
foreach (var x in this)
{
x.Value.Name = x.Key;
}
}
}
public class Register
{
public Byte Id { get; set; }
public String Name { get; set; }
public Detail[] Details { get; set; }
}
public class Detail
{
public V Version { get; set; }
public String Type { get; set; }
public String StaticType { get; set; }
public String Description { get; set; }
public Privilege Privilege { get; set; }
public Values Values { get; set; }
}
public class Values
{
public Object Minimum { get; set; }
public Object Maximum { get; set; }
public Object Default { get; set; }
}
public class Privilege
{
public Privileges Lvl1 { get; set; }
public Privileges Lvl2 { get; set; }
public Privileges Lvl3 { get; set; }
public Privileges Lvl4 { get; set; }
public Privileges Lvl5 { get; set; }
public Privileges Lvl6 { get; set; }
public Privileges Lvl7 { get; set; }
public Privileges Lvl8 { get; set; }
}
public enum Privileges
{
NA,
RO,
WO,
RW,
}
public class Statuses : Dictionary<String, Status>
{
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
foreach (var x in this)
{
x.Value.Name = x.Key;
}
}
}
public class Status
{
public Byte Id { get; set; }
public String Name { get; set; }
}
/// <summary>
/// 0B
/// D0
/// FF C6 25 F3
/// 00
/// 0A
/// 11 08
/// 11 08
///
/// 04 01 C7 47 9F 77 17 00 6A 00 08 08 00 00 00 00 05 68 46 89 02 01 01 16 00 0A 00 00 02 71 02 71 00 00 00 00 00 00 00 08
/// </summary>
//var bytes = new[] { 0x08, 0x11 };
//var bits = new Byte[16];
//var x = 0;
//foreach (var @byte in bytes)
//{
// for (var i = 0; i< 8; i++, x++)
// {
// bits[x] = (Byte) ((@byte >> i) & 1);
// }
//}
//Array.Reverse(bits);
//var type = bits[15] == 0 ? 'B' : 'R';
//var majorBits = new Byte[8];
//majorBits[0] = bits[14];
//majorBits[1] = bits[13];
//majorBits[2] = bits[12];
//var major = 0;
//for (var i = 0; i< 8; i++)
//{
// major |= majorBits[i] << i;
//}
//var minorBits = new Byte[8];
//majorBits[0] = bits[11];
//majorBits[1] = bits[10];
//majorBits[2] = bits[9];
//majorBits[2] = bits[8];
//var minor = 0;
//for (var i = 0; i< 8; i++)
//{
// minor |= minorBits[i] << i;
//}
//Console.WriteLine($"{type}{major}.{minor}.{0x08}");
//var programmingBatch = new JusteRegisterProgrammingBatch();
//if (programmingBatch.StartOnCOMPort("COM6"))
//{
// var task = new JusteRegisterProgrammingTask
// {
// Cmd = JustSirtMessage.W_PAM,
// P1 = new P811
// {
// DelPamSemi = true
// },
// Address = 319020415,
// Data = new Byte[]
// {
// // Metrology parameters
// 0x92, 0x10, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x71, 0x02, 0x00, 0x00,
// // Provide Pin Auth Level III
// 0x43, 0x03, 0x63, 0x93, 0x73, 0x22,
// }
// };
// programmingBatch.Run(task);
// Console.ReadKey();
// programmingBatch.Stop();
//}
//else
//{
// Console.WriteLine("Not connected!");
//}
// 01020304050607081112131415161718
// E6C88800DEB868C0D6A84880CE982840
//var encryptionKey = new Byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };
//var task = new JusteRegisterProgrammingTask
//{
// Cmd = JustSirtMessage.W_PAM,
// P1 = new P811
// {
// DelPamSemi = true,
// WakeUpCmd = true
// },
// Address = 4291305226,
// // Address = 319020415,
// Data = new Byte[]
// {
// // Change Key
// // 0x6C, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
// // LED on
// // 0x1F, 0x01, 0x08,
// // Reboot
// 0x0E, 0x00,
// // Provide Pin Auth Level I
// // 0x43, 0x01, 0x14, 0x30, 0x68, 0xD0,
// // Provide Pin Auth Level II
// // 0x43, 0x02, 0x14, 0x0E, 0x80, 0x40,
// // Provide Pin Auth Level III
// 0x43, 0x03, 0x63, 0x93, 0x73, 0x22,
// // Reset credits
// // 0x1F, 0x01, 0x03,
// },
// EncryptionKey = encryptionKey
//};
//programmingBatch.Run(task);
//task.Wait();
// 55 81 14 00 FF C8 1F 0A 0B 07 FA E3 AA EA 8A 7B 7B D9 A7 D7 D5 B8 16
// 55 81 14 00 FF C8 1F 0A 0B 07 FA E3 AA EA 8A 7B 7B D9 A7 D7 D5 B8 16
//var task = new JusteRegisterTask
//{
// Cmd = JustSirtMessage.W_PAM,
// P1 = new P811
// {
// DelPamSemi = true
// },
// Address = 319020415,
// Data = new Byte[]
// {
// // WUP stay awake
// 0x00, 0x00,
// // LAT
// 0x02, 0x00,
// // MBUS 7
// 0x05, 0x07,
// // TX
// 0x10, 0x00, 0x03,
// // Provide Pin Auth Level I
// // 0x43, 0x01, 0x14, 0x30, 0x68, 0xD0,
// // Provide Pin Auth Level II
// 0x43, 0x02, 0x14, 0x0E, 0x80, 0x40,
// // Provide Pin Auth Level III
// // 0x43, 0x03, 0x63, 0x93, 0x73, 0x22,
// // Reset credits
// // 0x1F, 0x01, 0x03,
// }
//};
//programmingBatch.Run(task);
//task.Wait();
//task = new JusteRegisterTask
//{
// Cmd = JustSirtMessage.W_PAM,
// P1 = new P811
// {
// DelPamSemi = true
// },
// Address = 319020415,
// Data = new Byte[]
// {
// // Parametersatz
// // Provide Pin Auth Level I
// // 0x43, 0x01, 0x14, 0x30, 0x68, 0xD0,
// // Provide Pin Auth Level II
// 0x43, 0x02, 0x14, 0x0E, 0x80, 0x40,
// // Provide Pin Auth Level III
// // 0x43, 0x03, 0x63, 0x93, 0x73, 0x22,
// // Reset credits
// // 0x1F, 0x01, 0x03,
// }
//};
//programmingBatch.Run(task);
//task.Wait();
//public static byte[] Decrypt(Byte[] key, params Byte[] message)
//{
// var decryptLength = message.Length;
// var decryptedBytes = new Byte[decryptLength];
// for (int i = 0; i < decryptLength; i++)
// {
// decryptedBytes[i] = message[i];
// }
// var start = 14;
// var end = start + decryptedBytes[7] 6;
// var token = decryptedBytes[9];
// for (var i = start; i < end; i++)
// {
// token += (Byte)(decryptedBytes[i (token & 0x3) 1] >> ((token >> 6) & 0x1));
// decryptedBytes[i] ^= key[(token >> 2) & 0x0F];
// if (token > 127)
// {
// decryptedBytes[i] = (Byte)~decryptedBytes[i];
// }
// }
// return decryptedBytes;
//}
//public static byte[] Encrypt(Byte[] key, UInt32 address, params Byte[] telegramBytes)
//{
// Console.WriteLine(address);
// Console.WriteLine(BitConverter.ToString(key));
// Console.WriteLine(BitConverter.ToString(telegramBytes));
// var telegramLength = telegramBytes.Length;
// var telegramIndex = 0;
// var encryptedBytes = new Byte[telegramLength + 6];
// var encryptLength = encryptedBytes.Length;
// var index = 0;
// encryptedBytes[index++] = (Byte)(address >> 24);
// encryptedBytes[index++] = (Byte)(address >> 16);
// encryptedBytes[index++] = (Byte)(address >> 8);
// encryptedBytes[index++] = (Byte)(address >> 0);
// foreach (var _byte in telegramBytes)
// {
// encryptedBytes[index++] = telegramBytes[telegramIndex++];
// }
// var telegramCRC = CalculateCrc(encryptedBytes, 1, (UInt16)(encryptLength 3));
// encryptedBytes[index++] = (Byte)(telegramCRC >> 8);
// encryptedBytes[index++] = (Byte)(telegramCRC >> 0);
// Console.WriteLine(BitConverter.ToString(encryptedBytes));
// var token = (Byte)0xFF;
// var reference = address;
// for (var i = 0; i < encryptLength; i++)
// {
// // Update pKeyDefinition for this byte
// token += (Byte)(((reference >> ((token & 0x3) << 3)) & 0xFF) >> ((token >> 6) & 1));
// // Update the unencrypted reference before the byte gets encrypted
// reference = (reference << 8);
// reference += encryptedBytes[i];
// // Encrypt the data by applying the resepective key
// encryptedBytes[i] ^= key[((token >> 2) & 0x0F)];
// // Check if data has to be inverted
// if (token > 127)
// {
// encryptedBytes[i] = (Byte)~encryptedBytes[i];
// }
// }
// Console.WriteLine(BitConverter.ToString(encryptedBytes));
// Console.WriteLine();
// return encryptedBytes;
//}
//public static ushort CalculateCrc(byte[] data, ushort start, ushort length)
//{
// byte zeichen, test;
// ushort crc_result;
// ushort ui_index;
// byte h;
// crc_result = 0xFFFF;
// ui_index = start;
// if (data.Length >= length + start)
// {
// while (ui_index < length + start)
// {
// zeichen = data[ui_index];
// ui_index++;
// for (h = 0; h < 8; h++)
// {
// test = 0;
// if ((crc_result & 0x8000) != 0)
// {
// test = 0x80;
// }
// crc_result <<= 1;
// if (((zeichen & 0x80) ^ test) != 0)
// {
// crc_result ^= 0x1021;
// }
// zeichen <<= 1;
// }
// }
// }
// return crc_result;
//}
}
}
//var connector = EregisterConnector.CreateNew("COM6", 1000);
//connector.Add(1, 0319020415, 0319020415);//433
//connector.AddHexCommand(1, "00 00");
//connector.Add(2, 0319020441, "4291317405", "4291317405", null, false); // 433
//connector.InitInspection();
//connector.Add(3, 4291317405, 4291317405);//433
//connector.AddHexCommand(3, "00 00");
// connector.RunCommands();
//var connector = EregisterConnector.CreateNew("COM6", 1000);
//connector.Add(1, 0319020415, 0319020415);//433
//connector.AddHexCommand(1, "00 00");
//connector.Add(2, 0319020441, 0319020441);//433
//connector.AddHexCommand(2, "00 00");
//connector.Add(3, 4291317405, 4291317405);//433
//connector.AddHexCommand(3, "00 00");
//connector.InitInspection();
//var connection = new OmniConnection();
//connection.UseUniPro("COM16");
//var system = connection.ViewSystemParameters();
//connection.Disconnect();
// 0x08, 0x0E, 0x13, 0x03, 0xEE, 0xAC, 0x00, 0x00, 0x01, 0xF4, 0x00, 0x00, 0x92, 0x0A, 0x00, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x13, 0x13, 0x03, 0xEE, 0xAC, 0x07, 0x0E, 0x10, 0xA0, 0x57, 0x4E, 0xDA, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x05, 0xA0, 0x0C, 0x03, 0x01, 0x2E, 0x46, 0x7C, 0x76, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x25, 0x14, 0x3B
// 0x0B, 0x10, 0x13, 0x03, 0xEE, 0xAC, 0x00, 0x0A, 0x11, 0x0B, 0x11, 0x08, 0x04, 0x02, 0xC8, 0xF4, 0xFB, 0xA7, 0x18, 0x00, 0x65, 0x00, 0x35, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xEE, 0x34, 0x02, 0x01, 0x01, 0x16, 0x00, 0x25, 0x02, 0x71, 0x00, 0x00, 0x82, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0xC3
//TX|01-01-01-01
//TX|9B-33-07-0D-0B-08-FD-03-00-00-E1-84-06-00-02-8B-00-54-25
//TX|01-01-01-01
//TX|9B-33-06-0D-0A-08-FD-67-00-E8-03-25-00-02-93-59-12
//RX|9B-43-07-0D-0B-00-01-00-E8-03-25-00-00-00-01-29-00-33-5A
//TX|01-01-01-01
//TX|9B-33-04-0D-06-08-FD-67-01-01-80-40-7F
//TX|01-01-01-01
//TX|9B-33-06-0D-0A-08-FD-67-00-06-00-1E-00-01-A7-0C-65
//TX|01-01-01-01
//TX|9B-33-04-0D-06-08-FD-67-01-01-80-40-7F
//TX|01-01-01-01
//TX|9B-33-06-0D-0A-08-FD-67-00-05-00-25-00-01-AD-CC-4A
//TX|01-01-01-01
//TX|9B-33-04-0D-06-08-FD-67-01-01-80-40-7F
}

View File

@ -9,9 +9,10 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Common.Hardware.Interfaces.Ports.Sirt</RootNamespace>
<AssemblyName>Common.Hardware.Interfaces.Ports.Sirt</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -22,6 +23,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>IDE0003;IDE0017;IDE0049;</NoWarn>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -30,6 +32,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -41,39 +44,28 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="JustSirtMessage.cs" />
<Compile Include="JustSirtProxy.cs" />
<Compile Include="Parameters\AuthLevel.cs" />
<Compile Include="Parameters\BluetoothOperating.cs" />
<Compile Include="Parameters\ByteExtensions.cs" />
<Compile Include="Parameters\OperatingModes.cs" />
<Compile Include="Parameters\P11.cs" />
<Compile Include="Parameters\P12.cs" />
<Compile Include="Parameters\P811.cs" />
<Compile Include="Parameters\PAMStatus.cs" />
<Compile Include="Parameters\PamTimeout.cs" />
<Compile Include="Parameters\RFModuleOperating.cs" />
<Compile Include="Parameters\SirtOperating.cs" />
<Compile Include="Requests\ReadPamRequest.cs" />
<Compile Include="Requests\ReadRegRequest.cs" />
<Compile Include="SIRTRequest.cs" />
<Compile Include="Requests\WritePamRequest.cs" />
<Compile Include="Requests\WriteRegRequest.cs" />
<Compile Include="Responses\AcknOrAnswerResponse.cs" />
<Compile Include="Responses\FromAirResponse.cs" />
<Compile Include="SIRTResponse.cs" />
<Compile Include="SIRTMessage.cs" />
<Compile Include="SIRTBroadcaster.cs" />
<Compile Include="SIRTConstants.cs" />
<Compile Include="SirtBroadcaster.cs" />
<Compile Include="SirtHub.cs" />
<Compile Include="SirtMessage.cs" />
<Compile Include="SirtConnection.cs" />
<Compile Include="SirtTask.cs" />
<Compile Include="SirtTaskState.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SIRTTask.cs" />
<Compile Include="SIRTTask[TRequest].cs" />
<Compile Include="Tasks\ActivateSIRTTask.cs" />
<Compile Include="Tasks\DeleteFromPamPoolTask.cs" />
<Compile Include="Tasks\IdentifySIRTTask.cs" />
<Compile Include="Tasks\ReadPamPoolTask.cs" />
<Compile Include="Tasks\WritePamTask.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Utils\Common.Utils.Extensions\Common.Utils.Extensions.csproj">
<Project>{05F0CCAF-9F2B-45F9-A7F8-12F29AD182F3}</Project>
<Name>Common.Utils.Extensions</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Utils\Crc16Ccitt\Crc16Ccitt.csproj">
<Project>{91DEF0C0-AA4F-40AE-8F18-CB717FDE7E7F}</Project>
<Name>Crc16Ccitt</Name>

View File

@ -1,166 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
public class JustSirtMessage
{
public const Byte MIN_LEN = 12;
public const Byte PC2SIRT = 0x55;
public const Byte SIRT2PC = 0xFF;
public const Byte W_PAM = 0x81;
public const Byte R_PAM = 0x82;
public const Byte W_REG = 0x84;
public const Byte R_REG = 0x87;
public const Byte FROMAIR = 0x11;
public const Byte ACKNANSW = 0x12;
public const Byte STOP = 0x16;
public const Byte BUP = 0x00;
public const Byte LAT = 0x01;
public const Byte DEBUG = 0x0B;
public const Byte SEMI = 0x08;
private readonly DateTime timestamp;
private Byte[] bytes;
public JustSirtMessage(DateTime? timestamp = null)
{
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = new Byte[MIN_LEN];
this.bytes[0] = PC2SIRT;
}
public JustSirtMessage(Byte[] bytes, DateTime? timestamp = null)
{
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = bytes;
}
public Byte Cmd
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte P1
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte P2
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public UInt32 Address
{
get
{
var address = 0U;
address ^= (UInt32)this.bytes[4] << 24;
address ^= (UInt32)this.bytes[5] << 16;
address ^= (UInt32)this.bytes[6] << 8;
address ^= (UInt32)this.bytes[7] << 0;
return address;
}
set
{
this.bytes[4] = (Byte)(value >> 24);
this.bytes[5] = (Byte)(value >> 16);
this.bytes[6] = (Byte)(value >> 8);
this.bytes[7] = (Byte)(value >> 0);
}
}
public Byte Length => this.bytes[8];
public Byte[] Data
{
get
{
var data = new Byte[this.Length];
Array.Copy(this.bytes, 9, data, 0, this.Length);
return data;
}
set
{
if (value is null)
{
value = new Byte[0];
}
this.bytes[8] = (Byte)value.Length;
Array.Resize(ref this.bytes, MIN_LEN + this.Length);
Array.Clear(this.bytes, 9, this.bytes.Length - 9);
Array.Copy(value, 0, this.bytes, 9, this.Length);
}
}
public UInt16 CRC
{
get
{
var length = this.bytes.Length;
var crc = default(UInt16);
crc ^= (UInt16)(this.bytes[length - 3] << 8);
crc ^= (UInt16)(this.bytes[length - 2] << 0);
return crc;
}
}
public Byte[] ToByteArray()
{
var length = this.bytes.Length;
var crc = this.CRCCCITT(1, length - 3);
this.bytes[length - 3] = (Byte)(crc >> 8);
this.bytes[length - 2] = (Byte)(crc >> 0);
this.bytes[length - 1] = STOP;
return this.bytes;
}
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
public static implicit operator Byte[](JustSirtMessage message)
=> message.ToByteArray() ?? new Byte[0];
private UInt16 CRCCCITT(Int32 start, Int32 length)
{
var crc = (UInt16)0xFFFF;
for (var b = start; b < length; b++)
{
var _byte = this.bytes[b];
var token = (UInt16)((_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;
}
}
}

View File

@ -1,135 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Timers;
public class JustSirtProxy
{
private readonly JustSerialPort serialPort;
private readonly List<Byte> buffer;
private readonly Timer timer;
public JustSirtProxy(String portName)
{
var settings = new SerialPortSettings
{
BaudRate = SerialPortBaudRate.X115200,
DataBits = SerialPortDataBits.X8,
Parity = SerialPortParity.None,
PortName = portName,
StopBits = SerialPortStopBits.One
};
this.serialPort = new JustSerialPort(settings);
this.buffer = new List<Byte>();
this.timer = new Timer();
}
public event Action<JustSirtMessage> MessageReceived;
public Boolean IsOpen => this.serialPort.IsOpen;
public event Action<String> Logging
{
add => this.serialPort.Logging += value;
remove => this.serialPort.Logging -= value;
}
public void Log(Object value) => this.serialPort.Log(value);
public Boolean TryClose()
{
var closed = false;
try
{
this.timer.Stop();
this.serialPort.TryClose();
closed = true;
}
catch (Exception e)
{
this.Log(e);
}
return closed;
}
public Boolean TryOpen()
{
var opened = this.serialPort.TryOpen();
if (opened)
{
this.timer.Elapsed += this.Timer_Elapsed;
this.timer.AutoReset = true;
this.timer.Interval = 50;
this.timer.Start();
opened = true;
}
return opened;
}
public void WriteBytes(params Byte[] bytes)
=> this.serialPort.WriteBytes(bytes);
private Byte[] bytes;
private Int32 bytesLength;
private Int32 bufferLength;
private Int32 start;
private Int32 lengthIX;
private Byte length;
private Int32 stopIX;
private void Timer_Elapsed(Object sender, ElapsedEventArgs _1)
{
this.bytes = this.serialPort.ReadBytes();
this.bytesLength = this.bytes.Length;
if (this.bytesLength > 0)
{
this.buffer.AddRange(this.bytes);
}
this.bufferLength = this.buffer.Count;
this.start = this.buffer.IndexOf(JustSirtMessage.SIRT2PC);
if (this.start < 0)
{
this.buffer.Clear();
return;
}
this.lengthIX = this.start + 8;
if (this.lengthIX >= this.bufferLength)
{
return;
}
this.length = this.buffer[this.lengthIX];
this.stopIX = this.lengthIX + this.length + 3;
if (this.stopIX >= this.bufferLength)
{
return;
}
else if (this.buffer[this.stopIX] != JustSirtMessage.STOP)
{
return;
}
this.bytesLength = this.stopIX - this.start + 1;
this.bytes = new Byte[this.bytesLength];
this.buffer.CopyTo(this.start, this.bytes, 0, this.bytesLength);
this.buffer.RemoveRange(0, this.start + this.bytesLength);
this.MessageReceived?.Invoke(new JustSirtMessage(this.bytes));
}
}
}

View File

@ -1,45 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using System;
public class AuthLevel
{
public enum Level : UInt64
{
I = 0x004301143068D0,
II = 0x004302140E8040,
III = 0x00430363937322,
}
private readonly Level pin;
private readonly Byte[] bytes;
private AuthLevel(Level pin)
{
this.pin = pin;
this.bytes = new Byte[6];
var bytes = BitConverter.GetBytes((UInt64)this.pin);
Array.Copy(bytes, 0, this.bytes, 0, this.bytes.Length);
}
public static readonly AuthLevel I = Level.I;
public static readonly AuthLevel II = Level.II;
public static readonly AuthLevel III = Level.III;
public override String ToString()
=> BitConverter.ToString(this.bytes);
public static implicit operator AuthLevel(Level level)
=> new AuthLevel(level);
public static implicit operator UInt64(AuthLevel level)
=> (UInt64)level.pin;
public static implicit operator Byte[](AuthLevel level)
=> level.bytes;
public static implicit operator String (AuthLevel level)
=> level.ToString();
}
}

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
public class BluetoothOperating
@ -55,7 +57,7 @@
}
public static implicit operator Byte(BluetoothOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator BluetoothOperating(Byte _byte)
=> new BluetoothOperating(_byte.GetBits());

View File

@ -1,31 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using System;
public static class ByteExtensions
{
public static Byte[] GetBits(this Byte @byte)
{
var bits = new Byte[8];
for (int i = 0; i < 8; i++)
{
bits[i] = (Byte)((@byte >> i) & 1);
}
return bits;
}
public static Byte GetByte(this Byte[] bits)
{
var @byte = default(int);
for (int i = 0; i < 8; i++)
{
@byte |= bits[i] << i;
}
return (Byte)@byte;
}
}
}

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -170,7 +172,7 @@
}
public static implicit operator Byte(P11 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P11(Byte _byte)
=> new P11(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -162,7 +164,7 @@
}
public static implicit operator Byte(P12 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P12(Byte _byte)
=> new P12(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -233,7 +235,7 @@
}
public static implicit operator Byte(P811 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P811(Byte _byte)
=> new P811(_byte.GetBits());

View File

@ -0,0 +1,65 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
public class PAMStatus
{
private readonly Byte[] bits;
public PAMStatus(Byte _byte)
=> this.bits = _byte.GetBits();
public Boolean CMD_UNKNOWN => this.bits[0] == 1;
public Boolean WRONG_AUTH => this.bits[1] == 1;
public Boolean EXPIRED_AUTH => this.bits[2] == 1;
public Boolean MIXED_TYPES => this.bits[3] == 1;
public Boolean OUT_OF_RANGE => this.bits[4] == 1;
public override String ToString()
{
var status = nameof(OK);
var value = this.bits.ToByte();
if ((value & 1) == 1)
{
status = nameof(CMD_UNKNOWN);
}
if ((value & 2) == 2)
{
status = nameof(WRONG_AUTH);
}
if ((value & 4) == 4)
{
status = nameof(EXPIRED_AUTH);
}
if ((value & 8) == 8)
{
status = nameof(MIXED_TYPES);
}
if ((value & 16) == 16)
{
status = nameof(OUT_OF_RANGE);
}
return status;
}
public static Byte OK = 0;
public static implicit operator Byte(PAMStatus status)
=> status?.bits?.ToByte() ?? 0xFF;
public static implicit operator String(PAMStatus status)
=> status?.ToString();
}
}

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
{
using Common.Utils.Extensions;
using System;
public class RFModuleOperating
@ -21,7 +23,7 @@
Array.Copy(this.bits, 0, bits, 0, 4);
return (OperatingModes)bits.GetByte();
return (OperatingModes)bits.ToByte();
}
set
{
@ -68,7 +70,7 @@
}
public static implicit operator Byte(RFModuleOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator RFModuleOperating(Byte _byte)
=> new RFModuleOperating(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Parameters
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using Common.Utils.Extensions;
using System;
public class SirtOperating
@ -128,7 +130,7 @@
}
public static implicit operator Byte(SirtOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator SirtOperating(Byte _byte)
=> new SirtOperating(_byte.GetBits());

View File

@ -1,35 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Requests
{
using Common.Hardware.Interfaces.Ports.Sirt;
using System;
public class ReadPamRequest : SIRTRequest
{
/// <summary>
/// <list>
/// <item>
/// <term>true</term>
/// <description>shows content of PAM structure of this address</description>
/// </item>
/// <item>
/// <term>false</term>
/// <description>show stored PAM for this address</description>
/// </item>
/// </list>
/// </summary>
public Boolean PamStruct
{
get => this.message.P1 == 1;
set => this.message.P1 = (Byte)(value ? 1 : 0);
}
protected override Byte[] ToByteArray()
{
this.message.Start = SIRTConstants.Pc2Sirt;
this.message.Cmd = SIRTConstants.ReadPam;
return this.message.ToByteArray();
}
}
}

View File

@ -1,23 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Requests
{
using Common.Hardware.Interfaces.Ports.Sirt;
using System;
public class ReadRegRequest : SIRTRequest
{
public Byte ReadLength
{
get => this.message.P2;
set => this.message.P2 = value;
}
protected override Byte[] ToByteArray()
{
this.message.Start = SIRTConstants.Pc2Sirt;
this.message.Cmd = SIRTConstants.ReadReg;
return this.message.ToByteArray();
}
}
}

View File

@ -1,87 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Requests
{
using Common.Hardware.Interfaces.Ports.Sirt;
using Common.Hardware.Interfaces.Ports.Sirt.Parameters;
using System;
public class WritePamRequest : SIRTRequest
{
private readonly P811 parameter811 = default(Byte);
public WritePamRequest()
=> this.parameter811 = this.message.P1;
/// <summary>
/// <inheritdoc cref="P811.WakeUpModul"/>
/// </summary>
public Boolean WakeUpModul
{
get => this.parameter811.WakeUpModul;
set => this.parameter811.WakeUpModul = value;
}
/// <summary>
/// <inheritdoc cref="P811.WakeUpCmd"/>
/// </summary>
public Boolean WakeUpCmd
{
get => this.parameter811.WakeUpCmd;
set => this.parameter811.WakeUpCmd = value;
}
/// <summary>
/// <inheritdoc cref="P811.IgnoreTimeout"/>
/// </summary>
public Boolean IgnoreTimeout
{
get => this.parameter811.IgnoreTimeout;
set => this.parameter811.IgnoreTimeout = value;
}
/// <summary>
/// <inheritdoc cref="P811.DelPamSemi"/>
/// </summary>
public Boolean DelPamSemi
{
get => this.parameter811.DelPamSemi;
set => this.parameter811.DelPamSemi = value;
}
/// <summary>
/// <inheritdoc cref="P811.DelPamTx"/>
/// </summary>
public Boolean DelPamTx
{
get => this.parameter811.DelPamTx;
set => this.parameter811.DelPamTx = value;
}
/// <summary>
/// <inheritdoc cref="P811.DelPamAdr"/>
/// </summary>
public Boolean DelPamAdr
{
get => this.parameter811.DelPamAdr;
set => this.parameter811.DelPamAdr = value;
}
/// <summary>
/// <inheritdoc cref="P811.DelPamAll"/>
/// </summary>
public Boolean DelPamAll
{
get => this.parameter811.DelPamAll;
set => this.parameter811.DelPamAll = value;
}
protected override Byte[] ToByteArray()
{
this.message.Start = SIRTConstants.Pc2Sirt;
this.message.Cmd = SIRTConstants.WritePam;
this.message.P1 = this.parameter811;
return this.message.ToByteArray();
}
}
}

View File

@ -1,24 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Requests
{
using Common.Hardware.Interfaces.Ports.Sirt;
using System;
public class WriteRegRequest : SIRTRequest
{
public Byte WriteLength
{
get => this.message.P2;
set => this.message.P2 = value;
}
protected override Byte[] ToByteArray()
{
this.message.Start = SIRTConstants.Pc2Sirt;
this.message.Cmd = SIRTConstants.WriteReg;
this.message.P2 = this.message.Length;
return this.message.ToByteArray();
}
}
}

View File

@ -1,58 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Responses
{
using Common.Hardware.Interfaces.Ports.Sirt.Parameters;
using System;
public class AcknOrAnswerResponse : SIRTResponse
{
private readonly P12 parameterP12;
public AcknOrAnswerResponse(Byte[] bytes) : base(bytes)
=> this.parameterP12 = this.message.P1;
/// <summary>
/// <inheritdoc cref="P12.BufFull"/>
/// </summary>
public Boolean BufFull => this.parameterP12.BufFull;
/// <summary>
/// <inheritdoc cref="P12.OsBusy"/>
/// </summary>
public Boolean OsBusy => this.parameterP12.OsBusy;
/// <summary>
/// <inheritdoc cref="P12.WrongCRC"/>
/// </summary>
public Boolean WrongCRC => this.parameterP12.WrongCRC;
/// <summary>
/// <inheritdoc cref="P12.CmdNotExecuted"/>
/// </summary>
public Boolean CmdNotExecuted => this.parameterP12.CmdNotExecuted;
/// <summary>
/// <inheritdoc cref="P12.CmdUnknown"/>
/// </summary>
public Boolean CmdUnknown => this.parameterP12.CmdUnknown;
/// <summary>
/// <inheritdoc cref="P12.NoEntry"/>
/// </summary>
public Boolean NoEntry => this.parameterP12.NoEntry;
/// <summary>
/// <inheritdoc cref="P12.ByteUnknown"/>
/// </summary>
public Boolean ByteUnknown => this.parameterP12.ByteUnknown;
/// <summary>
/// <inheritdoc cref="P12.WildCardAddr"/>
/// </summary>
public Boolean WildCardAddr => this.parameterP12.WildCardAddr;
public String LastCmd => this.message.P2.ToString("X2");
public override Boolean IsCrcValid => base.IsCrcValid && (this.parameterP12 == 0 || this.parameterP12 == 128);
}
}

View File

@ -1,112 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Responses
{
using Common.Hardware.Interfaces.Ports.Sirt.Parameters;
using System;
public class FromAirResponse : SIRTResponse
{
private readonly P11 parameterP11;
private UInt16 mhz;
public FromAirResponse(Byte[] bytes) : base(bytes)
=> this.parameterP11 = this.message.P1;
/// <summary>
/// <inheritdoc cref="P11.SrcChannel"/>
/// </summary>
public Boolean SrcChannel => this.parameterP11.SrcChannel;
/// <summary>
/// <inheritdoc cref="P11.BothValid"/>
/// </summary>
public Boolean BothValid => this.parameterP11.BothValid;
/// <summary>
/// <inheritdoc cref="P11.InvalidMod1"/>
/// </summary>
public Boolean InvalidMod1 => this.parameterP11.InvalidMod1;
/// <summary>
/// <inheritdoc cref="P11.InvalidMod2"/>
/// </summary>
public Boolean InvalidMod2 => this.parameterP11.InvalidMod2;
/// <summary>
/// <inheritdoc cref="P11.LenOverflow"/>
/// </summary>
public Boolean LenOverflow => this.parameterP11.LenOverflow;
/// <summary>
/// <inheritdoc cref="P11.Attention"/>
/// </summary>
public Boolean Attention => this.parameterP11.Attention;
/// <summary>
/// <inheritdoc cref="P11.ModeRF"/>
/// </summary>
public Boolean ModeRF => this.parameterP11.ModeRF;
/// <summary>
/// <inheritdoc cref="P11.ModeSensus"/>
/// </summary>
public Boolean ModeSensus => this.parameterP11.ModeSensus;
public UInt16 MHz
{
get => this.mhz;
set
{
this.mhz = value;
this.ReceivePowerDbm = this.CalculateReceivePowerDbm(this.mhz, this.message.P2);
this.ReceivePowerPer = this.CalculateReceivePowerPer(this.mhz, this.message.P2);
}
}
public Double ReceivePowerDbm { get; private set; }
public Double ReceivePowerPer { get; private set; }
private Double CalculateReceivePowerDbm(Int32 MHz, Byte rssi)
{
var value = default(Double);
if (MHz == 433)
{
value = rssi * 0.5 - 140;
}
else if (MHz == 868)
{
value = rssi * 0.5 - 131.3;
}
return value;
}
private Double CalculateReceivePowerPer(Int32 MHz, Byte rssi)
{
var value = default(Double);
if (MHz == 433)
{
value = -57.6667 + 0.7333 * rssi;
}
else if (MHz == 868)
{
value = -40.316 + 0.66 * rssi;
}
if (value > 100)
{
value = 100;
}
else if (value < 0)
{
value = 0;
}
return value;
}
}
}

View File

@ -1,29 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
public abstract class SIRTRequest
{
internal readonly SIRTMessage message = new SIRTMessage();
public UInt32 Address
{
get => this.message.Address;
set => this.message.Address = value;
}
public Byte[] Payload
{
get => this.message.Payload;
set => this.message.Payload = value;
}
public override String ToString()
=> BitConverter.ToString(this);
protected abstract Byte[] ToByteArray();
public static implicit operator Byte[] (SIRTRequest request)
=> request.ToByteArray();
}
}

View File

@ -1,33 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
using Xylem.Common.Utils.Crc16Ccitt;
public class SIRTResponse
{
internal readonly SIRTMessage message;
public SIRTResponse(Byte[] bytes)
{
this.message = new SIRTMessage(bytes);
var existingCRC = this.message.CRC;
var calculatedCRC = Crc16Ccitt.CalculateCRC1021LSBFirst(bytes, 1, bytes.Length - 3);
this.IsCrcValid = existingCRC[0] == calculatedCRC[1]
&& existingCRC[1] == calculatedCRC[0];
}
public Byte ResponseType => this.message.Cmd;
public UInt32 Address => this.message.Address;
public Byte[] Payload => this.message.Payload;
public virtual Boolean IsCrcValid { get; }
public static implicit operator Byte[] (SIRTResponse response)
=> response?.message.Bytes ?? new Byte[0];
}
}

View File

@ -1,47 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using System;
public abstract class SIRTTask<TRequest> : SIRTTask where TRequest : SIRTRequest, new()
{
protected readonly TRequest request;
protected SIRTTask(UInt32 timeout) : base(timeout)
{
this.request = new TRequest();
this.Cmd = this.request.message.Cmd;
}
public override UInt32 Address
{
get => this.request.Address;
set => this.request.Address = value;
}
internal override void BeginAddResponse(AcknOrAnswerResponse response)
{
this.BeginAddResponse();
var done = this.AcknOrAnswerReceived(response);
this.EndAddResponse(done);
}
internal override void BeginAddResponse(FromAirResponse response)
{
this.BeginAddResponse();
var done = this.FromAirReceived(response);
this.EndAddResponse(done);
}
protected virtual Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => false;
protected virtual Boolean FromAirReceived(FromAirResponse response) => false;
protected override Byte[] GetRequestBytes() => this.request;
}
}

View File

@ -1,220 +1,248 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using Common.Hardware.Interfaces.Ports.Sirt.Tasks;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public class SIRTBroadcaster : SirtSerialPort
public class SirtBroadcaster
{
private readonly ConcurrentDictionary<UInt32, Queue<SIRTTask>> tasks;
private readonly SirtConnection connection;
private readonly ConcurrentDictionary<int, uint?> pampool;
private readonly ConcurrentDictionary<uint, DateTime> endpoints;
private readonly ConcurrentDictionary<uint, SirtTask> runningTasks;
private readonly ConcurrentDictionary<uint, ConcurrentQueue<SirtTask>> pendingTasks;
private CancellationTokenSource cancellationTokenSource;
private CancellationToken cancellationToken;
public SIRTBroadcaster(SerialPortSettings settings) : base(settings)
public SirtBroadcaster(String portName)
{
this.tasks = new ConcurrentDictionary<UInt32, Queue<SIRTTask>>();
this.DataReceived += this.SirtBroadcaster_DataReceived;
this.connection = new SirtConnection(portName);
this.connection.Exception += this.Throw;
this.connection.MessageReceived += this.Connection_MessageReceived;
this.pampool = new ConcurrentDictionary<int, uint?>();
this.endpoints = new ConcurrentDictionary<uint, DateTime>();
this.runningTasks = new ConcurrentDictionary<uint, SirtTask>();
this.pendingTasks = new ConcurrentDictionary<uint, ConcurrentQueue<SirtTask>>();
}
public event Action<Exception> Exception;
public event Action<String, Int32> Activated;
public event Action<UInt32> EndpointAvailable;
public UInt64 Id { get; private set; }
public String SIRTID { get; private set; }
public String SirtId { get; private set; }
public UInt16 MHz { get; private set; }
public Int32 MHz { get; private set; }
public void Add(SIRTTask task)
public Boolean IsRunning { get; private set; }
public void Add(SirtTask task)
{
task.AddressChanged += this.MoveToNewAddress;
task.Cancelled += _task => _task.Retry(60);
task.Done += this.RemoveSucceededAndExecuteNext;
task.Cancelled += this.Task_Dismiss;
task.Completed += this.Task_Dismiss;
this.tasks
.GetOrAdd(task.Address, new Queue<SIRTTask>())
this.pendingTasks
.GetOrAdd(task.Address, new ConcurrentQueue<SirtTask>())
.Enqueue(task);
}
public override void Close()
public void Start()
{
this.IsRunning = false;
if (this.connection.EnsureConnected())
{
this.pampool.Clear();
this.endpoints.Clear();
this.pendingTasks.Clear();
this.runningTasks.Clear();
var awaiter = new ManualResetEventSlim();
var task = SirtTask.ActivateSIRT;
task.Cancelled += _ => awaiter.Set();
task.Completed += _ => awaiter.Set();
task.Cancelled += this.Task_Dismiss;
task.Completed += this.Task_Dismiss;
this.runningTasks.TryAdd(task.Address, task);
this.connection.SendMessage(task);
awaiter.Wait();
awaiter.Reset();
if (task.State == SirtTaskState.Completed)
{
task = SirtTask.IdentifySIRT;
task.Cancelled += _ => awaiter.Set();
task.Completed += _ => awaiter.Set();
task.Cancelled += this.Task_Dismiss;
task.Completed += this.Task_Dismiss;
this.runningTasks.TryAdd(task.Address, task);
this.connection.SendMessage(task);
awaiter.Wait();
awaiter.Reset();
if (task.State == SirtTaskState.Completed && task.Last?.Length == 8)
{
this.Id = BitConverter.ToUInt64(task.Last, 0);
this.SirtId = BitConverter.ToString(task.Last);
this.MHz = this.SirtId[10] == '0' ? 868 : 433;
this.IsRunning = true;
}
}
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
Task.Run(this.StartObservingPamPool, this.cancellationToken);
Task.Run(this.StartObservingPendingTasks, this.cancellationToken);
}
}
public void Stop()
{
this.connection.MessageReceived -= this.Connection_MessageReceived;
this.connection.Exception -= this.Throw;
this.IsRunning = false;
try
{
this.cancellationTokenSource.Cancel();
this.cancellationTokenSource.Cancel(true);
}
catch (Exception e)
{
this.LogMessage(e.ToString());
this.Throw(e);
}
base.Close();
}
public override void Open()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
base.Open();
this.ActivateSIRT();
this.StartTasksExecutionAsync();
// this.StartPamPoolTrackingAsync();
}
private void ActivateSIRT()
{
var manuelResetEventSlim = new ManualResetEventSlim();
var activationTask = new ActivateSIRTTask();
activationTask.Cancelled += _ => manuelResetEventSlim.Set();
activationTask.Done += _ => manuelResetEventSlim.Set();
this.Add(activationTask);
this.Write(activationTask);
manuelResetEventSlim.Wait();
manuelResetEventSlim.Reset();
tasks.TryRemove(activationTask.Address, out var _);
var identificationTask = new IdentifySIRTTask();
identificationTask.Cancelled += task => manuelResetEventSlim.Set();
identificationTask.Done += task => manuelResetEventSlim.Set();
identificationTask.Identified += sirtID =>
try
{
this.SIRTID = sirtID;
this.connection.Close();
}
catch (Exception e)
{
this.Throw(e);
}
this.pampool.Clear();
this.endpoints.Clear();
this.pendingTasks.Clear();
this.runningTasks.Clear();
}
if (!String.IsNullOrWhiteSpace(this.SIRTID))
public uint[] ViewEndpoints()
=> this.endpoints.Keys.ToArray();
public uint?[] ViewPamPool()
=> this.pampool.Values.ToArray();
private void Connection_MessageReceived(SirtMessage message)
{
if (this.runningTasks.TryGetValue(message.Address, out var task) && task != null)
{
task.ReceiveMessage(message, this.MHz);
}
this.endpoints.AddOrUpdate(message.Address, DateTime.Now, (k, v) => DateTime.Now);
}
private async Task StartObservingPamPool()
{
var awaiter = new ManualResetEventSlim();
var task = SirtTask.ReadPamPool;
task.Cancelled += this.Task_Dismiss;
task.Completed += this.Task_Dismiss;
task.Completed += _task =>
{
var payload = new byte[] { };
if (_task is AnswerTask answerTask)
{
this.MHz = (UInt16)(this.SIRTID[10] == '1' ? 433 : 868);
payload = answerTask.Last;
}
var length = payload?.Length ?? 0;
if (length == 20)
{
uint? address;
var i = 0;
for (var x = 0; x < 5; x++)
{
address = 0;
address ^= (uint)(payload[i++] << 24);
address ^= (uint)(payload[i++] << 16);
address ^= (uint)(payload[i++] << 8);
address ^= payload[i++];
if (address == uint.MaxValue)
{
address = null;
}
this.pampool.AddOrUpdate(x, address, (k, v) => address);
}
}
awaiter.Set();
};
this.Add(identificationTask);
this.Write(identificationTask);
manuelResetEventSlim.Wait();
manuelResetEventSlim.Reset();
tasks.TryRemove(identificationTask.Address, out var _);
while (!this.cancellationToken.IsCancellationRequested)
{
this.runningTasks.TryAdd(task.Address, task);
this.connection.SendMessage(task);
awaiter.Wait();
awaiter.Reset();
task.Reset();
var deleteFromPamPool = new DeleteFromPamPoolTask(0xFFFFFFFF);
deleteFromPamPool.Cancelled += x => this.RemoveCancelled(x);
deleteFromPamPool.Done += x => manuelResetEventSlim.Set();
this.Write(deleteFromPamPool);
this.Activated?.Invoke(this.SIRTID, this.MHz);
await Task.Delay(1);
}
}
private void SirtBroadcaster_DataReceived(Byte[] data)
private async Task StartObservingPendingTasks()
{
var address = default(UInt32);
var dataType = data[1];
if (dataType == SIRTConstants.FromAir)
while (!this.cancellationToken.IsCancellationRequested)
{
var response = new FromAirResponse(data);
response.MHz = this.MHz;
address = response.Address;
var pendingAddresses = this.pendingTasks.Keys.ToArray();
if (this.tasks.TryGetValue(address, out var queue) && queue.Count > 0)
foreach (var address in pendingAddresses)
{
queue.Peek()?.BeginAddResponse(response);
}
}
else if (dataType == SIRTConstants.AcknOrAnswer)
{
var response = new AcknOrAnswerResponse(data);
address = response.Address;
if (this.tasks.TryGetValue(address, out var queue) && queue.Count > 0)
{
queue.Peek()?.BeginAddResponse(response);
}
}
else
{
var response = new SIRTResponse(data);
address = response.Address;
}
this.EndpointAvailable?.Invoke(address);
}
private void StartTasksExecutionAsync()
{
Task.Factory.StartNew(state =>
{
if (state is SIRTBroadcaster broadcaster)
{
var tasks = broadcaster.tasks;
while (true)
if (this.runningTasks.ContainsKey(address))
{
foreach (var address in tasks.Keys)
continue;
}
if (this.pendingTasks.TryGetValue(address, out var pendingTasks))
{
if (pendingTasks.TryPeek(out var task))
{
if (tasks.TryGetValue(address, out var queue))
if (task.Cmd == SirtMessage.W_PAM && this.pampool.Any(x => x.Value == address))
{
if (queue.Count > 0)
{
var peek = queue.Peek();
continue;
}
if (peek != null && !peek.IsRunning)
{
this.Write(peek);
peek.IsRunning = true;
}
}
if (pendingTasks.TryDequeue(out task))
{
this.runningTasks.AddOrUpdate(address, task, (_1, _2) => task);
this.connection.SendMessage(task);
}
}
}
}
}, this, this.cancellationToken);
}
private void MoveToNewAddress(UInt32 oldAddress, UInt32 newAddress)
{
if (this.tasks.TryRemove(oldAddress, out var queue))
{
this.tasks.GetOrAdd(newAddress, queue);
await Task.Delay(1);
}
}
private void RemoveSucceededAndExecuteNext(SIRTTask task)
{
if (this.tasks.TryGetValue(task.Address, out var queue))
{
if (queue.Count > 0)
{
var peek = queue.Peek();
private void Task_Dismiss(SirtTask task)
=> this.runningTasks.TryRemove(task?.Address ?? 0, out var _);
if (peek.IsDone)
{
queue.Dequeue();
}
}
}
}
private void RemoveCancelled(SIRTTask task)
{
if (this.tasks.TryGetValue(task.Address, out var queue))
{
if (queue.Count > 0)
{
var peek = queue.Peek();
var manuelResetEventSlim = new ManualResetEventSlim();
var deleteFromPamPool = new DeleteFromPamPoolTask(task.Address);
this.Write(deleteFromPamPool);
if (!peek.IsCancelled)
{
task.Retry(60);
}
}
}
}
private void Throw(Exception exception)
=> this.Exception?.Invoke(exception);
}
}

View File

@ -0,0 +1,155 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class SirtConnection
{
private readonly ISerialPort serialPort;
private readonly List<Byte> buffer;
private CancellationTokenSource cancellationTokenSource;
private CancellationToken cancellationToken;
public SirtConnection(String portName)
{
var settings = new SerialPortSettings
{
BaudRate = SerialPortBaudRate.X115200,
DataBits = SerialPortDataBits.X8,
Parity = SerialPortParity.None,
PortName = portName,
StopBits = SerialPortStopBits.One
};
this.serialPort = new SerialPort(settings);
this.serialPort.Exception += this.Throw;
this.buffer = new List<Byte>();
}
public event Action<Exception> Exception;
public event Action<SirtMessage> MessageReceived;
public void Close()
{
this.serialPort.Close();
this.buffer.Clear();
try
{
this.cancellationTokenSource.Cancel(true);
}
catch (Exception e)
{
this.Throw(e);
}
}
public bool EnsureConnected()
{
this.serialPort.Close();
this.serialPort.Open();
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
Task.Run(this.StartReading, this.cancellationToken);
Task.Run(this.StartParsing, this.cancellationToken);
return this.serialPort.IsOpen();
}
public bool IsOpen() => this.serialPort.IsOpen();
public void SendMessage(SirtMessage message)
=> this.serialPort.WriteBytes(message);
private async Task StartParsing()
{
var bufferLength = default(int);
var startIX = default(int);
var lengthIX = default(int);
var dataLength = default(int);
var stopIX = default(int);
var messageLength = default(int);
var message = default(byte[]);
while (!this.cancellationToken.IsCancellationRequested)
{
try
{
bufferLength = this.buffer.Count;
if (bufferLength >= 13)
{
startIX = this.buffer.IndexOf(SirtMessage.SIRT2PC);
if (startIX < 0)
{
this.buffer.Clear();
continue;
}
lengthIX = startIX + 8;
if (lengthIX >= bufferLength)
{
continue;
}
dataLength = this.buffer[lengthIX];
stopIX = lengthIX + dataLength + 3;
if (stopIX >= bufferLength)
{
continue;
}
else if (this.buffer[stopIX] != SirtMessage.STOP)
{
continue;
}
messageLength = stopIX - startIX + 1;
message = new Byte[messageLength];
this.buffer.CopyTo(startIX, message, 0, messageLength);
this.MessageReceived?.Invoke(new SirtMessage(message));
this.buffer.RemoveRange(0, startIX + messageLength);
}
}
catch (Exception e)
{
this.Throw(e);
}
await Task.Delay(1);
}
}
private async Task StartReading()
{
var bytes = default(byte[]);
var bytesLength = default(int);
while (!this.cancellationTokenSource.IsCancellationRequested)
{
bytes = this.serialPort.ReadBytes();
bytesLength = bytes?.Length ?? 0;
if (bytesLength > 0)
{
this.buffer.AddRange(bytes);
}
await Task.Delay(1);
}
}
private void Throw(Exception exception)
=> this.Exception?.Invoke(exception);
private void Throw(String _, Exception exception)
=> this.Exception?.Invoke(exception);
}
}

View File

@ -1,30 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System;
public static class SIRTConstants
{
public const Int32 CmdIndex = 1;
public const Int32 LengthIndex = 8;
public const Int32 MinLength = 12;
public const Byte AcknOrAnswer = 0x12;
public const Byte FromAir = 0x11;
public const Byte Pc2Sirt = 0x55;
public const Byte ReadPam = 0x82;
public const Byte ReadReg = 0x87;
public const Byte Sirt2Pc = 0xFF;
public const Byte StopByte = 0x16;
public const Byte WritePam = 0x81;
public const Byte WriteReg = 0x84;
public const Byte Bup = 0x00;
public const Byte Lat = 0x01;
public const Byte Semi = 0x08;
public const Byte Logger = 0x09;
public const Byte Test = 0x0A;
public const Byte Debug = 0x0B;
public const Byte EncFlexNet = 0x10;
public const Byte Pam = 0x20;
}
}

View File

@ -0,0 +1,30 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using System.Collections.Concurrent;
public class SirtHub
{
private readonly ConcurrentDictionary<int, ConcurrentDictionary<ulong, SirtBroadcaster>> sirts;
public SirtHub(string[] portNames)
{
this.sirts = new ConcurrentDictionary<int, ConcurrentDictionary<ulong, SirtBroadcaster>>();
foreach (var portName in portNames)
{
var broadcaster = new SirtBroadcaster(portName);
broadcaster.Start();
if (broadcaster.IsRunning)
{
this.sirts
.GetOrAdd(broadcaster.MHz, new ConcurrentDictionary<ulong, SirtBroadcaster>())
.AddOrUpdate(broadcaster.Id, broadcaster, (k, v) => broadcaster);
}
broadcaster.Stop();
}
}
}
}

View File

@ -2,33 +2,42 @@
{
using System;
using Xylem.Common.Utils.Crc16Ccitt;
internal class SIRTMessage
public class SirtMessage
{
public const Byte MIN_LEN = 12;
public const Byte PC2SIRT = 0x55;
public const Byte SIRT2PC = 0xFF;
public const Byte W_PAM = 0x81;
public const Byte R_PAM = 0x82;
public const Byte W_REG = 0x84;
public const Byte R_REG = 0x87;
public const Byte FROMAIR = 0x11;
public const Byte ACKNANSW = 0x12;
public const Byte STOP = 0x16;
public const Byte BUP = 0x00;
public const Byte LAT = 0x01;
public const Byte DEBUG = 0x0B;
public const Byte SEMI = 0x08;
private readonly DateTime timestamp;
private Byte[] bytes;
private Int32 bytesLength;
public SIRTMessage()
public SirtMessage(DateTime? timestamp = null)
{
this.bytes = new Byte[SIRTConstants.MinLength];
this.bytesLength = this.bytes.Length;
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = new Byte[MIN_LEN];
this.bytes[0] = PC2SIRT;
}
public SIRTMessage(Byte[] bytes)
public SirtMessage(Byte[] bytes, DateTime? timestamp = null)
{
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = bytes;
this.bytesLength = this.bytes.Length;
}
public Byte Start
{
get => this.bytes[0];
set => this.bytes[0] = value;
}
public Byte Cmd
{
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
@ -49,44 +58,35 @@
{
get
{
var address = new Byte[4];
var address = 0U;
Array.Copy(this.bytes, 4, address, 0, 4);
Array.Reverse(address);
address ^= (UInt32)this.bytes[4] << 24;
address ^= (UInt32)this.bytes[5] << 16;
address ^= (UInt32)this.bytes[6] << 8;
address ^= (UInt32)this.bytes[7];
return BitConverter.ToUInt32(address, 0);
return address;
}
set
{
var address = BitConverter.GetBytes(value);
Array.Reverse(address);
Array.Copy(address, 0, this.bytes, 4, 4);
this.bytes[4] = (Byte)(value >> 24);
this.bytes[5] = (Byte)(value >> 16);
this.bytes[6] = (Byte)(value >> 8);
this.bytes[7] = (Byte)value;
}
}
public Byte Length
{
get => this.bytes[8];
set
{
this.bytes[8] = value;
var newLength = SIRTConstants.MinLength + value;
public Byte Length => this.bytes[8];
Array.Resize(ref this.bytes, newLength);
this.bytesLength = this.bytes.Length;
}
}
public Byte[] Payload
public Byte[] Data
{
get
{
var payload = new Byte[this.Length];
var data = new Byte[this.Length];
Array.Copy(this.bytes, 9, payload, 0, this.Length);
Array.Copy(this.bytes, 9, data, 0, this.Length);
return payload;
return data;
}
set
{
@ -95,45 +95,72 @@
value = new Byte[0];
}
this.Length = (Byte)value.Length;
var newLength = SIRTConstants.MinLength + this.Length;
this.bytes[8] = (Byte)value.Length;
Array.Resize(ref this.bytes, newLength);
Array.Resize(ref this.bytes, MIN_LEN + this.Length);
Array.Clear(this.bytes, 9, this.bytes.Length - 9);
Array.Copy(value, 0, this.bytes, 9, this.Length);
this.bytesLength = this.bytes.Length;
}
}
internal Byte[] CRC => new Byte[]
public UInt16 CRC
{
this.bytes[this.bytesLength - 3],
this.bytes[this.bytesLength - 2]
};
get
{
var length = this.bytes.Length;
var crc = default(UInt16);
crc ^= (UInt16)(this.bytes[length - 3] << 8);
crc ^= (UInt16)(this.bytes[length - 2] << 0);
internal Byte[] Bytes => this.bytes;
return crc;
}
}
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
internal Byte[] ToByteArray()
public Byte[] ToByteArray()
{
var crc = Crc16Ccitt.CalculateCRC1021LSBFirst(this.bytes, 1, this.bytes.Length - 3);
var length = this.bytes.Length;
var crc = this.CRCCCITT(1, length - 3);
this.bytes[this.bytesLength - 3] = crc[1];
this.bytes[this.bytesLength - 2] = crc[0];
this.bytes[this.bytesLength - 1] = SIRTConstants.StopByte;
this.bytes[length - 3] = (Byte)(crc >> 8);
this.bytes[length - 2] = (Byte)(crc >> 0);
this.bytes[length - 1] = STOP;
return this.bytes;
}
public static implicit operator SIRTMessage(Byte[] bytes)
=> new SIRTMessage(bytes);
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
public static implicit operator Byte[](SIRTMessage message)
=> message.ToByteArray();
public static implicit operator Byte[](SirtMessage message)
=> message.ToByteArray() ?? new Byte[0];
public static implicit operator String (SIRTMessage message)
=> message.ToString();
private UInt16 CRCCCITT(Int32 start, Int32 length)
{
var crc = (UInt16)0xFFFF;
for (var b = start; b < length; b++)
{
var _byte = this.bytes[b];
var token = (UInt16)((_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;
}
}
}

View File

@ -1,97 +1,173 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using Common.Hardware.Interfaces.Ports.Sirt.Requests;
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using Common.Hardware.Interfaces.Ports.Sirt.Parameters;
using System;
using System.Collections.Concurrent;
using System.Timers;
public abstract class SIRTTask
public class SirtTask
{
protected const UInt32 TIMEOUT_SECONDS = 15;
protected readonly Timer timer;
private readonly SirtMessage request;
private readonly ConcurrentStack<SirtMessage> responses;
protected readonly UInt32 timeout;
protected readonly DateTime created;
protected readonly ReadRegRequest readRegRequest;
protected readonly ReadPamRequest readPamRequest;
protected readonly WriteRegRequest writeRegRequest;
protected SIRTTask(UInt32 timeout)
public SirtTask()
{
this.timeout = timeout;
this.created = DateTime.Now;
this.Timestamp = DateTime.MinValue;
this.State = SirtTaskState.Pending;
this.timer = new Timer();
this.request = new SirtMessage();
this.responses = new ConcurrentStack<SirtMessage>();
// Cancel after 10 seconds
this.timer.AutoReset = false;
this.timer.Interval = 10_000;
this.timer.Elapsed += this.Timer_Elapsed;
}
public event Action<SIRTTask> Done;
public event Action<SIRTTask> Cancelled;
public event Action<UInt32, UInt32> AddressChanged;
public event Action<Byte[]> TRXLogging;
public event Action<SirtTask> Completed;
public event Action<SirtTask> Cancelled;
public virtual UInt32 Address { get; set; }
public Boolean IsRunning { get; internal set; }
public Byte Cmd { get; protected set; }
public DateTime Timestamp { get; protected set; }
public Boolean IsDone { get; protected set; }
public Boolean IsCancelled { get; protected set; }
internal abstract void BeginAddResponse(AcknOrAnswerResponse response);
internal abstract void BeginAddResponse(FromAirResponse response);
internal void Retry(Double seconds)
public Byte Cmd
{
if (this.IsDone || (DateTime.Now - this.created).TotalSeconds > seconds)
get => this.request.Cmd;
set => this.request.Cmd = value;
}
public Byte P1
{
get => this.request.P1;
set => this.request.P1 = value;
}
public Byte P2
{
get => this.request.P2;
set => this.request.P2 = value;
}
public UInt32 Address
{
get => this.request.Address;
set => this.request.Address = value;
}
public Byte[] Data
{
get => this.request.Data;
set => this.request.Data = value;
}
public SirtTaskState State { get; private set; }
public virtual void ReceiveMessage(SirtMessage response, Int32 mhz)
{
if (this.State != SirtTaskState.Completed && this.State != SirtTaskState.Cancelled)
{
this.IsCancelled = true;
this.responses.Push(response);
this.State = SirtTaskState.Running;
if (this.request.Cmd == SirtMessage.W_PAM)
{
if (response.Cmd == SirtMessage.FROMAIR && response.Data[0] == SirtMessage.SEMI)
{
this.State = SirtTaskState.Completed;
}
}
else if (response.Cmd == SirtMessage.ACKNANSW)
{
this.State = SirtTaskState.Completed;
}
}
else
if (this.State == SirtTaskState.Completed)
{
this.IsCancelled = false;
this.IsRunning = false;
this.Completed?.Invoke(this);
this.timer.Stop();
}
}
protected void BeginAddResponse()
public virtual void Reset()
{
if (this.Timestamp == DateTime.MinValue)
{
this.Timestamp = DateTime.Now;
}
this.State = SirtTaskState.Pending;
this.responses.Clear();
this.timer.Stop();
}
protected void EndAddResponse(Boolean done)
public virtual Byte[] ToByteArray()
=> this.request.ToByteArray();
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
private void Timer_Elapsed(Object sender, ElapsedEventArgs e)
{
if (done)
{
this.NotifyDone();
}
else if ((DateTime.Now - this.Timestamp).TotalSeconds > this.timeout)
{
this.NotifyCancelled();
}
this.State = SirtTaskState.Cancelled;
this.Cancelled?.Invoke(this);
this.timer.Stop();
}
protected abstract Byte[] GetRequestBytes();
public static implicit operator Byte[] (SirtTask task)
=> task?.ToByteArray() ?? new Byte[] { };
protected void NotifyAddressChanged(UInt32 oldAddress, UInt32 newAddress)
=> this.AddressChanged?.Invoke(oldAddress, newAddress);
public static implicit operator SirtMessage(SirtTask task)
=> task?.request ?? new SirtMessage();
protected void NotifyCancelled() => this.Cancelled?.Invoke(this);
protected void NotifyDone()
internal static readonly AnswerTask ActivateSIRT = new AnswerTask
{
this.IsDone = true;
Cmd = SirtMessage.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 }
}
};
this.Done?.Invoke(this);
internal static readonly AnswerTask IdentifySIRT = new AnswerTask
{
Cmd = SirtMessage.R_REG,
Address = 0x11001820,
P2 = 0x08
};
internal static readonly AnswerTask ReadPamPool = new AnswerTask
{
Cmd = SirtMessage.R_PAM,
Address = 0xFFFFFFFF
};
internal static SirtTask DeleteFromPamPool(UInt32 address) => new SirtTask
{
Cmd = SirtMessage.W_PAM,
P1 = new P811 { DelPamAdr = true },
Address = address
};
}
public class AnswerTask : SirtTask
{
public AnswerTask() : base()
=> this.timer.Interval = 1000;
public Byte[] Last { get; private set; }
public override void ReceiveMessage(SirtMessage response, Int32 mhz)
{
if (this.State == SirtTaskState.Completed)
{
this.Last = response.Data ?? new byte[] { };
}
base.ReceiveMessage(response, mhz);
}
protected void NotifyTRX(Byte[] bytes) => this.TRXLogging?.Invoke(bytes);
public static implicit operator Byte[] (SIRTTask task) => task.GetRequestBytes();
}
}

View File

@ -0,0 +1,10 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
public enum SirtTaskState
{
Pending = 0,
Running = 1,
Completed = 2,
Cancelled = 3
}
}

View File

@ -1,35 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Tasks
{
using Common.Hardware.Interfaces.Ports.Sirt.Parameters;
using Common.Hardware.Interfaces.Ports.Sirt.Requests;
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using System;
internal class ActivateSIRTTask : SIRTTask<WriteRegRequest>
{
private UInt32 address;
public ActivateSIRTTask() : base(TIMEOUT_SECONDS)
{
this.request.Address = 0x20000000;
this.address = this.request.Address;
this.request.Payload = new Byte[]
{
new SirtOperating { /* standard */ },
new BluetoothOperating { BtOff = true },
new RFModuleOperating { RfOff = true },
new RFModuleOperating { OpMode = OperatingModes.ReceiveF1TransmitSensusRFF3 },
new PamTimeout { Minutes = 1 }
};
}
public override UInt32 Address
{
get => this.address;
set => this.address = value;
}
protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => response.IsCrcValid;
}
}

View File

@ -1,17 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Tasks
{
using System;
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
public class DeleteFromPamPoolTask : WritePamTask
{
public DeleteFromPamPoolTask(UInt32 address)
{
this.Address = address;
this.request.DelPamAdr = true;
}
protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => true;
}
}

View File

@ -1,49 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Tasks
{
using Common.Hardware.Interfaces.Ports.Sirt.Requests;
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using System;
internal class IdentifySIRTTask : SIRTTask<ReadRegRequest>
{
private UInt32 address;
public IdentifySIRTTask() : base(TIMEOUT_SECONDS)
{
this.request.Address = 0x11001820;
this.address = this.request.Address;
this.request.ReadLength = 8;
}
public event Action<String> Identified;
public override UInt32 Address
{
get => this.address;
set => this.address = value;
}
protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response)
{
if (!response.IsCrcValid)
{
this.NotifyCancelled();
return false;
}
var payload = response.Payload;
var identified = payload.Length > 0;
if (identified && this.Identified != null)
{
var sirtID = BitConverter.ToString(payload);
this.Identified.Invoke(sirtID);
}
return identified;
}
}
}

View File

@ -1,68 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt.Tasks
{
using Common.Hardware.Interfaces.Ports.Sirt.Requests;
using Common.Hardware.Interfaces.Ports.Sirt.Responses;
using System;
internal class ReadPamPoolTask : SIRTTask<ReadPamRequest>
{
private UInt32 address;
public ReadPamPoolTask() : base(TIMEOUT_SECONDS)
{
this.request.Address = 0xFFFFFFFF;
this.address = this.request.Address;
}
public event Action<UInt32[]> AddressesParsed;
public override UInt32 Address
{
get => this.address;
set => this.address = value;
}
protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response)
{
if (!response.IsCrcValid)
{
this.NotifyCancelled();
return false;
}
var payload = response.Payload;
var length = payload.Length;
var parsed = false;
if (length == 20)
{
var bytes = new Byte[4];
var addresses = new UInt32[5];
for (var i = 0; i < length; i += 4)
{
Array.Clear(bytes, 0, 4);
Array.Copy(payload, i, bytes, 0, 4);
Array.Reverse(bytes);
var address = BitConverter.ToUInt32(bytes, 0);
if (address == UInt32.MaxValue)
{
address = 0;
}
addresses[i / 4] = address;
}
this.AddressesParsed?.Invoke(addresses);
parsed = true;
}
return parsed;
}
}
}

View File

@ -1,74 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.Sirt
{
using Common.Hardware.Interfaces.Ports.Sirt.Requests;
using System;
public class WritePamTask : SIRTTask<WritePamRequest>
{
public WritePamTask() : base(TIMEOUT_SECONDS)
{
}
public WritePamTask(UInt32 timeout) : base(timeout)
{
}
public override UInt32 Address
{
get => this.request.Address;
set => this.request.Address = value;
}
public Boolean WakeUpModul
{
get => this.request.WakeUpModul;
set => this.request.WakeUpModul = value;
}
public Boolean WakeUpCmd
{
get => this.request.WakeUpCmd;
set => this.request.WakeUpCmd = value;
}
public Boolean IgnoreTimeout
{
get => this.request.IgnoreTimeout;
set => this.request.IgnoreTimeout = value;
}
public Boolean DelPamSemi
{
get => this.request.DelPamSemi;
set => this.request.DelPamSemi = value;
}
public Boolean DelPamTx
{
get => this.request.DelPamTx;
set => this.request.DelPamTx = value;
}
public Boolean DelPamAdr
{
get => this.request.DelPamAdr;
set => this.request.DelPamAdr = value;
}
public Boolean DelPamAll
{
get => this.request.DelPamAll;
set => this.request.DelPamAll = value;
}
public Byte[] Payload
{
get => this.request.Payload;
set => this.request.Payload = value;
}
}
}

View File

@ -51,7 +51,6 @@
<Compile Include="JustSirtTask.cs" />
<Compile Include="JustTaskStatus.cs" />
<Compile Include="Parameters\BluetoothOperating.cs" />
<Compile Include="Parameters\ByteExtensions.cs" />
<Compile Include="Parameters\OperatingModes.cs" />
<Compile Include="Parameters\P11.cs" />
<Compile Include="Parameters\P12.cs" />

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
public class BluetoothOperating
@ -55,7 +57,7 @@
}
public static implicit operator Byte(BluetoothOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator BluetoothOperating(Byte _byte)
=> new BluetoothOperating(_byte.GetBits());

View File

@ -1,31 +0,0 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using System;
public static class ByteExtensions
{
public static Byte[] GetBits(this Byte @byte)
{
var bits = new Byte[8];
for (int i = 0; i < 8; i++)
{
bits[i] = (Byte)((@byte >> i) & 1);
}
return bits;
}
public static Byte GetByte(this Byte[] bits)
{
var @byte = default(int);
for (int i = 0; i < 8; i++)
{
@byte |= bits[i] << i;
}
return (Byte)@byte;
}
}
}

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -170,7 +172,7 @@
}
public static implicit operator Byte(P11 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P11(Byte _byte)
=> new P11(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -162,7 +164,7 @@
}
public static implicit operator Byte(P12 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P12(Byte _byte)
=> new P12(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
/// <summary>
@ -233,7 +235,7 @@
}
public static implicit operator Byte(P811 param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator P811(Byte _byte)
=> new P811(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
public class RFModuleOperating
@ -21,7 +23,7 @@
Array.Copy(this.bits, 0, bits, 0, 4);
return (OperatingModes)bits.GetByte();
return (OperatingModes)bits.ToByte();
}
set
{
@ -68,7 +70,7 @@
}
public static implicit operator Byte(RFModuleOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator RFModuleOperating(Byte _byte)
=> new RFModuleOperating(_byte.GetBits());

View File

@ -1,5 +1,7 @@
namespace Common.Hardware.Interfaces.Ports.SirtBroadcaster.Parameters
{
using Common.Utils.Extensions;
using System;
public class SirtOperating
@ -128,7 +130,7 @@
}
public static implicit operator Byte(SirtOperating param)
=> param.bits.GetByte();
=> param.bits.ToByte();
public static implicit operator SirtOperating(Byte _byte)
=> new SirtOperating(_byte.GetBits());

View File

@ -22,6 +22,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>IDE0003;IDE0049;</NoWarn>
<DocumentationFile>bin\Debug\Common.Hardware.Interfaces.Ports.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -42,7 +43,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="IrdaSerialPort.cs" />
<Compile Include="JustSerialPort.cs" />
<Compile Include="ISerialPort.cs" />
<Compile Include="SerialPort.cs" />
<Compile Include="SerialPortBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SerialPortBaudRate.cs" />

View File

@ -0,0 +1,54 @@
namespace Common.Hardware.Interfaces.Ports
{
using System;
/// <summary>
/// Interface that exposes the <see cref="System.IO.Ports.SerialPort"/> features.
/// </summary>
public interface ISerialPort
{
/// <summary>
/// Occurs every time a <see cref="System.Exception"/> is thrown.
/// </summary>
event Action<string, Exception> Exception;
/// <summary>
/// Safely closes the serial port. Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
void Close();
/// <summary>
/// Returns whether the serial port exists and is open. Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
bool IsOpen();
/// <summary>
/// Safely opens the serial port. Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
void Open();
/// <summary>
/// Safely reads the incomming bytes into <see cref="System.Byte"/>[] if any, by default returns empty array.
/// Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
byte[] ReadBytes();
/// <summary>
/// Safely reads a <see cref="System.String"/> if any, by default returns <see cref="System.String.Empty"/>.
/// Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
string ReadLine();
/// <summary>
/// Safely writes the provided <see cref="System.Byte"/>[] to the serial port.
/// Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
void WriteBytes(params byte[] bytes);
/// <summary>
/// Safely writes the provided <see cref="System.String"/> to the serial port.
/// Exceptions are thrown through the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort.Exception"/> event.
/// </summary>
void WriteLine(string line);
}
}

View File

@ -1,135 +0,0 @@
namespace Common.Hardware.Interfaces.Ports
{
using System;
using System.Collections.Concurrent;
using System.IO.Ports;
public class JustSerialPort
{
private static readonly ConcurrentDictionary<String, SerialPort> serialPorts
= new ConcurrentDictionary<String, SerialPort>();
private readonly SerialPortSettings serialPortSettings;
private readonly String portName;
private Int32 readBufferSize;
private Byte[] buffer;
public Boolean IsOpen
{
get => serialPorts.TryGetValue(this.portName, out var serialPort)
&& serialPort.IsOpen;
}
public JustSerialPort(SerialPortSettings serialPortSettings)
{
this.serialPortSettings = serialPortSettings;
this.portName = this.serialPortSettings.PortName;
}
public event Action<String> Logging;
public void Log(Object message)
=> this.Logging?.Invoke($"{this.portName}|{message}");
public Boolean TryClose()
{
var closed = false;
try
{
if (serialPorts.TryRemove(this.portName, out var serialPort))
{
serialPort.Close();
serialPort = null;
closed = true;
}
}
catch (Exception e)
{
this.Log(e);
}
return closed;
}
public Boolean TryOpen()
{
var opened = false;
_ = this.TryClose();
try
{
var serialPort = new SerialPort
{
BaudRate = this.serialPortSettings.BaudRate,
DataBits = this.serialPortSettings.DataBits,
Parity = this.serialPortSettings.Parity,
PortName = this.serialPortSettings.PortName,
StopBits = this.serialPortSettings.StopBits,
WriteTimeout = 100,
ReadTimeout = 100,
};
if (serialPorts.TryAdd(this.portName, serialPort))
{
serialPort.Open();
this.readBufferSize = serialPort.ReadBufferSize;
this.buffer = new Byte[this.readBufferSize];
opened = serialPort.IsOpen;
}
}
catch (Exception e)
{
this.Log(e);
}
return opened;
}
public Byte[] ReadBytes()
{
var length = 0;
var bytes = new Byte[length];
if (serialPorts.TryGetValue(this.portName, out var serialPort))
{
if (serialPort.IsOpen && serialPort.BytesToRead > 0)
{
Array.Clear(this.buffer, 0, this.readBufferSize);
length = serialPort.Read(this.buffer, 0, this.readBufferSize);
bytes = new Byte[length];
Array.Copy(this.buffer, 0, bytes, 0, length);
}
}
return bytes;
}
public override String ToString()
=> $"{this.serialPortSettings.PortName}, "
+ $"{this.serialPortSettings.BaudRate}, "
+ $"{this.serialPortSettings.DataBits}, "
+ $"{this.serialPortSettings.Parity}, "
+ $"{this.serialPortSettings.StopBits}";
public void WriteBytes(params Byte[] bytes)
{
if (bytes != null)
{
var bytesLength = bytes.Length;
if (bytes.Length > 0 && serialPorts.TryGetValue(this.portName, out var serialPort))
{
if (serialPort.IsOpen)
{
serialPort.Write(bytes, 0, bytes.Length);
}
}
}
}
}
}

View File

@ -0,0 +1,192 @@
namespace Common.Hardware.Interfaces.Ports
{
using System;
using System.Collections.Concurrent;
using System.Linq;
using SystemSerialPort = System.IO.Ports.SerialPort;
/// <summary>
/// Class that implements the <see cref="Common.Hardware.Interfaces.Ports.ISerialPort"/> features over one of the opened <see cref="System.IO.Ports.SerialPort"/>.
/// </summary>
public class SerialPort : ISerialPort
{
/// <summary>
/// Because it is possible that the serial port is used out of the current thread,
/// all opened <see cref="System.IO.Ports.SerialPort"/>s are stored in a static
/// <see cref="System.Collections.Concurrent.ConcurrentDictionary{TKey, TValue}"/> that is accessible from any thread and is stored on the current thread.
/// Where the key is <see cref="System.String"/> and the value is <see cref="System.IO.Ports.SerialPort"/>
/// </summary>
private static readonly ConcurrentDictionary<string, SystemSerialPort> serialPorts
= new ConcurrentDictionary<string, SystemSerialPort>();
/// <summary>
/// Holds the current <see cref="System.IO.Ports.SerialPort"/> settings ready for use on <see cref="Common.Hardware.Interfaces.Ports.SerialPort.Open()"/>
/// </summary>
private readonly SerialPortSettings settings;
/// <summary>
/// Returns current COM port name.
/// </summary>
private string portName => this.settings.PortName;
public SerialPort(SerialPortSettings serialPortSettings)
{
this.settings = serialPortSettings;
if (!SystemSerialPort.GetPortNames().Any(x => x.Equals(this.portName, StringComparison.InvariantCultureIgnoreCase)))
{
throw new ArgumentOutOfRangeException(nameof(SystemSerialPort.PortName), "Dose not exists!");
}
}
public event Action<string, Exception> Exception;
public void Close()
{
try
{
if (serialPorts.TryRemove(this.portName, out var serialPort))
{
serialPort.Close();
serialPort.ErrorReceived -= this.SerialPort_ErrorReceived;
}
}
catch (Exception e)
{
this.Throw(e);
}
}
public bool IsOpen()
{
try
{
if (serialPorts.TryGetValue(this.portName, out var serialPort))
{
return serialPort.IsOpen;
}
}
catch (Exception e)
{
this.Throw(e);
}
return false;
}
public void Open()
{
try
{
var serialPort = new SystemSerialPort
{
BaudRate = this.settings.BaudRate,
DataBits = this.settings.DataBits,
Parity = this.settings.Parity,
PortName = this.settings.PortName,
StopBits = this.settings.StopBits
};
if (serialPorts.TryAdd(this.portName, serialPort))
{
serialPort.ErrorReceived += this.SerialPort_ErrorReceived;
serialPort.Open();
}
}
catch (Exception e)
{
this.Throw(e);
}
}
public byte[] ReadBytes()
{
var length = 0;
var bytes = new byte[length];
try
{
if (serialPorts.TryGetValue(this.portName, out var serialPort) && serialPort.IsOpen)
{
bytes = new byte[serialPort.ReadBufferSize];
length = serialPort.Read(bytes, 0, bytes.Length);
Array.Resize(ref bytes, length);
}
}
catch (Exception e)
{
this.Throw(e);
}
return bytes;
}
public string ReadLine()
{
try
{
if (serialPorts.TryGetValue(this.portName, out var serialPort) && serialPort.IsOpen)
{
return serialPort.ReadLine();
}
}
catch (Exception e)
{
this.Throw(e);
}
return default(string);
}
public override string ToString()
=> $"{this.settings.PortName}, "
+ $"{this.settings.BaudRate}, "
+ $"{this.settings.DataBits}, "
+ $"{this.settings.Parity}, "
+ $"{this.settings.StopBits}";
public void WriteBytes(params byte[] bytes)
{
try
{
if (serialPorts.TryGetValue(this.portName, out var serialPort) && serialPort.IsOpen)
{
serialPort.Write(bytes, 0, bytes.Length);
}
}
catch (Exception e)
{
this.Throw(e);
}
}
public void WriteLine(string line)
{
try
{
if (serialPorts.TryGetValue(this.portName, out var serialPort) && serialPort.IsOpen)
{
serialPort.WriteLine(line);
}
}
catch (Exception e)
{
this.Throw(e);
}
}
private void SerialPort_ErrorReceived(Object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
this.Close();
this.Open();
this.Throw(new InvalidOperationException($"{nameof(System.IO.Ports.SerialError)}: {nameof(e.EventType)} = {e.EventType}"));
}
private void Throw(Exception exception)
=> this.Exception?.Invoke(this.portName, exception);
}
}

View File

@ -7,8 +7,8 @@
public abstract class SerialPortBase
{
private static readonly ConcurrentDictionary<String, SerialPort> serialPorts
= new ConcurrentDictionary<String, SerialPort>();
private static readonly ConcurrentDictionary<String, System.IO.Ports.SerialPort> serialPorts
= new ConcurrentDictionary<String, System.IO.Ports.SerialPort>();
private readonly SerialPortSettings settings;
@ -69,7 +69,7 @@
{
this.ReadSize = default(Int32);
var serialPort = new SerialPort
var serialPort = new System.IO.Ports.SerialPort
{
BaudRate = this.settings.BaudRate,
DataBits = this.settings.DataBits,
@ -172,7 +172,7 @@
Thread.Sleep(sleep);
}
private Boolean TryGetSerialPort(out SerialPort serialPort)
private Boolean TryGetSerialPort(out System.IO.Ports.SerialPort serialPort)
=> serialPorts.TryGetValue(this.PortName, out serialPort)
&& serialPort?.IsOpen == true;
}

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>IDE0047;</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

View File

@ -152,8 +152,8 @@ namespace Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.StreamingProtocol
{
case "@l":
//protocol @m starts with all contents of protocol @l and contains additional fields
//which needn't to be decoded as those are used for DEBUG
case "@n":
//which needn't be decoded as those are used for DEBUG
case "@n":
if (rawRecordIsValid || !_ignoreCorruptedData)
{
DecodeProtocolL(ref _dataMagFluxRec, rawMsgFields);
@ -189,13 +189,17 @@ namespace Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.StreamingProtocol
/// <remarks date="2023-Jun-07" author="T.Wiedebusch">
/// - Reverse volume multiplied with -1.0 as the test bench expects a negative value for reverse volume.
/// </remarks>
/// <remarks date="2024-Oct-28" author="T.Wiedebusch">
/// - CRC is the last field of the data stream as new protocol "@n" is dynamic of size while the beginning
/// is identical to "@l".
/// </remarks>
private static void DecodeProtocolL(ref MagFluxRecord dataMagFluxRec, IList<String> fields)
{
// time stamp attachment
dataMagFluxRec.DecodedTime = DateTimeOffset.UtcNow;
// extract received CRC
dataMagFluxRec.Crc = UInt16.Parse(fields[(Int32)ProtLsubString.Crc], NumberStyles.HexNumber);
dataMagFluxRec.Crc = UInt16.Parse(fields[fields.Count - 1], NumberStyles.HexNumber);
// build result values
dataMagFluxRec.ForwardVolumeCm = UInt64.Parse(fields[(Int32)ProtLsubString.FwdVolume],
@ -226,7 +230,7 @@ namespace Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.StreamingProtocol
/// field position in protocol 'l' (small 'L')
private enum ProtLsubString
{
//do not remove this needed for position in record and it is sorted
// Sorted to "@l" field positions.
ProtType,
FwdVolume,
RevVolume,
@ -234,8 +238,7 @@ namespace Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.StreamingProtocol
FlowRate,
StatusBits,
UniqueId,
SensorId,
Crc
SensorId
}
}
}

View File

@ -0,0 +1,19 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class ActivateMetrologyTestMode : Pam
{
public ActivateMetrologyTestMode() : base(3, ActivateMetrologyTestMode)
{
}
public UInt16 Mode
{
get => this.bytes.ToUInt16BE(1);
set => value.GetBytesBE().CopyTo(this.bytes, 1);
}
}
}

View File

@ -1,17 +0,0 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ActivationByFlow : DebugCmd
{
public ActivationByFlow() : base(ActivationByFlow)
{
}
public Byte RotationsX10
{
get => this.bytes[0];
set => this.bytes[0] = value;
}
}
}

View File

@ -4,14 +4,14 @@
using System;
public class AlarmMask : Pam
public class AlarmsMask : Pam
{
private readonly Byte[] bits;
protected readonly Byte[] bits;
protected AlarmMask(Int32 length, Byte cmd) : base(length, cmd)
protected AlarmsMask(Int32 length, Byte cmd) : base(length, cmd)
=> this.bits = new Byte[8];
public AlarmMask(Byte value) : base(2, 0)
public AlarmsMask(Byte value, Byte cmd = DeactivateAlarms) : base(2, cmd)
=> this.bits = value.GetBits();
public Boolean SpecificError
@ -32,7 +32,7 @@
set => this.bits[2] = (Byte)(value ? 1 : 0);
}
public Boolean Byckflow
public Boolean Backflow
{
get => this.bits[3] == 1;
set => this.bits[3] = (Byte)(value ? 1 : 0);
@ -62,7 +62,7 @@
set => this.bits[7] = (Byte)(value ? 1 : 0);
}
protected override Byte[] ToByteArray()
public override Byte[] ToByteArray()
{
this.bytes[1] = this.bits.ToByte();

View File

@ -5,8 +5,8 @@
public enum AuthLevel : UInt64
{
O = 0x00_00_00_00_00_00_00_00,
I = 0x00_00_00_0D_68_30_14_01,
II = 0x00_00_00_40_80_0E_14_02,
III = 0x00_00_00_22_73_93_63_03,
I = 0x01_00_00_0D_68_30_14_01,
II = 0x02_00_00_40_80_0E_14_02,
III = 0x03_00_00_22_73_93_63_03,
}
}

View File

@ -5,10 +5,15 @@
public class ChangeCustomerText : Pam
{
private Int32 serialno;
public ChangeCustomerText() : base(10, ChangeCustomerText)
{
}
public ChangeCustomerText(Object text) : this()
=> this.Text = $"{text}".Trim();
public String Text
{
get => Encoding.ASCII.GetString(this.bytes, 1, 9);

View File

@ -0,0 +1,31 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class ChangeDataLoggerSettings : Pam
{
public ChangeDataLoggerSettings() : base(5, ChangeDataLoggerSettings)
{
}
public UInt16 TimeInterval
{
get => this.bytes.ToUInt16BE(1);
set => value.GetBytesBE().CopyTo(this.bytes, 1);
}
public Byte TimeOfMinimumFlow
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte MinimumFlow
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
}
}

View File

@ -0,0 +1,29 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ChangeFixedDateReadingSettings : Pam
{
public ChangeFixedDateReadingSettings() : base(4, ChangeFixedDateReadingSettings)
{
}
public Byte DayOfMonth
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte SettingI
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte SettingII
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
}
}

View File

@ -0,0 +1,22 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class ChangeMeterId : Pam
{
public ChangeMeterId() : base(5, ChangeMeterId)
{
}
public ChangeMeterId(UInt32 meterId) : this()
=> this.MeterId = meterId;
public UInt32 MeterId
{
get => this.bytes.ToUInt32BE(1);
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 1);
}
}
}

View File

@ -10,7 +10,10 @@
{
}
public UInt32 Value
public ChangeMeterReading(UInt32 value) : this()
=> this.DisplayVolume = value;
public UInt32 DisplayVolume
{
get => this.bytes.ToUInt32BigEndian(1);
set => value.ToBigEndianBytes().CopyTo(this.bytes, 1);

View File

@ -4,7 +4,6 @@
public partial class ChangeNumberOfDeals : Pam
{
public ChangeNumberOfDeals() : base(2, ChangeNimberOfDeals)
{
}

View File

@ -2,12 +2,15 @@
{
using System;
public class ChangeLATWindows : Pam
public class ChangeNumberOfLatWindows : Pam
{
public ChangeLATWindows() : base(2, ChangeLATWindowsN)
public ChangeNumberOfLatWindows() : base(2, ChangeLATWindowsN)
{
}
public ChangeNumberOfLatWindows(Byte n) : this()
=> this.N = n;
public Byte N
{
get => this.bytes[1];

View File

@ -0,0 +1,29 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ChangePin : Pam
{
public ChangePin() : base(6, ChangePin)
{
}
public AuthLevel AuthLevel
{
get
{
var bytes = new Byte[8];
Array.Copy(this.bytes, 1, bytes, 0, 5);
return (AuthLevel)BitConverter.ToUInt64(bytes, 0);
}
set
{
var bytes = BitConverter.GetBytes((UInt64)value);
Array.Copy(bytes, 0, this.bytes, 1, 5);
}
}
}
}

View File

@ -10,6 +10,9 @@
{
}
public ChangeRadioId(UInt32 address) : this()
=> this.Address = address;
public UInt32 Address
{
get => this.bytes.ToUInt32BigEndian(1);

View File

@ -0,0 +1,41 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class ChangeSensusRFEncryptionKey : Pam
{
public ChangeSensusRFEncryptionKey() : base(17, ChangeSensusRFEncryptionKey)
{
}
public ChangeSensusRFEncryptionKey(Byte[] encryptionKey) : this()
=> encryptionKey.CopyTo(this.bytes, 1);
public Byte[] Key
{
get
{
var key = new Byte[16];
Array.Copy(this.bytes, 1, key, 0, 16);
return key;
}
set
{
if (value?.Length == 16)
{
value.CopyTo(this.bytes, 1);
}
}
}
public String HexKey
{
get => BitConverter.ToString(this.Key).Replace("-", String.Empty);
set => this.Key = value.ToByteArray();
}
}
}

View File

@ -2,7 +2,7 @@
{
using System;
public class State : DebugCmd
public class ChangeState : DebugCmd
{
public enum Modes : Byte
{
@ -10,7 +10,7 @@
Shipment = 1,
}
public State() : base(State)
public ChangeState() : base(State)
{
}

View File

@ -1,70 +0,0 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ChangeTransmission : Pam
{
private Byte oldn;
private Byte newn;
private Byte oldt;
private Byte newt;
protected ChangeTransmission(Int32 length, Byte cmd) : base(length, cmd)
{
}
public ChangeTransmission() : base(3, ChangeTransmitionInterval)
{
}
public Byte LatWindowIntervalCount
{
get => this.bytes[1];
set
{
this.oldn = this.newn;
this.newn = value;
if (this.IsValid)
{
this.bytes[2] = this.newn;
}
else
{
this.newn = this.oldn;
this.oldn = this.bytes[2];
}
}
}
public Byte LatTXIntervalSeconds
{
get => this.bytes[2];
set
{
this.oldt = this.newt;
this.newt = value;
if (this.IsValid)
{
this.bytes[2] = this.newt;
}
else
{
this.newt = this.oldt;
this.oldt = this.bytes[2];
}
}
}
protected Boolean IsValid
{
get
{
var x = this.newt * (this.newn + 1);
return 0 < x && x <= 3600;
}
}
}
}

View File

@ -0,0 +1,22 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class ChangeTransmissionInterval : Pam
{
public ChangeTransmissionInterval() : base(3, ChangeTransmitionInterval)
{
}
public ChangeTransmissionInterval(Byte seconds) : this()
=> this.Seconds = seconds;
public UInt16 Seconds
{
get => this.bytes.ToUInt16BE(1);
set => value.GetBytesBE().CopyTo(this.bytes, 1);
}
}
}

View File

@ -8,10 +8,27 @@
{
}
public WakeUpMode Mode
public ChangeWakeUp(WakeUpMode mode) : base(2, ChangeWakeUpMode)
=> this.WakeUpMode = mode;
public WakeUpMode WakeUpMode
{
get => (WakeUpMode)this.bytes[1];
set => this.bytes[1] = (Byte)value;
}
public Byte Mode
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public static ChangeWakeUp AutoOff => WakeUpMode.SleepAutoOff;
public static ChangeWakeUp AutoOn => WakeUpMode.SleepAutoOn;
public static ChangeWakeUp StayAwake => WakeUpMode.StayAwake;
public static implicit operator ChangeWakeUp(WakeUpMode mode) => new ChangeWakeUp(mode);
}
}

View File

@ -41,51 +41,85 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ActivationByFlow.cs" />
<Compile Include="AlarmMask.cs" />
<Compile Include="ActivateMetrologyTestMode.cs" />
<Compile Include="AlarmsMask.cs" />
<Compile Include="ChangeCustomerText.cs" />
<Compile Include="ChangeDataLoggerSettings.cs" />
<Compile Include="ChangePin.cs" />
<Compile Include="ChangeSensusRFEncryptionKey.cs" />
<Compile Include="ChangeFixedDateReadingSettings.cs" />
<Compile Include="ChangeMeterId.cs" />
<Compile Include="ChangeMeterReading.cs" />
<Compile Include="ChangeRadioId.cs" />
<Compile Include="ChangeTransmissionInterval.cs" />
<Compile Include="DeactivateTransmitter.cs" />
<Compile Include="DecimalPointLocations.cs" />
<Compile Include="DisableOTAFirmwareUpdate.cs" />
<Compile Include="EncapsulatedFlexNet.cs" />
<Compile Include="EregisterFeatures.cs" />
<Compile Include="EregisterFeaturesDebug.cs" />
<Compile Include="FactoryComplete.cs" />
<Compile Include="GetCustomerDebug.cs" />
<Compile Include="MBusMode.cs" />
<Compile Include="MeterTypes.cs" />
<Compile Include="MeterUnits.cs" />
<Compile Include="OTAMode.cs" />
<Compile Include="PamAttribute.cs" />
<Compile Include="ParameterizeBrokenPipeDetection.cs" />
<Compile Include="ParameterizeLeakageDetection.cs" />
<Compile Include="Ping.cs" />
<Compile Include="PowerLevelModes.cs" />
<Compile Include="ProvidePin.cs" />
<Compile Include="AuthLevel.cs" />
<Compile Include="DebugCmd.cs" />
<Compile Include="DisableCredits.cs" />
<Compile Include="EnableCredits.cs" />
<Compile Include="MeterType.cs" />
<Compile Include="SetMeterType.cs" />
<Compile Include="OpticalTelegram.cs" />
<Compile Include="Options.cs" />
<Compile Include="OTAFWUpdate.cs" />
<Compile Include="ReceiveSequenceOfTestTelegrams.cs" />
<Compile Include="RegisterMode.cs" />
<Compile Include="RequestDebugTelegram.cs" />
<Compile Include="RequestFixedDateReading.cs" />
<Compile Include="RequestLoggingData.cs" />
<Compile Include="RequestMemoryDump.cs" />
<Compile Include="ResetAlarms.cs" />
<Compile Include="ResetCredits.cs" />
<Compile Include="ResetMode.cs" />
<Compile Include="SendBubbleUpBurst.cs" />
<Compile Include="SendSequenceOfTestTelegrams.cs" />
<Compile Include="SendTestPattern.cs" />
<Compile Include="SerialOutput.cs" />
<Compile Include="SetActivationByThreshold.cs" />
<Compile Include="SetActivityCreditLimits.cs" />
<Compile Include="SetAlarms.cs" />
<Compile Include="SetBatteryUsageTestOffset.cs" />
<Compile Include="SetBytterySeconds.cs" />
<Compile Include="ChangeLATWindows.cs" />
<Compile Include="ChangeNumberOfLatWindows.cs" />
<Compile Include="ChangeNumberOfDeals.cs" />
<Compile Include="ChangeTransmission.cs" />
<Compile Include="CustomerDebug.cs" />
<Compile Include="DeactivateAlarms.cs" />
<Compile Include="GetDebug.cs" />
<Compile Include="Pam.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ChangeWakeUp.cs" />
<Compile Include="RebootsCounter.cs" />
<Compile Include="SetDateAndTime.cs" />
<Compile Include="SetRebootCount.cs" />
<Compile Include="Reset.cs" />
<Compile Include="AlarmPersistence.cs" />
<Compile Include="SetFrequencyOffset.cs" />
<Compile Include="SetHistoricalErrorLimit.cs" />
<Compile Include="SetMetrologyParameters.cs" />
<Compile Include="SetPCB.cs" />
<Compile Include="SetPcbId.cs" />
<Compile Include="SetPowerLevel.cs" />
<Compile Include="SetSpecificError.cs" />
<Compile Include="SetTestFastActivityBupTiming.cs" />
<Compile Include="SetTFXParameters.cs" />
<Compile Include="State.cs" />
<Compile Include="SetVariablePcbId.cs" />
<Compile Include="SingleBytePam.cs" />
<Compile Include="ChangeState.cs" />
<Compile Include="WakeUpMode.cs" />
<Compile Include="WMBusMode.cs" />
<Compile Include="WMBusTransmition.cs" />
<Compile Include="WirelessMBusMode.cs" />
<Compile Include="OpenMeteringTransmitionIntervalWMBus.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Utils\Common.Utils.Extensions\Common.Utils.Extensions.csproj">

View File

@ -2,7 +2,7 @@
{
public class CustomerDebug : Pam
{
public CustomerDebug() : base(3, RequestCustomerDebug)
public CustomerDebug() : base(3, GetCustomerDebug)
{
}
}

View File

@ -1,9 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class DeactivateAlarms : AlarmMask
using System;
public class DeactivateAlarms : AlarmsMask
{
public DeactivateAlarms() : base(2, DeactivateAlarms)
{
}
public DeactivateAlarms(Byte alarmsMask) : base(alarmsMask, DeactivateAlarms)
{
}
}
}

View File

@ -0,0 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class DeactivateTransmitter : SingleBytePam
{
public DeactivateTransmitter() : base(DeactivateTransmitter)
{
}
public DeactivateTransmitter(Byte value) : base(value, DeactivateTransmitter)
{
}
}
}

View File

@ -9,6 +9,11 @@
public static implicit operator Byte[] (DebugCmd cmd) => cmd.bytes;
/// <summary>
/// No action accept sending Debug Telegram
/// </summary>
protected const Byte RequestDebugTelegram = 0;
/// <summary>
/// Change from Production Mode to Shipment Mode. 1 = Shipment
/// </summary>
@ -25,33 +30,64 @@
/// </summary>
protected const Byte DisableCredits = 4;
/// <summary>
/// Toggles routing received packets out the serial port
/// </summary>
protected const Byte SerialOutput = 5;
/// <summary>
/// Bit field following the Alarm Byte definition. 1 indicates setting the alarm.
/// Only currently enabled Alarms can be set.
/// </summary>
internal const Byte SetAlarms = 6;
/// <summary>
/// Turns on the indicated Specific Error Flag
/// </summary>
protected const Byte SetSpecificError = 7;
/// <summary>
/// Number of minutes to send LED data 0 will shut down the optical data.
/// </summary>
internal const Byte OpticalTelegram = 8;
/// <summary>
/// Restores most NV to default except radio ID, PCB ID, calibrations and metrology data Beta FW only
/// </summary>
protected const Byte FactoryComplete = 9;
/// <summary>
/// Restores counter settings controlled changed by the Deactivate Counter command.
/// </summary>
internal const Byte EnableCredits = 10;
/// <summary>
/// Used to offset the present battery consumption level to allow simulation of Low Battery,
/// Very Low Battery and End of Life testing.Not intended to be used except in a test environment.
/// </summary>
protected const Byte SetBatteryUsageTestOffset = 11;
/// <summary>
/// Used for testing OTA software updates. Not intended to be used except in a test environment.
/// </summary>
protected const Byte SetTestFastActivityBupTiming = 12;
/// <summary>
/// Used to change the number of activity credits allowed in a 24 hour period for each mode of operation.
/// </summary>
protected const Byte SetActivityCreditLimits = 13;
/// <summary>
/// 0 Set to Default Rotations value of 8 (8*10) Rotations
/// 1 - 255 Increments of 10 * setting which translates to(10 to 2550) Rotations.
/// </summary>
internal const Byte ActivationByFlow = 15;
internal const Byte SetActivationByThreshold = 15;
/// <summary>
/// 1 Disables Firmware Update.
/// 2 Enable Firmware Update (Only available in Beta Firmware and when the unit is not Sealed (Production Mode)).
/// </summary>
internal const Byte OTAFWUpdate = 16;
internal const Byte DisableOTA = 16;
/// <summary>
/// 0 Residential Meter: Meter Type reported in SEMI is set to 10 and Flow Reporting is limited to +/-32767.

View File

@ -0,0 +1,20 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class DisableOTAFirmwareUpdate : DebugCmd
{
public DisableOTAFirmwareUpdate() : base(DisableOTA)
{
}
public DisableOTAFirmwareUpdate(Byte parameter) : this()
=> this.bytes[1] = parameter;
public OTAMode Mode
{
get => (OTAMode)this.bytes[1];
set => this.bytes[1] = (Byte)value;
}
}
}

View File

@ -0,0 +1,149 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class EregisterFeatures
{
[Pam(AuthLevel.II)]
public ChangeWakeUp ChangeWakeUp { get; set; }
[Pam(AuthLevel.O)]
public SetPowerLevel SetPowerLevelSensusRF { get; set; }
[Pam(AuthLevel.III)]
public SetPowerLevel SetPowerLevelFlexNet { get; set; }
[Pam(AuthLevel.II)]
public ChangeNumberOfLatWindows ChangeNumberOfLatWindows { get; set; }
[Pam(AuthLevel.I)]
public ResetAlarms ResetAlarms { get; set; }
[Pam(AuthLevel.II, true)]
public DeactivateTransmitter DeactivateTransmiter { get; set; }
[Pam(AuthLevel.II)]
public WirelessMBusMode WirelessMBusMode { get; set; }
[Pam(AuthLevel.O)]
public DeactivateAlarms DeactivateAlarms { get; set; }
[Pam(AuthLevel.O)]
public ChangeNumberOfDeals ChangeNumberOfDeals { get; set; }
[Pam(AuthLevel.O)]
public ParameterizeLeakageDetection ParameterizeLeakageDetection { get; set; }
[Pam(AuthLevel.O)]
public ParameterizeBrokenPipeDetection ParameterizeBrokenPipeDetection { get; set; }
[Pam(AuthLevel.I)]
public SetHistoricalErrorLimit SetHistoricalErrorLimit { get; set; }
[Pam(AuthLevel.III, true)]
public Reset Reset { get; set; }
[Pam(AuthLevel.II)]
public ChangeTransmissionInterval ChangeTransmissionInterval { get; set; }
[Pam(AuthLevel.II)]
public OpenMeteringTransmitionIntervalWMBus OpenMeteringTransmitionIntervalWMBus { get; set; }
[Pam(AuthLevel.III, true)]
public SendBubbleUpBurst SendBubbleUpBurst { get; set; }
[Pam(AuthLevel.III, true)]
public SetFrequencyOffset SetFrequencyOffset { get; set; }
[Pam(AuthLevel.I)]
public ActivateMetrologyTestMode ActivateMetrologyTestMode { get; set; }
[Pam(AuthLevel.III)]
public SetRebootCount SetRebootCount { get; set; }
[Pam(AuthLevel.III, true)]
public EregisterFeaturesDebug Debug { get; set; }
[Pam(AuthLevel.O)]
public ChangeFixedDateReadingSettings ChangeFixedDateReadingSettings { get; set; }
[Pam(AuthLevel.II, true)]
public GetCustomerDebug GetCustomerDebug { get; set; }
[Pam(AuthLevel.III)]
public ChangeMeterReading ChangeMeterReading { get; set; }
[Pam(AuthLevel.III)]
public ChangeMeterId ChangeMeterId { get; set; }
[Pam(AuthLevel.I)]
public SetDateAndTime SetDateAndTime { get; set; }
[Pam(AuthLevel.O)]
public ChangeDataLoggerSettings ChangeDataLoggerSettings { get; set; }
[Pam(AuthLevel.III)]
public SetBytterySeconds SetBytterySeconds { get; set; }
// TODO: Implement in builder
[Pam(AuthLevel.III)]
public ChangeRadioId ChangeRadioId { get; set; }
[Pam(AuthLevel.III)]
public SetPcbId SetPcbId { get; set; }
[Pam(AuthLevel.O, true)]
public RequestFixedDateReading RequestFixedDateReading { get; set; }
[Pam(AuthLevel.O, true)]
public RequestLoggingData RequestLoggingData { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.I, true)]
public ChangePin ChangePinI { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.II, true)]
public ChangePin ChangePinII { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.III, true)]
public ChangePin ChangePinIII { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.O)]
public ProvidePin ProvidePin { get; set; }
[Pam(AuthLevel.III, true)]
public SendTestPattern SendTestPattern { get; set; }
[Pam(AuthLevel.III, true)]
public RequestMemoryDump RequestMemoryDump { get; set; }
[Pam(AuthLevel.III, true)]
public SendSequenceOfTestTelegrams SendSequenceOfTestTelegrams { get; set; }
[Pam(AuthLevel.III, true)]
public ReceiveSequenceOfTestTelegrams ReceiveSequenceOfTestTelegrams { get; set; }
[Pam(AuthLevel.II)]
public ChangeCustomerText ChangeCustomerText { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.O)]
public ChangeSensusRFEncryptionKey ChangeSensusRFEncryptionKey { get; set; }
[Pam(AuthLevel.II)]
public EncapsulatedFlexNet EncapsulatedFlexNet { get; set; }
[Pam(AuthLevel.O)]
public SetTFXParameters SetTFXParameters { get; set; }
[Pam(AuthLevel.III, true)]
public SetMetrologyParameters SetMetrologyParameters { get; set; }
[Pam(AuthLevel.O, true)]
public Ping Ping { get; set; }
[Pam(AuthLevel.III)]
public SetVariablePcbId SetVariablePcbId { get; set; }
}
}

View File

@ -0,0 +1,50 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class EregisterFeaturesDebug
{
[Pam(AuthLevel.III, true)]
public RequestDebugTelegram RequestDebugTelegram { get; set; }
[Pam(AuthLevel.III, true)]
public ResetCredits ResetCredits { get; set; }
[Pam(AuthLevel.III, true)]
public DisableCredits DisableCredits { get; set; }
[Pam(AuthLevel.III, true)]
public SerialOutput SerialOutput { get; set; }
[Pam(AuthLevel.III, true)]
public SetAlarms SetAlarm { get; set; }
[Pam(AuthLevel.III, true)]
public SetSpecificError SetSpecificError { get; set; }
[Pam(AuthLevel.III, true)]
public OpticalTelegram OpticalTelegram { get; set; }
[Pam(AuthLevel.III, true)]
public FactoryComplete FactoryComplete { get; set; }
[Pam(AuthLevel.III, true)]
public EnableCredits EnableCredits { get; set; }
[Pam(AuthLevel.III, true)]
public SetBatteryUsageTestOffset SetBatteryUsageTestOffset { get; set; }
[Pam(AuthLevel.III, true)]
public SetTestFastActivityBupTiming SetTestFastActivityBupTiming { get; set; }
[Pam(AuthLevel.III, true)]
public SetActivityCreditLimits SetActivityCreditLimits { get; set; }
[Pam(AuthLevel.III, true)]
public SetActivationByThreshold SetActivationByThreshold { get; set; }
[Pam(AuthLevel.III, true)]
public DisableOTAFirmwareUpdate DisableOTAFirmwareUpdate { get; set; }
[Pam(AuthLevel.III, true)]
public SetMeterType SetMeterType { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class FactoryComplete : DebugCmd
{
public FactoryComplete() : base(FactoryComplete)
{
}
}
}

View File

@ -0,0 +1,9 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class GetCustomerDebug : Pam
{
public GetCustomerDebug() : base(3, GetCustomerDebug)
{
}
}
}

View File

@ -1,20 +0,0 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class GetDebug : Pam
{
public GetDebug() : base(3, GetDebug)
{
}
public DebugCmd Cmd { get; set; }
protected override Byte[] ToByteArray()
{
Array.Copy(this.Cmd, 0, this.bytes, 1, 2);
return base.ToByteArray();
}
}
}

View File

@ -1,17 +0,0 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class OTAFWUpdate : DebugCmd
{
protected OTAFWUpdate() : base(OTAFWUpdate)
{
}
public Boolean Enabled
{
get => this.bytes[0] == 2;
set => this.bytes[0] = (Byte)(value ? 2 : 1);
}
}
}

View File

@ -0,0 +1,10 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public enum OTAMode : Byte
{
DisableFWUpdate = 1,
EnableFWUpdate = 2,
}
}

View File

@ -0,0 +1,22 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class OpenMeteringTransmitionIntervalWMBus : Pam
{
public OpenMeteringTransmitionIntervalWMBus() : base(3, WMBusTransmisionInterval)
{
}
public OpenMeteringTransmitionIntervalWMBus(UInt16 seconds) : this()
=> this.Seconds = seconds;
public UInt16 Seconds
{
get => this.bytes.ToUInt16BE(1);
set => value.GetBytesBE().CopyTo(this.bytes, 1);
}
}
}

View File

@ -8,6 +8,9 @@
{
}
public OpticalTelegram(Byte minutes) : this()
=> this.Minutes = minutes;
public Byte Minutes
{
get => this.bytes[1];

View File

@ -25,7 +25,7 @@
return this;
}
protected virtual Byte[] ToByteArray()
public virtual Byte[] ToByteArray()
=> this.bytes;
public static implicit operator Byte[] (Pam pam)
@ -34,216 +34,216 @@
/// <summary>
/// 0 Change Wake Up 1 no 2
/// </summary>
protected const Byte ChangeWakeUpMode = 0;
public const Byte ChangeWakeUpMode = 0;
/// <summary>
/// 1 Set power level 1 no (Production Mode for SensusRF Power Level) 3 (For setting FlexNet Power Level)
/// </summary>
protected const Byte SetPowerLevel = 1;
public const Byte SetPowerLevel = 1;
/// <summary>
/// 2* Change number of LAT Windows N 1 no 2
/// </summary>
protected const Byte ChangeLATWindowsN = 2;
public const Byte ChangeLATWindowsN = 2;
/// <summary>
/// 3 Reset Alarms 1 no 1
/// </summary>
protected const Byte ResetAlarms = 3;
public const Byte ResetAlarms = 3;
/// <summary>
/// 4 Deactivate Transmitter 1 yes 2
/// </summary>
protected const Byte DeactivateTransmitter = 4;
public const Byte DeactivateTransmitter = 4;
/// <summary>
/// 5* Wireless MBus Mode 1 no 2
/// </summary>
protected const Byte WirelessMBusMode = 5;
public const Byte ChangeWirelessMBusMode = 5;
/// <summary>
/// 6* Deactivate Alarms 1 no 0
/// </summary>
protected const Byte DeactivateAlarms = 6;
public const Byte DeactivateAlarms = 6;
/// <summary>
/// 7* Change Number of Dials 1 no 0
/// </summary>
protected const Byte ChangeNimberOfDeals = 7;
public const Byte ChangeNimberOfDeals = 7;
/// <summary>
/// 10 Parameterize LeakageDetection 1 no 0
/// </summary>
protected const Byte SetLeakageDetection = 10;
public const Byte ParameterizeLeakageDetection = 10;
/// <summary>
/// 11 Parameterize BrokenPipe-Detection 1 no 0
/// </summary>
protected const Byte SetBrokenPipeDetection = 11;
public const Byte ParameterizeBrokenPipeDetection = 11;
/// <summary>
/// 12* Set historical error limit (alarm persistence) 1 no 1
/// </summary>
protected const Byte SetHistoricalErrorLimit = 12;
public const Byte SetHistoricalErrorLimit = 12;
/// <summary>
/// 14 Reset 1 yes 3
/// </summary>
protected const Byte Reset = 14;
public const Byte Reset = 14;
/// <summary>
/// 16* Change Transmission Interval 2 no 2
/// </summary>
protected const Byte ChangeTransmitionInterval = 16;
public const Byte ChangeTransmitionInterval = 16;
/// <summary>
/// 17* Open Metering Transmission Interval (Wireless MBus) 2 no 2
/// </summary>
protected const Byte WMBusTransmisionInterval = 17;
public const Byte WMBusTransmisionInterval = 17;
/// <summary>
/// 19 Send Bubble Up Burst 2 yes 3
/// </summary>
protected const Byte SendBUPBurst = 19;
public const Byte SendBubbleUpBurst = 19;
/// <summary>
/// 20 Set frequency offset 2 yes 3
/// </summary>
protected const Byte SetFrequencyOffset = 20;
public const Byte SetFrequencyOffset = 20;
/// <summary>
/// 21 Activate Metrology Test Mode 2 no 1
/// </summary>
protected const Byte ActivateTestMode = 21;
public const Byte ActivateMetrologyTestMode = 21;
/// <summary>
/// 22 Set Reboot Count 2 no? (Production Mode) 3
/// </summary>
protected const Byte RebootsCounter = 22;
public const Byte SetRebootCount = 22;
/// <summary>
/// 31 Get debug 2 yes 3
/// </summary>
protected const Byte GetDebug = 31;
public const Byte GetDebug = 31;
/// <summary>
/// 32 Change Fixed Date Reading Settings 3 no 0
/// </summary>
protected const Byte ChangeFixedDateReading = 32;
public const Byte ChangeFixedDateReadingSettings = 32;
/// <summary>
/// 33 Get Customer Debug 2 yes 2
/// </summary>
protected const Byte RequestCustomerDebug = 33;
public const Byte GetCustomerDebug = 33;
/// <summary>
/// 48 Change Meter Reading 4 no(Production Mode) 3
/// </summary>
protected const Byte ChangeMeterReading = 48;
public const Byte ChangeMeterReading = 48;
/// <summary>
/// 49 Change Meter-ID 4 no(Production Mode) 3
/// </summary>
protected const Byte ChangeMeterId = 49;
public const Byte ChangeMeterId = 49;
/// <summary>
/// 50 Set date and time 4 no 1
/// </summary>
protected const Byte SetDatetime = 50;
public const Byte SetDateAndTime = 50;
/// <summary>
/// 51 Change settings for data logger 4 no 0
/// </summary>
protected const Byte ChangeDataLoggerSettings = 51;
public const Byte ChangeDataLoggerSettings = 51;
/// <summary>
/// 52 Set Battery Seconds (Time Alive) 4 no 3
/// </summary>
protected const Byte SetBatterySeconds = 52;
public const Byte SetBatterySeconds = 52;
/// <summary>
/// 53 Change Radio ID 4 no 3
/// </summary>
protected const Byte ChangeRadioId = 53;
public const Byte ChangeRadioId = 53;
/// <summary>
/// 54 Set PCB ID 4 no? (Serial Only, Production Mode) 3
/// </summary>
protected const Byte SetPCB = 54;
public const Byte SetPCB = 54;
/// <summary>
/// 64 Request Fixed Date Reading 5 yes 0
/// </summary>
protected const Byte RequestFixedDateReading = 64;
public const Byte RequestFixedDateReading = 64;
/// <summary>
/// 65 Request Logging Data 5 yes 0
/// </summary>
protected const Byte RequestLoggingData = 65;
public const Byte RequestLoggingData = 65;
/// <summary>
/// 66 Change PIN 5 yes 1, 2, 3
/// </summary>
protected const Byte ChangePin = 66;
public const Byte ChangePin = 66;
/// <summary>
/// 67* Provide PIN 5 no 0
/// </summary>
protected const Byte ProvidePin = 67;
public const Byte ProvidePin = 67;
/// <summary>
/// 68 Send Test Pattern 6 yes 3
/// </summary>
protected const Byte SendTestPattern = 68;
public const Byte SendTestPattern = 68;
/// <summary>
/// 69 Request Memory Dump 6 yes 3
/// </summary>
protected const Byte MemoryDump = 69;
public const Byte MemoryDump = 69;
/// <summary>
/// 72 Send Sequence of Test-Telegrams 7 yes 3
/// </summary>
protected const Byte SendTestTelegrams = 72;
public const Byte SendSequenceOfTestTelegrams = 72;
/// <summary>
/// 73 Receive Sequence of Test-Telegrams 7 yes 3
/// </summary>
protected const Byte ReceiveTestTelegrams = 73;
public const Byte ReceiveSequenceOfTestTelegrams = 73;
/// <summary>
/// 80 Change Customer Text 9 no 2
/// </summary>
protected const Byte ChangeCustomerText = 80;
public const Byte ChangeCustomerText = 80;
/// <summary>
/// 108 Change SensusRF Encryption Key 16 no 2
/// </summary>
protected const Byte ChangeSensusRFEncKey = 108;
public const Byte ChangeSensusRFEncryptionKey = 108;
/// <summary>
/// 144 Encapsulated FlexNet variable yes 0
/// </summary>
protected const Byte EncapsulatedFlexNet = 144;
public const Byte EncapsulatedFlexNet = 144;
/// <summary>
/// 145 Set TFX Parameters TBD no 0 Yes
/// </summary>
protected const Byte TFXParameters = 145;
public const Byte TFXParameters = 145;
/// <summary>
/// 146 Set Metrology Parameters 16 yes(Production Mode) 3
/// </summary>
protected const Byte MetrologyParameters = 146;
public const Byte MetrologyParameters = 146;
/// <summary>
/// 147 Ping variable yes 0 Yes
/// </summary>
protected const Byte Ping = 147;
public const Byte Ping = 147;
/// <summary>
/// 148 Set Variable PCB ID variable no 3
/// </summary>
protected const Byte VariablePCB = 148;
public const Byte SetVariablePcbId = 148;
}
}

View File

@ -0,0 +1,18 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class PamAttribute : Attribute
{
public PamAttribute(AuthLevel authLevel, Boolean isSingleCmd = false)
{
this.AuthLevel = authLevel;
this.IsSingleCmd = isSingleCmd;
}
public AuthLevel AuthLevel { get; }
public Boolean IsSingleCmd { get; }
}
}

View File

@ -0,0 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ParameterizeBrokenPipeDetection : SingleBytePam
{
public ParameterizeBrokenPipeDetection() : base(ParameterizeBrokenPipeDetection)
{
}
public ParameterizeBrokenPipeDetection(Byte value) : base(value, ParameterizeBrokenPipeDetection)
{
}
}
}

View File

@ -0,0 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ParameterizeLeakageDetection : SingleBytePam
{
public ParameterizeLeakageDetection() : base(ParameterizeLeakageDetection)
{
}
public ParameterizeLeakageDetection(Byte value) : base(value, ParameterizeLeakageDetection)
{
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class Ping : Pam
{
public Ping() : base(1 /* TODO: TBD */, Ping)
{
}
}
}

View File

@ -0,0 +1,54 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
// TODO: parameters - TBD
public class ReceiveSequenceOfTestTelegrams : Pam
{
public ReceiveSequenceOfTestTelegrams() : base(8, ReceiveSequenceOfTestTelegrams)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
public Byte Parameter6
{
get => this.bytes[6];
set => this.bytes[6] = value;
}
public Byte Parameter7
{
get => this.bytes[7];
set => this.bytes[7] = value;
}
}
}

View File

@ -0,0 +1,9 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class RequestDebugTelegram : DebugCmd
{
public RequestDebugTelegram() : base(RequestDebugTelegram)
{
}
}
}

View File

@ -0,0 +1,42 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
// TODO: parameters - TBD
public class RequestFixedDateReading : Pam
{
public RequestFixedDateReading() : base(6, RequestFixedDateReading)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
}
}

View File

@ -0,0 +1,42 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
// TODO: parameters - TBD
public class RequestLoggingData : Pam
{
public RequestLoggingData() : base(6, RequestLoggingData)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
}
}

View File

@ -0,0 +1,47 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class RequestMemoryDump : Pam
{
public RequestMemoryDump() : base(7, MemoryDump)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
public Byte Parameter6
{
get => this.bytes[6];
set => this.bytes[6] = value;
}
}
}

View File

@ -0,0 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class ResetAlarms : SingleBytePam
{
public ResetAlarms() : base(ResetAlarms)
{
}
public ResetAlarms(Byte value = Byte.MaxValue) : base(value, ResetAlarms)
{
}
}
}

View File

@ -0,0 +1,19 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using Common.Utils.Extensions;
using System;
public class SendBubbleUpBurst : Pam
{
public SendBubbleUpBurst() : base(3, SendBubbleUpBurst)
{
}
public UInt16 Value
{
get => this.bytes.ToUInt16BE(1);
set => value.GetBytesBE().CopyTo(this.bytes, 1);
}
}
}

View File

@ -0,0 +1,54 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
// TODO: parameters - TBD
public class SendSequenceOfTestTelegrams : Pam
{
public SendSequenceOfTestTelegrams() : base(8, SendSequenceOfTestTelegrams)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
public Byte Parameter6
{
get => this.bytes[6];
set => this.bytes[6] = value;
}
public Byte Parameter7
{
get => this.bytes[7];
set => this.bytes[7] = value;
}
}
}

View File

@ -0,0 +1,48 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
// TODO: parameters - TBD
public class SendTestPattern : Pam
{
public SendTestPattern() : base(6, SendTestPattern)
{
}
public Byte Parameter1
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public Byte Parameter2
{
get => this.bytes[2];
set => this.bytes[2] = value;
}
public Byte Parameter3
{
get => this.bytes[3];
set => this.bytes[3] = value;
}
public Byte Parameter4
{
get => this.bytes[4];
set => this.bytes[4] = value;
}
public Byte Parameter5
{
get => this.bytes[5];
set => this.bytes[5] = value;
}
public Byte Parameter6
{
get => this.bytes[6];
set => this.bytes[6] = value;
}
}
}

View File

@ -0,0 +1,9 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
public class SerialOutput : DebugCmd
{
public SerialOutput() : base(SerialOutput)
{
}
}
}

Some files were not shown because too many files have changed in this diff Show More