blob: d1aab3ec8f2eb62f757a9afd9cef21e68fb8c006 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace Tango.Integration.Emergency
{
/// <summary>
/// Represents a USB serial port emergency switch notification provider.
/// </summary>
/// <seealso cref="Tango.Integration.Emergency.IEmergencyNotificationProvider" />
public class UsbEmergencyNotificationProvider : IEmergencyNotificationProvider
{
private Timer _timer;
private bool _busy;
/// <summary>
/// Gets or sets a value indicating whether to enable emergency detection and notification.
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Gets or sets the current emergency status.
/// </summary>
public EmergencyStatus Status { get; set; }
/// <summary>
/// Gets or sets the address/port of the detection device.
/// </summary>
public string Address { get; set; }
/// <summary>
/// Gets or sets the read timeout for the loop-back signal.
/// </summary>
public TimeSpan ReadTimeout { get; set; }
/// <summary>
/// Gets or sets the signal output.
/// </summary>
public String SignalOutput { get; set; }
/// <summary>
/// Occurs when the emergency status has changed.
/// </summary>
public event EventHandler<EmergencyStatusChangedEventArgs> StatusChanged;
/// <summary>
/// Initializes a new instance of the <see cref="UsbEmergencyNotificationProvider"/> class.
/// </summary>
/// <param name="port">The port.</param>
public UsbEmergencyNotificationProvider(String port)
{
SignalOutput = "1";
Address = port;
ReadTimeout = TimeSpan.FromMilliseconds(500);
_timer = new Timer(2000);
_timer.Elapsed += _timer_Elapsed;
_timer.Start();
}
/// <summary>
/// Called when the status has been changed.
/// </summary>
/// <param name="status">The status.</param>
/// <param name="errorException">The error exception.</param>
protected virtual void OnStatusChanged(EmergencyStatus status, Exception errorException = null)
{
if (Status != status)
{
Status = status;
StatusChanged?.Invoke(this, new EmergencyStatusChangedEventArgs()
{
Status = status,
ErrorException = errorException,
});
}
}
/// <summary>
/// Handles the Elapsed event of the _timer.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="ElapsedEventArgs"/> instance containing the event data.</param>
[DebuggerNonUserCode]
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (IsEnabled && !_busy)
{
_busy = true;
SerialPort serial = new SerialPort(Address);
try
{
serial.ReadTimeout = (int)ReadTimeout.TotalMilliseconds;
serial.Open();
serial.Write(SignalOutput + "\n");
try
{
string output = serial.ReadLine();
if (output == SignalOutput)
{
OnStatusChanged(EmergencyStatus.On);
}
else
{
OnStatusChanged(EmergencyStatus.Off);
}
}
catch (TimeoutException)
{
OnStatusChanged(EmergencyStatus.Off);
}
catch (Exception ex)
{
OnStatusChanged(EmergencyStatus.Error, ex);
}
}
catch (Exception ex)
{
OnStatusChanged(EmergencyStatus.Error, ex);
}
finally
{
try
{
serial.Dispose();
_busy = false;
}
catch { }
}
}
}
}
}
|