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}'"),
 | |
|             };
 | |
|         }
 | |
|     }
 | |
| }
 |