using FSM5000FSI; using FSM5000FSIAPI.Version3; using System; using System.CodeDom; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FAtoPA { class FSM { public static bool Started = false; private FSIConfig? config; private FSIController controller; private List listenerlist; public Dictionary ItemTypeDictionary { get; } public Dictionary AvailableNodes { get; } private EventInterface? _event; public FSM(EventInterface callback) { _event = callback; controller = FSIController.GetInstance(); ItemTypeDictionary = new Dictionary(); AvailableNodes = new Dictionary(); listenerlist = new List(); } /// /// Initialize Fire Alarm Module /// /// 1 - 255 /// 1 - 255 /// 1 - 255 /// on a system with multiple network adapter, use this to specify which adapter will be used public FSM(EventInterface callback, byte netgroup, byte netnode, byte pna, byte[] localip) : this(callback) { SetConfig(netgroup, netnode, pna, localip); } public void SetConfig(byte netgroup, byte netnode, byte pna, byte[] localip) { config = new FSIConfig(); config.MPNetGroup = netgroup; config.MPNetNode = netnode; config.PNA = pna; config.LocalIPAddress = localip; config.RepositoryLocation = ".\\repository"; } /// /// Optional option if using Multicast Communication /// /// true if want to use Multicast /// target Multicast IP, if not available, default to 239.192.0.1 /// target Port, if not available, default to 25000 public void MulticastConfig(Boolean useMulticast, byte[] MulticastIP, ushort PortNumber) { byte[] defaultip = new byte[] { 239, 192, 0, 1 }; ushort defaultport = 25000; AdvancedFSIConfig advancedFSIConfig = new AdvancedFSIConfig(); advancedFSIConfig.IsIPMulticast = useMulticast; if (useMulticast) { if (MulticastIP != null && MulticastIP.Length == 4) advancedFSIConfig.MulticastAddress = MulticastIP; else advancedFSIConfig.MulticastAddress = defaultip; if (PortNumber>1 && PortNumber<65535) advancedFSIConfig.PortNumber = PortNumber; else advancedFSIConfig.PortNumber = defaultport; } advancedFSIConfig.NetstackTraceLevel = SourceLevels.Error; if (config!=null) config.AdvancedFSIConfig = advancedFSIConfig; } /// /// Start FSM Monitoring /// public void Start() { // internal Listeners controller.AddListener(new ConfigListener(ItemTypeDictionary, AvailableNodes, listenerlist)); controller.AddListener(new StateListener(AvailableNodes, listenerlist)); TraceConsoleWritter outputter = new TraceConsoleWritter(); controller.SetTraceLevel(SourceLevels.Warning); //for support issues please set the level to SourceLevels.Verbose Result result = controller.Startup(config); Console.WriteLine("[FSM] Start result = "+result.ToString()); } public void AddListener(FSMResultInterface listener) { if (listenerlist != null) listenerlist.Add(listener); } /// /// Stop FSM Monitoring /// public void Stop() { if (controller != null) { try { //TODO : somehow bikin crash terus //Result result = controller.Shutdown(); //Console.WriteLine("[FSM] Shutdown result = " + result.ToString()); } catch (Exception e) { Console.WriteLine("[FSM] Error on Stop: " + e.Message); } } } } /// /// The Config Listener receives all information about the configuration /// received from the panel network. The information must be stored in real application /// to know the devices from the panel network and the possible commands. /// class ConfigListener : IPanelConfigListener { private Dictionary type_dictionary; private Dictionary node_data; private List listeners; public ConfigListener(Dictionary type, Dictionary data, List listener) { this.type_dictionary = type; this.node_data = data; this.listeners = listener; } /// /// Akan muncul di pertama kali, untuk informasi bahwa device dengan FunctionalType [X} memiliki deskripsi [Y] /// /// public void SetItemType(ItemType devItemType) { if (type_dictionary != null) { int type = int.Parse(devItemType.FunctionalType.ToString()); if (!type_dictionary.ContainsKey(type)) type_dictionary.Add(type, devItemType.Description); } Console.Out.WriteLine("Item type " + devItemType.FunctionalType + " (" + devItemType.Description + ")"); } /// /// Akan muncul di urutan kedua, untuk informasi node device apa saja yang terdeteksi di system /// /// public void SetItem(Item devItem) { if (node_data != null) { String SIID = devItem.SIID.ToString(); int type = int.Parse(devItem.FunctionalType.ToString()); if (!node_data.ContainsKey(SIID)) { NodeData nodeData = new NodeData(); nodeData.SIID = devItem.SIID; nodeData.Type = type; nodeData.Label = devItem.Label; nodeData.Description = type_dictionary.ContainsKey(type) ? type_dictionary[type] : "Unknown"; node_data.Add(SIID, nodeData); // notify all listeners if (listeners != null) foreach (var item in listeners) item.DiscoveredSIID(SIID, nodeData); } } Console.Out.WriteLine("Item (" + devItem.SIID + ", " + devItem.FunctionalType + " (" + devItem.Label + ")"); } /// /// Akan muncul kalau suatu node hilang dari system /// /// public void RemoveItem(SIID address) { if (node_data != null) { String SIID = address.ToString(); if (node_data.ContainsKey(SIID)) node_data.Remove(SIID); } Console.Out.WriteLine("SI " + address + " removed."); } } /// /// The State Listener receive all states for devices send by the panel network. /// Ini yang paling penting, untuk trigger ke Modbus dan VX3000 /// class StateListener : IStateListener { private Dictionary node_data; private List listeners; public StateListener(Dictionary data, List listener) { this.node_data= data; this.listeners = listener; } /// /// Akan muncul ketiga dan seterusnya, ketika ada perubahan status dari node device /// /// public void SetItemState(ItemState devItemState) { if (node_data != null) { String SIID = devItemState.SIID.ToString(); NodeData nd = node_data[SIID]; if (nd != null) { NodeState? prev = nd.State; nd.State = new NodeState(devItemState); // notify all listeners if (listeners != null) foreach (var item in listeners) item.NewState(SIID, prev, nd.State); if (prev != null) { Console.WriteLine("SIID="+SIID+" Change LogicalState from "+prev.LogicalState+" to "+nd.State.LogicalState); } else { Console.Out.WriteLine("New State for SIID=" + SIID + " LogicalState=" + nd.State.LogicalState); } } } //Console.Out.WriteLine("State " + devItemState.SIID + " = " + devItemState.LogicalState); } /// /// Akan muncul sekali di awal mula, sebagai informasi waktu di panel system /// /// public void SetMPNetTime(DateTime mpNetTime) { Console.Out.WriteLine("Time is " + mpNetTime + "."); } } /// /// Receive the traces from the FSI and output the traces to console /// In real application it is very useful to write the traces to files /// for suppport issues /// class TraceConsoleWritter : TraceListener { public override void Write(string? message) { if (message!=null && message.Length>0) Console.Out.Write(message); } public override void WriteLine(string? message) { if (message != null && message.Length > 0) Console.Out.WriteLine(message); } } }