Files
pamhagen-sysctrl/PamhagenSysCtrl/Helpers/PamhagenPlant.cs
T

309 lines
10 KiB
C#

using System.IO;
using System.Windows;
namespace PamhagenSysCtrl.Helpers {
public class PamhagenPlant : IDisposable {
protected PamhagenPlc? Plc;
protected bool IsRunning = true;
protected Thread? BackgroundThread;
public event EventHandler<PlantEventArgs>? Update;
protected bool ActuatorsChanged = false;
protected PamhagenPlc.ActuatorStates Actuators;
protected PamhagenPlc.SensorStates Sensors;
public bool IsValveOpen(int n) => !IsValveClosed(n);
public bool IsValveClosed(int n) => Sensors.GetDS(n);
public bool WantValveClosed(int n) => !WantValveOpen(n);
public bool WantValveOpen(int n) => Actuators.GetV(n);
public bool IsA1Selected => Sensors.TroughSelector == 1;
public bool IsA2Selected => Sensors.TroughSelector == 2;
public FillState FillLevelA1 => Sensors.FillingLevels.A1;
public FillState FillLevelA2 => Sensors.FillingLevels.A2;
public FillState FillLevelPress1 => Sensors.FillingLevels.Press1;
public FillState FillLevelPress2 => Sensors.FillingLevels.Press2;
public FillState FillLevelT1 => Sensors.FillingLevelTanks[0];
public FillState FillLevelT2 => Sensors.FillingLevelTanks[1];
public FillState FillLevelT3 => Sensors.FillingLevelTanks[2];
public FillState FillLevelT4 => Sensors.FillingLevelTanks[3];
public FillState FillLevelT5 => Sensors.FillingLevelTanks[4];
public FillState FillLevelT6 => Sensors.FillingLevelTanks[5];
public FillState FillLevelT7 => Sensors.FillingLevelTanks[6];
public FillState FillLevelT8 => Sensors.FillingLevelTanks[7];
public FillState FillLevelT9 => Sensors.FillingLevelTanks[8];
public double GradationOe => Sensors.GradationOe;
public MotorState PresseQuerSchnecke => Sensors.PresseQuerSchnecke;
public bool WantA1Selected => Actuators.GetV(58);
public bool WantA2Selected => !Actuators.GetV(58);
public bool IsTroughAugerActive => Actuators.TroughAuger;
public bool IsReblerActive => Actuators.Rebler;
public bool IsStirrerA1Active => Actuators.StirrerA1;
public bool IsStirrerA2Active => Actuators.StirrerA2;
public bool IsBeltActive => Actuators.Belt;
public bool IsAuger1Active => Actuators.Auger1;
public bool IsAuger2Active => Actuators.Auger2;
public bool IsWasteDisposalActive => IsBeltActive || IsAuger1Active || IsAuger2Active;
public bool IsGradationPumpActive => Actuators.GradationPump;
public PamhagenPlant(string portName) {
Plc = new(portName);
}
protected virtual void RaiseUpdateEvent(PlantEventArgs evt) {
App.MainDispatcher.BeginInvoke(() => Update?.Invoke(this, evt));
}
public async Task StartThread() {
if (Plc == null) throw new Exception();
await Plc.TestConnection();
Actuators = await Plc.ReadOutputs();
BackgroundThread = new Thread(new ParameterizedThreadStart(BackgroundLoop));
BackgroundThread.Start();
}
public void Dispose() {
IsRunning = false;
BackgroundThread?.Join();
Plc?.Dispose();
GC.SuppressFinalize(this);
}
protected async void BackgroundLoop(object? parameters) {
while (IsRunning && Plc != null) {
try {
if (ActuatorsChanged) {
await Plc.WriteOutputs(Actuators);
ActuatorsChanged = false;
}
Sensors = await Plc.ReadInputs();
RaiseUpdateEvent(new());
} catch (Exception exc) {
var str = "Bei der SPS ist ein Fehler aufgetreten:\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "SPS-Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
if (exc is TimeoutException or IOException) {
Plc?.Dispose();
Plc = null;
IsRunning = false;
} else {
await Task.Delay(1000);
}
}
}
try {
if (Plc != null)
await Plc.WriteOutputs(new() { Valves = Actuators.Valves });
} catch (Exception exc) {
var str = "Beim Schließen der Verbindung zur SPS ist ein Fehler aufgetreten:\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "SPS-Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public void CommitChanges() {
ActuatorsChanged = true;
}
public MotorState MP1 {
get => Actuators.MP1;
set => Actuators.MP1 = (value != MotorState.Halt && value != MotorState.Forward && value != MotorState.Backward) ? throw new ArgumentException("Invalid state for MP1") : value;
}
public MotorState MP2 {
get => Actuators.MP2;
set => Actuators.MP2 = (value != MotorState.Halt && value != MotorState.Forward && value != MotorState.Backward) ? throw new ArgumentException("Invalid state for MP2") : value;
}
public MotorState P12 {
get => Actuators.P12;
set => Actuators.P12 = (value != MotorState.Halt && value != MotorState.Forward) ? throw new ArgumentException("Invalid state for P12") : value;
}
public MotorState P3 {
get => Actuators.P3;
set => Actuators.P3 = (value != MotorState.Halt && value != MotorState.Forward) ? throw new ArgumentException("Invalid state for P3") : value;
}
public MotorState P4 {
get => Actuators.P4;
set => Actuators.P4 = (value != MotorState.Halt && value != MotorState.Forward) ? throw new ArgumentException("Invalid state for P4") : value;
}
public MotorState P5 {
get => Actuators.P5;
set => Actuators.P5 = (value != MotorState.Halt && value != MotorState.Forward) ? throw new ArgumentException("Invalid state for P5") : value;
}
public MotorState P6 {
get => Actuators.P6;
set => Actuators.P6 = (value != MotorState.Halt && value != MotorState.Forward) ? throw new ArgumentException("Invalid state for P6") : value;
}
public void OpenV(int n) => SetV(n, true);
public void CloseV(int n) => SetV(n, false);
protected void SetV(int n, bool val) {
if (n < 1 || n > 57) throw new ArgumentException("Invalid value for n: 1 <= #V <= 57");
Actuators.SetV(n, val);
}
public void SelectA1() {
Actuators.SetV(58, true);
//if (IsReblerActive) Actuators.StirrerA1 = true;
}
public void SelectA2() {
Actuators.SetV(58, false);
//if (IsReblerActive) Actuators.StirrerA2 = true;
}
public void StartTroughAuger() {
Actuators.TroughAuger = true;
}
public void StopTroughAuger() {
Actuators.TroughAuger = false;
}
public void StartRebler() {
Actuators.Rebler = true;
}
public void StopRebler() {
Actuators.Rebler = false;
}
public void StartStirrerA1() {
Actuators.StirrerA1 = true;
}
public void StopStirrerA1() {
Actuators.StirrerA1 = false;
}
public void StartStirrerA2() {
Actuators.StirrerA2 = true;
}
public void StopStirrerA2() {
Actuators.StirrerA2 = false;
}
public void StartBelt() {
Actuators.Belt = true;
}
public void StopBelt() {
Actuators.Belt = false;
}
public void StartAuger1() {
Actuators.Auger1 = true;
}
public void StopAuger1() {
Actuators.Auger1 = false;
}
public void StartAuger2() {
Actuators.Auger2 = true;
}
public void StopAuger2() {
Actuators.Auger2 = false;
}
public void StartWasteDisposal() {
StartBelt();
StartAuger1();
StartAuger2();
}
public void StopWasteDisposal() {
StopBelt();
StopAuger1();
StopAuger2();
}
public void StartGradationPump() {
Actuators.GradationPump = true;
}
public void StopGradationPump() {
Actuators.GradationPump = false;
}
public void StartMP1Forward() {
Actuators.MP1 = MotorState.Forward;
}
public void StartMP1Backward() {
Actuators.MP1 = MotorState.Backward;
}
public void StopMP1() {
Actuators.MP1 = MotorState.Halt;
}
public void StartMP2Forward() {
Actuators.MP2 = MotorState.Forward;
}
public void StartMP2Backward() {
Actuators.MP2 = MotorState.Backward;
}
public void StopMP2() {
Actuators.MP2 = MotorState.Halt;
}
public void StartP12() {
Actuators.P12 = MotorState.Forward;
}
public void StopP12() {
Actuators.P12 = MotorState.Halt;
}
public void StartP3() {
Actuators.P3 = MotorState.Forward;
}
public void StopP3() {
Actuators.P3 = MotorState.Halt;
}
public void StartP4() {
Actuators.P4 = MotorState.Forward;
}
public void StopP4() {
Actuators.P4 = MotorState.Halt;
}
public void StartP5() {
Actuators.P5 = MotorState.Forward;
}
public void StopP5() {
Actuators.P5 = MotorState.Halt;
}
public void StartP6() {
Actuators.P6 = MotorState.Forward;
}
public void StopP6() {
Actuators.P6 = MotorState.Halt;
}
}
}