From 5e280883032c71c994a687a5ab06c079d6eac0da Mon Sep 17 00:00:00 2001 From: rdkartono Date: Mon, 25 Nov 2024 15:55:47 +0700 Subject: [PATCH] add translation table from FSM LogicalState to Modbus Register Value --- FAtoPA.Net.csproj | 35 +++++++++ FSM.cs | 23 +++++- FSMModbusData.cs | 52 +++++++++++++ InputBox.xaml | 43 +++++++++++ InputBox.xaml.cs | 77 +++++++++++++++++++ MainWindow.xaml.cs | 186 +++++++++++++++++++++++---------------------- 6 files changed, 323 insertions(+), 93 deletions(-) create mode 100644 FSMModbusData.cs create mode 100644 InputBox.xaml create mode 100644 InputBox.xaml.cs diff --git a/FAtoPA.Net.csproj b/FAtoPA.Net.csproj index c4dda1c..32ac3ad 100644 --- a/FAtoPA.Net.csproj +++ b/FAtoPA.Net.csproj @@ -17,6 +17,21 @@ true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true AnyCPU @@ -170,7 +185,11 @@ MSBuild:Compile Designer + + + InputBox.xaml + MSBuild:Compile Designer @@ -188,6 +207,10 @@ MainWindow.xaml Code + + Designer + MSBuild:Compile + @@ -219,6 +242,18 @@ + + + False + Microsoft .NET Framework 4.8 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + diff --git a/FSM.cs b/FSM.cs index ec6de69..e887b41 100644 --- a/FSM.cs +++ b/FSM.cs @@ -12,6 +12,9 @@ using System.Threading.Tasks; namespace FAtoPA { + /// + /// Class to handle Fire Alarm System Monitoring + /// class FSM { public static bool Started = false; @@ -21,6 +24,11 @@ namespace FAtoPA public Dictionary ItemTypeDictionary { get; } public Dictionary AvailableNodes { get; } private EventInterface _event; + /// + /// to count the incoming event, then update at _event; + /// + public static long eventcounter = 0; + public FSM(EventInterface callback) { _event = callback; @@ -75,6 +83,7 @@ namespace FAtoPA /// public void Start() { + eventcounter = 0; controller = FSIController.GetInstance(); // internal Listeners controller.AddListener(new ConfigListener(ItemTypeDictionary, AvailableNodes, listenerlist)); @@ -150,6 +159,7 @@ namespace FAtoPA public void SetItemType(ItemType devItemType) { //Debug.WriteLine($"Item type {devItemType.FunctionalType} ({devItemType.Description})"); + if (type_dictionary != null) { int type = int.Parse(devItemType.FunctionalType.ToString()); @@ -160,7 +170,10 @@ namespace FAtoPA } else Debug.WriteLine($"type_dictionary already have key={type}"); } + + FSM.eventcounter++; + } /// @@ -191,7 +204,8 @@ namespace FAtoPA } else Debug.WriteLine($"node_data already have SIID={SIID}"); } - + FSM.eventcounter++; + } /// @@ -207,7 +221,8 @@ namespace FAtoPA if (node_data.ContainsKey(SIID)) node_data.Remove(SIID); } - + FSM.eventcounter++; + } } @@ -260,7 +275,8 @@ namespace FAtoPA } else Debug.WriteLine($"node_data doesn't contain SIID {SIID}"); } else Debug.WriteLine("node_data is null"); - + + FSM.eventcounter++; } @@ -271,6 +287,7 @@ namespace FAtoPA public void SetMPNetTime(DateTime mpNetTime) { Debug.WriteLine($"Time is {mpNetTime}"); + FSM.eventcounter++; } } diff --git a/FSMModbusData.cs b/FSMModbusData.cs new file mode 100644 index 0000000..3970c3c --- /dev/null +++ b/FSMModbusData.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FAtoPA.Net +{ + internal class FSMModbusData : INotifyPropertyChanged + { + private string _logicalstate; + public String LogicalState + { + get { return _logicalstate; } + set + { + if (_logicalstate != value) + { + + _logicalstate = value; + OnPropertyChanged(nameof(LogicalState)); + } + } + } + private short _register; + public short Register + { + get { return _register; } + set + { + if (_register != value) + { + _register = value; + OnPropertyChanged(nameof(Register)); + } + } + } + + public FSMModbusData(String logicalstate, short register) + { + LogicalState = logicalstate; + Register = register; + } + + protected void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/InputBox.xaml b/InputBox.xaml new file mode 100644 index 0000000..73d3045 --- /dev/null +++ b/InputBox.xaml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + private void Create_Default_ModbusTranslationTable() { - ModbusTranslationTable = new ObservableCollection>(); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.INVALID.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.NORMAL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.TROUBLE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.FIRE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.FIRE_PRE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.VERIFY_FIRE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.HEAT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.SUPERVISORY.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.SMOKE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.ACTIVATION.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.ACTIVATION_FAILED.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.TAMPER.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.COVER_OPEN.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.PAPER_OUT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WARNING.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.TROUBLE_LIGHT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WATCHDOGRESTART.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.ON.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.OFF.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.POLLUTION.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.POLLUTION_LIGHT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.MONITOR.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WATER.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.POWERFAIL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.MANUAL_ALARM.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.PAS_WAIT_FOR_ACK.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.PAS_INVESTIGATE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.AC_CHANGED.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.AC_COUNTDOWN_STARTED.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.AC_TAMPER.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.FIRE_INT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.ERROR.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.UNKNOWN.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.MATCHALL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.NET_CONFIG_MISMATCH.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.UNKNOWN_ITEM.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.MISSING_ITEM.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.INCOMPATIBLE_SOFTWARE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.INCOMPATIBLE_NET_PROTOCOL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.INFO_ALARM.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.CHEMICAL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WARNING_HEAT.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WARNING_SMOKE.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.WARNING_CHEMICAL.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.REBOOT_READY.ToString(), 0)); - ModbusTranslationTable.Add(new KeyValuePair(SILogicalState.LASTLOGICAL.ToString(), 0)); + ModbusTranslationTable = new ObservableCollection(); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.INVALID.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.NORMAL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.TROUBLE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.FIRE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.FIRE_PRE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.VERIFY_FIRE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.HEAT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.SUPERVISORY.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.SMOKE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.ACTIVATION.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.ACTIVATION_FAILED.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.TAMPER.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.COVER_OPEN.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.PAPER_OUT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WARNING.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.TROUBLE_LIGHT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WATCHDOGRESTART.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.ON.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.OFF.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.POLLUTION.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.POLLUTION_LIGHT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.MONITOR.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WATER.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.POWERFAIL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.MANUAL_ALARM.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.PAS_WAIT_FOR_ACK.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.PAS_INVESTIGATE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.AC_CHANGED.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.AC_COUNTDOWN_STARTED.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.AC_TAMPER.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.FIRE_INT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.ERROR.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.UNKNOWN.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.MATCHALL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.NET_CONFIG_MISMATCH.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.UNKNOWN_ITEM.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.MISSING_ITEM.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.INCOMPATIBLE_SOFTWARE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.INCOMPATIBLE_NET_PROTOCOL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.INFO_ALARM.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.CHEMICAL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WARNING_HEAT.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WARNING_SMOKE.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.WARNING_CHEMICAL.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.REBOOT_READY.ToString(), 0)); + ModbusTranslationTable.Add(new FSMModbusData(SILogicalState.LASTLOGICAL.ToString(), 0)); Save_ModbusTranslationTable(); } @@ -306,9 +296,12 @@ namespace FAtoPA.Net vx3k = new VX3K(new VX3KEvent(this.vxstatusbar)); //vx3k.Connect(config.VX_TargetIP, config.VX_TargetPort); + List ConditionON = new List(); + List ConditionOFF = new List(); + fsm.AddListener(new FSMTableUpdater(FsmTableMember, DetectedSIID, DetectedSIIDCount)); - fsm.AddListener(new ModbusTriggerFromFSM(FsmTableMember, ModbusTableMember, modbusSlave, ConditionON, ConditionOFF)); + fsm.AddListener(new ModbusTriggerFromFSM(FsmTableMember, ModbusTableMember, modbusSlave, ModbusTranslationTable)); fsm.AddListener(new VXTriggerFromFSM(FsmTableMember, VXTableMember, vx3k, ConditionON, ConditionOFF)); } @@ -1183,10 +1176,10 @@ namespace FAtoPA.Net Debug.WriteLine("FSMtoModbusTranslationTable_AutoGeneratingColumn : " + e.PropertyName); switch (e.PropertyName) { - case "Key": + case "LogicalState": e.Column.Width = DataGridLength.Auto; break; - case "Value": + case "Register": e.Column.Width = DataGridLength.Auto; break; @@ -1202,9 +1195,26 @@ namespace FAtoPA.Net try { - KeyValuePair vv = (KeyValuePair)selected; - Debug.WriteLine($"Selected Key={vv.Key}, Value={vv.Value}"); - //TODO create InputBox to select Value for Key + FSMModbusData vv = (FSMModbusData)selected; + Debug.WriteLine($"Selected Key={vv.LogicalState}, Value={vv.Register}"); + + InputBox ib = new InputBox(vv.LogicalState, vv.Register); + bool? haschange = ib.ShowDialog(); + if (haschange.Value) + { + Debug.WriteLine($"Changed Key={ib.FsmState}, Value={ib.ModbusRegister}"); + for (int ii = 0; ii < ModbusTranslationTable.Count; ii++) + { + if (ModbusTranslationTable[ii].LogicalState == vv.LogicalState) + { + ModbusTranslationTable[ii].Register = ib.ModbusRegister; + break; + } + + } + FSMtoModbusTranslationTable.InvalidateProperty(DataGrid.ItemsSourceProperty); + + } } catch(Exception exception) { Debug.WriteLine("FSMtoModbusTranslationTable_MouseDoubleClick Error : " + exception.Message); @@ -1469,15 +1479,13 @@ namespace FAtoPA.Net ObservableCollection source; ObservableCollection data; ModbusSlave slave; - List ConditionON; - List ConditionOFF; - public ModbusTriggerFromFSM(ObservableCollection source, ObservableCollection data, ModbusSlave slave, List conditionON, List conditionOFF) + ObservableCollection translation; + public ModbusTriggerFromFSM(ObservableCollection source, ObservableCollection data, ModbusSlave slave, ObservableCollection translation) { this.source = source; this.data = data; this.slave = slave; - ConditionON = conditionON; - ConditionOFF = conditionOFF; + this.translation = translation; } /// @@ -1522,29 +1530,27 @@ namespace FAtoPA.Net { if (slave != null) { - if (ConditionON != null && ConditionOFF != null) + if (translation != null) { - if (ConditionON.Contains(current.LogicalState)) + foreach (var x in translation) { - Debug.WriteLine($"NewState for SIID={SIID} State={current.LogicalState} is ConditionON"); - slave.SetRegister(dt.Register, 1); - dt.Value = "ON"; - } - else if (ConditionOFF.Contains(current.LogicalState)) - { - Debug.WriteLine($"NewState for SIID={SIID} State={current.LogicalState} is ConditionOFF"); - slave.SetRegister(dt.Register, 0); - dt.Value = "OFF"; - } - else - { - Debug.WriteLine($"NewState for SIID={SIID} in Modbus is ignored because Condition ON/OFF is not met"); - dt.Value = "RULE NOT AVAILABLE"; + if (x.LogicalState.Equals(current.LogicalState)) + { + ushort reg = (ushort)x.Register; + Debug.WriteLine($"NewState for SIID={SIID} State={current.LogicalState} is Register={reg}"); + slave.SetRegister(dt.Register, reg); + dt.Value = "" + reg; + dt.LastUpdate = DateTime.Now.ToString(); + return; + } } + Debug.WriteLine($"Translation for SIID={SIID} LogicalState={current.LogicalState} is not found"); + dt.Value = "RULE NOT SET"; } + else { - Debug.WriteLine($"Condition ON/OFF for SIID={SIID} in Modbus is not set"); + Debug.WriteLine($"Translation for SIID={SIID} in Modbus is not set"); dt.Value = "RULE NOT SET"; } } @@ -1570,8 +1576,8 @@ namespace FAtoPA.Net ObservableCollection data; ObservableCollection source; VX3K vx; - List ConditionON; - List ConditionOFF; + List ConditionON; + List ConditionOFF; public VXTriggerFromFSM(ObservableCollection source, ObservableCollection data, VX3K vx, List conditionON, List conditionOFF) { this.source = source;