common/Ui/GenesisToolBox/frmSetup.cs
2026-04-23 17:50:07 +02:00

701 lines
26 KiB
C#

using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
using Xylem.Common.Hardware.Interfaces.Ports.SerialPorts;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Utils.Logging;
namespace Xylem.Common.Ui.GenesisToolBox
{
/// <summary>
/// Setup of GTB
/// </summary>
public partial class FrmSetup : Form
{
private const String RequestPortString = "RequestPort";
private const String RequestTypeString = "RequestType";
private const String StreamingPortString = "StreamingPort";
private const String SlotTypeString = "RefTemperature";
private const String SlotString = "Slot";
private const String StreamingDetectString = "DetectStreaming";
private const String RequestDetectString = "DetectRequest";
private const String ValueString = "Value";
private const String TextString = "Text";
private String _fileString;
private readonly String _serialConfigFilePathName;
private readonly String _offlinePwdPathName;
private readonly DataTable _slotConfigDataTable = new DataTable();
//private readonly List<String> _sirt433MhzComports = new List<String>();
//private readonly List<String> _sirt868MHzComports = new List<String>();
private readonly SirtConfig _sirtConfig = new SirtConfig();
private readonly ProcessConfig _configuration = new ProcessConfig();
/// <summary>
/// Ctor
/// </summary>
public FrmSetup()
{
_serialConfigFilePathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"Genesis", ProgramConfig.SerialConfigFileName);
_offlinePwdPathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"Genesis", ProgramConfig.OfflineInfoFile);
if (!File.Exists(_offlinePwdPathName))
{
_listOfOfflinePasswords.Add(new OfflinePasswordItem("", ""));
File.WriteAllText(_offlinePwdPathName, JsonConvert.SerializeObject(_listOfOfflinePasswords));
}
//build header of data table for reference by name
_slotConfigDataTable.Columns.Add(SlotString, typeof(String));
_slotConfigDataTable.Columns.Add(StreamingPortString, typeof(String));
_slotConfigDataTable.Columns.Add(RequestPortString, typeof(String));
_slotConfigDataTable.Columns.Add(RequestTypeString, typeof(String));
_slotConfigDataTable.Columns.Add(SlotTypeString, typeof(String));
InitializeComponent();
tbcSlot.Name = SlotString;
cbcRequestPort.Name = RequestPortString;
cbcRequestType.Name = RequestTypeString;
cbcStreamingPort.Name = StreamingPortString;
cbcSlotType.Name = SlotTypeString;
btcDetectStreaming.Name = StreamingDetectString;
btcDetectRequest.Name = RequestDetectString;
btcDetectStreaming.Name = StreamingDetectString;
tbcSlot.HeaderText = SlotString;
cbcRequestPort.HeaderText = RequestPortString;
cbcRequestType.HeaderText = RequestTypeString;
cbcStreamingPort.HeaderText = StreamingPortString;
btcDetectRequest.HeaderText = RequestDetectString;
btcDetectStreaming.HeaderText = StreamingDetectString;
cbcSlotType.HeaderText = SlotTypeString;
LoadFromFile();
_configuration.ReadProcessConfig();
cbUseMinMaxCheck.Checked = _configuration.UseMinMaxCheck;
cbUseRegisterWatch.Checked = _configuration.UseRegisterWatchService;
txtWachSeriveUrl.Text = _configuration.RegisterWatchServiceUrl;
cbUpdateFiles.Checked = _configuration.AutoUpdateFiles;
cbxProductionMode.Checked = _configuration.ProductionMode;
_sirtConfig.ReadSirtConfig();
tbxSirtStationId.Text = _sirtConfig.StationId?.ToString();
tbxSirtBoxNo.Text = _sirtConfig.SirtBoxNo?.ToString();
if (_sirtConfig.SirtComport433MHz != null)
cbxSirtComport433MHz.Items.Add(_sirtConfig.SirtComport433MHz);
if (_sirtConfig.SirtComport868MHz != null)
cbxSirtComport868MHz.Items.Add(_sirtConfig.SirtComport868MHz);
var comPorts = SerialPort.GetPortNames().ToList();
foreach (var comPort in comPorts.Where(comPort => !cbxSirtComport433MHz.Items.Contains(comPort)))
{
cbxSirtComport433MHz.Items.Add(comPort);
}
foreach (var comPort in comPorts.Where(comPort => !cbxSirtComport868MHz.Items.Contains(comPort)))
{
cbxSirtComport868MHz.Items.Add(comPort);
}
cbxSirtComport433MHz.Text = cbxSirtComport433MHz.Items[0].ToString();
cbxSirtComport868MHz.Text = cbxSirtComport868MHz.Items[0].ToString();
if (_sirtConfig.ServiceSirtComport433MHz != null)
cbxSirtService433MHz.Items.Add(_sirtConfig.ServiceSirtComport433MHz);
if (_sirtConfig.ServiceSirtComport868MHz != null)
cbxSirtService868MHz.Items.Add(_sirtConfig.ServiceSirtComport868MHz);
foreach (var comPort in comPorts.Where(comPort => !cbxSirtService433MHz.Items.Contains(comPort)))
{
cbxSirtService433MHz.Items.Add(comPort);
}
foreach (var comPort in comPorts.Where(comPort => !cbxSirtService868MHz.Items.Contains(comPort)))
{
cbxSirtService868MHz.Items.Add(comPort);
}
cbxSirtService433MHz.Text = cbxSirtService433MHz.Items[0].ToString();
cbxSirtService868MHz.Text = cbxSirtService868MHz.Items[0].ToString();
}
private void BtnReload_Click(Object sender, EventArgs e)
{
LoadFromFile();
LoadOfflineFile();
}
private void BtnStore_Click(Object sender, EventArgs e)
{
StoreToPc();
StoreOfflineFile();
StoreSirtSettings();
}
private void StoreSirtSettings()
{
// Get the SIRT settings from the GUI
if (int.TryParse(tbxSirtStationId.Text, out var intNo))
{
_sirtConfig.StationId = intNo;
}
if (int.TryParse(tbxSirtBoxNo.Text, out intNo))
{
_sirtConfig.SirtBoxNo = intNo;
}
_sirtConfig.SirtComport433MHz = cbxSirtComport433MHz.Text;
_sirtConfig.SirtComport868MHz = cbxSirtComport868MHz.Text;
_sirtConfig.ServiceSirtComport433MHz = cbxSirtService433MHz.Text;
_sirtConfig.ServiceSirtComport868MHz = cbxSirtService868MHz.Text;
_sirtConfig.Update();
}
private void StoreToPc()
{
var newFileContent = new List<SlotConfig>();
for (var row = 0; row < dgvConfig.Rows.Count; row++)
{
var slotStr = (String)dgvConfig.Rows[row].Cells[SlotString].Value;
int.TryParse(slotStr, out var slot);
var irdaType = typeof(IrdaSerialPort).FullName;
if (dgvConfig.Rows[row].Cells[RequestTypeString].Value != null)
{
irdaType = (String)dgvConfig.Rows[row].Cells[RequestTypeString].Value;
}
var requestPort = new PortConfig()
{
PortName = (String)dgvConfig.Rows[row].Cells[RequestPortString].Value,
Type = irdaType
};
var streamingPort = new PortConfig()
{
PortName = (String)dgvConfig.Rows[row].Cells[StreamingPortString].Value,
Type = typeof(UartSerialPort).FullName
};
var slotType = SlotType.DutMeter;
if (dgvConfig.Rows[row].Cells[SlotTypeString].Value != null)
{
var isChecked = dgvConfig.Rows[row].Cells[SlotTypeString].Value.ToString();
if (bool.TrueString == isChecked)
{
slotType = SlotType.TemperatureMeter;
}
}
if (!string.IsNullOrEmpty(slotStr))
{
newFileContent.Add(new SlotConfig()
{ Slot = slot, Request = requestPort, Streaming = streamingPort, Type = slotType });
}
}
var text = JsonConvert.SerializeObject(newFileContent);
// Overwrite only on changed content
if (text == _fileString)
{
LoadFromFile();
return;
}
//save file only on changed content
if (File.Exists(_serialConfigFilePathName))
{
var backupSerialConfigFile = $"{Path.GetDirectoryName(_serialConfigFilePathName)}" +
$"\\Backup_{DateTime.Now:yyyyMMdd}_{DateTime.Now:HHmmss}_{ProgramConfig.SerialConfigFileName}";
File.Move(_serialConfigFilePathName, backupSerialConfigFile);
}
File.WriteAllText(_serialConfigFilePathName, text);
LoadFromFile();
LoadOfflineFile();
}
private void LoadFromFile()
{
_slotConfigDataTable.Clear();
dgvConfig.Rows.Clear();
if (!File.Exists(_serialConfigFilePathName))
{
return;
}
SlotConfig[] meterConfigList;
using (var tr = new StreamReader(_serialConfigFilePathName))
{
_fileString = tr.ReadToEnd();
meterConfigList = JsonConvert.DeserializeObject<SlotConfig[]>(_fileString);
}
foreach (var item in meterConfigList)
{
var row = _slotConfigDataTable.NewRow();
row[SlotString] = item.Slot;
row[RequestPortString] = item.Request.PortName;
row[RequestTypeString] = item.Request.Type;
row[StreamingPortString] = item.Streaming.PortName;
row[SlotTypeString] = item.Type == SlotType.TemperatureMeter;
_slotConfigDataTable.Rows.Add(row);
}
foreach (DataRow row in _slotConfigDataTable.Rows)
{
dgvConfig.Rows.Add(AddRowToGrid(row));
}
}
private DataGridViewRow AddRowToGrid(DataRow row = null)
{
var newRow = new DataGridViewRow();
var slotCell = new DataGridViewTextBoxCell();
newRow.Cells.Add(slotCell);
var requestPortCell = new DataGridViewComboBoxCell
{
DataSource = GetPorts(),
DisplayMember = TextString,
ValueMember = ValueString
};
newRow.Cells.Add(requestPortCell);
var requestTypeCell = new DataGridViewComboBoxCell
{
DataSource = GetTypes(),
DisplayMember = TextString,
ValueMember = ValueString
};
newRow.Cells.Add(requestTypeCell);
var streamingPortCell = new DataGridViewComboBoxCell
{
DataSource = GetPorts(),
DisplayMember = TextString,
ValueMember = ValueString
};
newRow.Cells.Add(streamingPortCell);
var slotTypeCell = new DataGridViewCheckBoxCell();
slotTypeCell.Value = false;// SlotType.DutMeter.GetHashCode();
if (row == null)
{
return newRow;
}
slotCell.Value = row[SlotString];
streamingPortCell.Value = row[StreamingPortString];
requestPortCell.Value = row[RequestPortString];
try
{
requestTypeCell.Value = row[RequestTypeString];
}
catch (Exception)
{
// ignored
}
slotTypeCell.Value = row[SlotTypeString];// Enum.Parse(typeof(SlotType), row[_slotTypeString].ToString()).GetHashCode();
newRow.Cells.Add(slotTypeCell);
return newRow;
}
// ReSharper disable once UnusedMember.Local
private DataTable GetSlotTypes()
{
var ret = new DataTable();
ret.Columns.Add(TextString);
ret.Columns.Add(ValueString, typeof(Int32));
ret.Rows.Add("DutMeter", SlotType.DutMeter.GetHashCode());
ret.Rows.Add("TemperatureMeter", SlotType.TemperatureMeter.GetHashCode());
return ret;
}
private DataTable GetPorts()
{
var ret = new DataTable();
ret.Columns.Add(ValueString);
ret.Columns.Add(TextString);
var portList = SerialPort.GetPortNames().ToList();
foreach (var item in portList)
{
ret.Rows.Add(item, item);
}
foreach (DataRow row in _slotConfigDataTable.Rows)
{
if (portList.All(pl => pl != (String)row[StreamingPortString]))
{
ret.Rows.Add(row[StreamingPortString].ToString(), BaseSerialPort.PortNotAssigned);
}
if (portList.All(pl => pl != (String)row[RequestPortString]))
{
ret.Rows.Add(row[RequestPortString].ToString(), BaseSerialPort.PortNotAssigned);
}
}
return ret;
}
private static DataTable GetTypes()
{
var ret = new DataTable();
ret.Columns.Add(ValueString);
ret.Columns.Add(TextString);
ret.Rows.Add(typeof(UartSerialPort).FullName, nameof(UartSerialPort));
ret.Rows.Add(typeof(RfidSerialPort).FullName, nameof(RfidSerialPort));
ret.Rows.Add(typeof(IrdaSerialPort).FullName, nameof(IrdaSerialPort));
return ret;
}
private ConcurrentBag<String> _countRawData = new ConcurrentBag<String>();
private void DgvConfig_CellContentClick(Object sender, DataGridViewCellEventArgs e)
{
if (!dgvConfig.Columns[e.ColumnIndex].Name.Contains(StreamingDetectString) &&
!dgvConfig.Columns[e.ColumnIndex].Name.Contains(RequestDetectString))
{
return;
}
StoreToPc();
var slotString = (String)dgvConfig.Rows[e.RowIndex].Cells[SlotString].Value;
int.TryParse(slotString, out var slot);
using (var mb = new MeterBatch())
{
using (var meter = new GenesisMeter())
{
meter.SetupFromConfigFile(slot, false);
mb.AddMeter(meter);
const String checkMark = "\u2714";
if (dgvConfig.Columns[e.ColumnIndex].Name.Contains(StreamingDetectString))
{
_countRawData = new ConcurrentBag<String>();
meter.StreamingPort.OnRawRecordReceived += delegate (Object o, BasePortDataEventArgs rawMsg)
{
_countRawData.Add((String)rawMsg.GetData());
};
Thread.Sleep(500);
if (_countRawData.Any())
{
var text = $"SUCCESS\nSlot: {slot}\nStreaming port: {meter.StreamingPort.GetPortName()}\n\n{checkMark}";
MessageBox.Show(text, @"SUCCESS", MessageBoxButtons.OK);
dgvConfig.Rows[e.RowIndex].Cells[StreamingDetectString].Style.BackColor = Color.Green;
}
else
{
var text = $"FAILED\nSlot: {slot}\nStreaming port: {meter.StreamingPort.GetPortName()}";
MessageBox.Show(text, @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
dgvConfig.Rows[e.RowIndex].Cells[StreamingDetectString].Style.BackColor = Color.Red;
}
_countRawData = new ConcurrentBag<String>();
}
else
{
meter.Logout();
var pcbId = meter.GetPcbId();
if (string.IsNullOrEmpty(pcbId))
{
var text = $"FAILED\nSlot: {slot}\nRequest port: {meter.RequestPort.GetPortName()}";
MessageBox.Show(text, @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
dgvConfig.Rows[e.RowIndex].Cells[RequestDetectString].Style.BackColor = Color.Red;
}
else
{
var text = $"SUCCESS\nSlot: {slot}\nRequest port: {meter.RequestPort.GetPortName()}\n\n{checkMark}";
MessageBox.Show(text, @"SUCCESS", MessageBoxButtons.OK);
dgvConfig.Rows[e.RowIndex].Cells[RequestDetectString].Style.BackColor = Color.Green;
}
}
}
}
}
private void dgvConfig_DataError(Object sender, DataGridViewDataErrorEventArgs e)
{
}
private void cbUseRegisterWatch_CheckedChanged(Object sender, EventArgs e)
{
_configuration.UseRegisterWatchService = cbUseRegisterWatch.Checked;
_configuration.Update();
StoreToPc();
}
private void cbUseMinMaxCheck_CheckedChanged(Object sender, EventArgs e)
{
_configuration.UseMinMaxCheck = cbUseMinMaxCheck.Checked;
_configuration.Update();
StoreToPc();
}
private void textBox1_TextChanged(Object sender, EventArgs e)
{
_configuration.RegisterWatchServiceUrl = txtWachSeriveUrl.Text;
_configuration.Update();
StoreToPc();
}
private void cbUpdateFiles_CheckedChanged(Object sender, EventArgs e)
{
_configuration.AutoUpdateFiles = cbUpdateFiles.Checked;
_configuration.Update();
StoreToPc();
}
private List<OfflinePasswordItem> _listOfOfflinePasswords = new List<OfflinePasswordItem>();
private void FrmSetup_Load(Object sender, EventArgs e)
{
LoadOfflineFile();
cbxProductionMode.CheckedChanged += cbxProductionMode_CheckedChanged;
}
private void StoreOfflineFile()
{
try
{
// remove empty cells
var listToRemove = _listOfOfflinePasswords.Where(offlinePwd => string.IsNullOrEmpty(offlinePwd.PcbID)).ToList();
foreach (var itemToRemove in listToRemove)
{
_listOfOfflinePasswords.Remove(itemToRemove);
}
_listOfOfflinePasswords.Add(new OfflinePasswordItem("", ""));
File.WriteAllText(_offlinePwdPathName, JsonConvert.SerializeObject(_listOfOfflinePasswords));
dgvofflinePw.CellValidated -= dgvofflinePw_CellValidated;
dgvofflinePw.DataSource = null;
dgvofflinePw.DataSource = _listOfOfflinePasswords;
dgvofflinePw.CellValidated += dgvofflinePw_CellValidated;
}
catch (Exception)
{
// ignored
}
}
private void LoadOfflineFile()
{
try
{
_listOfOfflinePasswords = JsonConvert.DeserializeObject<List<OfflinePasswordItem>>(File.ReadAllText(_offlinePwdPathName));
}
catch (Exception)
{
_listOfOfflinePasswords = new List<OfflinePasswordItem>();
}
finally
{
if (!_listOfOfflinePasswords.Any())
{
_listOfOfflinePasswords.Add(new OfflinePasswordItem("", ""));
}
dgvofflinePw.CellValidated -= dgvofflinePw_CellValidated;
dgvofflinePw.DataSource = null;
dgvofflinePw.DataSource = _listOfOfflinePasswords;
dgvofflinePw.CellValidated += dgvofflinePw_CellValidated;
}
}
private void dgvofflinePw_CellValidated(Object sender, DataGridViewCellEventArgs e)
{
StoreOfflineFile();
}
private void cmdAddOffline_Click(Object sender, EventArgs e)
{
_listOfOfflinePasswords.Add(new OfflinePasswordItem("", ""));
dgvofflinePw.DataSource = null;
dgvofflinePw.DataSource = _listOfOfflinePasswords;
}
private void cbxProductionMode_CheckedChanged(Object sender, EventArgs e)
{
if (cbxProductionMode.Checked)
{
MessageBox.Show(@"Production mode! Configuration.json has to be the latest! ");
}
else
{
// ReSharper disable once LocalizableElement
MessageBox.Show("Developer mode! Configuration.json can be exchanged on individual requirements.\n" +
"\nRISK:\n" +
"- Register ranges cannot be checked\n" +
"- Register may not be able to access");
}
_configuration.ProductionMode = cbxProductionMode.Checked;
_configuration.Update();
StoreToPc();
}
private void tabPage4_Click(Object sender, EventArgs e)
{
try
{
var path = NLogHelper.GetCurrentApplicationFolder();
var a = XElement.Load(path);
lblLocalCurrentPath.Text = a.Elements().First(s => s.Name.LocalName == "variable").Attributes().First(s => s.Value == "BasePath").NextAttribute.Value;
}
catch (Exception ex)
{
lblLocalCurrentPath.Text = ex.Message;
}
try
{
var path = NLogHelper.GetApplicationDataPath();
var b = XElement.Load(path);
lblGlobalCurrentPath.Text = b.Elements().First(s => s.Name.LocalName == "variable").Attributes().First(s => s.Value == "BasePath").NextAttribute.Value;
}
catch (Exception ex)
{
lblGlobalCurrentPath.Text = ex.Message;
}
}
private void Add(String path, String newDest)
{
try
{
var a = XElement.Load(path);
var firstIsVariable = a.Elements().First();
if (firstIsVariable.Name.LocalName != "variable" )
{
var newElm = new XElement("variable", null);
newElm.SetAttributeValue("name", "BasePath");
newElm.SetAttributeValue("value", newDest);
a.AddFirst(newElm);
}
else if (a.Elements().First(b => b.Name.LocalName == "variable").Attributes()
.All(s => s.Value != "BasePath"))
{
var newElm = new XElement("variable", null);
newElm.SetAttributeValue("name", "BasePath");
newElm.SetAttributeValue("value", newDest);
a.AddFirst(newElm);
}
else
{
a.Elements().First(b => b.Name.LocalName == "variable").Attributes()
.First(s => s.Value == "BasePath").NextAttribute.Value = newDest;
}
a.Save(path);
tabPage4_Click(this, null);
}
catch (Exception)
{
// ignore;
}
}
private void btnLocalDefaultLocal_Click(Object sender, EventArgs e)
{
Add(NLogHelper.GetCurrentApplicationFolder(), "C:\\GenesisLog\\");
}
private void btnLocalDefaultLan_Click(Object sender, EventArgs e)
{
Add(NLogHelper.GetCurrentApplicationFolder(), "\\\\sla12buma\\cordonelds$\\${machinename}");
}
private void btnGlobalDefaultLocal_Click(Object sender, EventArgs e)
{
Add(NLogHelper.GetApplicationDataPath(), "C:\\GenesisLog\\");
}
private void btnGlobalDefaultLan_Click(Object sender, EventArgs e)
{
Add(NLogHelper.GetApplicationDataPath(), "\\\\sla12buma\\cordonelds$\\${{machinename}}");
}
private void btnGlobalSearch_Click(Object sender, EventArgs e)
{
var dia = new FolderBrowserDialog();
dia.ShowDialog();
Add(NLogHelper.GetApplicationDataPath(), dia.SelectedPath);
}
private void btnLocalSearch_Click(Object sender, EventArgs e)
{
var dia = new FolderBrowserDialog();
dia.ShowDialog();
Add(NLogHelper.GetCurrentApplicationFolder(), dia.SelectedPath);
}
private void btnAddRow_Click(Object sender, EventArgs e)
{
dgvConfig.Rows.Add(AddRowToGrid());
}
}
}