diff --git a/PamhagenSysCtrl/Helpers/PamhagenPlant.cs b/PamhagenSysCtrl/Helpers/PamhagenPlant.cs index 49fb6c4..f93cbeb 100644 --- a/PamhagenSysCtrl/Helpers/PamhagenPlant.cs +++ b/PamhagenSysCtrl/Helpers/PamhagenPlant.cs @@ -9,7 +9,7 @@ namespace PamhagenSysCtrl.Helpers { protected bool IsRunning = true; protected Thread? BackgroundThread; - public event EventHandler? Update; + public event EventHandler? Update; protected bool ActuatorsChanged = false; protected PamhagenPlc.ActuatorStates Actuators; @@ -48,13 +48,14 @@ namespace PamhagenSysCtrl.Helpers { 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(EventArgs evt) { + protected virtual void RaiseUpdateEvent(PlantEventArgs evt) { App.MainDispatcher.BeginInvoke(() => Update?.Invoke(this, evt)); } @@ -81,7 +82,7 @@ namespace PamhagenSysCtrl.Helpers { ActuatorsChanged = false; } Sensors = await Plc.ReadInputs(); - RaiseUpdateEvent(EventArgs.Empty); + 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; @@ -220,6 +221,18 @@ namespace PamhagenSysCtrl.Helpers { Actuators.Auger2 = false; } + public void StartWasteDisposal() { + StartBelt(); + StartAuger1(); + StartAuger2(); + } + + public void StopWasteDisposal() { + StopBelt(); + StopAuger1(); + StopAuger2(); + } + public void StartGradationPump() { Actuators.GradationPump = true; } diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Graph.cs b/PamhagenSysCtrl/Helpers/Pipeline/Graph.cs new file mode 100644 index 0000000..9a69ee2 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Graph.cs @@ -0,0 +1,31 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class Graph { + + protected HashSet Nodes = []; + protected HashSet Edges = []; + + public Graph() { + + } + + public Pipe CreatePipe(INode start, INode end) { + Nodes.Add(start); + Nodes.Add(end); + var p = new Pipe(start, end); + Edges.Add(p); + return p; + } + + public void Draw(Canvas canvas) { + foreach (var e in Edges) { + e.Draw(canvas); + } + foreach (var n in Nodes) { + n.Draw(canvas); + } + } + + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/IEdge.cs b/PamhagenSysCtrl/Helpers/Pipeline/IEdge.cs new file mode 100644 index 0000000..384632a --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/IEdge.cs @@ -0,0 +1,13 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public interface IEdge { + + public INode Start { get; } + public INode End { get; } + public bool Orientation { get; } + + public void Draw(Canvas canvas); + + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/INode.cs b/PamhagenSysCtrl/Helpers/Pipeline/INode.cs new file mode 100644 index 0000000..d38b496 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/INode.cs @@ -0,0 +1,13 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public interface INode { + + public double CenterX { get; } + public double CenterY { get; } + public string Label { get; } + + public void Draw(Canvas canvas); + + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/ISink.cs b/PamhagenSysCtrl/Helpers/Pipeline/ISink.cs new file mode 100644 index 0000000..8c3b158 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/ISink.cs @@ -0,0 +1,5 @@ +namespace PamhagenSysCtrl.Helpers.Pipeline { + public interface ISink : INode { + public bool IsFull { get; } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/ISource.cs b/PamhagenSysCtrl/Helpers/Pipeline/ISource.cs new file mode 100644 index 0000000..4c23848 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/ISource.cs @@ -0,0 +1,5 @@ +namespace PamhagenSysCtrl.Helpers.Pipeline { + public interface ISource : INode { + public bool IsFilled { get; } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Pipe.cs b/PamhagenSysCtrl/Helpers/Pipeline/Pipe.cs new file mode 100644 index 0000000..a8b843b --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Pipe.cs @@ -0,0 +1,60 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class Pipe : IEdge { + + public INode Start { get; set; } + public INode End { get; set; } + public bool Orientation { get; set; } + + public Pipe(INode start, INode end, bool orientation = false) { + Start = start; + End = end; + Orientation = orientation; + } + + public void Draw(Canvas canvas) { + var x1 = Start.CenterX; + var y1 = Start.CenterY; + var x2 = Orientation ? Start.CenterX : End.CenterX; + var y2 = Orientation ? End.CenterY : Start.CenterY; + var x3 = End.CenterX; + var y3 = End.CenterY; + var a1 = new Line() { + X1 = x1, Y1 = y1, X2 = x2, Y2 = y2, + StrokeThickness = 10, + Stroke = Brushes.Black, + StrokeStartLineCap = PenLineCap.Square, + StrokeEndLineCap = PenLineCap.Square, + }; + var a2 = new Line() { + X1 = x1, Y1 = y1, X2 = x2, Y2 = y2, + StrokeThickness = 6, + Stroke = Brushes.Gray, + StrokeStartLineCap = PenLineCap.Square, + StrokeEndLineCap = PenLineCap.Square, + }; + var b1 = new Line() { + X1 = x2, Y1 = y2, X2 = x3, Y2 = y3, + StrokeThickness = 10, + Stroke = Brushes.Black, + StrokeStartLineCap = PenLineCap.Square, + StrokeEndLineCap = PenLineCap.Square, + }; + var b2 = new Line() { + X1 = x2, Y1 = y2, X2 = x3, Y2 = y3, + StrokeThickness = 6, + Stroke = Brushes.Gray, + StrokeStartLineCap = PenLineCap.Square, + StrokeEndLineCap = PenLineCap.Square, + }; + canvas.Children.Add(a1); + canvas.Children.Add(b1); + canvas.Children.Add(a2); + canvas.Children.Add(b2); + } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs b/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs new file mode 100644 index 0000000..1ee674e --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/PipeJoin.cs @@ -0,0 +1,28 @@ +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class PipeJoin : INode { + + public double CenterX { get; set; } + public double CenterY { get; set; } + public string Label { get; } = ""; + + public PipeJoin(double x, double y) { + CenterX = x; + CenterY = y; + } + + public void Draw(Canvas canvas) { + var e = new Rectangle() { + Height = 18, + Width = 18, + Fill = Brushes.Black, + }; + e.SetValue(Canvas.LeftProperty, CenterX - 9); + e.SetValue(Canvas.TopProperty, CenterY - 9); + canvas.Children.Add(e); + } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Pump.cs b/PamhagenSysCtrl/Helpers/Pipeline/Pump.cs new file mode 100644 index 0000000..824fe84 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Pump.cs @@ -0,0 +1,20 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class Pump : INode { + + public double CenterX { get; set; } + public double CenterY { get; set; } + public string Label { get; set; } + + public Pump(string label, double x, double y) { + CenterX = x; + CenterY = y; + Label = label; + } + + public void Draw(Canvas canvas) { + + } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Tank.cs b/PamhagenSysCtrl/Helpers/Pipeline/Tank.cs new file mode 100644 index 0000000..7cb1db4 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Tank.cs @@ -0,0 +1,27 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + class Tank : INode, ISink, ISource { + + public double CenterX { get; set; } + public double CenterY { get; set; } + public string Label { get; set; } + public bool IsFull => CallbackIsFull(); + public bool IsFilled => CallbackIsFilled(); + + protected Func CallbackIsFilled; + protected Func CallbackIsFull; + + public Tank(string label, double x, double y, Func cbFilled, Func cbFull) { + CenterX = x; + CenterY = y; + Label = label; + CallbackIsFilled = cbFilled; + CallbackIsFull = cbFull; + } + + public void Draw(Canvas canvas) { + + } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Trough.cs b/PamhagenSysCtrl/Helpers/Pipeline/Trough.cs new file mode 100644 index 0000000..e86d6c5 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Trough.cs @@ -0,0 +1,24 @@ +using System.Windows.Controls; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class Trough : INode, ISource { + + public double CenterX { get; set; } + public double CenterY { get; set; } + public string Label { get; set; } + public bool IsFilled => CallbackIsFilled(); + + protected Func CallbackIsFilled; + + public Trough(string label, double x, double y, Func cbFilled) { + CenterX = x; + CenterY = y; + Label = label; + CallbackIsFilled = cbFilled; + } + + public void Draw(Canvas canvas) { + + } + } +} diff --git a/PamhagenSysCtrl/Helpers/Pipeline/Valve.cs b/PamhagenSysCtrl/Helpers/Pipeline/Valve.cs new file mode 100644 index 0000000..21184db --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Pipeline/Valve.cs @@ -0,0 +1,39 @@ +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace PamhagenSysCtrl.Helpers.Pipeline { + public class Valve : INode { + + public double CenterX { get; set; } + public double CenterY { get; set; } + public string Label { get; set; } + + public bool IsOpen => CallbackIsOpen(); + public bool WantOpen => CallbackWantOpen(); + + protected Func CallbackIsOpen; + protected Func CallbackWantOpen; + + public Valve(string label, double x, double y, Func cbOpen, Func cbWant) { + CenterX = x; + CenterY = y; + Label = label; + CallbackIsOpen = cbOpen; + CallbackWantOpen = cbWant; + } + + public void Draw(Canvas canvas) { + var e = new Ellipse() { + Height = 20, + Width = 20, + Fill = Brushes.Gray, + Stroke = Brushes.Black, + StrokeThickness = 2, + }; + e.SetValue(Canvas.LeftProperty, CenterX - 10); + e.SetValue(Canvas.TopProperty, CenterY - 10); + canvas.Children.Add(e); + } + } +} diff --git a/PamhagenSysCtrl/Helpers/PlantEventArgs.cs b/PamhagenSysCtrl/Helpers/PlantEventArgs.cs new file mode 100644 index 0000000..8f93ad3 --- /dev/null +++ b/PamhagenSysCtrl/Helpers/PlantEventArgs.cs @@ -0,0 +1,3 @@ +namespace PamhagenSysCtrl.Helpers { + public class PlantEventArgs : EventArgs { } +} diff --git a/PamhagenSysCtrl/Windows/MainWindow.xaml.cs b/PamhagenSysCtrl/Windows/MainWindow.xaml.cs index 4118bac..e93380d 100644 --- a/PamhagenSysCtrl/Windows/MainWindow.xaml.cs +++ b/PamhagenSysCtrl/Windows/MainWindow.xaml.cs @@ -1,4 +1,5 @@ using PamhagenSysCtrl.Helpers; +using PamhagenSysCtrl.Windows; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -51,10 +52,13 @@ namespace PamhagenSysCtrl { var str = $"Beim Aufbauen einer Verbindung zur SPS ist ein Fehler aufgetreten:\n\n{exc.GetType().Name}: {exc.Message}"; if (exc.InnerException != null) str += $"\n\n{exc.InnerException.GetType().Name}: {exc.InnerException.Message}"; MessageBox.Show(str, "SPS-Fehler", MessageBoxButton.OK, MessageBoxImage.Error); + return; } + var w = new PlantSchemeWindow(); + w.Show(); } - public void OnUpdate(object? sender, EventArgs evt) { + public void OnUpdate(object? sender, PlantEventArgs evt) { if (sender is not PamhagenPlant plant) return; for (int i = 1; i <= 60; i++) { diff --git a/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml new file mode 100644 index 0000000..57bb41c --- /dev/null +++ b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml @@ -0,0 +1,12 @@ + + + + + + diff --git a/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs new file mode 100644 index 0000000..4e8086c --- /dev/null +++ b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs @@ -0,0 +1,49 @@ +using PamhagenSysCtrl.Helpers; +using PamhagenSysCtrl.Helpers.Pipeline; +using System.Drawing; +using System.Security.Cryptography.X509Certificates; +using System.Windows; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace PamhagenSysCtrl.Windows { + public partial class PlantSchemeWindow : Window { + + public PlantSchemeWindow() { + InitializeComponent(); + App.Plant?.Update += OnUpdate; + + var graph = new Graph(); + + var mw1 = new Trough("MW1", 200, 50, () => App.Plant?.FillLevelA1 != FillState.Empty); + var mw2 = new Trough("MW2", 50, 50, () => App.Plant?.FillLevelA1 != FillState.Empty); + var mp1 = new Pump("MP1", 200, 80); + var mp2 = new Pump("MP2", 50, 80); + + var x1 = new PipeJoin(200, 100); + var x2 = new PipeJoin(50, 100); + + var v1 = new Valve("V1", 200, 150, () => App.Plant?.IsValveOpen(1) ?? false, () => App.Plant?.WantValveOpen(1) ?? false); + var v2 = new Valve("V2", 50, 150, () => App.Plant?.IsValveOpen(2) ?? false, () => App.Plant?.WantValveOpen(2) ?? false); + var v3 = new Valve("V3", 80, 150, () => App.Plant?.IsValveOpen(3) ?? false, () => App.Plant?.WantValveOpen(3) ?? false); + var v4 = new Valve("V4", 170, 150, () => App.Plant?.IsValveOpen(4) ?? false, () => App.Plant?.WantValveOpen(4) ?? false); + + graph.CreatePipe(mw1, mp1); + graph.CreatePipe(mw2, mp2); + graph.CreatePipe(mp1, x1); + graph.CreatePipe(mp2, x2); + graph.CreatePipe(x1, v1); + graph.CreatePipe(x1, v4); + graph.CreatePipe(x2, v2); + graph.CreatePipe(x2, v3); + + graph.Draw(SchemeCanvas); + } + + public void OnUpdate(object? sender, PlantEventArgs evt) { + if (sender is not PamhagenPlant plant) return; + + + } + } +}