diff --git a/Installer/Files/config.ini b/Installer/Files/config.ini index 41bb4c4..32a31fd 100644 --- a/Installer/Files/config.ini +++ b/Installer/Files/config.ini @@ -5,3 +5,29 @@ port = COM1 [update] url = https://elwig.at/files/pamhagen-sysctrl/latest auto = true + +[xbe24] +a1 = PATH_MW2_PRESS1 +a2 = PATH_MW2_PRESS2 +a3 = PATH_MW2_T1 +a4 = PATH_MW2_T2 +a5 = PATH_MW2_T3 +a6 = PATH_MW2_T4 +b1 = START_REBLER +b2 = STOP_REBLER +b3 = SELECT_MW2 +b4 = TOGGLE_STIRRER_MW2 +b5 = START_MP2 +b6 = STOP_MP2 +c1 = START_TROUGH_AUGER +c2 = STOP_TROUGH_AUGER +c3 = SELECT_MW1 +c4 = TOGGLE_STIRRER_MW1 +c5 = START_MP1 +c6 = STOP_MP2 +d1 = PATH_MW1_PRESS1 +d2 = PATH_MW1_PRESS2 +d3 = PATH_MW1_T1 +d4 = PATH_MW1_T2 +d5 = PATH_MW1_T3 +d6 = PATH_MW1_T4 diff --git a/PamhagenSysCtrl/App.xaml.cs b/PamhagenSysCtrl/App.xaml.cs index 4664813..5ab7288 100644 --- a/PamhagenSysCtrl/App.xaml.cs +++ b/PamhagenSysCtrl/App.xaml.cs @@ -34,6 +34,9 @@ namespace PamhagenSysCtrl { } protected override async void OnStartup(StartupEventArgs evt) { + if (Config == null) + return; + Version = new Version(typeof(App).GetTypeInfo().Assembly.GetCustomAttribute()?.InformationalVersion.Split('+')[0] ?? "0.0.0"); Plant = new(Config.PlcPort); diff --git a/PamhagenSysCtrl/Helpers/Config.cs b/PamhagenSysCtrl/Helpers/Config.cs index 6771f8d..8764a99 100644 --- a/PamhagenSysCtrl/Helpers/Config.cs +++ b/PamhagenSysCtrl/Helpers/Config.cs @@ -12,8 +12,11 @@ namespace PamhagenSysCtrl.Helpers { public string? UpdateUrl; public bool UpdateAuto; + public PamhagenPlant.ShortcutKey?[] Xbe24KeyMap; + public Config(string filename) { FileName = filename; + Xbe24KeyMap = new PamhagenPlant.ShortcutKey?[24]; Read(); } @@ -23,10 +26,26 @@ namespace PamhagenSysCtrl.Helpers { PlcPort = config["plc:port"] ?? "COM1"; UpdateUrl = config["update:url"]; UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower()); + var xbe24 = config.GetSection("xbe24"); + for (char c = 'a'; c <= 'd'; c++) { + for (int r = 1; r <= 6; r++) { + int n = (c - 'a') * 6 + r - 1; + var s = xbe24[$"{c}{r}"]?.ToUpper(); + Xbe24KeyMap[n] = s == null ? null : Enum.Parse(s); + } + } } catch (Exception exc) { MessageBox.Show($"Die Konfigurationsdatei konnte nicht gelesen werden:\n\n{exc.Message}", "Konfigurationsdatei lesen", MessageBoxButton.OK, MessageBoxImage.Error); Application.Current.Shutdown(); } } + + public PamhagenPlant.ShortcutKey? MapKey(int n) { + return n < 0 || Xbe24KeyMap.Length < n ? null : Xbe24KeyMap[n]; + } + + public int? MapKey(PamhagenPlant.ShortcutKey key) { + return Xbe24KeyMap.IndexOf(key) is int n ? n == -1 ? null : n : null; + } } } diff --git a/PamhagenSysCtrl/Helpers/Extensions.cs b/PamhagenSysCtrl/Helpers/Extensions.cs new file mode 100644 index 0000000..11dafea --- /dev/null +++ b/PamhagenSysCtrl/Helpers/Extensions.cs @@ -0,0 +1,15 @@ +using System.Windows.Media; + +namespace PamhagenSysCtrl.Helpers { + public static class Extensions { + + public static void SetBacklight(this Xbe24Keyboard k, PamhagenPlant.ShortcutKey key, Color color, bool flashing = false) { + if (App.Config.MapKey(key) is int n) + k.SetBacklight(n, color, flashing); + } + + public static bool IsKeyPressed(this Xbe24Keyboard k, PamhagenPlant.ShortcutKey key) { + return App.Config.MapKey(key) is int n && k.IsKeyPressed(n); + } + } +} diff --git a/PamhagenSysCtrl/Helpers/PamhagenGraph.cs b/PamhagenSysCtrl/Helpers/PamhagenGraph.cs index 49274d3..97c334c 100644 --- a/PamhagenSysCtrl/Helpers/PamhagenGraph.cs +++ b/PamhagenSysCtrl/Helpers/PamhagenGraph.cs @@ -29,6 +29,12 @@ namespace PamhagenSysCtrl.Helpers { public readonly Tank Tank7; public readonly Tank Tank8; public readonly Tank Tank9; + public readonly Valve V5; + public readonly Valve V6; + public readonly Valve V7; + public readonly Valve V8; + + public readonly Dictionary PathShortcuts; public PamhagenGraph() { double mw2X = -118; @@ -116,23 +122,23 @@ namespace PamhagenSysCtrl.Helpers { CreatePipe(v4, x5, true); CreatePipe(x5, x6, true); - var v5 = CreateValve(5, x1X + 6, ltg1Y, 1); - var v6 = CreateValve(6, x1X + 6, ltg2Y + 8, 3); - var v7 = CreateValve(7, x1X + 6, ltg2Y, 3); - var v8 = CreateValve(8, x1X - 6, ltg2Y + 8, 0); + V5 = CreateValve(5, x1X + 6, ltg1Y, 1); + V6 = CreateValve(6, x1X + 6, ltg2Y + 8, 3); + V7 = CreateValve(7, x1X + 6, ltg2Y, 3); + V8 = CreateValve(8, x1X - 6, ltg2Y + 8, 0); var v9 = CreateValve(9, ltg2X, ltg5Y + 8, 2); - CreatePipe(x4, v5); - CreatePipe(x4, v6, true); - CreatePipe(x6, v7); - CreatePipe(x6, v8); - CreatePipe(v7, v9, label: "Ltg. 2", labelOffsetX: 6); + CreatePipe(x4, V5); + CreatePipe(x4, V6, true); + CreatePipe(x6, V7); + CreatePipe(x6, V8); + CreatePipe(V7, v9, label: "Ltg. 2", labelOffsetX: 6); var xv15 = new PipeJoin(ltg1X, wt1Y + 8); var xv11 = new PipeJoin(ltg2X, wt1Y + 14); var x7 = new PipeJoin(ltg2X, ltg5Y); - CreatePipe(v5, xv15, label: "Ltg. 1", labelOffsetX: 6); + CreatePipe(V5, xv15, label: "Ltg. 1", labelOffsetX: 6); CreatePipe(v9, x7); CreatePipe(x7, xv11); @@ -380,8 +386,8 @@ namespace PamhagenSysCtrl.Helpers { var xp7 = new PipeJoin(pr2cX, ltg8Y); var xp8 = new PipeJoin(pr2cX, ltg9Y); - CreatePipe(v6, xp1, true, label: "Ltg. 3", labelOffsetX: 6); - CreatePipe(v8, xp2, true, label: "Ltg. 4", labelOffsetX: 18); + CreatePipe(V6, xp1, true, label: "Ltg. 3", labelOffsetX: 6); + CreatePipe(V8, xp2, true, label: "Ltg. 4", labelOffsetX: 18); CreatePipe(v49, xp3, true, label: "Ltg. 8"); CreatePipe(P6, xp4, true, label: "Ltg. 9"); CreatePipe(xp1, v51, true); @@ -410,6 +416,75 @@ namespace PamhagenSysCtrl.Helpers { CreatePipe(xp8, zv2, true); CreateInlet(zv1, Press1, true); CreateInlet(zv2, Press2, true); + + PathShortcuts = []; + foreach (var key in Enum.GetValues()) { + var n = Enum.GetName(key); + if (n?.StartsWith("PATH_") != true) continue; + ISource src; + Pump p; + INode? inter = null; + ISink sink; + if (n.StartsWith("PATH_MW1_")) { + src = MW1; + p = MP1; + } else if (n.StartsWith("PATH_MW2_")) { + src = MW2; + p = MP2; + } else if (n.StartsWith("PATH_T12_")) { + src = Tank1; + p = P12; + } else if (n.StartsWith("PATH_T3_")) { + src = Tank3; + p = P3; + } else if (n.StartsWith("PATH_T4_")) { + src = Tank4; + p = P4; + } else if (n.StartsWith("PATH_T5_")) { + src = Tank5; + p = P5; + } else if (n.StartsWith("PATH_P6_")) { + src = Tank6; + p = P6; + } else { + continue; + } + if (n.Contains("_LTG1_")) { + inter = V5; + } else if (n.Contains("_LTG2_")) { + inter = V7; + } else if (n.Contains("_LTG3_")) { + inter = V6; + } else if (n.Contains("_LTG4_")) { + inter = V8; + } + if (n.EndsWith("_PRESS1")) { + sink = Press1; + } else if (n.EndsWith("_PRESS2")) { + sink = Press2; + } else if (n.EndsWith("_T1")) { + sink = Tank1; + } else if (n.EndsWith("_T2")) { + sink = Tank2; + } else if (n.EndsWith("_T3")) { + sink = Tank3; + } else if (n.EndsWith("_T4")) { + sink = Tank4; + } else if (n.EndsWith("_T5")) { + sink = Tank5; + } else if (n.EndsWith("_T6")) { + sink = Tank6; + } else if (n.EndsWith("_T7")) { + sink = Tank7; + } else if (n.EndsWith("_T8")) { + sink = Tank8; + } else if (n.EndsWith("_T9")) { + sink = Tank9; + } else { + continue; + } + PathShortcuts[key] = (src, p, inter, sink); + } } protected ControlledValve CreateValve(int n, double x, double y, int o) { diff --git a/PamhagenSysCtrl/Helpers/PamhagenPlant.cs b/PamhagenSysCtrl/Helpers/PamhagenPlant.cs index 15b3260..8ff7014 100644 --- a/PamhagenSysCtrl/Helpers/PamhagenPlant.cs +++ b/PamhagenSysCtrl/Helpers/PamhagenPlant.cs @@ -7,25 +7,56 @@ using System.Windows.Media; namespace PamhagenSysCtrl.Helpers { public class PamhagenPlant : IDisposable { - public enum Xbe24Key { - START_REBLER = 6, STOP_REBLER = 7, - START_TROUGH_AUGER = 12, STOP_TROUGH_AUGER = 13, - SELECT_MW1 = 14, SELECT_MW2 = 8, - STIRRER_MW1 = 15, STIRRER_MW2 = 9, - START_MP1 = 16, STOP_MP1 = 17, - START_MP2 = 10, STOP_MP2 = 11, - FAST_SELECT_MW1_1 = 18, - FAST_SELECT_MW1_2 = 19, - FAST_SELECT_MW1_3 = 20, - FAST_SELECT_MW1_4 = 21, - FAST_SELECT_MW1_5 = 22, - FAST_SELECT_MW1_6 = 23, - FAST_SELECT_MW2_1 = 0, - FAST_SELECT_MW2_2 = 1, - FAST_SELECT_MW2_3 = 2, - FAST_SELECT_MW2_4 = 3, - FAST_SELECT_MW2_5 = 4, - FAST_SELECT_MW2_6 = 5, + public enum ShortcutKey { + START_REBLER, STOP_REBLER, TOGGLE_REBLER, INDICATE_REBLER, + START_WASTE_DISPOSAL, STOP_WASTE_DISPOSAL, TOGGLE_WASTE_DISPOSAL, INDICATE_WASTE_DISPOSAL, + START_AUGER1, STOP_AUGER1, TOGGLE_AUGER1, INDICATE_AUGER1, + START_AUGER2, STOP_AUGER2, TOGGLE_AUGER2, INDICATE_AUGER2, + START_AUGER3, STOP_AUGER3, TOGGLE_AUGER3, INDICATE_AUGER3, + INDICATE_PRESS_CROSS_AUGER, + START_TROUGH_AUGER, STOP_TROUGH_AUGER, TOGGLE_TROUGH_AUGER, INDICATE_TROUGH_AUGER, + SELECT_MW1, INDICATE_MW1_SELECTED, + SELECT_MW2, INDICATE_MW2_SELECTED, + INDICATE_MW1, INDICATE_MW1_EMPTY, INDICATE_MW1_FILLED, INDICATE_MW1_HALF, INDICATE_MW1_FULL, + INDICATE_MW2, INDICATE_MW2_EMPTY, INDICATE_MW2_FILLED, INDICATE_MW2_HALF, INDICATE_MW2_FULL, + START_STIRRER_MW1, STOP_STIRRER_MW1, TOGGLE_STIRRER_MW1, INDICATE_STIRRER_MW1, + START_STIRRER_MW2, STOP_STIRRER_MW2, TOGGLE_STIRRER_MW2, INDICATE_STIRRER_MW2, + START_MP1, STOP_MP1, TOGGLE_MP1, INDICATE_MP1, + START_MP2, STOP_MP2, TOGGLE_MP2, INDICATE_MP2, + ENABLE_P12, DISABLE_P12, TOGGLE_P12, INDICATE_P12, + ENABLE_P3, DISABLE_P3, TOGGLE_P3, INDICATE_P3, + ENABLE_P4, DISABLE_P4, TOGGLE_P4, INDICATE_P4, + ENABLE_P5, DISABLE_P5, TOGGLE_P5, INDICATE_P5, + ENABLE_P6, DISABLE_P6, TOGGLE_P6, INDICATE_P6, + INDICATE_PRESS1_CLEARANCE, + INDICATE_PRESS2_CLEARANCE, + PATH_MW1_PRESS1, PATH_MW1_LTG3_PRESS1, PATH_MW1_LTG4_PRESS1, + PATH_MW1_PRESS2, PATH_MW1_LTG3_PRESS2, PATH_MW1_LTG4_PRESS2, + PATH_MW1_T1, PATH_MW1_LTG1_T1, PATH_MW1_LTG2_T1, + PATH_MW1_T2, PATH_MW1_LTG1_T2, PATH_MW1_LTG2_T2, + PATH_MW1_T3, PATH_MW1_LTG1_T3, PATH_MW1_LTG2_T3, + PATH_MW1_T4, PATH_MW1_LTG1_T4, PATH_MW1_LTG2_T4, + PATH_MW1_T5, PATH_MW1_LTG1_T5, PATH_MW1_LTG2_T5, + PATH_MW1_T6, PATH_MW1_LTG1_T6, PATH_MW1_LTG2_T6, + PATH_MW1_T7, PATH_MW1_LTG1_T7, PATH_MW1_LTG2_T7, + PATH_MW1_T8, PATH_MW1_LTG1_T8, PATH_MW1_LTG2_T8, + PATH_MW1_T9, PATH_MW1_LTG1_T9, PATH_MW1_LTG2_T9, + PATH_MW2_PRESS1, PATH_MW2_LTG3_PRESS1, PATH_MW2_LTG4_PRESS1, + PATH_MW2_PRESS2, PATH_MW2_LTG3_PRESS2, PATH_MW2_LTG4_PRESS2, + PATH_MW2_T1, PATH_MW2_LTG1_T1, PATH_MW2_LTG2_T1, + PATH_MW2_T2, PATH_MW2_LTG1_T2, PATH_MW2_LTG2_T2, + PATH_MW2_T3, PATH_MW2_LTG1_T3, PATH_MW2_LTG2_T3, + PATH_MW2_T4, PATH_MW2_LTG1_T4, PATH_MW2_LTG2_T4, + PATH_MW2_T5, PATH_MW2_LTG1_T5, PATH_MW2_LTG2_T5, + PATH_MW2_T6, PATH_MW2_LTG1_T6, PATH_MW2_LTG2_T6, + PATH_MW2_T7, PATH_MW2_LTG1_T7, PATH_MW2_LTG2_T7, + PATH_MW2_T8, PATH_MW2_LTG1_T8, PATH_MW2_LTG2_T8, + PATH_MW2_T9, PATH_MW2_LTG1_T9, PATH_MW2_LTG2_T9, + PATH_T12_PRESS1, PATH_T12_PRESS2, PATH_T12_T1, PATH_T12_T2, PATH_T12_T3, PATH_T12_T4, PATH_T12_T5, PATH_T12_T6, PATH_T12_T7, PATH_T12_T8, PATH_T12_T9, + PATH_T3_PRESS1, PATH_T3_PRESS2, PATH_T3_T1, PATH_T3_T2, PATH_T3_T3, PATH_T3_T4, PATH_T3_T5, PATH_T3_T6, PATH_T3_T7, PATH_T3_T8, PATH_T3_T9, + PATH_T4_PRESS1, PATH_T4_PRESS2, PATH_T4_T1, PATH_T4_T2, PATH_T4_T3, PATH_T4_T4, PATH_T4_T5, PATH_T4_T6, PATH_T4_T7, PATH_T4_T8, PATH_T4_T9, + PATH_T5_PRESS1, PATH_T5_PRESS2, PATH_T5_T1, PATH_T5_T2, PATH_T5_T3, PATH_T5_T4, PATH_T5_T5, PATH_T5_T6, PATH_T5_T7, PATH_T5_T8, PATH_T5_T9, + PATH_P6_PRESS1, PATH_P6_PRESS2, } protected PamhagenPlc? Plc; @@ -114,61 +145,65 @@ namespace PamhagenSysCtrl.Helpers { protected void UpdateKeyboardBacklights(object? sender, PlantEventArgs evt) { if (sender is not PamhagenPlant plant || plant.Keyboard is not Xbe24Keyboard k) return; - k.SetBacklight((int)Xbe24Key.START_REBLER, State.Rebler_IsActive ? Color.FromRgb(0, 255, 0) : State.Auger1_IsActive ? Color.FromRgb(255, 255, 0) : State.WasteDisposal_IsActive ? Color.FromRgb(32, 32, 4) : Color.FromRgb(4, 32, 4)); - k.SetBacklight((int)Xbe24Key.STOP_REBLER, !State.Rebler_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); + // TODO update all keys - k.SetBacklight((int)Xbe24Key.START_TROUGH_AUGER, !State.TroughAuger_HasClearance ? k.IsKeyPressed((int)Xbe24Key.START_TROUGH_AUGER) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.TroughAuger_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); - k.SetBacklight((int)Xbe24Key.STOP_TROUGH_AUGER, !State.TroughAuger_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); + k.SetBacklight(ShortcutKey.START_REBLER, State.Rebler_IsActive ? Color.FromRgb(0, 255, 0) : State.Auger1_IsActive ? Color.FromRgb(255, 255, 0) : State.WasteDisposal_IsActive ? Color.FromRgb(32, 32, 4) : Color.FromRgb(4, 32, 4)); + k.SetBacklight(ShortcutKey.STOP_REBLER, !State.Rebler_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); - k.SetBacklight((int)Xbe24Key.SELECT_MW2, State.MW2_WantSelected || State.MW2_IsSelected ? Color.FromRgb(0, 0, 255) : Color.FromRgb(4, 4, 16), State.MW2_WantSelected && !State.MW2_IsSelected); - k.SetBacklight((int)Xbe24Key.SELECT_MW1, State.MW1_WantSelected || State.MW1_IsSelected ? Color.FromRgb(0, 0, 255) : Color.FromRgb(4, 4, 16), State.MW1_WantSelected && !State.MW1_IsSelected); + k.SetBacklight(ShortcutKey.START_TROUGH_AUGER, !State.TroughAuger_HasClearance ? k.IsKeyPressed(ShortcutKey.START_TROUGH_AUGER) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.TroughAuger_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); + k.SetBacklight(ShortcutKey.STOP_TROUGH_AUGER, !State.TroughAuger_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); - var buttons = new Dictionary { - [Xbe24Key.FAST_SELECT_MW1_1] = (Graph.MW1, Graph.MP1, Graph.Press1), - [Xbe24Key.FAST_SELECT_MW2_1] = (Graph.MW2, Graph.MP2, Graph.Press1), - [Xbe24Key.FAST_SELECT_MW1_2] = (Graph.MW1, Graph.MP1, Graph.Press2), - [Xbe24Key.FAST_SELECT_MW2_2] = (Graph.MW2, Graph.MP2, Graph.Press2), - [Xbe24Key.FAST_SELECT_MW1_3] = (Graph.MW1, Graph.MP1, Graph.Tank1), - [Xbe24Key.FAST_SELECT_MW2_3] = (Graph.MW2, Graph.MP2, Graph.Tank1), - [Xbe24Key.FAST_SELECT_MW1_4] = (Graph.MW1, Graph.MP1, Graph.Tank2), - [Xbe24Key.FAST_SELECT_MW2_4] = (Graph.MW2, Graph.MP2, Graph.Tank2), - [Xbe24Key.FAST_SELECT_MW1_5] = (Graph.MW1, Graph.MP1, Graph.Tank3), - [Xbe24Key.FAST_SELECT_MW2_5] = (Graph.MW2, Graph.MP2, Graph.Tank3), - [Xbe24Key.FAST_SELECT_MW1_6] = (Graph.MW1, Graph.MP1, Graph.Tank4), - [Xbe24Key.FAST_SELECT_MW2_6] = (Graph.MW2, Graph.MP2, Graph.Tank4), - }; + k.SetBacklight(ShortcutKey.SELECT_MW2, State.MW2_WantSelected || State.MW2_IsSelected ? Color.FromRgb(0, 0, 255) : Color.FromRgb(4, 4, 16), State.MW2_WantSelected && !State.MW2_IsSelected); + k.SetBacklight(ShortcutKey.SELECT_MW1, State.MW1_WantSelected || State.MW1_IsSelected ? Color.FromRgb(0, 0, 255) : Color.FromRgb(4, 4, 16), State.MW1_WantSelected && !State.MW1_IsSelected); - bool preparingMP1 = false, preparingMP2 = false; - bool highlightOffMP1 = false, highlightOffMP2 = false; - foreach (var (idx, d) in buttons) { + bool prepMP1 = false, prepMP2 = false, prepP12 = false, prepP3 = false, prepP4 = false, prepP5 = false, prepP6 = false; + bool hiOffMP1 = false, hiOffMP2 = false, hiOffP12 = false, hiOffP3 = false, hiOffP4 = false, hiOffP5 = false, hiOffP6 = false; + foreach (var (key, d) in Graph.PathShortcuts) { + if (App.Config.MapKey(key) is not int idx) + continue; var isRunning = d.Pump.IsActive; + // TODO consider intermediate if (plant.Graph.SelectedPaths.Select(p => (Pipeline.Path?)p).FirstOrDefault(p => p?.Start == d.Source && p?.Hops.Last().Node == d.Sink) is Pipeline.Path path) { - // TODO + // TODO also account for valves guarding path var isReady = path.Hops.All(h => h.Node is not ControlledValve v || v.IsOpen == v.WantOpen); - if (!isReady && d.Pump == Graph.MP1) preparingMP1 = true; - if (!isReady && d.Pump == Graph.MP2) preparingMP2 = true; + if (!isReady) { + if (d.Pump == Graph.MP1) prepMP1 = true; + if (d.Pump == Graph.MP2) prepMP2 = true; + if (d.Pump == Graph.P12) prepP12 = true; + if (d.Pump == Graph.P3) prepP3 = true; + if (d.Pump == Graph.P4) prepP4 = true; + if (d.Pump == Graph.P5) prepP5 = true; + if (d.Pump == Graph.P6) prepP6 = true; + } var isDefault = !path.Hops.SkipLast(1).Any(h => h.Node is not Valve && h.Node is not PipeJoin && h.Node is not Pump); - k.SetBacklight((int)idx, isRunning ? isDefault ? Color.FromRgb(0, 255, 255) : Color.FromRgb(255, 64, 255) : isDefault ? Color.FromRgb(0, 0, 255) : Color.FromRgb(128, 0, 128), !isReady); + k.SetBacklight(idx, isRunning ? isDefault ? Color.FromRgb(0, 255, 255) : Color.FromRgb(255, 64, 255) : isDefault ? Color.FromRgb(0, 0, 255) : Color.FromRgb(128, 0, 128), !isReady); } else { var isFree = Graph.GetFreePath([d.Source, d.Sink], overrideStart: true) != null; - if (isRunning && k.IsKeyPressed((int)idx) && d.Pump == Graph.MP1) highlightOffMP1 = true; - if (isRunning && k.IsKeyPressed((int)idx) && d.Pump == Graph.MP2) highlightOffMP2 = true; - k.SetBacklight((int)idx, isRunning ? k.IsKeyPressed((int)idx) ? Color.FromRgb(255, 16, 0) : Color.FromRgb(4, 4, 4) : isFree ? Color.FromRgb(8, 8, 32) : k.IsKeyPressed((int)idx) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(4, 4, 4)); + if (isRunning && k.IsKeyPressed(idx)) { + if (d.Pump == Graph.MP1) hiOffMP1 = true; + if (d.Pump == Graph.MP2) hiOffMP2 = true; + if (d.Pump == Graph.P12) hiOffP12 = true; + if (d.Pump == Graph.P3) hiOffP3 = true; + if (d.Pump == Graph.P4) hiOffP4 = true; + if (d.Pump == Graph.P5) hiOffP5 = true; + if (d.Pump == Graph.P6) hiOffP6 = true; + } + k.SetBacklight(idx, isRunning ? k.IsKeyPressed(idx) ? Color.FromRgb(255, 16, 0) : Color.FromRgb(4, 4, 4) : isFree ? Color.FromRgb(8, 8, 32) : k.IsKeyPressed(idx) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(4, 4, 4)); } } - if (!plant.State.MP2_HasPathClearance && plant.State.MP2_HasDryRunClearance && preparingMP2) { - k.SetBacklight((int)Xbe24Key.START_MP2, Color.FromRgb(4, 32, 4), true); + if (!plant.State.MP2_HasPathClearance && plant.State.MP2_HasDryRunClearance && prepMP2) { + k.SetBacklight(ShortcutKey.START_MP2, Color.FromRgb(4, 32, 4), true); } else { - k.SetBacklight((int)Xbe24Key.START_MP2, !State.MP2_HasClearance ? k.IsKeyPressed((int)Xbe24Key.START_MP2) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.MP2_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); + k.SetBacklight(ShortcutKey.START_MP2, !State.MP2_HasClearance ? k.IsKeyPressed(ShortcutKey.START_MP2) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.MP2_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); } - if (!plant.State.MP1_HasPathClearance && plant.State.MP1_HasDryRunClearance && preparingMP1) { - k.SetBacklight((int)Xbe24Key.START_MP1, Color.FromRgb(4, 32, 4), true); + if (!plant.State.MP1_HasPathClearance && plant.State.MP1_HasDryRunClearance && prepMP1) { + k.SetBacklight(ShortcutKey.START_MP1, Color.FromRgb(4, 32, 4), true); } else { - k.SetBacklight((int)Xbe24Key.START_MP1, !State.MP1_HasClearance ? k.IsKeyPressed((int)Xbe24Key.START_MP1) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.MP1_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); + k.SetBacklight(ShortcutKey.START_MP1, !State.MP1_HasClearance ? k.IsKeyPressed(ShortcutKey.START_MP1) ? Color.FromRgb(255, 32, 0) : Color.FromRgb(32, 4, 4) : State.MP1_IsActive ? Color.FromRgb(0, 255, 0) : Color.FromRgb(4, 32, 4)); } - k.SetBacklight((int)Xbe24Key.STOP_MP2, highlightOffMP2 ? Color.FromRgb(255, 32, 0) : !State.MP2_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); - k.SetBacklight((int)Xbe24Key.STOP_MP1, highlightOffMP1 ? Color.FromRgb(255, 32, 0) : !State.MP1_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); + k.SetBacklight(ShortcutKey.STOP_MP2, hiOffMP2 ? Color.FromRgb(255, 32, 0) : !State.MP2_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); + k.SetBacklight(ShortcutKey.STOP_MP1, hiOffMP1 ? Color.FromRgb(255, 32, 0) : !State.MP1_IsActive ? Color.FromRgb(255, 0, 0) : Color.FromRgb(32, 4, 4)); } public void Dispose() { @@ -241,26 +276,25 @@ namespace PamhagenSysCtrl.Helpers { } } - public void FastSelect(ISource source, ISink sink) { + public void FastSelect(ISource source, INode? intermediate, ISink sink) { if (Graph.SelectedPaths.Select(p => (Pipeline.Path?)p).FirstOrDefault(p => p?.Start == source, null) is Pipeline.Path p1) { if (p1.Hops.Any(h => h.Node is Pump p && p.IsActive)) throw new NoClearanceException("Pumpe aktiv"); Graph.RemovePath(p1); - if (p1.Hops.Last().Node == sink) + if (p1.Hops.Last().Node == sink && (intermediate == null || p1.Hops.Any(h => h.Node == intermediate))) return; } - if (Graph.GetFreePath([source, sink]) is Pipeline.Path p2) { + if (Graph.GetFreePath(intermediate == null ? [source, sink] : [source, intermediate, sink]) is Pipeline.Path p2) { Graph.AddPath(p2); } } private void Keyboard_KeyDown(object? sender, int keyIndex) { - if (Plc == null) return; - var key = (Xbe24Key)keyIndex; + if (Plc == null || App.Config.MapKey(keyIndex) is not ShortcutKey key) return; try { - if (key == Xbe24Key.START_REBLER) { + if (key == ShortcutKey.START_REBLER) { Plc.StartRebler(); - } else if (key == Xbe24Key.STOP_REBLER) { + } else if (key == ShortcutKey.STOP_REBLER) { if (State.Rebler_IsActive) { Plc.StopRebler(); } else { @@ -270,47 +304,28 @@ namespace PamhagenSysCtrl.Helpers { Plc.StopAuger3(); } } - } else if (key == Xbe24Key.START_TROUGH_AUGER) { + } else if (key == ShortcutKey.START_TROUGH_AUGER) { Plc.StartTroughAuger(); - } else if (key == Xbe24Key.STOP_TROUGH_AUGER) { + } else if (key == ShortcutKey.STOP_TROUGH_AUGER) { Plc.StopTroughAuger(); - } else if (key == Xbe24Key.SELECT_MW2) { + } else if (key == ShortcutKey.SELECT_MW2) { Plc.SelectMW2(); - } else if (key == Xbe24Key.SELECT_MW1) { + } else if (key == ShortcutKey.SELECT_MW1) { Plc.SelectMW1(); - } else if (key == Xbe24Key.START_MP2) { + } else if (key == ShortcutKey.START_MP2) { Plc.StartMP2Forward(); - } else if (key == Xbe24Key.STOP_MP2) { + } else if (key == ShortcutKey.STOP_MP2) { Plc.StopMP2(); - } else if (key == Xbe24Key.START_MP1) { + } else if (key == ShortcutKey.START_MP1) { Plc.StartMP1Forward(); - } else if (key == Xbe24Key.STOP_MP1) { + } else if (key == ShortcutKey.STOP_MP1) { Plc.StopMP1(); - } else if (key == Xbe24Key.FAST_SELECT_MW1_1) { - FastSelect(Graph.MW1, Graph.Press1); - } else if (key == Xbe24Key.FAST_SELECT_MW1_2) { - FastSelect(Graph.MW1, Graph.Press2); - } else if (key == Xbe24Key.FAST_SELECT_MW1_3) { - FastSelect(Graph.MW1, Graph.Tank1); - } else if (key == Xbe24Key.FAST_SELECT_MW1_4) { - FastSelect(Graph.MW1, Graph.Tank2); - } else if (key == Xbe24Key.FAST_SELECT_MW1_5) { - FastSelect(Graph.MW1, Graph.Tank3); - } else if (key == Xbe24Key.FAST_SELECT_MW1_6) { - FastSelect(Graph.MW1, Graph.Tank4); - } else if (key == Xbe24Key.FAST_SELECT_MW2_1) { - FastSelect(Graph.MW2, Graph.Press1); - } else if (key == Xbe24Key.FAST_SELECT_MW2_2) { - FastSelect(Graph.MW2, Graph.Press2); - } else if (key == Xbe24Key.FAST_SELECT_MW2_3) { - FastSelect(Graph.MW2, Graph.Tank1); - } else if (key == Xbe24Key.FAST_SELECT_MW2_4) { - FastSelect(Graph.MW2, Graph.Tank2); - } else if (key == Xbe24Key.FAST_SELECT_MW2_5) { - FastSelect(Graph.MW2, Graph.Tank3); - } else if (key == Xbe24Key.FAST_SELECT_MW2_6) { - FastSelect(Graph.MW2, Graph.Tank4); + } else if (Graph.PathShortcuts.TryGetValue(key, out var path)) { + FastSelect(path.Source, path.Intermediate, path.Sink); + } else { + return; } + RaiseUpdateEvent(new()); } catch (NoClearanceException) { // Keyboard?.SetBacklight(keyIndex, Color.FromRgb(255, 0, 0)); } catch (Exception) { @@ -319,7 +334,7 @@ namespace PamhagenSysCtrl.Helpers { } private void Keyboard_KeysChanged(object? sender, Xbe24Keyboard.KeyState state) { - RaiseUpdateEvent(new()); + UpdateKeyboardBacklights(this, new()); } public void OpenV(int n) => Plc?.OpenV(n); diff --git a/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs index 6981deb..4e840e0 100644 --- a/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs +++ b/PamhagenSysCtrl/Windows/PlantSchemeWindow.xaml.cs @@ -216,7 +216,7 @@ namespace PamhagenSysCtrl.Windows { private void FastSelectButton_Click(object sender, RoutedEventArgs? evt) { if (sender is not Button b || !FastSelectPaths.TryGetValue(b, out var val)) return; - App.Plant?.FastSelect(val.Source, val.Sink); + App.Plant?.FastSelect(val.Source, null, val.Sink); OnUpdate(null, null); _lastSource = null; }