309 lines
10 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|