412 lines
16 KiB
C#
412 lines
16 KiB
C#
using ByteArrayStyle;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
|
|
|
namespace Xylem.Common.Ui.GenesisToolBox
|
|
{
|
|
//CUSTOMER_AlarmEnableMask UInt32 Bit set of those alarms which are being monitored.
|
|
//CUSTOMER_AlarmBroadcastMask UInt32 Bit set of those alarms which will generate events.
|
|
//CUSTOMER_AlarmVisualMask UInt32 Bit set of those alarms which are displayed with IDs and the alarm icon.
|
|
|
|
[Flags]
|
|
internal enum AlarmMask
|
|
{
|
|
ALARM_REBOOT = 1 << 0,
|
|
ALARM_LOW_BATTERY = 1 << 1,
|
|
ALARM_VERY_LOW_BATTERY = 1 << 2, /* For consistency with st_alarm_bit_t only */
|
|
ALARM_CONFIG_ERROR = 1 << 3,
|
|
ALARM_EMPTY_PIPE = 1 << 4,
|
|
ALARM_MAGNETIC_TAMPER = 1 << 5, /* For consistency with st_alarm_bit_t only */
|
|
ALARM_REVERSE_FLOW = 1 << 6,
|
|
ALARM_SUSPECT_LEAK = 1 << 7,
|
|
ALARM_BROKEN_PIPE = 1 << 8,
|
|
ALARM_LOW_PRESSURE = 1 << 9,
|
|
ALARM_HIGH_PRESSURE = 1 << 10,
|
|
ALARM_LOW_TEMPERATURE = 1 << 11,
|
|
ALARM_HIGH_TEMPERATURE = 1 << 12,
|
|
ALARM_RADIO_ERROR = 1 << 13,
|
|
ALARM_METROLOGY_PARAMS = 1 << 14,
|
|
ALARM_METROLOGY_MEASURE = 1 << 15,
|
|
ALARM_MAX = 1 << 16
|
|
};
|
|
|
|
|
|
|
|
public partial class FrmAlarmMng : Form
|
|
{
|
|
private GenesisMeter _currentGenesis;
|
|
private MeterBatch _meterBatch = new MeterBatch();
|
|
private List<NumericUpDown> registerControls = new List<NumericUpDown>();
|
|
|
|
public FrmAlarmMng()
|
|
{
|
|
InitializeComponent();
|
|
|
|
var RegisterSource = new List<Tuple<String, Type, String, UInt32, UInt32, UInt32>>();
|
|
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_ExcessFlowVolumeThreshold", typeof(UInt32), "Flow rate above which broken pipe alarm is set in 1/256 l/h ", 0, 4294967295, 639999));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_LeakTimeThreshold", typeof(UInt32), "Time threshold for leak alarm in minutes ", 0, 69632, 360));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_ReverseFlowTimeThreshold", typeof(UInt16), "Number of measurements in reverse flow required to set reverse flow alarm ", 0, 65535, 1800));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_ExcessFlowTimeThreshold", typeof(UInt32), "Time threshold for broken pipe alarm in minutes ", 0, 69632, 180));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_LeakFlowThreshold", typeof(UInt32), "Flow rate above which leak alarm can be set in 1/256 l/h ", 0, 4294967295, 6399));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_TemperatureHighThreshold", typeof(UInt32), "High temperature alarm threshold in 0.1°C ", 0, 800, 500));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_TemperatureHighDelay", typeof(UInt32), "Time threshold for high temperature alarm in seconds ", 0, 10800, 600));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_TemperatureLowThreshold", typeof(UInt32), "Low temperature alarm threshold in 0.1°C ", 0, 4294967295, 20));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_TemperatureLowDelay", typeof(UInt32), "Time threshold for low temperature alarm in seconds ", 0, 10800, 600));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_PressureHighThreshold", typeof(UInt32), "High pressure alarm threshold in Pa ", 0, 2550000, 1600000));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_PressureHighDelay", typeof(UInt32), "Time threshold for high pressure alarm in seconds ", 0, 10800, 600));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_PressureLowThreshold", typeof(UInt32), "Low pressure alarm threshold in Pa ", 0, 2550000, 30000));
|
|
RegisterSource.Add(new Tuple<String, Type, String, UInt32, UInt32, UInt32>("CUSTOMER_PressureLowDelay", typeof(UInt32), "Time threshold for low pressure alarm in seconds ", 0, 10800, 600));
|
|
var i = 0;
|
|
|
|
var currentHeight = 70;
|
|
foreach (var item in RegisterSource)
|
|
{
|
|
Label lblName = new Label();
|
|
Label lblType = new Label();
|
|
Label lblMin = new Label();
|
|
Label lblMax = new Label();
|
|
Label lblDefault = new Label();
|
|
TextBox txtDesc = new TextBox();
|
|
|
|
NumericUpDown nud = new NumericUpDown();
|
|
|
|
nud.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((Byte)(0)));
|
|
nud.Location = new System.Drawing.Point(230, currentHeight);
|
|
nud.Name = $"nudc{i}";
|
|
nud.Size = new System.Drawing.Size(140, 25);
|
|
nud.Tag = item;
|
|
|
|
nud.Minimum = item.Item4;
|
|
nud.Maximum = item.Item5;
|
|
|
|
|
|
registerControls.Add(nud);
|
|
//
|
|
// lblc1
|
|
//
|
|
lblName.AutoSize = true;
|
|
lblName.Location = new System.Drawing.Point(10, currentHeight);
|
|
lblName.Name = $"lblName{i}";
|
|
lblName.Size = new System.Drawing.Size(220, 15);
|
|
lblName.Text = item.Item1;
|
|
|
|
|
|
currentHeight = currentHeight + 25;
|
|
|
|
txtDesc.Font = new System.Drawing.Font("Microsoft Sans Serif", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((Byte)(0)));
|
|
|
|
txtDesc.Enabled = false;
|
|
txtDesc.Multiline = true;
|
|
txtDesc.Name = $"txtDesc{i}";
|
|
txtDesc.Location = new System.Drawing.Point(10, currentHeight);
|
|
txtDesc.Size = new System.Drawing.Size(480, 20);
|
|
txtDesc.Text = $"Def={item.Item6} Min={item.Item4} Max={item.Item5} Desc={item.Item3.Trim()}";
|
|
|
|
|
|
currentHeight = currentHeight + 25;
|
|
|
|
|
|
i = i + 1;
|
|
groupBox5.Controls.Add(lblName);
|
|
groupBox5.Controls.Add(nud);
|
|
groupBox5.Controls.Add(txtDesc);
|
|
|
|
}
|
|
|
|
|
|
|
|
//CUSTOMER StoreConfiguration UInt32 Store all configuration items in non-volatile memory.
|
|
|
|
|
|
|
|
}
|
|
|
|
private void btnConnect_Click(Object sender, EventArgs e)
|
|
{
|
|
Int32 slotNR = 0;
|
|
if (!string.IsNullOrEmpty(cbComSlot.SelectedItem.ToString()) &&
|
|
int.TryParse(cbComSlot.SelectedItem.ToString(), out slotNR))
|
|
{
|
|
try
|
|
{
|
|
_meterBatch.RemoveAllMeters();
|
|
_currentGenesis = new GenesisMeter();
|
|
|
|
_currentGenesis.SetupFromConfigFile(slotNR);
|
|
_currentGenesis.EnableAutoLogon();
|
|
_meterBatch.AddMeter(_currentGenesis);
|
|
|
|
_meterBatch.MetersLogin();
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void btnRead_Click(Object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null)
|
|
{
|
|
clbAlarms.ItemCheck -= clbAlarms_ItemCheck;
|
|
var cAlarm = _currentGenesis.GetAlarms();
|
|
//MessageBox.Show($"Checkalarm EMPTY_PIPE = { _currentGenesis.HasAlarms(GenesisMeter.Alarm.EMPTY_PIPE)}");
|
|
|
|
clbAlarms.Items.Clear();
|
|
foreach (GenesisMeter.Alarm suit in (GenesisMeter.Alarm[])Enum.GetValues(typeof(GenesisMeter.Alarm)))
|
|
{
|
|
|
|
clbAlarms.Items.Add(suit, cAlarm.HasFlag(suit));
|
|
}
|
|
clbAlarms.ItemCheck += clbAlarms_ItemCheck;
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("not connected");
|
|
}
|
|
}
|
|
private void clbAlarms_SelectedIndexChanged(Object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
private void clbAlarms_ItemCheck(Object sender, ItemCheckEventArgs e)
|
|
{
|
|
if (e.NewValue == CheckState.Checked)
|
|
{
|
|
MessageBox.Show("Alarms cannot write, they have to set by meter");
|
|
e.NewValue = CheckState.Unchecked;
|
|
}
|
|
else if (e.NewValue == CheckState.Unchecked)
|
|
{
|
|
if (_currentGenesis != null)
|
|
{
|
|
//_currentGenesis.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE | GenesisMeter.Alarm.REBOOT);
|
|
var allEnums = ((GenesisMeter.Alarm[])Enum.GetValues(typeof(GenesisMeter.Alarm)));
|
|
if (allEnums.Length > e.Index)
|
|
{
|
|
_currentGenesis.ResetAlarm(allEnums[e.Index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void FrmAlarmMng_FormClosing(Object sender, FormClosingEventArgs e)
|
|
{
|
|
|
|
_currentGenesis?.Dispose();
|
|
_meterBatch?.Dispose();
|
|
}
|
|
|
|
private void btnReadAEM_Click(Object sender, EventArgs e)
|
|
{
|
|
ReadAlarm("CUSTOMER_AlarmEnableMask", lblAEM, clbAEM);
|
|
}
|
|
|
|
private Boolean lockEvents = false;
|
|
private void ReadAlarm(String registerName, Label resultLable, CheckedListBox clb)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
lockEvents = true;
|
|
clb.Items.Clear();
|
|
|
|
|
|
var registerContent = _currentGenesis.ReadRegister(registerName).ToList();
|
|
|
|
var hashCode = RegisterConverter.ConvertTo<UInt32>(registerContent.ToArray());
|
|
registerContent.Reverse();
|
|
resultLable.Text = ByteStyler.ToString(registerContent.ToArray());
|
|
var fullAlarm = (AlarmMask)hashCode;
|
|
var codeCounter = 0;
|
|
foreach (AlarmMask alarm in (AlarmMask[])Enum.GetValues(typeof(AlarmMask)))
|
|
{
|
|
var ItemChecked = fullAlarm.HasFlag(alarm);
|
|
clb.Items.Add($"{alarm.ToString()}(Code{codeCounter})", ItemChecked);
|
|
codeCounter = codeCounter + 1;
|
|
}
|
|
lockEvents = false;
|
|
}
|
|
}
|
|
|
|
|
|
private void setAlarm(String registerName, Label resultLable, CheckedListBox clb, Int32 changedIndex, Boolean changedValue)
|
|
{
|
|
if (lockEvents)
|
|
{
|
|
return;
|
|
}
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
lockEvents = true;
|
|
AlarmMask helper = 0;
|
|
UInt32 sumIChecked = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
for (Int32 i = 0; i < clb.Items.Count; i++)
|
|
{
|
|
if (i == changedIndex)
|
|
{
|
|
if (changedValue)
|
|
{
|
|
sb.AppendLine($"{i} << 1");
|
|
sumIChecked = sumIChecked + (UInt32)(1 << (i));
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
}
|
|
else if (clb.GetItemChecked(i))
|
|
{
|
|
//sb.Append("=1;");
|
|
//helper = helper.GetHashCode() + ((AlarmMaskOrigin)i) >> 1;
|
|
sb.AppendLine($"{i} << 1");
|
|
sumIChecked = sumIChecked + (UInt32)(1 << (i));
|
|
}
|
|
else
|
|
{
|
|
//sb.Append("=0;");
|
|
}
|
|
|
|
}
|
|
//40915
|
|
var binHelper = RegisterConverter.ConvertFrom(sumIChecked);
|
|
binHelper.Reverse();
|
|
|
|
|
|
_currentGenesis.WriteRegister(registerName, sumIChecked, true, true);
|
|
resultLable.Text = ByteStyler.ToString(binHelper);
|
|
lockEvents = false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void btnABM_Click(Object sender, EventArgs e)
|
|
{
|
|
ReadAlarm("CUSTOMER_AlarmBroadcastMask", lblABM, clbABM);
|
|
}
|
|
|
|
private void btnAVM_Click(Object sender, EventArgs e)
|
|
{
|
|
ReadAlarm("CUSTOMER_AlarmVisualMask", lblAVM, clbAVM);
|
|
}
|
|
|
|
private void clbABM_SelectedIndexChanged(Object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void clbAVM_SelectedIndexChanged(Object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void clbAEM_ItemCheck(Object sender, ItemCheckEventArgs e)
|
|
{
|
|
|
|
setAlarm("CUSTOMER_AlarmEnableMask", lblAEM, clbAEM, e.Index, e.NewValue == CheckState.Checked);
|
|
}
|
|
|
|
private void clbAEM_SelectedIndexChanged(Object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void clbABM_ItemCheck(Object sender, ItemCheckEventArgs e)
|
|
{
|
|
setAlarm("CUSTOMER_AlarmBroadcastMask", lblABM, clbABM, e.Index, e.NewValue == CheckState.Checked);
|
|
}
|
|
|
|
private void clbAVM_ItemCheck(Object sender, ItemCheckEventArgs e)
|
|
{
|
|
setAlarm("CUSTOMER_AlarmVisualMask", lblAVM, clbAVM, e.Index, e.NewValue == CheckState.Checked);
|
|
}
|
|
|
|
private void button1_Click(Object sender, EventArgs e)
|
|
{
|
|
//read
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
foreach (var nud in registerControls)
|
|
{
|
|
if (nud.Tag is Tuple<String, Type, String, UInt32, UInt32, UInt32> source)
|
|
{
|
|
var a = _currentGenesis.ReadRegister(source.Item1);
|
|
if (source.Item2 == typeof(UInt32))
|
|
{
|
|
nud.Value = RegisterConverter.ConvertTo<UInt32>(a);
|
|
}
|
|
else if (source.Item2 == typeof(UInt16))
|
|
{
|
|
nud.Value = RegisterConverter.ConvertTo<UInt16>(a);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void button2_Click(Object sender, EventArgs e)
|
|
{
|
|
//write
|
|
|
|
}
|
|
|
|
private void button3_Click(object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
_currentGenesis.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0xFF, true, false);
|
|
}
|
|
}
|
|
|
|
private void button4_Click(object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
_currentGenesis.Logout();
|
|
}
|
|
}
|
|
|
|
private void btnReadMain_Click(object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
var registerContent = _currentGenesis.ReadRegister("SENSUSRADIO_MainAlarmMask").ToList();
|
|
var hashCode = RegisterConverter.ConvertTo<UInt32>(registerContent.ToArray());
|
|
registerContent.Reverse();
|
|
lblSENSUSRADIO_MainAlarmMask.Text = ByteStyler.ToString(registerContent.ToArray());
|
|
|
|
|
|
registerContent = _currentGenesis.ReadRegister("SENSUSRADIO_ExtendedAlarmMask").ToList();
|
|
hashCode = RegisterConverter.ConvertTo<UInt32>(registerContent.ToArray());
|
|
registerContent.Reverse();
|
|
lblRadioExt.Text = ByteStyler.ToString(registerContent.ToArray());
|
|
}
|
|
}
|
|
|
|
private void btnRadioExt_Click(object sender, EventArgs e)
|
|
{
|
|
if (_currentGenesis != null && _currentGenesis.IsLoggedOn)
|
|
{
|
|
_currentGenesis.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0xFF, true, false);
|
|
}
|
|
}
|
|
}
|
|
}
|