MagFluxToolBox - FrmSetup adapted to MagFlux device

This commit is contained in:
Thomas Wiedebusch
2023-04-20 05:32:53 +02:00
parent 7ff63d4ec7
commit 9c328a057c
17 changed files with 1422 additions and 33 deletions
@@ -0,0 +1,88 @@
using System;
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig
{
/// <summary>
/// Setup of communication timeouts and retries for request and streaming protocol,
/// this timeout starts the retry.
///
/// The individual timings of the hardware will be covert by the
/// <see cref="TransmitPortSettings.ResponseTimeoutMs"/>
/// injected by the different transmit protocols:
/// <see cref="IrdaTransmitProtocol"/>
/// <see cref="LedTransmitProtocol"/>
/// <see cref="RfidTransmitProtocol"/>
/// <see cref="UartTransmitProtocol"/>
/// </summary>
public static class CommunicationConfig
{
private static Int32 _requestRetries = DefaultRequestRetries;
/// <summary>
/// Maximum retries for one command at request protocol
/// at missing response.
/// </summary>
public static Int32 RequestRetries
{
get => _requestRetries;
set => _requestRetries = value > MaxRequestRetries ? MaxRequestRetries : value;
}
/// <summary>
/// Acceptable error code as valid answer to skip retries,
/// this might be 0x0004 for not installed application.
/// </summary>
public const UInt16 SkipRetryErrorCode = 0x0004;
/// <summary>
/// Default retries for one command at request protocol
/// at missing response.
/// </summary>
public const Int32 DefaultRequestRetries = 2;
/// <summary>
/// Limit retries to this value.
/// </summary>
private const Int32 MaxRequestRetries = 6;
/// <summary>
/// Send delay between records in milliseconds before
/// new record is going to be send or between retries,
/// this time is independent of the timeout, it is
/// used to delay the next send record after successful
/// response from meter.
/// </summary>
public const Int32 InterRecordSendDelayMs = 5;
//public const Int32 InterRecordSendDelayMs = 50;
/// <summary>
/// Timeout before retry will be initiated in milliseconds
/// for the response of the request protocol. This is an
/// offset value, the transmission specific timing will be
/// added from the transmit protocol timeout. This timeout
/// will be multiplied with the (retry + 1)!
/// </summary>
public const Int32 ResponseTimeoutMs = 250;
// public const Int32 ResponseTimeoutMs = 100;
/// <summary>
/// Timeout before retry will be initiated if the meter is
/// not ready indicated by a wakeup-message or decoding error.
/// </summary>
public const Int32 BusyTimeoutMs = 500;
// public const Int32 BusyTimeoutMs = 1000;
/// <summary>
/// Time to avoid automatic lock off of genesis device due to
/// missing communication with request protocol in seconds
/// </summary>
public const Int32 KeepSessionTimeS = 60 * 3;
/// <summary>
/// Time to update intermediate record for overflow detection
/// during a measurement and update of short-term measurement
/// in seconds
/// </summary>
public const Int32 MeasurementUpdateTimeS = 10;
}
}
@@ -0,0 +1,24 @@
using System;
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig.Const
{
public static class MeterConfig
{
/// <summary>
/// Calibration Factor on init from meter
/// Is also the factor to convert CalibrationFactors to readable number,
/// this is the default if the ProcessConfig.json file cannot be read.
/// </summary>
public const UInt16 CalibrationDefault = 15625;
/// <summary>
/// Channels for calibration
/// </summary>
public const Int32 CalibChannels = 3;
/// <summary>
/// Maximum calibration value in percent
/// </summary>
public const Double DefaultMaxCalibFactorTolerancePercent = 100.0;
}
}
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{70398B99-B134-4BBD-968B-7399B70C3CE2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig</RootNamespace>
<AssemblyName>Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CommunicationConfig.cs" />
<Compile Include="Const\MeterConfig.cs" />
<Compile Include="PortConfig.cs" />
<Compile Include="ProcessConfig.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SlotConfig.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,63 @@
using System;
using System.IO.Ports;
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig
{
/// <summary>
/// Collection of port settings
/// </summary>
public struct PortConfig
{
private String _portName;
/// <summary>
/// Assigns a port name and creates the serial port object
/// Port name e.g. "COM2"
/// </summary>
public String PortName
{
get =>
//if the serial port object does not exists
GetSerialPort() == null ? "NA" : _portName;
set
{
if (value == null) return;
_portName = value;
//create a serial port object
if (GetSerialPort() == null)
{
SetSerialPort(new SerialPort(value));
}
else
{
GetSerialPort().PortName = value;
}
}
}
/// <summary>
/// setup of port type from name (referenced as "Type" in config file)
/// </summary>
public String Type { get; set; }
private SerialPort _serialPort;
/// <summary>
/// using dotNets <see cref="GetSerialPort()"/> for connection
/// </summary>
public SerialPort GetSerialPort()
{
return _serialPort;
}
/// <summary>
/// using dotNets <see cref="GetSerialPort()"/> for connection
/// </summary>
private void SetSerialPort(SerialPort value)
{
_serialPort = value;
}
}
}
@@ -0,0 +1,121 @@
using System;
using System.ComponentModel;
using System.IO;
using Newtonsoft.Json;
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig
{
/// <summary>
/// Configuration of meter
/// </summary>
public class ProcessConfig
{
/// <summary>
/// ctor
/// </summary>
public ProcessConfig()
{
UseRegisterWatchService = false;
UseErrorLogger = false;
AutoUpdateFiles = false;
ProductionMode = true;
}
/// <summary>
/// Load configuration file from AppRoaming or working directory
/// </summary>
/// <param name="file"></param>
public ProcessConfig(String file)
{
// check for AppRoaming
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
nameof(MagFlux), file);
if (!File.Exists(configFile))
{
// take actual working directory
configFile = Path.Combine(file);
if (!File.Exists(configFile))
{
UseRegisterWatchService = false;
UseErrorLogger = false;
return;
}
}
using (var tr = new StreamReader(configFile))
{
var meterConfig = JsonConvert.DeserializeObject<ProcessConfig>(tr.ReadToEnd());
UseRegisterWatchService = meterConfig.UseRegisterWatchService;
RegisterWatchServiceUrl = meterConfig.RegisterWatchServiceUrl;
UseMinMaxCheck = meterConfig.UseMinMaxCheck;
UseErrorLogger = meterConfig.UseErrorLogger;
ErrorLoggerServiceUrl = meterConfig.ErrorLoggerServiceUrl;
UseCalibrationLogger = meterConfig.UseCalibrationLogger;
CalibrationLoggerServiceUrl = meterConfig.CalibrationLoggerServiceUrl;
AutoUpdateFiles = meterConfig.AutoUpdateFiles;
ProductionMode = meterConfig.ProductionMode;
}
}
/// <summary>
/// Write file to AppRoaming and backup it to actual working directory
/// </summary>
/// <param name="file"></param>
public void Update(String file)
{
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
nameof(MagFlux), file);
File.WriteAllText(configFile, JsonConvert.SerializeObject(this));
File.WriteAllText(file, JsonConvert.SerializeObject(this));
}
/// <summary>
///
/// </summary>
public Boolean UseRegisterWatchService { get; set; }
/// <summary>
///
/// </summary>
public String RegisterWatchServiceUrl { get; set; }
/// <summary>
///
/// </summary>
public Boolean UseMinMaxCheck { get; set; }
/// <summary>
///
/// </summary>
public Boolean UseErrorLogger { get; set; }
/// <summary>
///
/// </summary>
public String ErrorLoggerServiceUrl { get; set; }
/// <summary>
///
/// </summary>
public Boolean UseCalibrationLogger { get; set; }
/// <summary>
///
/// </summary>
public String CalibrationLoggerServiceUrl { get; set; }
/// <summary>
///
/// </summary>
public Boolean AutoUpdateFiles { get; set; }
[DefaultValue(true)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public Boolean ProductionMode { get; set; } = true;
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Xylem")]
[assembly: AssemblyProduct("MagFluxConfig")]
[assembly: AssemblyCopyright("Copyright © Xylem 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("70398b99-b134-4bbd-968b-7399b70c3ce2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,26 @@
using System;
namespace Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig
{
/// <summary>
/// Container for port configuration
/// </summary>
public class SlotConfig
{
/// <summary>
/// Slot number
/// </summary>
public Int32 Slot { get; set; }
/// <summary>
/// Request port settings
/// </summary>
public PortConfig Request { get; set; }
/// <summary>
/// Streaming port settings
/// </summary>
public PortConfig Streaming { get; set; }
}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net48" />
</packages>