tbf/TBF/Rig/RegisterReaders/GenesisRegReader/GenesisCfgCtrl.cs
Michal Buzik 52bd0d01ce Restore Genesis communication and Q3 calibration from special branches
A – Registration and execution
- Register GenesisCommunication Factory in the component list.
- Separate the Genesis form and sequence from iPerl communication.

B – Communication activities
- Restore initialization, connection, PCB reading, password and login.
- Include grouped login, mode switching and disconnection.
- Support processing up to 10 slots.

C1 – Input calibration factors
- Read three factors from Water meters / Text1–Text3.
- Validate integer values in the range 1–65535.
- Preserve the default of 15625 when all three fields are empty.

D – Q3 calibration
- Connect the Prepare Q3 → measurement → Write Q3 workflow.
- Add channel processing to FlyingStart and FlyingStartMassCollection.
- Reset previous measurement data and validate calculated factors.
- Mark factors as stored only after StoreCalibration succeeds.

E – Results and database
- Store calibration factors separately for each meter and channel.
- Add result entities, mappings and Q3 data.
- Extend DB.cs / EnsureSchema to create and update the schema.
- Preserve compatibility with the existing binary format.

Validation:
- Debug build and 18 tests passed.
- Simulated communication runs follow the same activity sequence.
- The complete Q3 workflow has not yet been verified on hardware.

Known limitation:
- An inherited mismatch in simulated responses and error propagation
  can produce an incorrect OK result; this change does not fix it.
2026-09-09 15:04:49 +02:00

226 lines
7.4 KiB
C#

///
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
using System;
using System.Net;
using System.Windows.Forms;
using Common;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.RegisterReaders.GenesisRegReader
{
public partial class GenesisCfgCtrl : UserControl, IComponentCfgCtrl
{
public bool ShowMore { get { return false; } }
GenesisCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as GenesisCfg;
Redraw();
}
}
public GenesisCfgCtrl()
{
InitializeComponent();
}
private void WaterMeterCfgCtrl_Load(object sender, EventArgs e)
{
nameLabel.Text = Strings.Name;
classNameLabel.Text = config.Factory.ClassName;
Init();
Redraw();
}
public void Closing()
{
}
public void Init()
{
if (!string.IsNullOrEmpty((config.CommunicationInterfaceBridge)))
{
string className = TbfComponents.FindComponent(config.CommunicationInterfaceBridge).ClassName;
}
//string[] communicationInterfaces = config.CommunicationInterfaceBridge;
//comboBoxCommunicationInterface.Items.Add();
ComponentParametersDlg parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.CmpntEntities != null)
{
foreach (var cmpnt in parent.CmpntEntities)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.BridgeComponents.GciBridge.Factory)
{
comboBoxCommunicationInterface.Items.Add(cmpnt.Name);
}
}
}
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
nameTextBox.Text = config.Name;
radioButton1.Checked = config.UseTcpIP;
radioButton2.Checked = !config.UseTcpIP;
ipAddressTextBox.Text = (config.OptoIPAddress != null) ? config.OptoIPAddress : "0.0.0.0";
tcpipPortTextBox.Text = config.OptoTcpipPortNr.ToString();
headPortNrTextBox.Text = config.HeadCommunicationComPortNr.ToString();
optoSerialPortTextBox.Text = config.OptoComPortNr.ToString();
rfidPortNrTextBox.Text = config.RfidComPortNr.ToString();
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
groupTextBox.Text = config.Group.ToString();
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterfaceBridge;
textBoxSlotNr.Text = config.SlotNr.ToString();
tBBeginDataFlush.Text = config.IBeginDataFlush.ToString();
checkBox_EnableShowChanels.Checked = config.EnableShowChanels;
tabPage2.Controls.Add(new GenesisHeadTestCtrl(config));
}
public void Unlock()
{
nameTextBox.Enabled = true;
radioButton1.Enabled = true;
radioButton2.Enabled = true;
ipAddressTextBox.Enabled = true;
tcpipPortTextBox.Enabled = true;
optoSerialPortTextBox.Enabled = true;
rfidPortNrTextBox.Enabled = true;
headPortNrTextBox.Enabled = true;
muxBoardNrTextBox.Enabled = true;
groupTextBox.Enabled = true;
comboBoxCommunicationInterface.Enabled = true;
textBoxSlotNr.Enabled = true;
tBBeginDataFlush.Enabled = true;
checkBox_EnableShowChanels.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
int dummy;
if (radioButton1.Checked)
{
IPAddress dummyIPAddress;
if (!IPAddress.TryParse(ipAddressTextBox.Text, out dummyIPAddress))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'IP address' is not valid";
}
ushort sdummy;
if (!ushort.TryParse(tcpipPortTextBox.Text, out sdummy))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'TCP/IP port nr.' is not valid";
}
}
else
{
if (!int.TryParse(optoSerialPortTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Opto serial port nr.' is not valid";
}
}
if (!int.TryParse(rfidPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'RFID serial port nr.' is not valid";
}
if (!int.TryParse(headPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Head communication serial port nr.' is not valid";
}
if (!int.TryParse(muxBoardNrTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, muxBoardNrLabel.Text);
}
if (!int.TryParse(groupTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, groupLabel.Text);
}
if (!int.TryParse(tBBeginDataFlush.Text, out dummy) || dummy < 0 || dummy > 10000)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, tBBeginDataFlush.Text);
}
if (string.IsNullOrEmpty(comboBoxCommunicationInterface.Text) || comboBoxCommunicationInterface.SelectedIndex < 0)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Communication Interface is not selected";
}
if (!int.TryParse(textBoxSlotNr.Text, out dummy) || dummy < 0 || dummy > 400)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, tBBeginDataFlush.Text);
}
return flags;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
if (radioButton1.Checked)
{
config.UseTcpIP = true;
config.OptoIPAddress = ipAddressTextBox.Text;
config.OptoTcpipPortNr = ushort.Parse(tcpipPortTextBox.Text);
}
else
{
config.UseTcpIP = false;
config.OptoComPortNr = int.Parse(optoSerialPortTextBox.Text);
}
config.RfidComPortNr = int.Parse(rfidPortNrTextBox.Text);
config.MuxBoardNr = int.Parse(muxBoardNrTextBox.Text);
config.Group = int.Parse(groupTextBox.Text);
config.CommunicationInterfaceBridge = comboBoxCommunicationInterface.SelectedIndex >= 0 ? comboBoxCommunicationInterface.SelectedItem.ToString() : null;
config.HeadCommunicationComPortNr = int.Parse(headPortNrTextBox.Text);
config.IBeginDataFlush = int.Parse(tBBeginDataFlush.Text);
config.EnableShowChanels = checkBox_EnableShowChanels.Checked;
config.SlotNr = int.Parse(textBoxSlotNr.Text);
return flags;
}
}
}