102 lines
4.1 KiB
C#
102 lines
4.1 KiB
C#
using System.IO.Ports;
|
|
using System.IO;
|
|
using System.Net.Sockets;
|
|
using System;
|
|
using System.Text;
|
|
|
|
namespace Elwig.Helpers.Weighing {
|
|
public abstract class Scale : IDisposable {
|
|
|
|
protected enum Output { RTS, DTR, OUT1, OUT2 };
|
|
|
|
protected SerialPort? Serial = null;
|
|
protected SerialPort? ControlSerialEmpty = null, ControlSerialFilling = null;
|
|
protected TcpClient? Tcp = null;
|
|
protected Stream Stream;
|
|
protected StreamReader Reader;
|
|
|
|
protected readonly Output? EmptyMode = null;
|
|
protected readonly Output? FillingClearanceMode = null;
|
|
protected readonly int EmptyDelay;
|
|
|
|
public int? WeightLimit { get; private set; }
|
|
public string? LogPath { get; private set; }
|
|
|
|
public static IScale FromConfig(ScaleConfig config) {
|
|
int? limit = config.Limit != null ? int.Parse(config.Limit) : null;
|
|
if (config.Type == "SysTec-IT") {
|
|
return new SysTecITScale(config.Id, config.Model!, config.Connection!, config.Empty, config.Filling, limit, config.Log);
|
|
} else if (config.Type == "Avery-Async") {
|
|
return new AveryEventScale(config.Id, config.Model!, config.Connection!, config.Empty, config.Filling, limit, config.Log);
|
|
} else if (config.Type == "Gassner") {
|
|
return new GassnerScale(config.Id, config.Model!, config.Connection!, config.Empty, config.Filling, limit, config.Log);
|
|
} else {
|
|
throw new ArgumentException($"Invalid scale type: \"{config.Type}\"");
|
|
}
|
|
}
|
|
|
|
protected Scale(string cnx, string? empty, string? filling, int? limit, string? log) {
|
|
if (cnx.StartsWith("serial:")) {
|
|
Serial = Utils.OpenSerialConnection(cnx);
|
|
Stream = Serial.BaseStream;
|
|
} else if (cnx.StartsWith("tcp:")) {
|
|
Tcp = Utils.OpenTcpConnection(cnx);
|
|
Stream = Tcp.GetStream();
|
|
} else {
|
|
throw new ArgumentException($"Unsupported scheme: \"{cnx.Split(':')[0]}\"");
|
|
}
|
|
Reader = new(Stream, Encoding.ASCII, false, 512);
|
|
|
|
LogPath = log;
|
|
|
|
if (empty != null) {
|
|
var parts = empty.Split(':');
|
|
if (parts.Length == 3) {
|
|
if (parts[0] != Serial?.PortName)
|
|
ControlSerialEmpty = Utils.OpenSerialConnection($"serial://{parts[0]}:9600");
|
|
} else if (parts.Length != 2) {
|
|
throw new ArgumentException("Invalid value for 'empty'");
|
|
}
|
|
EmptyMode = ConvertOutput(parts[^2]);
|
|
EmptyDelay = int.Parse(parts[^1]);
|
|
}
|
|
|
|
WeightLimit = limit;
|
|
if (filling != null) {
|
|
var parts = filling.Split(':');
|
|
if (parts.Length == 2) {
|
|
if (parts[0] != Serial?.PortName)
|
|
ControlSerialFilling = parts[0] != ControlSerialEmpty?.PortName ? Utils.OpenSerialConnection($"serial://{parts[0]}:9600") : ControlSerialEmpty;
|
|
} else if (parts.Length != 1) {
|
|
throw new ArgumentException("Invalid value for 'filling'");
|
|
}
|
|
FillingClearanceMode = ConvertOutput(parts[^1]);
|
|
}
|
|
|
|
if (FillingClearanceMode != null && WeightLimit == null)
|
|
throw new ArgumentException("Weight limit has to be set, if filling clearance supervision is enabled");
|
|
}
|
|
|
|
public void Dispose() {
|
|
Reader.Close();
|
|
Stream.Close();
|
|
Serial?.Close();
|
|
ControlSerialEmpty?.Close();
|
|
ControlSerialFilling?.Close();
|
|
Tcp?.Close();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected static Output? ConvertOutput(string? value) {
|
|
return value switch {
|
|
null => null,
|
|
"RTS" => Output.RTS,
|
|
"DTR" => Output.DTR,
|
|
"OUT1" => Output.OUT1,
|
|
"OUT2" => Output.OUT2,
|
|
_ => throw new ArgumentException($"Invalid value for argument: '{value}'"),
|
|
};
|
|
}
|
|
}
|
|
}
|