Add project files.
This commit is contained in:
280
FSM.cs
Normal file
280
FSM.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
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<FSMResultInterface> listenerlist;
|
||||
public Dictionary<int, String> ItemTypeDictionary { get; }
|
||||
public Dictionary<String, NodeData> AvailableNodes { get; }
|
||||
private EventInterface? _event;
|
||||
public FSM(EventInterface callback)
|
||||
{
|
||||
_event = callback;
|
||||
controller = FSIController.GetInstance();
|
||||
ItemTypeDictionary = new Dictionary<int, string>();
|
||||
AvailableNodes = new Dictionary<String, NodeData>();
|
||||
listenerlist = new List<FSMResultInterface>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize Fire Alarm Module
|
||||
/// </summary>
|
||||
/// <param name="netgroup">1 - 255</param>
|
||||
/// <param name="netnode">1 - 255</param>
|
||||
/// <param name="pna">1 - 255</param>
|
||||
/// <param name="localip">on a system with multiple network adapter, use this to specify which adapter will be used</param>
|
||||
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";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optional option if using Multicast Communication
|
||||
/// </summary>
|
||||
/// <param name="useMulticast">true if want to use Multicast</param>
|
||||
/// <param name="MulticastIP">target Multicast IP, if not available, default to 239.192.0.1</param>
|
||||
/// <param name="PortNumber">target Port, if not available, default to 25000</param>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start FSM Monitoring
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop FSM Monitoring
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
class ConfigListener : IPanelConfigListener
|
||||
{
|
||||
private Dictionary<int, String> type_dictionary;
|
||||
private Dictionary<String, NodeData> node_data;
|
||||
private List<FSMResultInterface> listeners;
|
||||
public ConfigListener(Dictionary<int, String> type, Dictionary<String, NodeData> data, List<FSMResultInterface> listener)
|
||||
{
|
||||
this.type_dictionary = type;
|
||||
this.node_data = data;
|
||||
this.listeners = listener;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Akan muncul di pertama kali, untuk informasi bahwa device dengan FunctionalType [X} memiliki deskripsi [Y]
|
||||
/// </summary>
|
||||
/// <param name="devItemType"></param>
|
||||
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 + ")");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Akan muncul di urutan kedua, untuk informasi node device apa saja yang terdeteksi di system
|
||||
/// </summary>
|
||||
/// <param name="devItem"></param>
|
||||
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 + ")");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Akan muncul kalau suatu node hilang dari system
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The State Listener receive all states for devices send by the panel network.
|
||||
/// Ini yang paling penting, untuk trigger ke Modbus dan VX3000
|
||||
/// </summary>
|
||||
class StateListener : IStateListener
|
||||
{
|
||||
private Dictionary<String,NodeData> node_data;
|
||||
private List<FSMResultInterface> listeners;
|
||||
public StateListener(Dictionary<String,NodeData> data, List<FSMResultInterface> listener)
|
||||
{
|
||||
this.node_data= data;
|
||||
this.listeners = listener;
|
||||
}
|
||||
/// <summary>
|
||||
/// Akan muncul ketiga dan seterusnya, ketika ada perubahan status dari node device
|
||||
/// </summary>
|
||||
/// <param name="devItemState"></param>
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Akan muncul sekali di awal mula, sebagai informasi waktu di panel system
|
||||
/// </summary>
|
||||
/// <param name="mpNetTime"></param>
|
||||
public void SetMPNetTime(DateTime mpNetTime)
|
||||
{
|
||||
Console.Out.WriteLine("Time is " + mpNetTime + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user