using Newtonsoft.Json; using System; using System.Diagnostics; using System.IO.Ports; using System.Runtime.CompilerServices; using System.Threading; using System.Windows.Forms; namespace FSRemotePowerSwitch { public partial class MainForm : Form { private static string SETTINGS_FILE = "Settings.txt"; private static string SERIALPORT_KEY = "LastSerialPort"; private static string EXP_FIRMWARE_VER = "ExpectedFirmwareVersion"; private bool connected; private Boolean Connected { [MethodImpl(MethodImplOptions.Synchronized)] get { return connected; } [MethodImpl(MethodImplOptions.Synchronized)] set { connected = value; } } private static bool requestPending; private static Boolean RequestPending { [MethodImpl(MethodImplOptions.Synchronized)] get { return requestPending; } [MethodImpl(MethodImplOptions.Synchronized)] set { requestPending = value; } } private Boolean initializing; private string firmwareVersion; private long timerCount; public MainForm() { initializing = false; Connected = false; firmwareVersion = new PropertiesHandler(SETTINGS_FILE).get(EXP_FIRMWARE_VER, "V0.0.1"); timerCount = 0; InitializeComponent(); initializeSerialPortComboBox(); } private void onFormShown(object sender, EventArgs e) { connect(); } private void connect() { if (serialPort.IsOpen) { serialPort.Close(); } if (serialPortsCboBox.SelectedItem != null) { Application.UseWaitCursor = true; serialPort.PortName = serialPortsCboBox.SelectedItem.ToString(); serialPort.Open(); sendVersionCmd(); Thread waitThread = new Thread(Wait); waitThread.Start(); } else { initStatusLbl.Text = "Kein Port verfügbar!"; connectedSerialPortLbl.Text = "Port: "; initProgressBar.Style = ProgressBarStyle.Continuous; initProgressBar.Value = 0; } } private void Wait() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds < 3000) { Thread.Sleep(50); if (Connected) { waitForPendingRequest(); sendRelayStatusCmd(); waitForPendingRequest(); sendWebCamStatusCmd(); waitForPendingRequest(); sendWebCamActualAzimutCmd(); BeginInvoke(new EventHandler(delegate { reconnectBtn.Visible = false; })); break; } } if (!Connected) { BeginInvoke(new EventHandler(delegate { initStatusLbl.Text = "Zeitüberschreitung!"; connectedSerialPortLbl.Text = "Port: "; initProgressBar.Style = ProgressBarStyle.Continuous; initProgressBar.Value = 0; reconnectBtn.Visible = true; })); } Application.UseWaitCursor = false; Cursor.Position = Cursor.Position; } private void waitForPendingRequest() { while(RequestPending) { Thread.Sleep(2); } } private void initializeSerialPortComboBox() { initializing = true; string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { if (!serialPortsCboBox.Items.Contains(port)) { serialPortsCboBox.Items.Add(port); } } PropertiesHandler serialPortCfg = new PropertiesHandler(SETTINGS_FILE); string lastselectedComPort = serialPortCfg.get(SERIALPORT_KEY, ""); serialPortsCboBox.SelectedItem = lastselectedComPort; initializing = false; } private void onSerialPortsCboBoxSelectedIndexChanged(object sender, EventArgs e) { PropertiesHandler serialPortCfg = new PropertiesHandler(SETTINGS_FILE); serialPortCfg.set(SERIALPORT_KEY, serialPortsCboBox.SelectedItem); serialPortCfg.Save(); if (!initializing) { reconnectBtn.Visible = false; connect(); } } private void onSerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) { while (serialPort.IsOpen && serialPort.BytesToRead > 0) { string s = readSerialPortData((SerialPort)sender); Message msg = JsonConvert.DeserializeObject(s); try { if (msg.Sender.Equals(Message.CMD_SENDER_AN) && msg.Cmd.Equals(Message.CMD_VER) && msg.Val.Equals(firmwareVersion)) { BeginInvoke(new EventHandler(delegate { Connected = true; initStatusLbl.Text = "Verbunden"; connectedSerialPortLbl.Text = "Port: " + ((SerialPort)sender).PortName; fwVersionLbl.Text = "Ver: " + firmwareVersion; initProgressBar.Style = ProgressBarStyle.Continuous; initProgressBar.Value = 100; openBtn.Enabled = false; closeBtn.Enabled = true; powerSwitchButton.Enabled = true; statusTimer.Enabled = true; })); } else if (msg.Sender.Equals(Message.CMD_SENDER_AN) && msg.Cmd.Equals(Message.CMD_STATUS_RELAY)) { RequestPending = false; BeginInvoke(new EventHandler(delegate { if (msg.Val.Equals(Message.CMD_VAL_ON)) { powerStateLed.BackgroundImage = FSRemotePowerSwitch.Properties.Resources.blue_led_on; powerSwitchButton.CheckStateChanged -= onSwitchCheckStateChanged; powerSwitchButton.Checked = true; powerSwitchButton.CheckStateChanged += onSwitchCheckStateChanged; } else if (msg.Val.Equals(Message.CMD_VAL_OFF)) { powerStateLed.BackgroundImage = FSRemotePowerSwitch.Properties.Resources.blue_led_off; powerSwitchButton.CheckStateChanged -= onSwitchCheckStateChanged; powerSwitchButton.Checked = false; powerSwitchButton.CheckStateChanged += onSwitchCheckStateChanged; } })); } else if (msg.Sender.Equals(Message.CMD_SENDER_AN) && msg.Cmd.Equals(Message.CMD_STATUS_CAM)) { RequestPending = false; BeginInvoke(new EventHandler(delegate { if (msg.Val.Equals(Message.CMD_VAL_ON)) { webCamRotatorPowerStatusLed.BackgroundImage = FSRemotePowerSwitch.Properties.Resources.blue_led_on; webCamRotatorPowerSwitch.CheckStateChanged -= onWebCamPowerSwitchCheckStateChanged; webCamRotatorPowerSwitch.Checked = true; webCamRotatorPowerSwitch.CheckStateChanged += onWebCamPowerSwitchCheckStateChanged; } else if (msg.Val.Equals(Message.CMD_VAL_OFF)) { webCamRotatorPowerStatusLed.BackgroundImage = FSRemotePowerSwitch.Properties.Resources.blue_led_off; webCamRotatorPowerSwitch.CheckStateChanged -= onWebCamPowerSwitchCheckStateChanged; webCamRotatorPowerSwitch.Checked = false; webCamRotatorPowerSwitch.CheckStateChanged += onWebCamPowerSwitchCheckStateChanged; } })); } else if (msg.Sender.Equals(Message.CMD_SENDER_AN) && msg.Cmd.Equals(Message.CMD_ZERO_CAM)) { BeginInvoke(new EventHandler(delegate { webCamRotator.Value = int.Parse(msg.Val); })); } else if (msg.Sender.Equals(Message.CMD_SENDER_AN) && msg.Cmd.Equals(Message.CMD_ACT_AZIMUT_CAM)) { RequestPending = false; BeginInvoke(new EventHandler(delegate { webCamRotator.Value = int.Parse(msg.Val); })); } } catch (Exception ex) when (ex is Newtonsoft.Json.JsonReaderException || ex is Newtonsoft.Json.JsonSerializationException) { initStatusLbl.Text = "Json Deserialize Exception!"; serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Dispose(); } } } private void onOpenBtnClick(object sender, EventArgs e) { if (serialPort.PortName != "COM1" && !serialPort.IsOpen) { serialPort.Open(); openBtn.Enabled = false; closeBtn.Enabled = true; powerSwitchButton.Enabled = true; } } private void onCloseBtnClick(object sender, EventArgs e) { if (serialPort.IsOpen) { serialPort.Close(); openBtn.Enabled = true; closeBtn.Enabled = false; powerSwitchButton.Enabled = false; } } private void onReconnectBtnClick(object sender, EventArgs e) { reconnectBtn.Visible = false; connect(); } private void onSwitchCheckStateChanged(object sender, EventArgs e) { if (powerSwitchButton.Checked) { sendRelayPowerCmd(Message.CMD_VAL_ON); } else { sendRelayPowerCmd(Message.CMD_VAL_OFF); } } private void onWebCamPowerSwitchCheckStateChanged(object sender, EventArgs e) { if (webCamRotatorPowerSwitch.Checked) { sendWebCamPowerCmd(Message.CMD_VAL_ON); } else { sendWebCamPowerCmd(Message.CMD_VAL_OFF); } } private String readSerialPortData(SerialPort serialPort) { string data = ""; int character = 0; ; do { if (serialPort.IsOpen) { character = serialPort.ReadByte(); data += (char)character; } } while ((char)character != '}'); return data; } private void sendVersionCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_VER; msg.Val = null; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); } } private void sendRelayPowerCmd(string value) { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_POWER_RELAY; msg.Val = value; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); } } private void sendRelayStatusCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_STATUS_RELAY; msg.Val = null; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); RequestPending = true; } } private void sendWebCamStatusCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_STATUS_CAM; msg.Val = null; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); RequestPending = true; } } private void sendWebCamPowerCmd(string value) { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_POWER_CAM; msg.Val = value; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); } } private void sendWebCamZeroCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_ZERO_CAM; msg.Val = "0"; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); } } private void sendWebCamAzimutCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_AZIMUT_CAM; msg.Val = webCamRotator.Value.ToString(); string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); } } private void sendWebCamActualAzimutCmd() { Message msg = new Message(); msg.Sender = Message.CMD_SENDER_PC; msg.Cmd = Message.CMD_ACT_AZIMUT_CAM; msg.Val = ""; string msJson = JsonConvert.SerializeObject(msg); if (serialPort.IsOpen) { serialPort.Write(msJson); RequestPending = true; } } private void onStatusTimerTick(object sender, EventArgs e) { if (timerCount % 2 == 0) { sendWebCamStatusCmd(); } else { sendRelayStatusCmd(); } timerCount++; } private void onMainFormClosing(object sender, FormClosingEventArgs e) { if (serialPort.IsOpen) { serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Close(); serialPort.Dispose(); } } private void onWebCamRotatorValueChanged(object Sender) { rotatorActValue.Text = webCamRotator.Value.ToString(); } private void onSetWebCamZero(object sender, EventArgs e) { sendWebCamZeroCmd(); } private void onWebCamRotatorMiddleAreaClicked(object Sender) { sendWebCamAzimutCmd(); } } }