Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dee3a9ae9 | ||
|
|
4e82f164c9 | ||
|
|
77f9ae167c | ||
|
|
eb0ec60ed2 | ||
|
|
9d4ae11de8 |
@@ -1,3 +1,7 @@
|
||||
|
||||
[plc]
|
||||
port = COM1
|
||||
|
||||
[update]
|
||||
url = https://elwig.at/files/pamhagen-sysctrl/latest
|
||||
auto = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using PamhagenSysCtrl.Dialogs;
|
||||
using PamhagenSysCtrl.Helpers;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
@@ -10,6 +11,8 @@ namespace PamhagenSysCtrl {
|
||||
public static PamhagenPlant? Plant;
|
||||
public static Dispatcher? MainDispatcher;
|
||||
|
||||
private readonly DispatcherTimer AutoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) };
|
||||
|
||||
public static readonly string DataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Anlagensteuerung Pamhagen");
|
||||
public static readonly string ConfigPath = Path.Combine(DataPath, "config.ini");
|
||||
public static readonly string InstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Anlagensteuerung Pamhagen");
|
||||
@@ -45,6 +48,51 @@ namespace PamhagenSysCtrl {
|
||||
}
|
||||
|
||||
base.OnStartup(evt);
|
||||
|
||||
if (Config.UpdateUrl != null && Config.UpdateAuto) {
|
||||
AutoUpdateTimer.Tick += async (_, _) => {
|
||||
try {
|
||||
await CheckForUpdates();
|
||||
} catch { }
|
||||
};
|
||||
AutoUpdateTimer.Start();
|
||||
await Dispatcher.BeginInvoke(async () => {
|
||||
await Task.Delay(1500);
|
||||
try {
|
||||
await CheckForUpdates();
|
||||
} catch { }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task CheckForUpdates(bool showResult = false) {
|
||||
if (Config.UpdateUrl == null) return;
|
||||
|
||||
try {
|
||||
var latest = await UpdateService.GetLatestInstallerUrl(Config.UpdateUrl);
|
||||
if (latest.HasValue && new Version(latest.Value.Version) > Version) {
|
||||
var dialog = new UpdateDialog(latest.Value.Version, latest.Value.Url, latest.Value.Size) {
|
||||
Owner = Current.MainWindow,
|
||||
};
|
||||
if (dialog.ShowDialog() == true) {
|
||||
Current.Shutdown();
|
||||
}
|
||||
} else if (showResult) {
|
||||
MessageBox.Show($"Die Anlagensteuerung ist auf dem aktuellen Stand.\n(Version {Version})", "Nach Updates suchen", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
} catch (OperationCanceledException) {
|
||||
if (showResult) {
|
||||
MessageBox.Show("Zeitüberschreitung beim Abrufen der Update-Informationen.", "Nach Updates suchen", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
if (showResult) {
|
||||
MessageBox.Show($"Die Update-Informationen konnten nicht abgerufen werden:\n\n{exc.Message}", "Nach Updates suchen", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async void Application_Exit(object sender, ExitEventArgs evt) {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<Window x:Class="PamhagenSysCtrl.Dialogs.UpdateDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="Update verfügbar - Anlagensteuerung Pamhagen"
|
||||
Height="220" Width="480"
|
||||
Closed="OnClosed">
|
||||
<Grid Margin="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock x:Name="Description" FontSize="14" TextAlignment="Center"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
Version <Run x:Name="VersionText" FontWeight="Bold">0.0.0</Run> ist verfügbar.<LineBreak/>
|
||||
Soll das Update heruntergeladen und installiert werden?<LineBreak/>
|
||||
(ca. <Run x:Name="SizeText">0</Run> MB)<LineBreak/><LineBreak/>
|
||||
<Run FontWeight="Bold">Hinweis:</Run> Die Anlagensteuerung wird für die Installation geschlossen.
|
||||
</TextBlock>
|
||||
|
||||
<StackPanel x:Name="DownloadPanel" Grid.Row="0" VerticalAlignment="Center" Visibility="Collapsed">
|
||||
<TextBlock x:Name="StatusText" Text="Update wird heruntergeladen..."
|
||||
FontSize="14" TextAlignment="Center" Margin="0,0,0,10"/>
|
||||
<ProgressBar x:Name="DownloadProgress" Height="24" Minimum="0" Maximum="100"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,18,0,0">
|
||||
<Button x:Name="InstallButton" Content="Installieren" IsDefault="True"
|
||||
Width="110" Height="30" Margin="0,0,12,0" Click="InstallButton_Click"/>
|
||||
<Button x:Name="CancelButton" Content="Abbrechen" IsCancel="True"
|
||||
Width="110" Height="30"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,45 @@
|
||||
using PamhagenSysCtrl.Helpers;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace PamhagenSysCtrl.Dialogs {
|
||||
public partial class UpdateDialog : Window {
|
||||
|
||||
private readonly string Url;
|
||||
private readonly CancellationTokenSource Cancellation = new();
|
||||
|
||||
public UpdateDialog(string version, string url, long size) {
|
||||
Url = url;
|
||||
InitializeComponent();
|
||||
VersionText.Text = version;
|
||||
SizeText.Text = Math.Ceiling(size / 1024d / 1024d).ToString("N0");
|
||||
}
|
||||
|
||||
private void OnClosed(object? sender, EventArgs evt) {
|
||||
Cancellation.Cancel();
|
||||
Cancellation.Dispose();
|
||||
}
|
||||
|
||||
private async void InstallButton_Click(object sender, RoutedEventArgs evt) {
|
||||
Description.Visibility = Visibility.Collapsed;
|
||||
DownloadPanel.Visibility = Visibility.Visible;
|
||||
InstallButton.IsEnabled = false;
|
||||
|
||||
try {
|
||||
var progress = new Progress<double>(value => DownloadProgress.Value = value * 100);
|
||||
var filename = Path.Combine(App.TempPath, $"PamhagenSysCtrl-{VersionText.Text}.msi");
|
||||
await UpdateService.DownloadInstaller(Url, filename, progress, Cancellation.Token);
|
||||
StatusText.Text = "Installer wird gestartet...";
|
||||
UpdateService.StartInstaller(filename);
|
||||
DialogResult = true;
|
||||
} catch (OperationCanceledException) {
|
||||
// Closing the dialog cancels an active download.
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show($"Das Update konnte nicht installiert werden:\n\n{exc.Message}", "Update installieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Description.Visibility = Visibility.Visible;
|
||||
DownloadPanel.Visibility = Visibility.Collapsed;
|
||||
InstallButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
private readonly string FileName;
|
||||
|
||||
public string PlcPort = "COM1";
|
||||
public string? UpdateUrl;
|
||||
public bool UpdateAuto;
|
||||
|
||||
public Config(string filename) {
|
||||
FileName = filename;
|
||||
@@ -19,6 +21,8 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
try {
|
||||
var config = new ConfigurationBuilder().AddIniFile(FileName).Build();
|
||||
PlcPort = config["plc:port"] ?? "COM1";
|
||||
UpdateUrl = config["update:url"];
|
||||
UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower());
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show($"Die Konfigurationsdatei konnte nicht gelesen werden:\n\n{exc.Message}", "Konfigurationsdatei lesen", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Application.Current.Shutdown();
|
||||
|
||||
@@ -43,31 +43,28 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected static FillState Int3ToFillState(int n) {
|
||||
return n switch {
|
||||
7 => FillState.Full,
|
||||
6 => FillState.Half,
|
||||
4 => FillState.Filled,
|
||||
0 => FillState.Empty,
|
||||
_ => FillState.Invalid,
|
||||
};
|
||||
protected static FillState Int3ToFillState(int n, bool bigEndian = true) {
|
||||
return
|
||||
(bigEndian && (n & 0x4) != 0) || (!bigEndian && (n & 0x1) != 0) ? FillState.Full :
|
||||
(bigEndian && (n & 0x2) != 0) || (!bigEndian && (n & 0x2) != 0) ? FillState.Half :
|
||||
(bigEndian && (n & 0x1) != 0) || (!bigEndian && (n & 0x4) != 0) ? FillState.Filled :
|
||||
n == 0 ? FillState.Empty :
|
||||
FillState.Invalid;
|
||||
}
|
||||
|
||||
protected static FillState Int2ToFillState(int n) {
|
||||
return n switch {
|
||||
2 => FillState.Full,
|
||||
0 => FillState.Filled,
|
||||
1 => FillState.Empty,
|
||||
_ => FillState.Invalid,
|
||||
};
|
||||
protected static FillState Int2ToFillState(int n, bool bigEndian = true) {
|
||||
return
|
||||
(bigEndian && (n & 0x2) != 0) || (!bigEndian && (n & 0x1) != 0) ? FillState.Full :
|
||||
(bigEndian && (n & 0x1) != 0) || (!bigEndian && (n & 0x2) != 0) ? FillState.Filled :
|
||||
n == 0 ? FillState.Empty :
|
||||
FillState.Invalid;
|
||||
}
|
||||
|
||||
protected static FillState Int1ToFillState(int n) {
|
||||
return n switch {
|
||||
1 => FillState.Full,
|
||||
0 => FillState.Unknown,
|
||||
_ => FillState.Invalid,
|
||||
};
|
||||
return
|
||||
n == 1 ? FillState.Full :
|
||||
n == 0 ? FillState.Unknown :
|
||||
FillState.Invalid;
|
||||
}
|
||||
|
||||
protected static MotorState Int2ToPumpState(int n, bool inverse) {
|
||||
@@ -110,8 +107,8 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
long pressure = (long)r1 | ((long)r2 << 16) | ((long)r3 << 32) | ((long)r4 << 48);
|
||||
pressure = (pressure & 0x01FFFFFFFFFFFFFF) | ((pressure & 0x0600000000000000) << 1);
|
||||
|
||||
var mw1 = Int3ToFillState((f1 ) & 0x7); // 111 011 001 000
|
||||
var mw2 = Int3ToFillState((f1 >> 3) & 0x7); // 111 011 001 000
|
||||
var mw1 = Int3ToFillState((f1 ) & 0x7, false); // 111 011 001 000
|
||||
var mw2 = Int3ToFillState((f1 >> 3) & 0x7, false); // 111 011 001 000
|
||||
var p1 = ((f1 >> 6) & 0x1) == 0; // 1 0
|
||||
var p2 = ((f1 >> 7) & 0x1) == 0; // 1 0
|
||||
var wp = ((f1 >> 8) & 0x3); // 10 01
|
||||
@@ -129,11 +126,11 @@ namespace PamhagenSysCtrl.Helpers {
|
||||
// -> factor: 0,03125 + (offset) 25 Oe
|
||||
double oe = v * 0.03125 + 25;
|
||||
|
||||
var t1 = Int2ToFillState((f2 ) & 0x3); // 10 01 00
|
||||
var t2 = Int2ToFillState((f2 >> 2) & 0x3); // 10 01 00
|
||||
var t3 = Int2ToFillState((f2 >> 4) & 0x3); // 10 01 00
|
||||
var t4 = Int2ToFillState((f2 >> 6) & 0x3); // 10 01 00
|
||||
var t5 = Int2ToFillState((f2 >> 8) & 0x3); // 10 01 00
|
||||
var t1 = Int1ToFillState(((f2 ) & 0x3) >> 1); // 1X 0X
|
||||
var t2 = Int1ToFillState(((f2 >> 2) & 0x3) >> 1); // 1X 0X
|
||||
var t3 = Int1ToFillState(((f2 >> 4) & 0x3) >> 1); // 1X 0X
|
||||
var t4 = Int1ToFillState(((f2 >> 6) & 0x3) >> 1); // 1X 0X
|
||||
var t5 = Int1ToFillState(((f2 >> 8) & 0x3) >> 1); // 1X 0X
|
||||
var t6 = Int1ToFillState((f2 >> 10) & 0x1); // 1 0
|
||||
var t7 = Int1ToFillState((f2 >> 11) & 0x1); // 1 0
|
||||
var t8 = Int1ToFillState((f2 >> 12) & 0x1); // 1 0
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace PamhagenSysCtrl.Helpers {
|
||||
public static class UpdateService {
|
||||
|
||||
public static async Task<(string Version, string Url, long Size)?> GetLatestInstallerUrl(string feedUrl) {
|
||||
try {
|
||||
using var client = new HttpClient() {
|
||||
Timeout = TimeSpan.FromSeconds(5),
|
||||
};
|
||||
client.DefaultRequestHeaders.UserAgent.Clear();
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd($"PamhagenSysCtrl/{App.Version} ({Environment.MachineName}, {Environment.OSVersion})");
|
||||
client.DefaultRequestHeaders.Accept.Clear();
|
||||
client.DefaultRequestHeaders.Accept.Add(new("application/json"));
|
||||
using var res = await client.GetAsync(feedUrl);
|
||||
if (!res.IsSuccessStatusCode)
|
||||
return null;
|
||||
|
||||
var json = JsonNode.Parse(await res.Content.ReadAsStringAsync());
|
||||
var latest = json!["data"]!.AsArray()[^1]!;
|
||||
return ((string)latest["version"]!, (string)latest["url"]!, (long)latest["size"]!);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task DownloadInstaller(string url, string filename, IProgress<double>? progress = null, CancellationToken cancellationToken = default) {
|
||||
try {
|
||||
using var client = new HttpClient() {
|
||||
Timeout = TimeSpan.FromSeconds(5),
|
||||
};
|
||||
client.DefaultRequestHeaders.UserAgent.Clear();
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd($"PamhagenSysCtrl/{App.Version} ({Environment.MachineName}, {Environment.OSVersion})");
|
||||
client.DefaultRequestHeaders.Accept.Clear();
|
||||
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
|
||||
await using (var destination = new FileStream(filename, FileMode.Create)) {
|
||||
await using var source = await response.Content.ReadAsStreamAsync(cancellationToken);
|
||||
var buffer = new byte[81920];
|
||||
long downloaded = 0;
|
||||
int read;
|
||||
while ((read = await source.ReadAsync(buffer, cancellationToken)) != 0) {
|
||||
await destination.WriteAsync(buffer.AsMemory(0, read), cancellationToken);
|
||||
downloaded += read;
|
||||
if (contentLength.HasValue) {
|
||||
progress?.Report((double)downloaded / contentLength.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progress?.Report(1);
|
||||
} catch {
|
||||
File.Delete(filename);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static void StartInstaller(string fileName) {
|
||||
var startInfo = new ProcessStartInfo {
|
||||
FileName = "msiexec.exe",
|
||||
UseShellExecute = true,
|
||||
Verb = "runas",
|
||||
};
|
||||
startInfo.ArgumentList.Add("/i");
|
||||
startInfo.ArgumentList.Add(Path.GetFullPath(fileName));
|
||||
|
||||
if (Process.Start(startInfo) == null) {
|
||||
throw new InvalidOperationException("Der Installer konnte nicht gestartet werden.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<Window x:Class="PamhagenSysCtrl.Windows.AboutWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Über - Anlagensteuerung Pamhagen"
|
||||
Height="340" Width="560" ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Grid>
|
||||
<TextBlock Margin="20,10" FontSize="12">
|
||||
<Bold>Produkt:</Bold> Anlagensteuerung Pamhagen<LineBreak/>
|
||||
<Bold>Beschreibung:</Bold> Schnittstelle zu einer SPS und grafische Benutzeroberfläche für die<LineBreak/>
|
||||
<Bold Foreground="Transparent">Beschreibung:</Bold> Steuerung der Anlage<LineBreak/>
|
||||
<Bold>Typ:</Bold> HMI- und SPS-Steuerungssoftware<LineBreak/>
|
||||
<Bold>Version:</Bold> <Run x:Name="VersionText">0.0.0</Run><LineBreak/>
|
||||
<Bold>Lizenz:</Bold> <Hyperlink NavigateUri="https://www.gnu.org/licenses/gpl-3.0.html" RequestNavigate="Hyperlink_RequestNavigate">GNU General Public License 3.0 (GPLv3)</Hyperlink><LineBreak/>
|
||||
<Bold>Entwickler:</Bold> Lorenz Stechauner, Thomas Hilscher<LineBreak/>
|
||||
<Bold>Kontakt:</Bold> <Hyperlink NavigateUri="mailto:lorenz.stechauner@necronda.net" RequestNavigate="Hyperlink_RequestNavigate">lorenz.stechauner@necronda.net</Hyperlink>, <Hyperlink NavigateUri="mailto:thomas.hilscher@gmail.com" RequestNavigate="Hyperlink_RequestNavigate">thomas.hilscher@gmail.com</Hyperlink><LineBreak/>
|
||||
<Bold>Quellcode:</Bold> <Hyperlink NavigateUri="C:\Program Files\Anlagensteuerung Pamhagen\src" RequestNavigate="Hyperlink_RequestNavigate_Explorer">C:\Program Files\Anlagensteuerung Pamhagen\src</Hyperlink>,<LineBreak/>
|
||||
<Bold Foreground="Transparent">Quellcode:</Bold> <Hyperlink NavigateUri="https://git.necronda.net/winzer/pamhagen-sysctrl" RequestNavigate="Hyperlink_RequestNavigate">https://git.necronda.net/winzer/pamhagen-sysctrl</Hyperlink><LineBreak/>
|
||||
<Bold>Entwicklungszeitraum:</Bold> 2026<LineBreak/>
|
||||
<LineBreak/>
|
||||
<Bold>Verwendete Technologien:</Bold><LineBreak/>
|
||||
Programmiersprache: C#<LineBreak/>
|
||||
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
||||
SPS-Schnittstelle: Serielle Verbindung<LineBreak/>
|
||||
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
namespace PamhagenSysCtrl.Windows {
|
||||
public partial class AboutWindow : Window {
|
||||
|
||||
public AboutWindow() {
|
||||
InitializeComponent();
|
||||
VersionText.Text = App.Version.ToString();
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs evt) {
|
||||
try {
|
||||
Process.Start(new ProcessStartInfo(evt.Uri.AbsoluteUri) { UseShellExecute = true });
|
||||
} catch { }
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate_Explorer(object sender, RequestNavigateEventArgs evt) {
|
||||
try {
|
||||
Process.Start("explorer.exe", evt.Uri.AbsoluteUri);
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,11 +45,16 @@
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Hilfe">
|
||||
<MenuItem Header="Über">
|
||||
<MenuItem Header="Über" Click="Menu_Help_About_Click">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="Menu_Help_CheckForUpdates" Header="Nach Updates suchen..." Click="Menu_Help_CheckForUpdates_Click">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace PamhagenSysCtrl.Windows {
|
||||
|
||||
public PlantSchemeWindow() {
|
||||
InitializeComponent();
|
||||
Menu_Help_CheckForUpdates.IsEnabled = App.Config.UpdateUrl != null;
|
||||
Graph = new();
|
||||
Graph.Draw(SchemeCanvas);
|
||||
FastSelectPaths = new Dictionary<Button, (ISource, Pump, ISink)> {
|
||||
@@ -117,6 +118,17 @@ namespace PamhagenSysCtrl.Windows {
|
||||
} catch { }
|
||||
}
|
||||
|
||||
private async void Menu_Help_CheckForUpdates_Click(object sender, RoutedEventArgs evt) {
|
||||
await App.CheckForUpdates(true);
|
||||
}
|
||||
|
||||
private void Menu_Help_About_Click(object sender, RoutedEventArgs evt) {
|
||||
var window = new AboutWindow {
|
||||
Owner = this,
|
||||
};
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private void FastSelectButton_EntryTroughStart_Click(object sender, RoutedEventArgs evt) {
|
||||
try {
|
||||
App.Plant?.StartTroughAuger();
|
||||
|
||||
@@ -1,2 +1,42 @@
|
||||
|
||||
# Anlagensteuerung Pamhangen
|
||||
Anlagensteuerung Pamhagen
|
||||
=========================
|
||||
|
||||
Schnittstelle zur SPS und grafische Benutzeroberfläche.
|
||||
Winzerkeller Seewinkel, Pamhagen.
|
||||
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
**Product:** Anlagensteuerung Pamhagen
|
||||
**Description:** Interface to a LPC and graphical user interface for controlling the plant/system
|
||||
**Type:** HMI and PLC Control Software
|
||||
**Version:** 0.0.3 ([Changelog](./CHANGELOG.md))
|
||||
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Source code:** https://git.necronda.net/winzer/pamhagen-sysctrl
|
||||
**Developement period:** 2026
|
||||
|
||||
**Technology Stack:**
|
||||
Language: C#
|
||||
Framework: Windows Presentation Framework (WPF)
|
||||
LPC-Interface: Serial connection
|
||||
Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||
|
||||
|
||||
Über
|
||||
====
|
||||
|
||||
**Produkt:** Anlagensteuerung Pamhagen
|
||||
**Beschreibung:** Schnittstelle zu einer SPS und grafische Benutzeroberfläche für die Steuerung der Anlage
|
||||
**Typ:** HMI- und SPS-Steuerungssoftware
|
||||
**Version:** 0.0.3 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Quellcode:** https://git.necronda.net/winzer/pamhagen-sysctrl
|
||||
**Entwicklungszeitraum:** 2026
|
||||
|
||||
**Verwendete Technologien:**
|
||||
Programmiersprache: C#
|
||||
Framework: Windows Presentation Framework (WPF)
|
||||
SPS-Schnittstelle: Serielle Verbindung
|
||||
Paketierung: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||
|
||||
Reference in New Issue
Block a user