|
@@ -0,0 +1,268 @@
|
|
|
+using FluentModbus;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Net;
|
|
|
+using System.Text;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Windows;
|
|
|
+using System.Windows.Markup;
|
|
|
+
|
|
|
+namespace AwInitilizer
|
|
|
+{
|
|
|
+ internal class ZhongShengLedControl : IDisposable
|
|
|
+ {
|
|
|
+ private readonly MainWindow mainWindow;
|
|
|
+ private const int DevAddress = 1;
|
|
|
+ private const int GreenAddress = 0;
|
|
|
+ private const int YelloAddress = 1;
|
|
|
+ private const int EmergencyAddress = 2;
|
|
|
+
|
|
|
+ private ModbusRtuClient modbusRtuClient;
|
|
|
+ private Task poolingMonitorTask;
|
|
|
+ private bool isInEmergency = false;
|
|
|
+ private CancellationTokenSource cancellationSource;
|
|
|
+ private bool IsInitCompleted => modbusRtuClient != null;
|
|
|
+ private SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
|
|
|
+ private bool isDisposing = false;
|
|
|
+ private bool isPoolingMonitorTaskComplete = false;
|
|
|
+
|
|
|
+ public ZhongShengLedControl(ModbusRtuClient comportClient, MainWindow mainWindow)
|
|
|
+ {
|
|
|
+ if (comportClient is null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ cancellationSource = new CancellationTokenSource();
|
|
|
+ this.mainWindow = mainWindow;
|
|
|
+ //mainWindow.OnUpdateStarting += MainWindow_OnUpdateStarting;
|
|
|
+ //mainWindow.OnUpdateCompleted += MainWindow_OnUpdateCompleted;
|
|
|
+
|
|
|
+ InitComport(comportClient);
|
|
|
+ InitMoniter();
|
|
|
+ }
|
|
|
+
|
|
|
+ public ZhongShengLedControl(string comport, MainWindow mainWindow)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(comport))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ cancellationSource = new CancellationTokenSource();
|
|
|
+ this.mainWindow = mainWindow;
|
|
|
+ //mainWindow.OnUpdateStarting += MainWindow_OnUpdateStarting;
|
|
|
+ //mainWindow.OnUpdateCompleted += MainWindow_OnUpdateCompleted;
|
|
|
+
|
|
|
+ InitComport(comport);
|
|
|
+ InitMoniter();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async void MainWindow_OnUpdateCompleted(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (!IsInitCompleted || isInEmergency)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await SetGreenOn(true);
|
|
|
+ await SetYelloOn(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ private async void MainWindow_OnUpdateStarting(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (!IsInitCompleted || isInEmergency)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ await SetGreenOn(false);
|
|
|
+ await SetYelloOn(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Dispose()
|
|
|
+ {
|
|
|
+ Application.Current.Dispatcher.Invoke(() => {
|
|
|
+ isDisposing = true;
|
|
|
+ //cancellationSource.Cancel();
|
|
|
+
|
|
|
+ Task.Delay(1000).Wait();
|
|
|
+
|
|
|
+ SetGreenOn(true).Wait();
|
|
|
+ SetYelloOn(false).Wait();
|
|
|
+ //mainWindow.OnUpdateStarting -= MainWindow_OnUpdateStarting;
|
|
|
+ //mainWindow.OnUpdateCompleted -= MainWindow_OnUpdateCompleted;
|
|
|
+ modbusRtuClient.Dispose();
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task DisposeAsync()
|
|
|
+ {
|
|
|
+ isDisposing = true;
|
|
|
+ //cancellationSource.Cancel();
|
|
|
+
|
|
|
+ //var wai = poolingMonitorTask.Result;
|
|
|
+ while(!isPoolingMonitorTaskComplete)
|
|
|
+ {
|
|
|
+ await Task.Delay(1000);
|
|
|
+ }
|
|
|
+
|
|
|
+ var test = poolingMonitorTask.Status;
|
|
|
+
|
|
|
+ await SetGreenOn(true);
|
|
|
+ await SetYelloOn(false);
|
|
|
+ //mainWindow.OnUpdateStarting -= MainWindow_OnUpdateStarting;
|
|
|
+ //mainWindow.OnUpdateCompleted -= MainWindow_OnUpdateCompleted;
|
|
|
+ modbusRtuClient.Dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void InitComport(ModbusRtuClient comportClient)
|
|
|
+ {
|
|
|
+ modbusRtuClient = comportClient;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void InitComport(string comport)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ modbusRtuClient = new ModbusRtuClient()
|
|
|
+ {
|
|
|
+ BaudRate = 38400,
|
|
|
+ StopBits = System.IO.Ports.StopBits.One,
|
|
|
+ Parity = System.IO.Ports.Parity.None //arity奇偶
|
|
|
+ };
|
|
|
+ modbusRtuClient.Connect(comport);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ MessageBox.Show("ZhongShengLed port open failed");
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void InitMoniter()
|
|
|
+ {
|
|
|
+ if (poolingMonitorTask != null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //poolingMonitorTask = MonitorTask(cancellationSource.Token);
|
|
|
+ poolingMonitorTask = Task.Factory.StartNew(() => MonitorTask().Wait(), TaskCreationOptions.AttachedToParent);
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task MonitorTask(CancellationToken token = default)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (!token.IsCancellationRequested && !isDisposing)
|
|
|
+ {
|
|
|
+ var emergencyDataRead = await Read(EmergencyAddress, token);
|
|
|
+ if (isDisposing) return ;
|
|
|
+ isInEmergency = emergencyDataRead > 0;
|
|
|
+ if (isInEmergency)
|
|
|
+ {
|
|
|
+ //await SetGreenOn(false);
|
|
|
+ await SetYelloOn(false, token);
|
|
|
+ if (isDisposing) return ;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ await SetGreenOn(false, token);
|
|
|
+ if (isDisposing) return ;
|
|
|
+ await SetYelloOn(true, token);
|
|
|
+ if (isDisposing) return ;
|
|
|
+ }
|
|
|
+ await Task.Delay(1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ isPoolingMonitorTaskComplete = true;
|
|
|
+ }
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task SetGreenOn(bool isOn, CancellationToken token = default)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //var greenValue = await Read(GreenAddress);
|
|
|
+ //var isGreenOn = greenValue == 0;
|
|
|
+ //if (isGreenOn != isOn)
|
|
|
+ //{
|
|
|
+ // await Write(GreenAddress, 1);
|
|
|
+ //}
|
|
|
+ await Write(GreenAddress, isOn ? (short)0 : (short)256, token);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task SetYelloOn(bool isOn, CancellationToken token = default)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //var yelloValue = await Read(YelloAddress);
|
|
|
+ //var isYellowOn = yelloValue > 0;
|
|
|
+ //if (isYellowOn != isOn)
|
|
|
+ //{
|
|
|
+ // await Write(YelloAddress, 1);
|
|
|
+ //}
|
|
|
+
|
|
|
+ await Write(YelloAddress, isOn ? (short)256 : (short)0, token);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task Write(int address, short value, CancellationToken token = default)
|
|
|
+ {
|
|
|
+ //await semaphore.WaitAsync();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await modbusRtuClient.WriteSingleRegisterAsync(DevAddress, address, value, token);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ //semaphore.Release();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<short?> Read(int address, CancellationToken token = default)
|
|
|
+ {
|
|
|
+ //await semaphore.WaitAsync();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //var result = await modbusRtuClient.ReadInputRegistersAsync<short>(DevAddress, address, 1);
|
|
|
+ var result = await modbusRtuClient.ReadHoldingRegistersAsync<short>(DevAddress, address, 1, token);
|
|
|
+ var resultArray = result.ToArray();
|
|
|
+ if (resultArray.Length == 0)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return resultArray[0];
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ //semaphore.Release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|