Fixes after testing live
This commit is contained in:
@@ -9,58 +9,59 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
public readonly record struct Status(Mode Mode, int Flags);
|
||||
|
||||
protected SerialPort Serial;
|
||||
protected Stream Stream;
|
||||
protected StreamReader Reader;
|
||||
|
||||
public T1(string portName, Parity parity = Parity.Odd) {
|
||||
Serial = new SerialPort(portName, 9600, parity, 8, StopBits.One);
|
||||
Serial = new SerialPort(portName, 9600, parity, 8, StopBits.One) {
|
||||
Handshake = Handshake.None,
|
||||
NewLine = "\r",
|
||||
ReadTimeout = 1000,
|
||||
WriteTimeout = 1000,
|
||||
DtrEnable = true,
|
||||
RtsEnable = true,
|
||||
Encoding = Encoding.ASCII,
|
||||
};
|
||||
Serial.Open();
|
||||
Stream = Serial.BaseStream ?? Stream.Null;
|
||||
Stream.ReadTimeout = 250;
|
||||
Stream.WriteTimeout = 250;
|
||||
Reader = new(Stream, Encoding.ASCII, false, 256);
|
||||
Serial.DiscardInBuffer();
|
||||
Serial.DiscardOutBuffer();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Reader.Dispose();
|
||||
Stream.Dispose();
|
||||
Serial.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected async Task SendCommand(string cmd, string? data = null, bool checksum = true) {
|
||||
// max 255 bytes
|
||||
byte[] d = new byte[255];
|
||||
int n = Encoding.ASCII.GetBytes($"(A{1:00}{cmd}", d);
|
||||
var line = new StringBuilder("(A", 256);
|
||||
line.AppendFormat("{0:00}{1}", 1, cmd);
|
||||
if (data != null) {
|
||||
if (data.Length > 244) throw new ArgumentException("T1 playload too long");
|
||||
n += Encoding.ASCII.GetBytes(data, 0, data.Length, d, n);
|
||||
line.Append(data);
|
||||
}
|
||||
if (checksum) {
|
||||
d[n++] = (byte)'&';
|
||||
byte chk = d.Take(n).Aggregate((s, c) => (byte)((s + c) & 0xFF));
|
||||
n += Encoding.ASCII.GetBytes($"{chk:X2}", 0, 2, d, n);
|
||||
line.Append('&');
|
||||
var chk = Enumerable.Range(0, line.Length).Aggregate(0, (c, i) => c + line[i]) & 0xFF;
|
||||
line.AppendFormat("{0:X2}", chk);
|
||||
}
|
||||
d[n++] = (byte)')';
|
||||
d[n++] = (byte)'\r';
|
||||
await Stream.WriteAsync(d.AsMemory(0, n));
|
||||
line.Append(')');
|
||||
Serial.WriteLine(line.ToString());
|
||||
}
|
||||
|
||||
protected async Task<(string, string)> ReceiveResponse(string? expectedCmd = null) {
|
||||
var line = await Reader.ReadUntilAsync('\r');
|
||||
var line = Serial.ReadLine();
|
||||
if (line == null) {
|
||||
throw new IOException("Verbindung zu SPS (T1) verloren");
|
||||
} else if (line.Length < 9 || !line.StartsWith("(A") || !line.EndsWith(")\r") || line[^5] != '&') {
|
||||
} else if (line.Length < 8 || !line.StartsWith("(A") || !line.EndsWith(')') || line[^4] != '&') {
|
||||
throw new FormatException("Invalid response from PLC (T1)");
|
||||
}
|
||||
|
||||
var chk1 = (byte)Convert.ToInt32(line[^4..^2], 16);
|
||||
var chk2 = Encoding.ASCII.GetBytes(line).SkipLast(4).Aggregate((s, c) => (byte)((s + c) & 0xFF));
|
||||
var chk1 = Convert.ToInt32(line[^3..^1], 16);
|
||||
var chk2 = Enumerable.Range(0, line.Length - 3).Aggregate(0, (c, i) => c + line[i]) & 0xFF;
|
||||
if (chk1 != chk2) {
|
||||
throw new IOException($"Ungültige Prüfsumme von SPS (T1)");
|
||||
}
|
||||
|
||||
var (cmd, data) = (line[4..6], line[6..^5]);
|
||||
var (cmd, data) = (line[4..6], line[6..^4]);
|
||||
if (cmd == "ST" && data[3] == '6') {
|
||||
// TODO check for other error bits?
|
||||
await SendCommand("ER");
|
||||
|
||||
Reference in New Issue
Block a user