using FSM5000FSIAPI.Version3;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace FAtoPA.Net
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private DispatcherTimer timer1s;
private Config config;
private Database database;
private FSM fsm;
private ModbusSlave modbusSlave;
private VX3K vx3k;
// untuk values di Combobox FSM SIID
public ObservableCollection FSMSIID { get; set; }
// untuk values di Combobox VX3K ID dan CIN
public ObservableCollection VX3KID { get; set; }
public ObservableCollection VX3KCIN { get; set; }
// untuk values di Combobox Modbus Registers
public ObservableCollection ModbusRegisters { get; set; }
public ObservableCollection NetGroupList { get; set; }
public ObservableCollection NetNodeList { get; set; }
public ObservableCollection PNAList { get; set; }
public ObservableCollection SINumberList { get; set; }
public ObservableCollection SISubList { get; set; }
ObservableCollection FsmTableMember { get; set; }
ObservableCollection ModbusTableMember { get; set; }
ObservableCollection VXTableMember { get; set; }
FSMEvent fsmEvent;
public MainWindow()
{
InitializeComponent();
// Di-isi dengan user input di Tab Fire Alarm
FSMSIID = new ObservableCollection();
// Isinya ada di Window_Loaded
ModbusRegisters = new ObservableCollection();
FsmTableMember = new ObservableCollection();
ModbusTableMember = new ObservableCollection();
VXTableMember = new ObservableCollection();
// Set default value for VX3KID and VX3KCIN
VX3KID = new ObservableCollection();
for (int i = 0; i < 40; i++)
{
VX3KID.Add(i);
}
VX3KCIN = new ObservableCollection();
for (int i = 0; i < 16; i++)
{
VX3KCIN.Add(i);
}
NetGroupList = new ObservableCollection();
NetNodeList = new ObservableCollection();
PNAList = new ObservableCollection();
SINumberList = new ObservableCollection();
SISubList = new ObservableCollection();
for (int ii = 1; ii < 256; ii++)
{
NetGroupList.Add(ii);
NetNodeList.Add(ii);
PNAList.Add(ii);
SINumberList.Add(ii);
SISubList.Add(ii);
}
siType.ItemsSource = Enum.GetValues(typeof(SIType)).Cast().ToList();
this.DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Window Loaded");
// Timer untuk update datetimebar tiap 1 detik
timer1s = new DispatcherTimer();
timer1s.Interval = new TimeSpan(0, 0, 1);
timer1s.Tick += Timer1s_Tick;
timer1s.Start();
// Load Config
config = new Config();
config.Load();
FSMConfig_NetGroup.Text = config.FSM_NetGroup.ToString();
FSMConfig_NetNode.Text = config.FSM_NetNode.ToString();
FSMConfig_PNA.Text = config.FSM_PNA.ToString();
FSMConfig_LocalIP.Text = config.FSM_LocalIP;
FSM_UseMulticast.IsChecked = config.FSM_UseMulticast;
FSMConfig_MulticastAddress.Text = config.FSM_MulticastIP;
FSMConfig_MulticastPort.Text = config.FSM_MulticastPort.ToString();
Debug.WriteLine("NetGroup : " + config.FSM_NetGroup);
Debug.WriteLine("NetNode : " + config.FSM_NetNode);
Debug.WriteLine("PNA : " + config.FSM_PNA);
Debug.WriteLine("LocalIP : " + config.FSM_LocalIP);
Debug.WriteLine("UseMulticast : " + config.FSM_UseMulticast);
Debug.WriteLine("MulticastIP : " + config.FSM_MulticastIP);
Debug.WriteLine("MulticastPort : " + config.FSM_MulticastPort);
ModbusListenPort.Text = config.Modbus_ListenPort.ToString();
ModbusDeviceID.Text = config.Modbus_DeviceID.ToString();
ModbusMaxRegister.Text = config.Modbus_MaxRegister.ToString();
VX3K_IP.Text = config.VX_TargetIP;
VX3K_Port.Text = config.VX_TargetPort.ToString();
// Load Database
database = new Database();
database.GetFSMDatas().ForEach(f => FsmTableMember.Add(f));
database.GetModbusDatas().ForEach(m => ModbusTableMember.Add(m));
database.GetVXDatas().ForEach(v => VXTableMember.Add(v));
FSMTable.ItemsSource = FsmTableMember;
ModbusTable.ItemsSource = ModbusTableMember;
VXTable.ItemsSource = VXTableMember;
// Load FSM
fsmEvent = new FSMEvent(this.firealarmstatusbar);
fsm = new FSM(fsmEvent, config.FSM_NetGroup, config.FSM_NetNode, config.FSM_PNA, IPAddress.Parse(config.FSM_LocalIP).GetAddressBytes());
if (config.FSM_UseMulticast)
{
fsm.MulticastConfig(config.FSM_UseMulticast, IPAddress.Parse(config.FSM_MulticastIP).GetAddressBytes(), config.FSM_MulticastPort);
}
ModbusRegisters.Clear();
for (int i = 0; i < config.Modbus_MaxRegister; i++)
{
ModbusRegisters.Add(i);
}
// Load Modbus Slave
modbusSlave = new ModbusSlave(new ModbusEvent(modbusstatusbar, ConnectedModbusClients, ConnectedModbusCount), config.Modbus_MaxRegister);
modbusSlave.ID = config.Modbus_DeviceID;
//modbusSlave.Start(config.Modbus_ListenPort);
// Connect with VX3000
vx3k = new VX3K(new VX3KEvent(this.vxstatusbar));
//vx3k.Connect(config.VX_TargetIP, config.VX_TargetPort);
fsm.AddListener(new FSMTableUpdater(FsmTableMember, DetectedSIID, DetectedSIIDCount));
fsm.AddListener(new ModbusTriggerFromFSM(FsmTableMember, ModbusTableMember, modbusSlave));
fsm.AddListener(new VXTriggerFromFSM(FsmTableMember, VXTableMember, vx3k));
}
private void Timer1s_Tick(object sender, EventArgs e)
{
datetimebar.Text = DateTime.Now.ToString();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Debug.WriteLine("Window Closing");
timer1s?.Stop();
fsm?.Stop();
modbusSlave?.Stop();
vx3k?.Disconnect();
}
private void btnStartStopFSM_Click(object sender, RoutedEventArgs e)
{
if (FSM.Started)
{
fsm?.Stop();
btnStartStopFSM.Content = "Start FSM Connection";
FSM.Started = false;
}
else
{
fsm?.Start();
btnStartStopFSM.Content = "Stop FSM Connection";
FSM.Started = true;
}
}
private void btnStartStopModbus_Click(object sender, RoutedEventArgs e)
{
if (ModbusSlave.Started)
{
modbusSlave?.Stop();
btnStartStopModbus.Content = "Start Modbus Connection";
ModbusSlave.Started = false;
}
else
{
if (config != null)
{
modbusSlave?.Start(config.Modbus_ListenPort);
btnStartStopModbus.Content = "Stop Modbus Connection";
ModbusSlave.Started = true;
}
}
}
private void btnStartStopVX_Click(object sender, RoutedEventArgs e)
{
if (VX3K.Started)
{
vx3k?.Disconnect();
btnStartStopVX.Content = "Start VX Connection";
VX3K.Started = false;
}
else
{
if (config != null)
{
vx3k?.Connect(config.VX_TargetIP, config.VX_TargetPort);
btnStartStopVX.Content = "Stop VX Connection";
VX3K.Started = true;
}
}
}
private void ApplyFSMConfig(object sender, RoutedEventArgs e)
{
if (config != null)
{
Boolean changed = false;
int netgroup = 0;
if (int.TryParse(FSMConfig_NetGroup.Text, out netgroup))
{
if (NetGroupList.Contains(netgroup))
{
if (netgroup != config.FSM_NetGroup)
{
config.FSM_NetGroup = (byte)netgroup;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Net Group");
return;
}
}
else
{
MessageBox.Show("Invalid Net Group");
return;
}
int netnode = 0;
if (int.TryParse(FSMConfig_NetNode.Text, out netnode))
{
if (NetNodeList.Contains(netnode))
{
if (netnode != config.FSM_NetNode)
{
config.FSM_NetNode = (byte)netnode;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Net Node");
return;
}
}
else
{
MessageBox.Show("Invalid Net Node");
return;
}
int pna = 0;
if (int.TryParse(FSMConfig_PNA.Text, out pna))
{
if (PNAList.Contains(pna))
{
if (pna != config.FSM_PNA)
{
config.FSM_PNA = (byte)pna;
changed = true;
}
}
else
{
MessageBox.Show("Invalid PNA");
return;
}
}
else
{
MessageBox.Show("Invalid PNA");
return;
}
if (TextIsIPAddress(FSMConfig_LocalIP.Text))
{
if (FSMConfig_LocalIP.Text != config.FSM_LocalIP)
{
config.FSM_LocalIP = FSMConfig_LocalIP.Text;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Local IP");
return;
}
if (FSM_UseMulticast.IsChecked != null)
{
if (FSM_UseMulticast.IsChecked != config.FSM_UseMulticast)
{
config.FSM_UseMulticast = (bool)FSM_UseMulticast.IsChecked;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Multicast Use");
return;
}
if (TextIsIPAddress(FSMConfig_MulticastAddress.Text))
{
if (FSMConfig_MulticastAddress.Text != config.FSM_MulticastIP)
{
config.FSM_MulticastIP = FSMConfig_MulticastAddress.Text;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Multicast Address");
return;
}
int multicastport = 0;
if (int.TryParse(FSMConfig_MulticastPort.Text, out multicastport))
{
if (multicastport >= 0 && multicastport <= 65535)
{
if (multicastport != config.FSM_MulticastPort)
{
config.FSM_MulticastPort = (ushort)multicastport;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Multicast Port");
return;
}
}
else
{
MessageBox.Show("Invalid Multicast Port");
return;
}
if (changed)
{
if (config.Save())
{
MessageBox.Show("FSM Config Saved");
//TODO : Restart FSM Connection
}
else MessageBox.Show("FSM Config Save Failed");
}
else MessageBox.Show("No changes in FSM Config");
}
else MessageBox.Show("Config is null");
}
private void ApplyModbusConfig(object sender, RoutedEventArgs e)
{
if (config != null)
{
Boolean changed = false;
int listenport = 0;
if (int.TryParse(ModbusListenPort.Text, out listenport))
{
if (listenport >= 0 && listenport <= 65535)
{
if (listenport != config.Modbus_ListenPort)
{
config.Modbus_ListenPort = (ushort)listenport;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Listen Port");
return;
}
}
else
{
MessageBox.Show("Invalid Listen Port");
return;
}
int devid = 0;
if (int.TryParse(ModbusDeviceID.Text, out devid))
{
if (devid >= 1 && devid <= 247)
{
if (devid != config.Modbus_DeviceID)
{
config.Modbus_DeviceID = (byte)devid;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Device ID");
return;
}
}
else
{
MessageBox.Show("Invalid Device ID");
return;
}
int maxreg = 0;
if (int.TryParse(ModbusMaxRegister.Text, out maxreg))
{
if (maxreg >= 1 && maxreg <= 10000)
{
if (maxreg != config.Modbus_MaxRegister)
{
config.Modbus_MaxRegister = (ushort)maxreg;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Max Register");
return;
}
}
else
{
MessageBox.Show("Invalid Max Register");
}
if (changed)
{
if (config.Save())
{
MessageBox.Show("Modbus Config Saved");
//TODO : Restart Modbus Connection
}
else MessageBox.Show("Modbus Config Save Failed");
}
else MessageBox.Show("No changes in Modbus Config");
}
else MessageBox.Show("Config is null");
}
private void ApplyVX3KConfig(object sender, RoutedEventArgs e)
{
if (config != null)
{
Boolean changed = false;
String ipaddress = "";
int port = 0;
try
{
IPAddress ip = IPAddress.Parse(VX3K_IP.Text);
ipaddress = ip.ToString();
if (ipaddress != config.VX_TargetIP)
{
config.VX_TargetIP = ipaddress;
changed = true;
}
}
catch (Exception)
{
MessageBox.Show("Invalid IP Address");
return;
}
if (int.TryParse(VX3K_Port.Text, out port))
{
if (port != config.VX_TargetPort)
{
config.VX_TargetPort = (ushort)port;
changed = true;
}
}
else
{
MessageBox.Show("Invalid Port");
return;
}
if (changed)
{
if (config.Save())
{
MessageBox.Show("VX3K Config Saved");
//TODO : Restart VX3K Connection
}
else MessageBox.Show("VX3K Config Save Failed");
}
else MessageBox.Show("No changes in VX3K Config");
}
else MessageBox.Show("Config is null");
}
// Regex Protection for FSMConfig_NetGroup
private void FSMConfig_NetGroup_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
// Regex Protection for FSMConfig_NetNode
private void FSMConfig_NetNode_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
// Regex Protection for FSMConfig_PNA
private void FSMConfig_PNA_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
// Regex Protection for FSMConfig_LocalIP
private void FSMConfig_LocalIP_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxIPAddressOnly(e);
}
// Regex Protection for FSMConfig_MulticastAddress
private void FSMConfig_MulticastAddress_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxIPAddressOnly(e);
}
// Regex Protection for FSMConfig_MulticastPort
private void FSMConfig_MulticastPort_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
// If NetGroup value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_NetGroup_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_FSMVerify(FSMConfig_NetGroup);
}
// If NetNode value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_NetNode_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_FSMVerify(FSMConfig_NetNode);
}
// If PNA value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_PNA_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_FSMVerify(FSMConfig_PNA);
}
// If LocalIP value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_LocalIP_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_IPVerify(FSMConfig_LocalIP);
}
// If MulticastAddress value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_MulticastAddress_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_IPVerify(FSMConfig_MulticastAddress);
}
// If MulticastPort value is changed, check for valid value. If not valid, change background to red
private void FSMConfig_MulticastPort_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_PortVerify(FSMConfig_MulticastPort);
}
// Only allow number input
private void TextBoxNumberOnly(TextCompositionEventArgs e)
{
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
}
private void TextBoxIPAddressOnly(TextCompositionEventArgs e)
{
//string pattern = @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
//Regex regex = new Regex(pattern);
//e.Handled = regex.IsMatch(e.Text);
e.Handled = TextIsIPAddress(e.Text);
}
private Boolean TextIsIPAddress(String vv)
{
if (vv != null)
{
if (vv.Length > 0)
{
string pattern = @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
Regex regex = new Regex(pattern);
return regex.IsMatch(vv);
}
}
return false;
}
// Verify Textbox value for FSM, which mostly only accept number 1 - 255
private void TextBox_FSMVerify(TextBox e)
{
if (int.TryParse(e.Text, out int result))
{
if (result < 0 || result > 255)
{
e.Background = Brushes.Red;
}
else
{
e.Background = Brushes.Transparent;
}
}
else
{
e.Background = Brushes.Red;
}
}
private void TextBox_IPVerify(TextBox e)
{
try
{
IPAddress.Parse(e.Text);
e.Background = Brushes.Transparent;
}
catch (Exception)
{
e.Background = Brushes.Red;
}
}
private void TextBox_PortVerify(TextBox e)
{
if (int.TryParse(e.Text, out int result))
{
if (result < 0 || result > 65535)
{
e.Background = Brushes.Red;
}
else
{
e.Background = Brushes.Transparent;
}
}
else
{
e.Background = Brushes.Red;
}
}
private void VX3K_IP_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxIPAddressOnly(e);
}
private void VX3K_Port_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
private void ModbusListenPort_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
private void ModbusDeviceID_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
private void ModbusMaxRegister_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBoxNumberOnly(e);
}
private void ModbusListenPort_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_PortVerify(ModbusListenPort);
}
private void VX3K_Port_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_PortVerify(VX3K_Port);
}
private void VX3K_IP_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox_IPVerify(VX3K_IP);
}
private void ModbusDeviceID_TextChanged(object sender, TextChangedEventArgs e)
{
int devid = 0;
if (int.TryParse(ModbusDeviceID.Text, out devid))
{
if (devid >= 1 && devid <= 247)
{
ModbusDeviceID.Background = Brushes.Transparent;
}
else
{
ModbusDeviceID.Background = Brushes.Red;
}
}
else
{
ModbusDeviceID.Background = Brushes.Red;
}
}
private void ModbusMaxRegister_TextChanged(object sender, TextChangedEventArgs e)
{
int maxreg = 0;
if (int.TryParse(ModbusMaxRegister.Text, out maxreg))
{
if (maxreg >= 1 && maxreg <= 10000)
{
ModbusMaxRegister.Background = Brushes.Transparent;
}
else
{
ModbusMaxRegister.Background = Brushes.Red;
}
}
else
{
ModbusMaxRegister.Background = Brushes.Red;
}
}
private void btnAddSIID_Click(object sender, RoutedEventArgs e)
{
SIID selected = GetSIID();
if (selected != null)
{
MessageBoxResult result = MessageBox.Show("Add SIID " + selected.ToString() + " ?", "Add SIID", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
FSMData f = new FSMData(selected.ToString());
if (database.AddFSMData(f))
{
FSMTable.ItemsSource = database.GetFSMDatas();
FSMSIID.Add(selected.ToString());
}
else MessageBox.Show("Failed to add to database");
}
else MessageBox.Show("Database is null");
}
}
else MessageBox.Show("Invalid Selection");
}
private void btnDelSIID_Click(object sender, RoutedEventArgs e)
{
SIID selected = GetSIID();
if (selected != null)
{
MessageBoxResult result = MessageBox.Show("Delete SIID " + selected.ToString() + " ?", "Delete SIID", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.RemoveFSMDatabySIID(selected.ToString()))
{
FSMTable.ItemsSource = database.GetFSMDatas();
FSMSIID.Remove(selected.ToString());
}
else MessageBox.Show("Failed to delete from database");
}
else MessageBox.Show("Database is null");
}
}
else MessageBox.Show("Invalid Selection");
}
private void btnClearSIID_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult result = MessageBox.Show("Clear all SIID ?", "Clear SIID", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.ClearFSMTable())
{
FSMTable.ItemsSource = database.GetFSMDatas();
FSMSIID.Clear();
}
else MessageBox.Show("Failed to clear database");
}
else MessageBox.Show("Database is null");
}
}
private SIID GetSIID()
{
int netgroup = 0;
int netnode = 0;
SIType sitype = 0;
int sinumber = 0;
int sisub = 0;
if (netGroupNumber.SelectedItem != null)
{
netgroup = (int)netGroupNumber.SelectedItem;
if (netNodeNumber.SelectedItem != null)
{
netnode = (int)netNodeNumber.SelectedItem;
if (siType.SelectedItem != null)
{
sitype = (SIType)siType.SelectedItem;
if (siNumber.SelectedItem != null)
{
sinumber = (int)siNumber.SelectedItem;
if (siSub.SelectedItem != null)
{
sisub = (int)siSub.SelectedItem;
return new SIID((byte)netgroup, (byte)netnode, sitype, (ushort)sinumber, (byte)sisub);
}
}
}
}
}
return null;
}
private void btnAddModbus_Click(object sender, RoutedEventArgs e)
{
String ssid = "";
int reg = 0;
if (ModbusSIIDComboBox.SelectedItem != null)
{
ssid = (string)ModbusSIIDComboBox.SelectedItem;
}
else
{
MessageBox.Show("Invalid SIID"); return;
}
if (ModbusRegister.SelectedItem != null)
{
reg = (int)ModbusRegister.SelectedItem;
}
else
{
MessageBox.Show("Invalid Register"); return;
}
MessageBoxResult result = MessageBox.Show("Add SIID " + ssid + " Link with Register " + reg + " ?", "Add Modbus Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
ModbusData m = new ModbusData(ssid, (ushort)reg);
if (database.AddModbusData(m))
{
ModbusTable.ItemsSource = database.GetModbusDatas();
}
else MessageBox.Show("Failed to add to database");
}
else MessageBox.Show("Database is null");
}
}
private void btnDelModbus_Click(object sender, RoutedEventArgs e)
{
String ssid = "";
String reg = "";
if (ModbusSIIDComboBox.SelectedItem != null)
{
ssid = (string)ModbusSIIDComboBox.SelectedItem;
}
else
{
MessageBox.Show("Invalid SIID"); return;
}
if (ModbusRegister.SelectedItem != null)
{
reg = (String)ModbusRegister.SelectedItem;
}
else
{
MessageBox.Show("Invalid Register"); return;
}
MessageBoxResult result = MessageBox.Show("Delete SIID " + ssid + " Link with Register " + reg + " ?", "Delete Modbus Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.RemoveModbusDatabySIID(ssid))
{
ModbusTable.ItemsSource = database.GetModbusDatas();
}
else MessageBox.Show("Failed to delete from database");
}
else MessageBox.Show("Database is null");
}
}
private void btnClearModbus_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult result = MessageBox.Show("Clear all Modbus Linkage ?", "Clear Modbus Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.ClearModbusTable())
{
ModbusTable.ItemsSource = database.GetModbusDatas();
}
else MessageBox.Show("Failed to clear database");
}
else MessageBox.Show("Database is null");
}
}
private void btnAddVX_Click(object sender, RoutedEventArgs e)
{
String ssid = "";
int id = 0;
int cin = 0;
if (VXSIIDComboBox.SelectedItem != null)
{
ssid = (string)VXSIIDComboBox.SelectedItem;
}
else
{
MessageBox.Show("Invalid SIID"); return;
}
if (VXFrame.SelectedItem != null)
{
id = (int)VXFrame.SelectedItem;
}
else
{
MessageBox.Show("Invalid ID"); return;
}
if (VXCIN.SelectedItem != null)
{
cin = (int)VXCIN.SelectedItem;
}
else
{
MessageBox.Show("Invalid CIN"); return;
}
MessageBoxResult result = MessageBox.Show("Add SIID " + ssid + " Link with Frame " + id + " CIN " + cin + " ?", "Add VX Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
VXData v = new VXData(ssid, (byte)id, (byte)cin);
if (database.AddVXData(v))
{
VXTable.ItemsSource = database.GetVXDatas();
}
else MessageBox.Show("Failed to add to database");
}
else MessageBox.Show("Database is null");
}
}
private void btnDelVX_Click(object sender, RoutedEventArgs e)
{
String ssid = "";
int id = 0;
int cin = 0;
if (VXSIIDComboBox.SelectedItem != null)
{
ssid = (string)VXSIIDComboBox.SelectedItem;
}
else
{
MessageBox.Show("Invalid SIID"); return;
}
if (VXFrame.SelectedItem != null)
{
id = (int)VXFrame.SelectedItem;
}
else
{
MessageBox.Show("Invalid ID"); return;
}
if (VXCIN.SelectedItem != null)
{
cin = (int)VXCIN.SelectedItem;
}
else
{
MessageBox.Show("Invalid CIN"); return;
}
MessageBoxResult result = MessageBox.Show("Delete SIID " + ssid + " Link with Frame " + id + " CIN " + cin + " ?", "Delete VX Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.RemoveVXDatabySIID(ssid))
{
VXTable.ItemsSource = database.GetVXDatas();
}
else MessageBox.Show("Failed to delete from database");
}
else MessageBox.Show("Database is null");
}
}
private void btnClearVX_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult result = MessageBox.Show("Clear all VX Linkage ?", "Clear VX Linkage", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
if (database != null)
{
if (database.ClearVXTable())
{
VXTable.ItemsSource = database.GetVXDatas();
}
else MessageBox.Show("Failed to clear database");
}
else MessageBox.Show("Database is null");
}
}
private void FSMTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
Debug.WriteLine("FSMTable_AutoGeneratingColumn : " + e.PropertyName);
switch (e.PropertyName)
{
case "SIID":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "Enable":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "Description":
e.Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
break;
case "Value":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "LastUpdate":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
}
}
private void ModbusTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
Debug.WriteLine("ModbusTable_AutoGeneratingColumn : " + e.PropertyName);
switch (e.PropertyName)
{
case "SIID":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "Register":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "Description":
e.Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
break;
case "Value":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "LastUpdate":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
}
}
private void VXTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
Debug.WriteLine("VXTable_AutoGeneratingColumn : " + e.PropertyName);
switch (e.PropertyName)
{
case "SIID":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "ID":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "CIN":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "Description":
e.Column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
break;
case "Value":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
case "LastUpdate":
e.Column.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
break;
}
}
}
// event handler for VX3K
class VX3KEvent : EventInterface
{
private TextBlock statusbar;
public VX3KEvent(TextBlock statusbar)
{
this.statusbar = statusbar;
}
public void ConnectStatus(bool success, string message)
{
Debug.WriteLine("VX-3000 ConnectStatus: " + success + " " + message);
if (statusbar != null) statusbar.Background = success ? Brushes.Green : Brushes.Transparent;
}
public void StatisticUpdate(uint TXOK, uint RXOK, uint TXErr, uint RXerr, uint TXBytes, uint RXBytes)
{
if (statusbar != null) statusbar.Text = "VX-3000 : TXOK: " + TXOK + " RXOK: " + RXOK + " TXErr: " + TXErr + " RXErr: " + RXerr + " TXBytes: " + TXBytes + " RXBytes: " + RXBytes;
}
public void Log(string msg)
{
Debug.WriteLine("VX-3000 Log: " + msg);
}
}
class ModbusEvent : ModbusSlaveEvent
{
private TextBlock statusbar;
private ListBox connectedlist;
private Label connectedcount;
private ObservableCollection ModbusSlave;
public ModbusEvent(TextBlock statusbar, ListBox connectedlist, Label connectedcount)
{
this.statusbar = statusbar;
this.connectedlist = connectedlist;
this.connectedcount = connectedcount;
ModbusSlave = new ObservableCollection();
ModbusSlave.CollectionChanged += (sender, e) => refresh_connectedlist();
}
private void refresh_connectedlist()
{
connectedlist.Items.Clear();
foreach (ModbusClientRecord client in ModbusSlave)
{
TextBlock l = new TextBlock();
l.Width = connectedlist.Width;
l.Margin = new Thickness(5, 0, 5, 0);
l.TextWrapping = TextWrapping.Wrap;
UpdateLabel(l, client);
connectedlist.Items.Add(l);
}
if (connectedcount != null) connectedcount.Content = "Connected : " + connectedlist.Items.Count;
}
void ModbusSlaveEvent.Log(string msg)
{
Debug.WriteLine("Modbus Log: " + msg);
}
void ModbusSlaveEvent.NewConnection(ModbusClientRecord client)
{
ModbusSlave.Add(client);
}
void ModbusSlaveEvent.CloseConnection(ModbusClientRecord client)
{
ModbusSlave.Remove(client);
}
void ModbusSlaveEvent.ConnectStatus(bool success, string message)
{
Debug.WriteLine("Modbus ConnectStatus: " + success + " " + message);
if (statusbar != null) statusbar.Background = success ? Brushes.Green : Brushes.Transparent;
}
public void TXRXStatusUpdate(ModbusClientRecord client)
{
foreach (var item in connectedlist.Items)
{
TextBlock l = (TextBlock)item;
if (l.Tag == client)
{
UpdateLabel(l, client);
return;
}
}
}
private void UpdateLabel(TextBlock l, ModbusClientRecord client)
{
l.Text = client.remoteEP + " TX: " + client.TXBytes + " RX: " + client.RXBytes + "TXOK: " + client.TXResponse + " RXOK: " + client.RXValidRequest;
}
}
class FSMEvent : EventInterface
{
private TextBlock statusbar;
public FSMEvent(TextBlock statusbar)
{
this.statusbar = statusbar;
}
public void ConnectStatus(bool success, string message)
{
if (statusbar != null)
{
statusbar.Dispatcher.Invoke(() =>
{
statusbar.Background = success ? Brushes.Green : Brushes.Transparent;
statusbar.Text = "FSM : " + message;
});
}
Debug.WriteLine("FSM ConnectStatus: " + success + " " + message);
}
public void Log(string msg)
{
Debug.WriteLine("FSM Log: " + msg);
}
public void StatisticUpdate(uint TXOK, uint RXOK, uint TXErr, uint RXerr, uint TXBytes, uint RXBytes)
{
if (statusbar != null)
{
statusbar.Dispatcher.Invoke(() =>
{
statusbar.Text = "FSM : TXOK: " + TXOK + " RXOK: " + RXOK + " TXErr: " + TXErr + " RXErr: " + RXerr + " TXBytes: " + TXBytes + " RXBytes: " + RXBytes;
});
}
}
}
// Class ini untuk update Table FSM
class FSMTableUpdater : FSMResultInterface
{
ObservableCollection data;
ListBox listbox;
Label countlabel;
int count = 0;
public FSMTableUpdater(ObservableCollection data, ListBox listbox, Label countlabel)
{
this.data = data;
this.listbox = listbox;
this.countlabel = countlabel;
}
public void DiscoveredSIID(string SIID, NodeData type)
{
Debug.WriteLine("Discovered SIID : " + SIID + " Type : " + type);
count++;
countlabel.Dispatcher.Invoke(() => countlabel.Content = "Count : " + count);
listbox.Dispatcher.Invoke(() => listbox.Items.Add(new Label() { Content = SIID + " : " + type.ToString() }));
}
public void NewState(string SIID, NodeState previous, NodeState current)
{
Debug.WriteLine("New State : " + SIID + " Previous : " + previous + " Current : " + current);
//FSMData dd = data.First(d => d.SIID == SIID);
//if (dd != null)
//{
// dd.LastUpdate = DateTime.Now.ToString();
// dd.Value = current.LogicalState ?? "Unknown";
//}
}
}
// Class ini untuk Update Modbus Register dari FSM Update
class ModbusTriggerFromFSM : FSMResultInterface
{
ObservableCollection source;
ObservableCollection data;
ModbusSlave slave;
public ModbusTriggerFromFSM(ObservableCollection source, ObservableCollection data, ModbusSlave slave)
{
this.source = source;
this.data = data;
this.slave = slave;
}
public void DiscoveredSIID(string SIID, NodeData type)
{
}
public void NewState(string SIID, NodeState previous, NodeState current)
{
//FSMData src = source.First(d => d.SIID == SIID);
//ModbusData dt = data.First(d => d.SIID == SIID);
//if (src != null && dt != null)
//{
// if (src.Enable)
// {
// if (dt.Register >= 0)
// {
// dt.LastUpdate = DateTime.Now.ToString();
// dt.Value = current.LogicalState ?? "Unknown";
// if (slave != null)
// {
// switch (current.LogicalState)
// {
// case "ON":
// slave.SetRegister(dt.Register, 1);
// break;
// case "NORMAL":
// case "OFF":
// slave.SetRegister(dt.Register, 0);
// break;
// }
// }
// }
// }
//}
}
}
// Class ini untuk Trigger VX3K dari FSM Update
class VXTriggerFromFSM : FSMResultInterface
{
ObservableCollection data;
ObservableCollection source;
VX3K vx;
public VXTriggerFromFSM(ObservableCollection source, ObservableCollection data, VX3K vx)
{
this.source = source;
this.data = data;
this.vx = vx;
}
public void DiscoveredSIID(string SIID, NodeData type)
{
}
public void NewState(string SIID, NodeState previous, NodeState current)
{
//FSMData src = source.First(d => d.SIID == SIID);
//VXData dt = data.First(d => d.SIID == SIID);
//if (src != null && dt != null)
//{
// if (src.Enable)
// {
// dt.LastUpdate = DateTime.Now.ToString();
// dt.Value = current.LogicalState ?? "Unknown";
// if (vx != null && vx.IsConnected())
// {
// switch (current.LogicalState)
// {
// case "ON":
// vx.Virtual_Contact_Input(dt.FrameID, dt.CIN, true);
// break;
// case "NORMAL":
// case "OFF":
// vx.Virtual_Contact_Input(dt.FrameID, dt.CIN, false);
// break;
// }
// }
// }
//}
}
}
}