ProductionUiCordonel: - re-organized to support multiple production processes - final - picking can be implemented
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Windows;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.PickingProcesses;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
@@ -11,24 +13,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
private void Application_Startup(Object sender, StartupEventArgs e)
|
||||
{
|
||||
switch (ConfigurationManager.AppSettings[$"Mode"])
|
||||
switch (ConfigurationManager.AppSettings["Mode"])
|
||||
{
|
||||
case "1":
|
||||
|
||||
var mainWindow = new FinalTest();
|
||||
mainWindow.Show();
|
||||
var ProductionWindow = new ProductionWindow(
|
||||
ProductionUiCordonel.Properties.Resources.StrEolSoftwareNameVersion,
|
||||
"ProductionUiCordonel", new EolProcessStateDef());
|
||||
ProductionWindow.Show();
|
||||
break;
|
||||
case "2":
|
||||
var Picking = new Picking();
|
||||
Picking.Show();
|
||||
ProductionWindow = new ProductionWindow(
|
||||
ProductionUiCordonel.Properties.Resources.StrPickingSoftwareNameVersion,
|
||||
"PickingUiCordonel", new PickingProcessStateDef());
|
||||
ProductionWindow.Show();
|
||||
break;
|
||||
default:
|
||||
var mainWindowDef = new FinalTest();
|
||||
mainWindowDef.Show();
|
||||
ProductionWindow = new ProductionWindow(
|
||||
ProductionUiCordonel.Properties.Resources.StrEolSoftwareNameVersion,
|
||||
"ProductionUiCordonel", new EolProcessStateDef());
|
||||
ProductionWindow.Show();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
<Window x:Class="Xylem.Common.Production.ProductionUiCordonel.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:productionUiCordonel="clr-namespace:Xylem.Common.Production.ProductionUiCordonel"
|
||||
mc:Ignorable="d"
|
||||
Title="Cordonel Production UI" MinHeight="500" MinWidth="400" Height="600" Width="644" Initialized="Window_Initialized" Closing="Window_Closing">
|
||||
|
||||
<DockPanel HorizontalAlignment="Right" Width="634" Height="569" VerticalAlignment="Top" Margin="0,0,2,0">
|
||||
<ToolBarTray DockPanel.Dock="Top">
|
||||
<ToolBar>
|
||||
<Label>Slot:</Label>
|
||||
<ComboBox Name="cbxSlotBox" Margin="0,5,0,0" VerticalAlignment="Top" SelectionChanged="CbxSlotBox_SelectionChanged" />
|
||||
|
||||
|
||||
<Button Name="BtnConntect" VerticalAlignment="Top" Click="BtnConnect_Click" HorizontalAlignment="Right" ToolTip="Force connect to meter">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="/Resources/Connect_16x.png" />
|
||||
<TextBlock Margin="3,0,0,0">Connect</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
|
||||
</ToolBar>
|
||||
<ToolBar Name="tbarOrder">
|
||||
<Label>Order:</Label>
|
||||
<TextBox Name="txtOrderNr" HorizontalAlignment="Left" Height="26" IsEnabled="False" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="81" />
|
||||
|
||||
</ToolBar>
|
||||
<ToolBar>
|
||||
<Label>Autodetect:</Label>
|
||||
<Button Name="BtnSwitchAutoDetect" VerticalAlignment="Top" Click="BtnSwitchAutoDetect_Click" HorizontalAlignment="Right" >
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="/Resources/Refresh_16x.png" />
|
||||
<TextBlock Name="tblkAutodetectState" Text="Off" Margin="3,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="100" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="0">
|
||||
<Label Content="PcbID:"/>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="1">
|
||||
<Label Name="lblPcbID" Content="-"/>
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="2" />
|
||||
<StatusBarItem Grid.Column="3">
|
||||
<TextBlock Name="lblMessage" Text="Init" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="4" />
|
||||
<StatusBarItem Grid.Column="5">
|
||||
<Label x:Name="lblState" Content="" HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" />
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
|
||||
<StackPanel Background="#FFE5E5E5" SizeChanged="StackPanel_SizeChanged" Height="506" VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="625" >
|
||||
<productionUiCordonel:FinalTest x:Name="ucFinalRadioTest" Loaded="UcFinalRadioTest_Loaded" Width="Auto" VerticalAlignment="Top" HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
|
||||
</DockPanel>
|
||||
</Window>
|
||||
@@ -1,451 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Model;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
//public class QuantityToBackgroundConverter : IValueConverter
|
||||
//{
|
||||
// public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
// {
|
||||
// var dc = DisplayCodes.None;
|
||||
|
||||
// if (DisplayCodes.TryParse(value.ToString(), out dc))
|
||||
// {
|
||||
// string hex = "";
|
||||
// int intValue;
|
||||
// if (int.TryParse(value.ToString(), out intValue))
|
||||
// {
|
||||
// hex = intValue.ToString("X");
|
||||
// }
|
||||
// return $"{dc} ({hex})";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return "?";
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
private Timer tmrAutoDetect;
|
||||
|
||||
public EventHandler OnPcbIdDetect;
|
||||
|
||||
private Int32 intervalWithoutDetect = 1000;
|
||||
private Int32 intervalWithDetect = 10000;
|
||||
private String _currentPcbID;
|
||||
|
||||
|
||||
public PickingViewModel PickingData = new PickingViewModel();
|
||||
|
||||
public String CurrentPcbID
|
||||
{
|
||||
set
|
||||
{
|
||||
if (_currentPcbID != value && !(string.IsNullOrEmpty(_currentPcbID) && value == null))
|
||||
{
|
||||
|
||||
if (_currentPcbID != value)
|
||||
{
|
||||
|
||||
if (!string.IsNullOrEmpty(_currentPcbID) && string.IsNullOrEmpty(value))
|
||||
{
|
||||
_currentPcbID = value;
|
||||
updateUi(lblPcbID, _currentPcbID);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentPcbID = value;
|
||||
updateUi(lblPcbID, _currentPcbID);
|
||||
|
||||
if (!string.IsNullOrEmpty(_currentPcbID))
|
||||
{
|
||||
GetPcbMapping(_currentPcbID);
|
||||
}
|
||||
}
|
||||
}
|
||||
OnPcbIdDetect?.Invoke(CurrentPcbID, EventArgs.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
get => _currentPcbID;
|
||||
}
|
||||
|
||||
public enum uiState
|
||||
{
|
||||
not_connected,
|
||||
connected
|
||||
}
|
||||
|
||||
private uiState _currentState;
|
||||
public uiState CurrentState
|
||||
{
|
||||
set
|
||||
{
|
||||
_currentState = value;
|
||||
updateUi(lblState, _currentState.ToString());
|
||||
}
|
||||
get => _currentState;
|
||||
}
|
||||
|
||||
private String _lastMsg;
|
||||
public String LastMsg
|
||||
{
|
||||
set
|
||||
{
|
||||
_lastMsg = value;
|
||||
updateUi(lblMessage, _lastMsg);
|
||||
}
|
||||
get => _lastMsg;
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
|
||||
}
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
public ApplicationSettings Settings { get; set; }
|
||||
private void Window_Initialized(Object sender, EventArgs e)
|
||||
{
|
||||
var configfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Hardware.WaterMeter.Genesis), ProgramConfig.SerialConfigFileName);
|
||||
|
||||
if (!File.Exists(configfile))
|
||||
{
|
||||
throw new ApplicationException($"Configuration file {configfile} not found ");
|
||||
}
|
||||
var tr = new StreamReader(configfile);
|
||||
var meterConfigList = JsonConvert.DeserializeObject<SlotConfig[]>(tr.ReadToEnd());
|
||||
|
||||
cbxSlotBox.Items.Clear();
|
||||
foreach (var item in meterConfigList.OrderBy(s => s.Slot))
|
||||
{
|
||||
cbxSlotBox.Items.Add(item.Slot);
|
||||
}
|
||||
|
||||
cbxSlotBox.SelectedIndex = 0;
|
||||
tmrAutoDetect = new Timer(intervalWithoutDetect);
|
||||
tmrAutoDetect.Elapsed += TmrAutoDetect_Elapsed;
|
||||
tmrAutoDetect.Enabled = false;
|
||||
|
||||
|
||||
Settings = new ApplicationSettings("ProductionUiConfig.json");
|
||||
|
||||
|
||||
useSetting(true);
|
||||
}
|
||||
|
||||
private void TmrAutoDetect_Elapsed(Object sender, ElapsedEventArgs e)
|
||||
{
|
||||
tmrAutoDetect.Enabled = false;
|
||||
var hasDetect = Detect(true, 1);
|
||||
if (hasDetect)
|
||||
{
|
||||
tmrAutoDetect.Interval = intervalWithDetect;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmrAutoDetect.Interval = intervalWithoutDetect;
|
||||
}
|
||||
tmrAutoDetect.Enabled = Settings.AutoDetect;
|
||||
}
|
||||
|
||||
|
||||
private void BtnConnect_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
var hasDetect = Detect(false, (Int32)cbxSlotBox.SelectedValue);
|
||||
|
||||
Settings.Slot = (Int32)cbxSlotBox.SelectedValue;
|
||||
storeSetting();
|
||||
}
|
||||
|
||||
private void updateUi(ContentControl c, String content)
|
||||
{
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() => { c.Content = content; }));
|
||||
}
|
||||
private void updateUi(TextBox c, String content)
|
||||
{
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() => { c.Text = content; }));
|
||||
}
|
||||
private void updateUi(TextBlock c, String content)
|
||||
{
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() => { c.Text = content; }));
|
||||
}
|
||||
|
||||
private MeterBatch CurrentBatch;
|
||||
private IGenesisMeter _currentMeter;
|
||||
private Boolean detectIsLocked;
|
||||
|
||||
private IGenesisMeter CurrentMeter
|
||||
{
|
||||
get => _currentMeter;
|
||||
set
|
||||
{
|
||||
_currentMeter = value;
|
||||
if (ucFinalRadioTest != null)
|
||||
{
|
||||
if (_currentMeter?.PcbId != null)
|
||||
{
|
||||
// ucFinalRadioTest.GenesisMeter = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ucFinalRadioTest.GenesisMeter = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean Detect(Boolean ignoreErrors, Int32 slot)
|
||||
{
|
||||
if (!detectIsLocked)
|
||||
{
|
||||
LastMsg = "Start Detect";
|
||||
Boolean hasDetect = false;
|
||||
if (string.IsNullOrEmpty(CurrentPcbID) || CurrentMeter == null)
|
||||
{
|
||||
var mb = new MeterBatch();
|
||||
var tryMeter = new GenesisMeter();
|
||||
try
|
||||
{
|
||||
tryMeter.SetupFromConfigFile(slot);
|
||||
mb.AddMeter(tryMeter);
|
||||
tryMeter.Logout();
|
||||
LastMsg = "Try to get PcbID";
|
||||
CurrentPcbID = tryMeter.GetPcbId();
|
||||
|
||||
hasDetect = !string.IsNullOrEmpty(CurrentPcbID);
|
||||
CurrentBatch = mb;
|
||||
CurrentMeter = tryMeter;
|
||||
if (hasDetect)
|
||||
{
|
||||
LastMsg = $"New PcbID detected {CurrentPcbID}";
|
||||
|
||||
CurrentMeter.Login();
|
||||
}
|
||||
else
|
||||
{
|
||||
LastMsg = "No Meter found";
|
||||
DisposeAllConnections();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!ignoreErrors)
|
||||
{
|
||||
MessageBox.Show($"Error occur.{ Environment.NewLine} {e.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LastMsg = "Check if Meter is still connected";
|
||||
var ret = CurrentMeter.GetPcbId();
|
||||
if (string.IsNullOrEmpty(ret) || ret != CurrentPcbID)
|
||||
{
|
||||
LastMsg = "Meter connection lost";
|
||||
hasDetect = false;
|
||||
DisposeAllConnections();
|
||||
|
||||
CurrentPcbID = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
LastMsg = "Meter is still connected";
|
||||
hasDetect = true;
|
||||
}
|
||||
}
|
||||
return hasDetect;
|
||||
}
|
||||
|
||||
LastMsg = "Meter is still connected (locked)";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void Window_Closing(Object sender, CancelEventArgs e)
|
||||
{
|
||||
DisposeAllConnections();
|
||||
}
|
||||
|
||||
private void DisposeAllConnections()
|
||||
{
|
||||
|
||||
if (CurrentBatch != null)
|
||||
{
|
||||
CurrentBatch.RemoveAllMeters();
|
||||
if (CurrentMeter != null)
|
||||
{
|
||||
CurrentMeter.Dispose();
|
||||
}
|
||||
CurrentBatch.Dispose();
|
||||
}
|
||||
PickingData.Empty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void GetPcbMapping(String pcbID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pcbID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var url = $"{ServiceUrls.MarriageServiceUrl()}GetSerialNumberAndOrderNumber?PcbId={pcbID}&withRadioAdress=true";
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var responseJson = LocalWebRequest.GetRequest(url);
|
||||
var a = JsonConvert.DeserializeObject<String[]>(responseJson);
|
||||
|
||||
|
||||
if (ucFinalRadioTest != null)
|
||||
{
|
||||
var tmpInt = 0;
|
||||
int.TryParse(a[1], out tmpInt);
|
||||
// ucFinalRadioTest.OrderNumber = tmpInt;
|
||||
|
||||
tmpInt = 0;
|
||||
if (a.Length > 2)
|
||||
{
|
||||
int.TryParse(a[2], out tmpInt);
|
||||
|
||||
}
|
||||
|
||||
//ucFinalRadioTest.RadioAddress = tmpInt;
|
||||
// ucFinalRadioTest.SerialNumber = a[0] + "/" + a[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is WebException)
|
||||
{
|
||||
MessageBox.Show($"Error on Store: {Environment.NewLine} { ((WebException)ex).Message}");
|
||||
}
|
||||
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void Button_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void UcFinalRadioTest_OnLockMeter(Object sender, EventArgs e)
|
||||
{
|
||||
detectIsLocked = true;
|
||||
|
||||
}
|
||||
|
||||
private void UcFinalRadioTestOnOnReleaseMeter(Object sender, EventArgs e)
|
||||
{
|
||||
detectIsLocked = false;
|
||||
//ucFinalRadioTest.SetUpBlank(false);
|
||||
}
|
||||
|
||||
|
||||
private void BtnSwitchAutoDetect_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
Settings.AutoDetect = !Settings.AutoDetect;
|
||||
storeSetting();
|
||||
useSetting();
|
||||
}
|
||||
|
||||
private void CbxSlotBox_SelectionChanged(Object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
private void storeSetting()
|
||||
{
|
||||
Settings.Update("ProductionUiConfig.json");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void useSetting(Boolean setSlot = false)
|
||||
{
|
||||
tmrAutoDetect.Enabled = Settings.AutoDetect;
|
||||
tblkAutodetectState.Text = "Off";
|
||||
if (Settings.AutoDetect)
|
||||
{
|
||||
tblkAutodetectState.Text = "On";
|
||||
}
|
||||
if (setSlot)
|
||||
{
|
||||
cbxSlotBox.SelectedValue = Settings.Slot;
|
||||
}
|
||||
}
|
||||
|
||||
private void StackPanel_SizeChanged(Object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
ucFinalRadioTest.Height = e.NewSize.Height;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
<Window x:Class="Xylem.Common.Production.ProductionUiCordonel.MultiMode"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="MultiMode" Height="322.026" Width="660.69" Loaded="Window_Loaded" Closed="Window_Closed">
|
||||
<Grid Margin="0,0,28,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="238" MinHeight="150"/>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition MinHeight="50"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="125"/>
|
||||
<ColumnDefinition Width="125"/>
|
||||
<ColumnDefinition Width="125"/>
|
||||
<ColumnDefinition Width="125"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="Kommissionierung" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="Scanner:" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="0" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="{Binding PickingScanner, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" Height="26" Width="115" />
|
||||
<Label Background="{Binding PickingResultColor}" Content="Ep:" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="2" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="{Binding PickingSlot, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="3" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="Medlung:" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="2" Grid.Column="0" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="{Binding PickingState, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="36,1,0,0" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Height="26" Width="332" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="Ergebnis:" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="3" Grid.Column="0" Height="26" Width="115" />
|
||||
|
||||
<Label Background="{Binding PickingResultColor}" Content="{Binding PickingResult, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Height="26" Width="359" />
|
||||
|
||||
|
||||
|
||||
<!--<Label Content="Dichtigkeit" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="0" Height="26" Width="105" />
|
||||
<Label Content="{Binding PressureHe.Sate}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" Height="26" Width="105" />
|
||||
|
||||
<Label Content="Druck" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="2" Grid.Column="0" Height="26" Width="105" />
|
||||
<Label Content="{Binding PressureSate}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" Height="26" Width="105" />
|
||||
|
||||
<Label Content="Verknüpfung" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="3" Grid.Column="0" Height="26" Width="105" />
|
||||
<Label Content="{Binding MarrySate}" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1" Height="26" Width="105" />-->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--<Grid Grid.Row="1" Grid.Column="0" Grid.RowSpan="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="12*"/>
|
||||
|
||||
<RowDefinition Height="10*"/>
|
||||
<RowDefinition Height="10*"/>
|
||||
<RowDefinition Height="10*"/>
|
||||
<RowDefinition Height="100*"/>
|
||||
<RowDefinition Height="1*"/>
|
||||
<RowDefinition Height="20*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="200" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
<Label x:Name="lblHeadline" Content="HE-Schnüffeln" Grid.Column="0" Grid.Row="0" FontWeight="Bold" FontSize="24" Height="47" VerticalAlignment="Top" Margin="0,0,113,0" Grid.RowSpan="2" Grid.ColumnSpan="2" />
|
||||
|
||||
<Label x:Name="lblLeakrate" Content="Grenz-Leckrate >" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="0" Grid.Column="2" Height="26" Width="123" />
|
||||
<TextBox x:Name="txtLeakrate" Height="26" IsEnabled="True" TextWrapping="Wrap" Text="{Binding Result.LeakRate, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Left" Width="171" TextChanged="TextBox_TextChanged"/>
|
||||
|
||||
|
||||
|
||||
<TextBox x:Name="TxtPresurePcbId" Height="26" IsEnabled="False" TextWrapping="Wrap" Text="{Binding CurrentPcbID, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Width="150" TextChanged="TextBox_TextChanged"/>
|
||||
<Label Content="PcbId" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="0" Height="26" Width="40"/>
|
||||
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="2">
|
||||
<TextBlock Text="Rev: "/>
|
||||
<Label Content="{Binding Result.Rev, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="26" Width="40"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<Label Content="Prüfdruck in bar" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="2" Grid.Column="0" Height="26" Width="113" Grid.ColumnSpan="2" />
|
||||
<TextBox x:Name="txtPressure" Height="26" IsEnabled="True" TextWrapping="Wrap" Text="{Binding Result.TestPressure, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Width="150" TextChanged="TextBox_TextChanged"/>
|
||||
|
||||
|
||||
<TextBox x:Name="txtTester" Height="26" IsEnabled="True" TextWrapping="Wrap" Text="{Binding Result.TesterName, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Left" Width="150" TextChanged="TextBox_TextChanged" />
|
||||
|
||||
|
||||
<Label Content="Prüfer" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="3" Grid.Column="0" Height="26" Width="85" />
|
||||
|
||||
|
||||
<ListView x:Name="listViewTestPotins" ItemsSource="{Binding Result.Testpoints, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="2" Grid.RowSpan="4" HorizontalAlignment="left" Width="251" Margin="10,10,0,0" Grid.ColumnSpan="2" >
|
||||
<ListView.View>
|
||||
<GridView >
|
||||
<GridViewColumn Header="Nr" >
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate >
|
||||
<Label Content="{Binding Ident}" Height="22" FontWeight="Bold" FontSize="10" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Wert" >
|
||||
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Text="{Binding Input}" Height="22" Width="100" FontWeight="Bold" FontSize="13" TextChanged="TextBox_TextChanged" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
|
||||
</GridViewColumn>
|
||||
|
||||
<GridViewColumn Header="" >
|
||||
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="Für alle übernehmen" Height="22" FontWeight="Bold" FontSize="13" Click="Button_Click" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
|
||||
</GridViewColumn>
|
||||
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
|
||||
<Label Content="Bemerkung" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Height="26" Width="113" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="2" />
|
||||
|
||||
<TextBox Text="{Binding Result.Remark, UpdateSourceTrigger=PropertyChanged}" Margin="10,10,10,7" TextWrapping="Wrap" AcceptsReturn="True" AcceptsTab="True" SpellCheck.IsEnabled="True" SpellCheck.SpellingReform="PreAndPostreform" Grid.Row="4" Grid.Column="1" TextChanged="TextBox_TextChanged"/>
|
||||
|
||||
|
||||
<Button Name="btnPresueOk" Background="LightGreen" Grid.ColumnSpan="2" Content="Bestanden" HorizontalAlignment="Left" Height="35" Margin="10,5,0,0" Grid.Row="6" VerticalAlignment="Top" Width="280" Click="BtnPresueOk_Click" Grid.Column="2"/>
|
||||
|
||||
<Button Name="btnPresueFailed" Background="LightPink" Grid.ColumnSpan="2" Content="Nicht Bestanden" HorizontalAlignment="Left" Height="35" Margin="9,5,0,0" Grid.Row="6" VerticalAlignment="Top" Width="281" Click="BtnPresueFailed_Click" Grid.Column="0" />
|
||||
|
||||
|
||||
|
||||
|
||||
</Grid>-->
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,206 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Model;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaktionslogik für MultiMode.xaml
|
||||
/// </summary>
|
||||
public partial class MultiMode : Window
|
||||
{
|
||||
//#region Raw Input API
|
||||
|
||||
//[DllImport("User32.dll")]
|
||||
//extern static uint GetRawInputDeviceList(IntPtr pRawInputDeviceList, ref uint uiNumDevices, uint cbSize);
|
||||
|
||||
//[DllImport("User32.dll")]
|
||||
//extern static uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);
|
||||
|
||||
//[DllImport("User32.dll")]
|
||||
//extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
|
||||
|
||||
//[DllImport("User32.dll")]
|
||||
//extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
|
||||
|
||||
//#endregion
|
||||
|
||||
MultiModeMasterViewModel multiModeMasterViewModel = new MultiModeMasterViewModel();
|
||||
|
||||
private List<MultiModeChild> Childs = new List<MultiModeChild>();
|
||||
|
||||
public ApplicationSettings AppSettings { get; private set; }
|
||||
//class RawInputDevice : InputDevice
|
||||
//{
|
||||
// public override IInputElement Target => throw new NotImplementedException();
|
||||
|
||||
// public override PresentationSource ActiveSource => throw new NotImplementedException();
|
||||
//}
|
||||
public MultiMode()
|
||||
{
|
||||
|
||||
DataContext = multiModeMasterViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
Topmost = false;
|
||||
}
|
||||
private void keyUp(Object sender, KeyEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
public void SetBaseFocus()
|
||||
{
|
||||
//foreach (var item in Childs)
|
||||
//{
|
||||
// item.Key.Activate();
|
||||
//}
|
||||
//this.Activate();
|
||||
//txtBarcodeInput.Focus();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private MultiModeChild addChild(IMultiModeChildViewModel model)
|
||||
{
|
||||
var a = new MultiModeChild(model);
|
||||
|
||||
a.Show();
|
||||
return a;
|
||||
}
|
||||
CancellationTokenSource cts;
|
||||
|
||||
private void Window_Loaded(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
AppSettings = new ApplicationSettings("MultiProductionUiConfig.json");
|
||||
multiModeMasterViewModel.StartPicking(cts);
|
||||
//var trigger = new List<string>();
|
||||
|
||||
//if (AppSettings.ChildForms == null || !AppSettings.ChildForms.Any())
|
||||
//{
|
||||
// AppSettings.ChildForms = new List<ApplicationSettings.MultiFormChilds>();
|
||||
|
||||
// AppSettings.ChildForms.Add(new ApplicationSettings.MultiFormChilds() { Name = "Picking", Slot = 1, ViewModelType = typeof(PickingMultiModeViewModel), StartPos = null, Visisble = true, TextPort = "COM11" });
|
||||
// AppSettings.ChildForms.Add(new ApplicationSettings.MultiFormChilds() { Name = "PressureHE", Slot = 3, ViewModelType = typeof(PressureMultiModeViewModel), StartPos = null, Visisble = true, TextPort = null });
|
||||
// AppSettings.ChildForms.Add(new ApplicationSettings.MultiFormChilds() { Name = "PressureHY", Slot = 1, ViewModelType = typeof(PressureMultiModeViewModel), StartPos = null, Visisble = true, TextPort = null });
|
||||
// AppSettings.ChildForms.Add(new ApplicationSettings.MultiFormChilds() { Name = "Marriage", Slot = 4, ViewModelType = typeof(MarriageMultiModeViewModel), StartPos = null, Visisble = true, TextPort = "COM1" });
|
||||
// AppSettings.Update("MultiProductionUiConfig.json");
|
||||
//}
|
||||
|
||||
|
||||
////AppSettings.ChildForms.ForEach(c => trigger.Add(c.TextPort.ToString()));
|
||||
|
||||
//cts = new CancellationTokenSource();
|
||||
|
||||
//foreach (var item in AppSettings.ChildForms)
|
||||
//{
|
||||
// if (item.Visisble)
|
||||
// {
|
||||
|
||||
|
||||
// IMultiModeChildViewModel mdl = null;
|
||||
// if (item.ViewModelType == typeof(PickingMultiModeViewModel))
|
||||
// {
|
||||
// mdl = new PickingMultiModeViewModel(item.Name, item.Slot, trigger, AppSettings.StationId);
|
||||
// }
|
||||
// else if (item.ViewModelType == typeof(PressureMultiModeViewModel))
|
||||
// {
|
||||
// mdl = new PressureMultiModeViewModel(item.Name, item.Slot, trigger, AppSettings.StationId);
|
||||
// }
|
||||
// else if (item.ViewModelType == typeof(MarriageMultiModeViewModel))
|
||||
// {
|
||||
// mdl = new MarriageMultiModeViewModel(item.Name, item.Slot, trigger, AppSettings.StationId);
|
||||
// }
|
||||
// if (mdl == null)
|
||||
// {
|
||||
// throw new ApplicationException("Bad configuration or old software");
|
||||
// }
|
||||
// var child = addChild(mdl);
|
||||
|
||||
// child.StartTextInputListener(item.TextPort, cts.Token);
|
||||
|
||||
// if (item.StartPos != null)
|
||||
// {
|
||||
// child.WindowStartupLocation = WindowStartupLocation.Manual;
|
||||
// child.Top = item.StartPos.Top;
|
||||
// child.Left = item.StartPos.Left;
|
||||
// child.Height = item.StartPos.Height;
|
||||
// child.Width = item.StartPos.Width;
|
||||
// child.UseDefaultPos = false;
|
||||
// }
|
||||
// child.PosChanged += delegate (object val, EventArgs a)
|
||||
// {
|
||||
// if (val is MultiModeChild mmc)
|
||||
// {
|
||||
// if (mmc.ViewModel is BaseMultiModeChildViewModel baseChild)
|
||||
// {
|
||||
// var aasd = AppSettings.ChildForms.FirstOrDefault(c => c.Name == baseChild.ChildName);
|
||||
// aasd.StartPos = new ApplicationSettings.Pos() { Height = mmc.Height, Left = mmc.Left, Top = mmc.Top, Width = mmc.Width };
|
||||
|
||||
// AppSettings.Update("MultiProductionUiConfig.json");
|
||||
// }
|
||||
// }
|
||||
|
||||
// };
|
||||
|
||||
|
||||
// child.Show();
|
||||
|
||||
// Childs.Add(child);
|
||||
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//SetBaseFocus();
|
||||
}
|
||||
|
||||
private void delegeChild_PosChange(Object sender, EventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void TxtBarcodeInput_TextChanged(Object sender, TextChangedEventArgs e)
|
||||
{
|
||||
//if (sender is TextBox text)
|
||||
//{
|
||||
// if (text.Text.ToLower().Contains("clear"))
|
||||
// {
|
||||
// text.Text = string.Empty;
|
||||
// }
|
||||
// else if (text.Text.Contains(System.Environment.NewLine))
|
||||
// {
|
||||
// foreach (var dispatchChild in Childs.Where(x => x.Value == text.Text[0]))
|
||||
// {
|
||||
// dispatchChild.Key.InputText(text.Text.Substring(1, text.Text.Length - 1).Trim());
|
||||
// }
|
||||
|
||||
// text.Text = "";
|
||||
// SetBaseFocus();
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
private void Window_Closed(Object sender, EventArgs e)
|
||||
{
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
|
||||
foreach (var item in Childs)
|
||||
{
|
||||
item.Dispose();
|
||||
|
||||
item.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
<Window
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ctls="clr-namespace:Xylem.Common.Production.ProductionUiCordonel.ctls"
|
||||
x:Class="Xylem.Common.Production.ProductionUiCordonel.MultiModeChild"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="MultiModeChild" Height="802.824" Width="704.975" WindowStartupLocation="Manual">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="25"/>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="25"/>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="25"/>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="25"/>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="20"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Name"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="0"/>
|
||||
|
||||
<Label Background="LightGray" FontSize="17pt"
|
||||
HorizontalContentAlignment="Right" Margin="10,5,10,0"
|
||||
VerticalAlignment="Top" Height="40"
|
||||
Content="{Binding ChildName}"
|
||||
Grid.Row="1" />
|
||||
<Label Content="Order"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="2"/>
|
||||
|
||||
<Label Background="LightGray" FontSize="17pt"
|
||||
HorizontalContentAlignment="Right" Margin="10,10,10,0"
|
||||
VerticalAlignment="Top" Height="40"
|
||||
Content="{Binding Order, UpdateSourceTrigger=PropertyChanged}"
|
||||
Grid.Row="3" />
|
||||
|
||||
<Label Content="SlotInfo"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="4"/>
|
||||
|
||||
<Label Background="LightGray" FontSize="17pt"
|
||||
HorizontalContentAlignment="Right" Margin="10,10,10,0"
|
||||
VerticalAlignment="Top" Height="40"
|
||||
Content="{Binding SlotInfo, UpdateSourceTrigger=PropertyChanged}"
|
||||
Grid.Row="5"/>
|
||||
|
||||
<Label Content="State"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Grid.Row="6"/>
|
||||
|
||||
<Label Background="LightGray" FontSize="17pt"
|
||||
HorizontalContentAlignment="Right" Margin="10,10,10,0"
|
||||
VerticalAlignment="Top" Height="40"
|
||||
Content="{Binding CurrentSlotStateText, UpdateSourceTrigger=PropertyChanged}"
|
||||
Grid.Row="7"/>
|
||||
|
||||
<ctls:ctlMultiModePressure x:Name="PressureControl" Visibility="{Binding VisibilityPressure}" Grid.Row="8" Margin="0,0,0,0" OnBarcodeInput="PressureControl_OnBarcodeInput" />
|
||||
<ctls:ctlMultiModePicking x:Name="PickingControl" Visibility="{Binding VisibilityPicking}" Grid.Row="8" Margin="0,0,0,0" />
|
||||
<ctls:ctlMultiModeMarriage x:Name="MarriageControl" Visibility="{Binding VisibilityMarriage}" Grid.Row="8" Margin="0,0,0,0"/>
|
||||
|
||||
<Button Content="POS" Grid.Row="9" Click="Button_Click" />
|
||||
<Button Content="Store" Grid.Row="10" Click="Button_Click_1" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,135 +0,0 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Event;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Model;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaktionslogik für MultiModeChild.xaml
|
||||
/// </summary>
|
||||
public partial class MultiModeChild : Window, IDisposable
|
||||
{
|
||||
public IMultiModeChildViewModel ViewModel;
|
||||
|
||||
public Boolean UseDefaultPos { get; internal set; } = true;
|
||||
public event EventHandler PosChanged;
|
||||
|
||||
|
||||
public MultiModeChild(IMultiModeChildViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = viewModel;
|
||||
DataContext = ViewModel;
|
||||
if (ViewModel is PressureMultiModeViewModel pressureModel)
|
||||
{
|
||||
PressureControl.setViewModel(pressureModel);
|
||||
|
||||
Left = 0;
|
||||
Top = 250;
|
||||
Height = SystemParameters.PrimaryScreenHeight - 300;
|
||||
Width = SystemParameters.PrimaryScreenWidth / 2;
|
||||
}
|
||||
if (ViewModel is PickingMultiModeViewModel pickingModel)
|
||||
{
|
||||
PickingControl.setViewModel(pickingModel);
|
||||
|
||||
Left = SystemParameters.VirtualScreenLeft;
|
||||
Top = SystemParameters.VirtualScreenTop;
|
||||
Height = SystemParameters.VirtualScreenHeight;
|
||||
Width = SystemParameters.VirtualScreenWidth - SystemParameters.PrimaryScreenWidth;
|
||||
}
|
||||
if (ViewModel is MarriageMultiModeViewModel marriageModel)
|
||||
{
|
||||
MarriageControl.setViewModel(marriageModel);
|
||||
|
||||
Left = SystemParameters.PrimaryScreenWidth / 2;
|
||||
Top = 250;
|
||||
Height = SystemParameters.PrimaryScreenHeight - 300;
|
||||
Width = SystemParameters.PrimaryScreenWidth / 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
internal void StartTextInputListener(String port, CancellationToken cancellation)
|
||||
{
|
||||
if (port == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var task = new Task(() =>
|
||||
{
|
||||
var a = new SerialPort(port);
|
||||
a.Open();
|
||||
a.NewLine = "\r";
|
||||
while (true)
|
||||
{
|
||||
if (cancellation.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var resText = a.ReadLine();
|
||||
Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
ViewModel.InputText(resText);
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}, cancellation);
|
||||
task.Start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
internal void InputText(String text)
|
||||
{
|
||||
ViewModel.InputText(text);
|
||||
}
|
||||
|
||||
private void BtnPresueFailed_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void TxtPresurePcbId_TextChanged(Object sender, TextChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void PressureControl_OnBarcodeInput(Object sender, StringArgs e)
|
||||
{
|
||||
InputText(e.Content);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ViewModel.Dispose();
|
||||
|
||||
}
|
||||
|
||||
private void Button_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button btn)
|
||||
{
|
||||
btn.Content = $"POS L{Left},T{Top },H{Height},W{Width}";
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_Click_1(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
PosChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
<Window
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Class="Xylem.Common.Production.ProductionUiCordonel.Picking"
|
||||
mc:Ignorable="d"
|
||||
Title="FinalTest" MinHeight="730" MinWidth="820" Height="730" Width="820" Initialized="Window_Initialized" Closing="Window_Closing" ResizeMode="CanMinimize" HorizontalAlignment="Right" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
|
||||
<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="2,2,2,2">
|
||||
<!--Tool Panel-->
|
||||
<!--ToolBarTray DockPanel.Dock="Top" Visibility="Visible" Background="#FFF0F0F0" HorizontalAlignment="Stretch" -->
|
||||
<Menu DockPanel.Dock="Top" Visibility="Visible" Background="#FFF0F0F0" HorizontalAlignment="Stretch">
|
||||
<Menu.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<DockPanel HorizontalAlignment="Stretch"></DockPanel>
|
||||
</ItemsPanelTemplate>
|
||||
</Menu.ItemsPanel>
|
||||
<MenuItem x:Name="optionsMenu" HorizontalAlignment="Right" Height="30" Width="60" Header="_Options" >
|
||||
<MenuItem x:Name="optionsMenuLogin" Header="_Login" HorizontalAlignment="Left" Click="OnLogin_Click"/>
|
||||
<MenuItem x:Name="optionsMenuLogout" Header="L_ogout" HorizontalAlignment="Left" Click="OnLogout_Click"/>
|
||||
<MenuItem x:Name="optionsMenuChangePassword" Header="Change Password" HorizontalAlignment="Left" Click="OnChangePassword_Click"/>
|
||||
</MenuItem>
|
||||
<Label Content="Slot: " Margin="2,2,2,2" Visibility="Hidden"/>
|
||||
<ComboBox x:Name="cbxSlotBox" Margin="2,2,2,2" SelectionChanged="CbxSlotBox_SelectionChanged" Visibility="Hidden"/>
|
||||
<Label x:Name="lblApprovalText" Margin="110,1,1,1" Content="SPECIAL APPROVAL - Id.Ver: 10.07" Foreground="#FFFB0808" FontSize="16" MouseDown="LblApprovalText_Click" HorizontalAlignment="Center"/>
|
||||
<MenuItem x:Name="hlpMenu" HorizontalAlignment="Right" Height="30" Width="40" FontSize="12" Header="Help" Click="HlpMenu_Click" />
|
||||
<!--Special approval / requirement-->
|
||||
</Menu>
|
||||
<!--/-->
|
||||
|
||||
<!--Status Panel-->
|
||||
<StatusBar DockPanel.Dock="Bottom" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="2,2,2,2">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="200" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="60" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="0" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Label Content="PcbID:" Margin="2,2,0,2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="1" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Label x:Name="lblPcbIdValue" Content="-" Margin="2,2,2,2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="2" />
|
||||
<StatusBarItem x:Name="lblOperator" Grid.Column="4" Margin="-1,1,-109,3" HorizontalAlignment="Center" VerticalAlignment="Stretch" />
|
||||
<Separator Grid.Column="7" />
|
||||
<StatusBarItem Grid.Column="8" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock x:Name="lblTimeText" Text="Elapsed Time [min:s]:" Margin="2,2,2,2" HorizontalAlignment="Right" VerticalAlignment="Stretch" />
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="9" Margin="0,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Stretch">
|
||||
<Label x:Name="lblTimeValue" Content="0:00" Margin="2,2,2,2" HorizontalAlignment="Right" VerticalAlignment="Stretch" />
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
<!--Grid Design-->
|
||||
<Grid Background="AliceBlue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="2,2,2,2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="17"/>
|
||||
<ColumnDefinition Width="113"/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="30"/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="30"/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
<ColumnDefinition Width="60"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!--Cordonel information-->
|
||||
<Label x:Name="lblSerialNumberTxt" Content="SerialNumber:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="2"/>
|
||||
<Label x:Name="lblOrderNumberText" Content="OrderNumber:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="2"/>
|
||||
<Label Content="Region:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="2"/>
|
||||
<Label x:Name="lblRadioAddressText" Content="RadioAddress:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="3" Grid.Column="2"/>
|
||||
<Label Content="Firmware:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="5"/>
|
||||
<Label x:Name="lblLutText" Content="LUT CRC:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="5"/>
|
||||
<Label x:Name="lblMeterSizeText" Content="Meter Size:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="5"/>
|
||||
|
||||
<Label Content="" x:Name="lblSerialNumberValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="3"/>
|
||||
<Label Content="" x:Name="lblOrderNumberValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="3"/>
|
||||
<Label Content="" x:Name="lblRegionValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="3"/>
|
||||
<Label Content="" x:Name="lblRadioAddressValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="3" Grid.Column="3"/>
|
||||
<Label Content="" x:Name="lblFwValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="6"/>
|
||||
<Label Content="" x:Name="lblLutValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="6"/>
|
||||
<Label Content="" x:Name="lblMeterSizeValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="6"/>
|
||||
|
||||
<!--Pictures-->
|
||||
<Border Grid.Row="0" Grid.RowSpan="4" Grid.Column="0" Margin="2,2,2,2" BorderThickness="1" BorderBrush="Black" Grid.ColumnSpan="2">
|
||||
<Image Margin="0,0,-1,-1" Source="/Resources/Cordonel With Display small.JPG" Stretch="Fill" />
|
||||
</Border>
|
||||
<Border Grid.Row="0" Grid.RowSpan="2" Grid.Column="9" Grid.ColumnSpan="2" Margin="2,2,2,2" BorderThickness="1" BorderBrush="Black" >
|
||||
<Image Margin="0,0,-1,-1" Source="/Resources/SensusLogoXylem.JPG" Stretch="Fill" />
|
||||
</Border>
|
||||
|
||||
<!--Process Information-->
|
||||
<DataGrid x:Name="dgTotalProcess" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="4" Grid.RowSpan="11" Grid.Column="0" Grid.ColumnSpan="4" ItemsSource="{Binding}"
|
||||
AutoGenerateColumns="True" SelectionMode="Single" IsReadOnly="True" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" IsEnabled="True" />
|
||||
<StackPanel x:Name="dpSubProcess" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="4" Grid.RowSpan="11" Grid.Column="5" Grid.ColumnSpan="3" />
|
||||
<GroupBox Header="Info" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="15" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="11" >
|
||||
<RichTextBox x:Name="rtbLog" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</GroupBox>
|
||||
|
||||
<!--Progress Bars and Info-->
|
||||
<ProgressBar x:Name="pbSubProgress" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,4,2,4" Grid.Row="19" Grid.Column="2" Grid.ColumnSpan="8" />
|
||||
<ProgressBar x:Name="pbTotalProgress" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,4,2,4" Grid.Row="20" Grid.Column="2" Grid.ColumnSpan="8" />
|
||||
<Label x:Name="lblSubProgressValue" HorizontalAlignment="Right" VerticalAlignment="Stretch" Margin="0,0,2,0" Grid.Row="19" Grid.Column="10" Content="0,0 %"/>
|
||||
<Label x:Name="lblTotalProgressValue" HorizontalAlignment="Right" VerticalAlignment="Stretch" Margin="0,0,2,0" Grid.Row="20" Grid.Column="10" Content="0,0 %"/>
|
||||
<Label x:Name="lblSingleProcessText" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="19" Grid.Column="0" Content="Single Process:" Grid.ColumnSpan="2" />
|
||||
<Label x:Name="lblTotalProcessText" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="20" Grid.Column="0" Content="Total Process:" Grid.ColumnSpan="2" />
|
||||
|
||||
<!--Buttons-->
|
||||
<Button x:Name="btnStart" HorizontalAlignment="Stretch" Margin="2,4,2,4" VerticalAlignment="Stretch" Grid.Column="9" Grid.ColumnSpan="2" Grid.Row="2" Grid.RowSpan="2" IsEnabled="false" Click="BtnStart_Click" Content="Start" />
|
||||
<Button x:Name="btnStop" HorizontalAlignment="Stretch" Margin="2,4,2,4" VerticalAlignment="Stretch" Grid.Column="9" Grid.ColumnSpan="2" Grid.Row="4" Grid.RowSpan="2" IsEnabled="false" Click="BtnStop_Click" Content="Stop" />
|
||||
</Grid>
|
||||
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
||||
@@ -1,928 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
|
||||
using Xylem.Common.Utils.Logging;
|
||||
using Xylem.Common.Utils.UserAccessCtrl;
|
||||
using Control = System.Windows.Forms.Control;
|
||||
using TextBox = System.Windows.Controls.TextBox;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for Picking.xaml
|
||||
/// </summary>
|
||||
public sealed partial class Picking
|
||||
{
|
||||
#region variables and properties
|
||||
private readonly ILogger _logger;
|
||||
// remind manually changed culture setting
|
||||
private static readonly CultureInfo _cultureInfo = Thread.CurrentThread.CurrentCulture;
|
||||
private static readonly AssemblyName _assemblyName = Assembly.GetExecutingAssembly().GetName();
|
||||
private static readonly String _assemblyExecRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
private static readonly Version _version = _assemblyName.Version;
|
||||
private readonly String _strSoftwareNameVersion;
|
||||
private RegisterLDAPUser _registerForm;
|
||||
|
||||
private Int32 Slot
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
// maximum processing steps for calculation of progress bar
|
||||
private Int32 _maxOverallProcessSteps;
|
||||
private Int32 _maxSingleProcessSteps;
|
||||
private ProcessController _processCtrl;
|
||||
private DateTimeOffset _startTime;
|
||||
private DispatcherTimer _timer;
|
||||
private String _lastLoggingTextToAvoidRepetition;
|
||||
private CordonelRequirements _productionRequirements;
|
||||
private UserAccessWindow _userAccessWindow;
|
||||
|
||||
#endregion
|
||||
|
||||
public Picking()
|
||||
{
|
||||
_logger = NLogHelper.CreateOrGetLogger("ProductionUiCordonel");
|
||||
|
||||
String msg;
|
||||
try
|
||||
{
|
||||
// returns true in DEBUG configuration
|
||||
if (!Logic.SoftwareAccessHelper.Access.HasAccess(_assemblyName))
|
||||
{
|
||||
msg = $"{Properties.Resources.StrStartMessageSwLicenseExpired} {_version}";
|
||||
_logger.Error(msg);
|
||||
MessageBox.Show(msg, Properties.Resources.StrProcessStateError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
msg = Properties.Resources.StrErrorMsgMissingNetworkConnetction + " " + e.Message ;
|
||||
_logger.Error(msg);
|
||||
MessageBox.Show(msg,
|
||||
Properties.Resources.StrProcessStateError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
// Log version to files for debug purposes
|
||||
_strSoftwareNameVersion = $"{Properties.Resources.StrSoftwareNameVersion} {_version}";
|
||||
_logger.Info(_strSoftwareNameVersion);
|
||||
|
||||
Title = _strSoftwareNameVersion;
|
||||
|
||||
//static labels
|
||||
UpdateContentControl(lblSerialNumberTxt, Properties.Resources.StrLblSerialNumberTxt + ":");
|
||||
UpdateContentControl(lblRadioAddressText, Properties.Resources.StrLblRadioAddressTxt + ":");
|
||||
UpdateContentControl(lblOrderNumberText, Properties.Resources.StrLblOrderNumberTxt + ":");
|
||||
UpdateContentControl(lblMeterSizeText, Properties.Resources.StrLblMeterSizeTxt + ":");
|
||||
UpdateContentControl(lblSingleProcessText, Properties.Resources.StrLblSingleProcessText + ":");
|
||||
UpdateContentControl(lblTotalProcessText, Properties.Resources.StrLblTotalProcessText + ":");
|
||||
optionsMenu.Header = Properties.Resources.StrMenuOptionsText;
|
||||
optionsMenuChangePassword.Header = Properties.Resources.StrMenuChangePasswordText;
|
||||
hlpMenu.Header = Properties.Resources.StrMenuHelpText;
|
||||
UpdateUi(lblApprovalText, "");
|
||||
UpdateUi(lblTimeText, Properties.Resources.StrLblTimeText + ":");
|
||||
|
||||
// buttons
|
||||
UpdateContentControl(btnStart, Properties.Resources.StrBtnStart);
|
||||
UpdateContentControl(btnStop, Properties.Resources.StrBtnStop);
|
||||
|
||||
InitializeFormState();
|
||||
|
||||
}
|
||||
|
||||
private ApplicationSettings Settings
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the FinalTest GUI:
|
||||
/// - Read the configuration file for slot and port assignments and settings,
|
||||
/// - Dispatch slots to slot combobox,
|
||||
/// - Read setting from "ProductionUiConfig.json" file for GUI and slot setup,
|
||||
/// - Create final process controller and install events,
|
||||
/// - Create a dispatch timer to display the elapsed time of the process.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Window_Initialized(Object sender, EventArgs e)
|
||||
{
|
||||
var configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
nameof(Hardware.WaterMeter.Genesis), ProgramConfig.SerialConfigFileName);
|
||||
|
||||
if (!File.Exists(configFile))
|
||||
{
|
||||
var msg = Properties.Resources.StrErrorMsgMissingConfigurationFile;
|
||||
MessageBox.Show(msg,
|
||||
Properties.Resources.StrProcessStateError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
_logger.Error(msg);
|
||||
throw new ApplicationException(msg);
|
||||
}
|
||||
var tr = new StreamReader(configFile);
|
||||
var meterConfigList = JsonConvert.DeserializeObject<SlotConfig[]>(tr.ReadToEnd());
|
||||
|
||||
cbxSlotBox.Items.Clear();
|
||||
if (meterConfigList != null)
|
||||
{
|
||||
foreach (var item in meterConfigList.OrderBy(s => s.Slot))
|
||||
{
|
||||
cbxSlotBox.Items.Add(item.Slot);
|
||||
}
|
||||
}
|
||||
|
||||
cbxSlotBox.SelectedIndex = 0;
|
||||
Settings = new ApplicationSettings("ProductionUiConfig.json");
|
||||
|
||||
UseSetting(true);
|
||||
|
||||
if (cbxSlotBox.SelectedItem == null || string.IsNullOrEmpty(cbxSlotBox.SelectedItem.ToString()) ||
|
||||
!int.TryParse(cbxSlotBox.SelectedItem.ToString(), out var slot))
|
||||
{
|
||||
Slot = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Slot = slot;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_processCtrl = new ProcessController(Slot);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex.Message);
|
||||
MessageBox.Show(ex.Message,
|
||||
Properties.Resources.StrProcessStateError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
throw new ApplicationException(ex.Message);
|
||||
}
|
||||
|
||||
//install the process changed event handler for single processes
|
||||
_processCtrl.OnSingleProcessStateChanged += SingleProcessStateChanged_Handler;
|
||||
_processCtrl.OnProcessLogRequest += ProcessLog_Handler;
|
||||
_processCtrl.OnProcessProgressChanged += ProcessProgress_Handler;
|
||||
_processCtrl.OnOverallProcessStateChanged += ProcessStateChange_Handler;
|
||||
|
||||
_timer = new DispatcherTimer();
|
||||
_timer.Tick += TmrProgressUpdate_Tick;
|
||||
_timer.Interval = TimeSpan.FromMilliseconds(500);
|
||||
|
||||
UpdateStatusGrid();
|
||||
}
|
||||
|
||||
private void Window_Closing(Object sender, CancelEventArgs e)
|
||||
{
|
||||
_userAccessWindow?.Close();
|
||||
_processCtrl.OnSingleProcessStateChanged -= SingleProcessStateChanged_Handler;
|
||||
_processCtrl.OnProcessLogRequest -= ProcessLog_Handler;
|
||||
_processCtrl.OnProcessProgressChanged -= ProcessProgress_Handler;
|
||||
_processCtrl.OnOverallProcessStateChanged -= ProcessStateChange_Handler;
|
||||
_userAccessWindow = null;
|
||||
|
||||
_processCtrl.Dispose();
|
||||
_processCtrl = null;
|
||||
_timer.Stop();
|
||||
_timer.Tick -= TmrProgressUpdate_Tick;
|
||||
_timer = null;
|
||||
_registerForm = null;
|
||||
}
|
||||
private void UseSetting(Boolean setSlot = false)
|
||||
{
|
||||
//tblkAutodetectState.Text = "Off";
|
||||
//if (Settings.AutoDetect)
|
||||
//{
|
||||
// tblkAutodetectState.Text = "On";
|
||||
//}
|
||||
if (setSlot)
|
||||
{
|
||||
cbxSlotBox.SelectedValue = Settings.Slot;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeFormState()
|
||||
{
|
||||
if (Software.IsRegistrationPending)
|
||||
{
|
||||
_registerForm = new RegisterLDAPUser();
|
||||
_registerForm.OnCancellation += OnUserAccessControlCancellation;
|
||||
UiElmEnable(optionsMenu, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiElmEnable(optionsMenu, true);
|
||||
UiElmEnable(optionsMenuChangePassword, Software.IsAutenticated);
|
||||
UiElmEnable(optionsMenuLogout, Software.IsAutenticated);
|
||||
UiElmEnable(optionsMenuLogin, !Software.IsAutenticated);
|
||||
UiElmEnable(btnStart, Software.IsAutenticated);
|
||||
UiElmEnable(btnStop, false);
|
||||
UpdateContentControl(lblOperator,
|
||||
Software.IsAutenticated
|
||||
? $"{Properties.Resources.StrLblOperatorNameText}: {Software.UserName}"
|
||||
: $"{Properties.Resources.StrLblOperatorNameText}: ?");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the user access window with login form or password change form.
|
||||
/// </summary>
|
||||
/// <param name="visible"></param>
|
||||
/// <param name="control">Windows forms control</param>
|
||||
/// <param name="headerTxt"></param>
|
||||
/// <remarks date="2025-Mar-25" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private void ShowUserAccessWindow(Boolean visible = true, Control control = null, String headerTxt = "")
|
||||
{
|
||||
if (visible && control != null)
|
||||
{
|
||||
UiElmEnable(optionsMenu, false);
|
||||
|
||||
if (_userAccessWindow == null)
|
||||
_userAccessWindow = new UserAccessWindow(control, headerTxt);
|
||||
// View the user access window as container for the windows forms password change and login
|
||||
_userAccessWindow.OnCloseWindow += OnUserAccessWindowClosed_Handler;
|
||||
_userAccessWindow.ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_userAccessWindow != null)
|
||||
{
|
||||
_userAccessWindow.OnCloseWindow -= OnUserAccessWindowClosed_Handler;
|
||||
try
|
||||
{
|
||||
_userAccessWindow.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
_userAccessWindow = null;
|
||||
}
|
||||
|
||||
if (_registerForm != null)
|
||||
_registerForm.OnCancellation -= OnUserAccessControlCancellation;
|
||||
|
||||
UiElmEnable(optionsMenu, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close event handler of the user access window with login form or password change form.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="eventArgs"></param>
|
||||
/// <remarks date="2025-Mar-25" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private void OnUserAccessWindowClosed_Handler(Object sender, EventArgs eventArgs)
|
||||
{
|
||||
ShowUserAccessWindow(false);
|
||||
InitializeFormState();
|
||||
}
|
||||
|
||||
private void UpdateUi(ContentControl c, String content, Brush color = null)
|
||||
{
|
||||
if (color == null)
|
||||
color = Brushes.Black;
|
||||
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
c.Content = content;
|
||||
c.Foreground = color;
|
||||
}));
|
||||
}
|
||||
|
||||
private void UpdateUi(TextBox c, String content, Brush color = null)
|
||||
{
|
||||
if (color == null)
|
||||
color = Brushes.Black;
|
||||
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
c.Text = content;
|
||||
c.Foreground = color;
|
||||
}));
|
||||
}
|
||||
private void UpdateUi(TextBlock c, String content, Brush color = null)
|
||||
{
|
||||
if (color == null)
|
||||
color = Brushes.Black;
|
||||
|
||||
c.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
c.Text = content;
|
||||
c.Foreground = color;
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the elapsed time as information
|
||||
/// </summary>
|
||||
/// <returns>information attached to process depending on region</returns>
|
||||
/// <remarks date="2024-Jul-11" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void SetTimeDisplay()
|
||||
{
|
||||
var time = DateTimeOffset.UtcNow;
|
||||
var timeSpan = time - _startTime;
|
||||
UpdateContentControl(lblTimeValue, $@"{(UInt32)timeSpan.TotalMinutes}:{timeSpan.Seconds:00}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common routine for state change:
|
||||
/// - Log state change,
|
||||
/// - Execute stop procedure on error.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks date="2020-Dec-12" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Aug-30" author="Thomas Wiedebusch">
|
||||
/// - Extended.
|
||||
/// </remarks>
|
||||
private void ProcessStateChange_Handler(Object sender, ProcessStateArgs e)
|
||||
{
|
||||
_logger.Debug($"Slot:{Slot} - Picking state: {e.State}");
|
||||
|
||||
// Nothing to display
|
||||
if (e.State == ProcessState.Idle)
|
||||
{
|
||||
// Update progress bars
|
||||
ProcessProgress_Handler(this, new ProcessProgressArgs(0,
|
||||
ProcessProgressArgs.ProcessProgressType.OverallProcessesSteps));
|
||||
ProcessProgress_Handler(this, new ProcessProgressArgs(0,
|
||||
ProcessProgressArgs.ProcessProgressType.ActualProcessSteps));
|
||||
}
|
||||
// Stop all procedures
|
||||
if (e.State == ProcessState.Stop)
|
||||
{
|
||||
_timer?.Stop();
|
||||
UiElmEnable(btnStart, true);
|
||||
UiElmEnable(btnStop, false);
|
||||
// update progress bars
|
||||
ProcessProgress_Handler(this, new ProcessProgressArgs(0,
|
||||
ProcessProgressArgs.ProcessProgressType.OverallProcessesSteps));
|
||||
ProcessProgress_Handler(this, new ProcessProgressArgs(0,
|
||||
ProcessProgressArgs.ProcessProgressType.ActualProcessSteps));
|
||||
// remove user control
|
||||
SetNewUserControl(null);
|
||||
}
|
||||
// Repeat failed tests
|
||||
if (e.State == ProcessState.RepeatFailedTests)
|
||||
{
|
||||
UiElmEnable(btnStart, false);
|
||||
UiElmEnable(btnStop, true);
|
||||
_timer?.Start();
|
||||
}
|
||||
// Stop time for manual operation and visual inspection as this is not part of the configuration
|
||||
if (e.State == ProcessState.CheckOrderNumber)
|
||||
{
|
||||
_timer?.Stop();
|
||||
}
|
||||
// Prepare shipping
|
||||
if (e.State == ProcessState.PrepareShippingMode)
|
||||
{
|
||||
_timer?.Stop();
|
||||
UiElmEnable(btnStart, false);
|
||||
UiElmEnable(btnStop, false);
|
||||
}
|
||||
// Ready for shipping
|
||||
if (e.State == ProcessState.ReadyForShipping)
|
||||
{
|
||||
StoreSuccessNote(out _);
|
||||
BtnStop_Click(this, null);
|
||||
}
|
||||
// Print return report
|
||||
if (e.State == ProcessState.PrintReturnReport)
|
||||
{
|
||||
PrintErrorNote();
|
||||
BtnStop_Click(this, null);
|
||||
}
|
||||
// Print success report
|
||||
if (e.State == ProcessState.PrintSuccessReport)
|
||||
{
|
||||
PrintSuccessNote();
|
||||
BtnStop_Click(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable UI elements
|
||||
/// </summary>
|
||||
/// <param name="elm"></param>
|
||||
/// <param name="isEnabled"></param>
|
||||
/// <param name="isVisible"></param>
|
||||
private void UiElmEnable(UIElement elm, Boolean isEnabled, Boolean isVisible = true)
|
||||
{
|
||||
elm.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
elm.Visibility = isVisible ? Visibility.Visible : Visibility.Hidden;
|
||||
elm.IsEnabled = isEnabled;
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill logging window with information
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-07-06" author="Thomas Wiedebusch">
|
||||
/// - Changed to rich text edit with colored output.
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-08-28" author="Thomas Wiedebusch">
|
||||
/// - Avoid output of repeated text or useless empty text.
|
||||
/// </remarks>
|
||||
private void ProcessLog_Handler(Object sender, ProcessLogArgs e)
|
||||
{
|
||||
rtbLog.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// remove unacceptable spacing between the lines
|
||||
rtbLog.Document.LineHeight = 1;
|
||||
|
||||
var color = e.Color ?? Brushes.Black;
|
||||
var text = e.Data;
|
||||
if (!string.IsNullOrEmpty(text) && !text.Equals(_lastLoggingTextToAvoidRepetition))
|
||||
{
|
||||
var tr = new TextRange(rtbLog.Document.ContentEnd, rtbLog.Document.ContentEnd)
|
||||
{
|
||||
Text = text
|
||||
};
|
||||
tr.ApplyPropertyValue(TextElement.ForegroundProperty, color);
|
||||
rtbLog.ScrollToEnd();
|
||||
rtbLog.AppendText(Environment.NewLine);
|
||||
}
|
||||
|
||||
_lastLoggingTextToAvoidRepetition = text;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set values for progress bar, maximum and actual for single process and overall process.
|
||||
/// - Limit values to 0.0..100.0.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-07-18" author="Thomas Wiedebusch">
|
||||
/// - Introduced multi line text with center alignment.
|
||||
/// </remarks>
|
||||
private void ProcessProgress_Handler(Object sender, ProcessProgressArgs e)
|
||||
{
|
||||
if (e.ProgressType == ProcessProgressArgs.ProcessProgressType.MaxOverallProcessSteps)
|
||||
{
|
||||
_maxOverallProcessSteps = e.Progress;
|
||||
}
|
||||
else if (e.ProgressType == ProcessProgressArgs.ProcessProgressType.MaxActualProcessSteps)
|
||||
{
|
||||
_maxSingleProcessSteps = e.Progress;
|
||||
}
|
||||
if (e.ProgressType == ProcessProgressArgs.ProcessProgressType.OverallProcessesSteps)
|
||||
{
|
||||
pbTotalProgress.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
// limit output to progress bar to 0..100 as integer for process bar
|
||||
var progress = _maxOverallProcessSteps <= 0 ? 0.0 : e.Progress * 100.0 / _maxOverallProcessSteps;
|
||||
progress = progress > 100.0 ? 100.0 : progress < 0.0 ? 0.0 : progress;
|
||||
pbTotalProgress.Value = (Int32)progress;
|
||||
UpdateContentControl(lblTotalProgressValue, $@"{progress:##0.0} %");
|
||||
}
|
||||
));
|
||||
}
|
||||
else if (e.ProgressType == ProcessProgressArgs.ProcessProgressType.ActualProcessSteps)
|
||||
{
|
||||
pbSubProgress.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
// limit output to progress bar to 0..100 as integer for process bar
|
||||
var progress = _maxSingleProcessSteps <= 0 ? 0.0 : e.Progress * 100.0 / _maxSingleProcessSteps;
|
||||
progress = progress > 100.0 ? 100.0 : progress < 0.0 ? 0.0 : progress;
|
||||
pbSubProgress.Value = (Int32)progress;
|
||||
UpdateContentControl(lblSubProgressValue, $@"{progress:##0.0} %");
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output message to control without access violation.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-07-11" author="Thomas Wiedebusch">
|
||||
/// - Introduced multi line text with center alignment.
|
||||
/// </remarks>
|
||||
private static void UpdateContentControl(ContentControl ctl, String text)
|
||||
{
|
||||
ctl.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
ctl.Content = new TextBlock()
|
||||
{
|
||||
Text = text,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
TextAlignment = TextAlignment.Center
|
||||
};
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Status grid update for all single processes
|
||||
/// </summary>
|
||||
private void UpdateStatusGrid()
|
||||
{
|
||||
var dt = new DataTable();
|
||||
dt.Columns.Add(Properties.Resources.StrDataTableColumnProcess);
|
||||
dt.Columns.Add(Properties.Resources.StrDataTableColumnState);
|
||||
var i = 0;
|
||||
if (_processCtrl?.Processes == null)
|
||||
return;
|
||||
foreach (var item in _processCtrl.Processes)
|
||||
{
|
||||
dt.Rows.Add();
|
||||
dt.Rows[i][0] = item.ProcessName;
|
||||
dt.Rows[i][1] = ProductionProcessStateHelper.GetTextFromProductionProcessState(item.SingleProcessState);
|
||||
i++;
|
||||
}
|
||||
|
||||
dgTotalProcess.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
dgTotalProcess.DataContext = dt;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatch new user control to main screen
|
||||
/// </summary>
|
||||
/// <param name="uc"></param>
|
||||
private void SetNewUserControl(UserControl uc)
|
||||
{
|
||||
dgTotalProcess.Dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
// remove last userControl
|
||||
dpSubProcess.Children.Clear();
|
||||
if (uc != null)
|
||||
{
|
||||
dpSubProcess.Children.Add(uc);
|
||||
DockPanel.SetDock(uc, Dock.Top); // & Dock.Left);
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
#region TimerControls
|
||||
/// <summary>
|
||||
/// Handle timing depending updates.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2024-07-11" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void TmrProgressUpdate_Tick(Object sender, EventArgs e)
|
||||
{
|
||||
SetTimeDisplay();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Update of status grid with information returned by user control.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-08-28" author="Thomas Wiedebusch">
|
||||
/// - Activate new user control on start of process.
|
||||
/// </remarks>
|
||||
private void SingleProcessStateChanged_Handler(Object sender, SingleProcessStateArgs e)
|
||||
{
|
||||
if (sender is IProductionProcess productionProcess)
|
||||
{
|
||||
if (e.SingleProcessState == SingleProcessState.Running)
|
||||
{
|
||||
// Set new user control
|
||||
SetNewUserControl(productionProcess.GetUserControl());
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove user control on idle, skipped, abort or error
|
||||
SetNewUserControl(null);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStatusGrid();
|
||||
UpdateGuiWithProductInfos();
|
||||
}
|
||||
|
||||
private void OnUserAccessControlCancellation(Control control)
|
||||
{
|
||||
OnUserAccessWindowClosed_Handler(this, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set labels of device information and order number
|
||||
/// </summary>
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-07-15" author="Thomas Wiedebusch">
|
||||
/// - Additional info of Cordonel.
|
||||
/// </remarks>
|
||||
private void UpdateGuiWithProductInfos()
|
||||
{
|
||||
var genesisMeter = _processCtrl?.GetGenesisMeter();
|
||||
_productionRequirements = _processCtrl?.GetProductionRequirements();
|
||||
|
||||
if (genesisMeter == null)
|
||||
return;
|
||||
|
||||
UpdateContentControl(lblOrderNumberValue,
|
||||
genesisMeter.OrderNumber != 0 ? genesisMeter.OrderNumber.ToString() : "?");
|
||||
|
||||
UpdateContentControl(lblRadioAddressValue,
|
||||
genesisMeter.RadioAddress != 0 ? genesisMeter.RadioAddress.ToString() : "");
|
||||
UpdateContentControl(lblRadioAddressText,
|
||||
genesisMeter.RadioAddress != 0 ? Properties.Resources.StrLblRadioAddressTxt + ":" : "");
|
||||
|
||||
UpdateContentControl(lblFwValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.FwVersion) ? genesisMeter.FwVersion : "?");
|
||||
|
||||
UpdateContentControl(lblMeterSizeValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.MeterSize) ? genesisMeter.MeterSize : "?");
|
||||
|
||||
UpdateContentControl(lblLutValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.LutCrc) ? genesisMeter.LutCrc : "?");
|
||||
|
||||
|
||||
UpdateContentControl(lblSerialNumberValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.CustomerSerialNumber) ? genesisMeter.CustomerSerialNumber : "?");
|
||||
|
||||
UpdateContentControl(lblRegionValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.Region) ? genesisMeter.Region : "?");
|
||||
|
||||
UpdateUi(lblPcbIdValue, !string.IsNullOrEmpty(genesisMeter.PcbId) ? genesisMeter.PcbId : "?");
|
||||
|
||||
var msg = "";
|
||||
var color = Brushes.Black;
|
||||
if (_productionRequirements?.IsSpecialActive != null && (Boolean)_productionRequirements.IsSpecialActive &&
|
||||
_productionRequirements?.IsSpecialApproved != null && (Boolean)_productionRequirements.IsSpecialApproved)
|
||||
{
|
||||
msg = $"{Properties.Resources.StrLblSpecialRequirement} - Id.Ver: {_productionRequirements.SpecialId}." +
|
||||
$"{_productionRequirements.SpecialVersion}";
|
||||
color = Brushes.Red;
|
||||
}
|
||||
else if (_productionRequirements?.IsStandardActive != null && (Boolean)_productionRequirements.IsStandardActive &&
|
||||
_productionRequirements?.IsStandardApproved != null && (Boolean)_productionRequirements.IsStandardApproved)
|
||||
{
|
||||
msg = $"{Properties.Resources.StrLblStandardRequirement} - Id.Ver: {_productionRequirements.StandardId}." +
|
||||
$"{_productionRequirements.StandardVersion}";
|
||||
}
|
||||
|
||||
UpdateUi(lblApprovalText, msg, color);
|
||||
}
|
||||
|
||||
//private void BtnSwitchAutoDetect_Click(Object sender, RoutedEventArgs e)
|
||||
//{
|
||||
// //Settings.AutoDetect = !Settings.AutoDetect;
|
||||
// //StoreSetting();
|
||||
// //UseSetting();
|
||||
//}
|
||||
|
||||
private void OnLogout_Click(Object sender, EventArgs e)
|
||||
{
|
||||
Software.Logout();
|
||||
InitializeFormState();
|
||||
}
|
||||
|
||||
private void OnLogin_Click(Object sender, EventArgs args)
|
||||
{
|
||||
ShowUserAccessWindow(true, new LoginForm(OnUserAccessControlCancellation),
|
||||
Properties.Resources.StrLoginMsg);
|
||||
}
|
||||
|
||||
private void OnChangePassword_Click(Object _, EventArgs _1)
|
||||
{
|
||||
ShowUserAccessWindow(true, new ChangePassword(OnUserAccessControlCancellation),
|
||||
Properties.Resources.StrChangePasswordMsg);
|
||||
}
|
||||
|
||||
private void CbxSlotBox_SelectionChanged(Object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void StoreSetting()
|
||||
{
|
||||
Settings.Update("ProductionUiConfig.json");
|
||||
}
|
||||
|
||||
//private void BtnConnect_Click(Object sender, RoutedEventArgs e)
|
||||
//{
|
||||
// Settings.Slot = (Int32)cbxSlotBox.SelectedValue;
|
||||
// StoreSetting();
|
||||
//}
|
||||
|
||||
private void BtnStart_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
UiElmEnable(btnStart, false);
|
||||
UiElmEnable(btnStop, true);
|
||||
|
||||
_startTime = DateTimeOffset.UtcNow;
|
||||
_timer?.Start();
|
||||
|
||||
// remove last userControl
|
||||
dpSubProcess.Children.Clear();
|
||||
rtbLog.Document.Blocks.Clear();
|
||||
_processCtrl?.SetProcessState(ProcessState.DetectCordonel);
|
||||
}
|
||||
|
||||
private void PrintErrorNote()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("========================================================================");
|
||||
sb.AppendLine(Properties.Resources.StrInstructionReturnPapers);
|
||||
sb.AppendLine("========================================================================");
|
||||
CreateFile(sb, out var fileName);
|
||||
Process.Start(fileName);
|
||||
}
|
||||
|
||||
private void StoreSuccessNote(out String fileName)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("========================================================================");
|
||||
sb.AppendLine(Properties.Resources.StrInfoSuccessPapers);
|
||||
sb.AppendLine("========================================================================");
|
||||
CreateFile(sb, out fileName);
|
||||
}
|
||||
|
||||
private void PrintSuccessNote()
|
||||
{
|
||||
StoreSuccessNote(out var fileName);
|
||||
Process.Start(fileName);
|
||||
}
|
||||
|
||||
private void CreateFile(StringBuilder sb, out String fileName)
|
||||
{
|
||||
if (sb == null)
|
||||
sb = new StringBuilder();
|
||||
|
||||
var genesisMeter = _processCtrl.GetGenesisMeter();
|
||||
var loggingPath = $"C:\\GenesisLog\\{DateTime.Now:yyyy-MM-dd}\\ProductionUiCordonel\\";
|
||||
fileName = $"{loggingPath}{DateTime.Now.ToString("yyyyMMddHHmmss")}_Report_{genesisMeter.PcbId}.txt";
|
||||
|
||||
sb.AppendLine(_strSoftwareNameVersion);
|
||||
sb.AppendLine("------------------------------------------------------------------------");
|
||||
sb.AppendLine($"{Properties.Resources.StrDateTime}: {DateTime.Now}");
|
||||
sb.AppendLine("------------------------------------------------------------------------");
|
||||
sb.AppendLine($"PcbId: {genesisMeter.PcbId}");
|
||||
sb.AppendLine($"{Properties.Resources.StrPrintOrderNumberTxt}: {genesisMeter.OrderNumber}");
|
||||
sb.AppendLine($"{Properties.Resources.StrLblSerialNumberTxt}: {genesisMeter.CustomerSerialNumber}");
|
||||
sb.AppendLine($"{Properties.Resources.StrLblOperatorNameText}: {Software.UserName}");
|
||||
sb.AppendLine("------------------------------------------------------------------------");
|
||||
var rtbText = new TextRange(
|
||||
rtbLog.Document.ContentStart,
|
||||
rtbLog.Document.ContentEnd
|
||||
);
|
||||
sb.Append($"{rtbText.Text}");
|
||||
File.WriteAllText(fileName, sb.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop button as user interaction to kill the finalization process
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void BtnStop_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
//set the process state to the state machine
|
||||
_processCtrl?.SetProcessState(ProcessState.Stop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open requirement in Web-Browser.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void LblApprovalText_Click(Object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
var requirementId = 0;
|
||||
var requirementWebPageLink = ServiceUrls.InspectCordonelRequirementInfoServiceUrl();
|
||||
if (_productionRequirements?.SpecialId != null &&
|
||||
_productionRequirements?.IsSpecialApproved != null &&
|
||||
_productionRequirements.SpecialId != 0)
|
||||
{
|
||||
requirementId = (Int32)_productionRequirements.SpecialId;
|
||||
requirementWebPageLink += $"SpecialRequirements#{requirementId}";
|
||||
}
|
||||
else if (_productionRequirements?.StandardId != null &&
|
||||
_productionRequirements?.IsStandardApproved != null &&
|
||||
_productionRequirements.StandardId != 0)
|
||||
{
|
||||
requirementId = (Int32)_productionRequirements.StandardId;
|
||||
requirementWebPageLink += $"StandardRequirements#{requirementId}";
|
||||
}
|
||||
|
||||
if (requirementId != 0)
|
||||
{
|
||||
Process.Start(requirementWebPageLink);
|
||||
}
|
||||
}
|
||||
|
||||
private void HlpMenu_Click(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filename = "";
|
||||
if (Thread.CurrentThread.CurrentCulture.Name.Contains("de"))
|
||||
{
|
||||
filename = Path.Combine(_assemblyExecRootPath, "Docu", @"Handbuch Cordonel Versandfertigmachen (VFM).pdf");
|
||||
}
|
||||
else if (Thread.CurrentThread.CurrentCulture.Name.Contains("en"))
|
||||
{
|
||||
filename = Path.Combine(_assemblyExecRootPath, "Docu", @"Manual Cordonel End of Line Test (EOL).pdf");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
Process.Start(filename);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Loaded(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!Software.IsAutenticated)
|
||||
OnLogin_Click(this, null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-77
@@ -14,18 +14,18 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public class BaseProcessStates
|
||||
public class BaseProcessStatesDef : IProcessStateDef
|
||||
{
|
||||
/// <summary>
|
||||
/// Collection of state information
|
||||
/// </summary>
|
||||
protected List<ProcessStateStruct> StateContainer { get; }
|
||||
public List<ProcessStateStruct> StateContainer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ctor:
|
||||
/// Initialize all hidden standard generic states
|
||||
/// </summary>
|
||||
protected BaseProcessStates()
|
||||
protected BaseProcessStatesDef()
|
||||
{
|
||||
StateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
@@ -81,14 +81,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the process start struct linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process state struct of the attached state</returns>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public ProcessStateStruct GetProcessStateStructOfState(ProcessState stateMachineState)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
@@ -96,14 +89,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the process linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process attached to the state</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public IProductionProcess GetProcessOfState(ProcessState stateMachineState)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
@@ -111,17 +97,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer.ProductionProcess).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current information of the state machine state
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>information attached to state depending on region</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Mar-18" author="Thomas Wiedebusch">
|
||||
/// - If state == null return error message.
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public String GetStateInfoOfState(ProcessState? stateMachineState)
|
||||
{
|
||||
if (stateMachineState == null)
|
||||
@@ -132,14 +108,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer.ProcessInfo).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the info text from production process
|
||||
/// </summary>
|
||||
/// <param name="process">process to look for state info text</param>
|
||||
/// <returns>information attached to process depending on region</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public String GetStateInfoOfProcess(IProductionProcess process)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
@@ -147,14 +116,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer.ProcessInfo).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the state machine state of the text
|
||||
/// </summary>
|
||||
/// <param name="text">information text to search if state is assigned</param>
|
||||
/// <returns>state attached to information text</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public ProcessState GetStateOfInfoText(String text)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
@@ -162,14 +124,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer.ProcessState).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the state machine state from for the process
|
||||
/// </summary>
|
||||
/// <param name="process">process to look for state info text</param>
|
||||
/// <returns>state attached to process</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public ProcessState GetStateOfProcess(IProductionProcess process)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
@@ -177,34 +132,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
select stateContainer.ProcessState).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get number of EOL relevant processes for statistic e.g. progress bar
|
||||
/// </summary>
|
||||
/// <returns>number of initialized processes</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Used marker for production relevant processes
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public Int32 GetNumberOfInitializedProcesses()
|
||||
{
|
||||
return StateContainer.Count(stateContainer => stateContainer.ProductionProcessNo != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a sorted list of all production processes in order of the execution sequence
|
||||
/// </summary>
|
||||
/// <returns>list of initialized processes</returns>
|
||||
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Used marker for production relevant processes
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
|
||||
/// - Changed to sorted list by production process number
|
||||
/// </remarks>
|
||||
///<inheritdoc/>
|
||||
public List<IProductionProcess> GetAllEolRelevantProcesses()
|
||||
{
|
||||
var sortedList = StateContainer
|
||||
+1
-1
@@ -590,7 +590,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
}
|
||||
|
||||
// Set the information of this software
|
||||
EolProgress.EOLSoftwareNameAndVersion = $"{Resources.StrSoftwareNameVersion} " +
|
||||
EolProgress.EOLSoftwareNameAndVersion = $"{Resources.StrEolSoftwareNameVersion} " +
|
||||
$"{Assembly.GetExecutingAssembly().GetName().Version}";
|
||||
|
||||
return EolProgress.EOLSoftwareNameAndVersion;
|
||||
|
||||
+109
-78
@@ -7,22 +7,46 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation for all production process states:
|
||||
/// - Production process class (representing a production process step),
|
||||
/// - Production process class (representing a production process step), null if hidden process,
|
||||
/// - attached state,
|
||||
/// - state information to display a text message.
|
||||
/// - state information to display a text message,
|
||||
/// - production process number to define where to display in the overview,
|
||||
/// - next state which should be executed after this succeeded,
|
||||
/// [optional]:
|
||||
/// - own error state,
|
||||
/// - own break state,
|
||||
/// - kick off state for parallel execution after starting this process in a separate task,
|
||||
/// - wait for single process to finish successfully,
|
||||
/// - wait for all processes to finish successfully,
|
||||
/// - start always independent of any result, e.g. the error state needs to be started if called!
|
||||
/// </summary>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public class EolStateMachineDef : BaseProcessStates
|
||||
public class EolProcessStateDef : BaseProcessStatesDef
|
||||
{
|
||||
/// <summary>
|
||||
/// State-machine definitions of production-processes which feeds the state-machine.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR PREPARATION:
|
||||
/// -----------------------------
|
||||
/// STEP 1: Define some states for your processes <see cref="ProcessState"/>
|
||||
/// STEP 2: Implement your processes like <see cref="DetectCordonel"/>
|
||||
/// STEP 3: Register and chain your states here
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR NORMAL USAGE:
|
||||
/// -----------------------------
|
||||
///
|
||||
/// Means one state automatically switched on successfully execution to the next required state.
|
||||
///
|
||||
/// Define the (e.g.):
|
||||
/// productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
|
||||
/// processState: ProcessState.DetectCordonel,
|
||||
/// processInfo: Resources.StrStateDetectCordonel,
|
||||
/// productionProcessNo: 0,
|
||||
/// nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
///
|
||||
/// If a special state is needed on errorExitState or breakExitState these can be assigned. Otherwise, the
|
||||
/// "errorExitState" is linked to the generic-error-state, the "breakExitState" to the abort-test-state.
|
||||
///
|
||||
@@ -33,30 +57,53 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// other. One example is a database access for data collection from different tables.
|
||||
///
|
||||
/// This is needed for non-blocking immediately new state change (not waiting for the successful execution of
|
||||
/// the actual new assigned process):
|
||||
/// E.g. all DB accesses need a certain time to get data, kicking off (fire and forget) the process without
|
||||
/// waiting for the result, the "nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion"
|
||||
/// has to be set to avoid a state change on successfully execution of the process.
|
||||
/// Instead, the "kickOffParallelState" has to be defined to immediately start the next process.
|
||||
/// the actual new assigned process).
|
||||
///
|
||||
/// Define the (e.g.):
|
||||
///
|
||||
/// INSTRUCTION TO DELAY THE START OF A PROCESS:
|
||||
/// --------------------------------------------
|
||||
/// productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
/// processState: ProcessState.ConnectCordonel,
|
||||
/// processInfo: Resources.StrStateConnectCordonel,
|
||||
/// productionProcessNo: 1,
|
||||
/// // Avoid automatic change after completion as parallel process is active
|
||||
/// nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
/// // Kick off parallel process execution after starting the "ConnectCordonel() task"
|
||||
/// kickOffParallelState: ProcessState.GetSerialNumberAndRadioAddress),
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION TO DELAY THE START OF A PROCESS AND WAIT ON RESULTS OF OTHER PROCESS(ES):
|
||||
/// -------------------------------------------------------------------------------------
|
||||
/// Each new process execution can be delayed as it may need the result of another process which is active.
|
||||
///
|
||||
/// Wait for a single process to complete:
|
||||
/// - set the "waitForSingleProcess" to the process-state to wait for.
|
||||
/// Set the "waitForSingleProcess" to the state of the process needed to wait for (e.g.):
|
||||
///
|
||||
/// productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
/// processState: ProcessState.CheckProductionState,
|
||||
/// processInfo: Resources.StrStateCheckProductionState,
|
||||
/// productionProcessNo: 4,
|
||||
/// // Avoid automatic change after completion as parallel process is active
|
||||
/// nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
/// // Kick off parallel process execution after starting
|
||||
/// kickOffParallelState: ProcessState.ProcessPasswordFile,
|
||||
/// // Wait until this process has been successfully completed
|
||||
/// waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
///
|
||||
/// Wait for all preceding processes to complete:
|
||||
/// - set the "waitForAllProcesses" to true.
|
||||
/// Wait for all preceding processes to complete to be sure to get all data and all processed are succeeded:
|
||||
/// Set the "waitForAllProcesses" to true (e.g.):
|
||||
/// productionProcess: new ExecPasswordFile(Resources.StrStatePasswordFile),
|
||||
/// processState: ProcessState.ProcessPasswordFile,
|
||||
/// processInfo: Resources.StrStatePasswordFile,
|
||||
/// productionProcessNo: 5,
|
||||
/// nextStateOnSuccess: ProcessState.ExecFinalParametrization,
|
||||
/// waitForAllProcesses: true),
|
||||
///
|
||||
/// </summary>
|
||||
public EolStateMachineDef()
|
||||
public EolProcessStateDef()
|
||||
{
|
||||
var stateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
#region ----------------------------------- GENERIC-STATES---------------------------------------------
|
||||
// Usage of the generic-state to detect the Cordonel on the communication line (request protocol)
|
||||
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
|
||||
// to change the state after successfully execution. The detection is the base for all others.
|
||||
new ProcessStateStruct(
|
||||
@@ -66,7 +113,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcessNo: 0,
|
||||
nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
|
||||
// Usage of the generic-state to check for new meter
|
||||
// Detection of Cordonel has to be completed before assigning next state. It has to be checked if
|
||||
// the meter changed to clear all collected contents of previous run. To UPDATE ALL INFORMATION after
|
||||
// new meter assignment the "DetectCordonel" has to be repeated to return here "Old Meter" and then
|
||||
@@ -79,7 +125,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
nextStateOnSuccess: ProcessState.DetectCordonel,
|
||||
errorExitState: ProcessState.ConnectCordonel),
|
||||
|
||||
// Usage of the generic-state to connect the Cordonel
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
@@ -92,7 +137,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetSerialNumberAndRadioAddress),
|
||||
|
||||
// Usage of the generic-state to get the serial-number and radio-address
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
@@ -105,6 +149,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState:ProcessState.GetProgrammingParameters),
|
||||
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
ProcessState.CheckOrderNumber,
|
||||
Resources.StrStateCheckOrderNumber,
|
||||
11,
|
||||
ProcessState.CheckSerialNumber),
|
||||
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
ProcessState.CheckSerialNumber,
|
||||
Resources.StrStateCheckSerialNumber,
|
||||
12,
|
||||
ProcessState.CheckAttachments),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- EOL-STATES ------------------------------------------------
|
||||
@@ -124,7 +184,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
@@ -142,7 +201,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The connection process has to be completed as a password change in the DB
|
||||
// will take place: Skeleton to Password Level 8. Not waiting for completion may cause side
|
||||
// effects on login. Wait for all processes to complete.
|
||||
@@ -156,7 +214,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
nextStateOnSuccess: ProcessState.ExecFinalParametrization,
|
||||
waitForAllProcesses: true),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This writes all setups to the device, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecFinalParametrization(Resources.StrStateFinalParametrization),
|
||||
@@ -165,7 +222,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcessNo: 6,
|
||||
nextStateOnSuccess: ProcessState.ExecStoreConfiguration),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The final parametrization has to be finished as this shall be stored
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Store configuration has to be executed exclusively with automatic
|
||||
@@ -176,86 +232,61 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcessNo: 7,
|
||||
nextStateOnSuccess: ProcessState.RebootCordonel),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The store configuration has to be executed to safe all settings
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Reboot has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecRebootCordonel(Resources.StrStateRebootCordonel),
|
||||
processState: ProcessState.RebootCordonel,
|
||||
processInfo: Resources.StrStateRebootCordonel,
|
||||
productionProcess: new ExecRebootCordonel(Resources.StrStateRebootCordonel),
|
||||
processState: ProcessState.RebootCordonel,
|
||||
processInfo: Resources.StrStateRebootCordonel,
|
||||
productionProcessNo: 8,
|
||||
nextStateOnSuccess: ProcessState.CheckFinalParametrization),
|
||||
nextStateOnSuccess: ProcessState.CheckFinalParametrization),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The reboot process including the store all configurations has to be
|
||||
// completed.
|
||||
// Check final configuration has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckFinalParametrization(Resources.StrStateCheckParametrization),
|
||||
ProcessState.CheckFinalParametrization,
|
||||
Resources.StrStateCheckParametrization,
|
||||
9,
|
||||
ProcessState.CheckRadio),
|
||||
productionProcess: new CheckFinalParametrization(Resources.StrStateCheckParametrization),
|
||||
processState: ProcessState.CheckFinalParametrization,
|
||||
processInfo: Resources.StrStateCheckParametrization,
|
||||
productionProcessNo:9,
|
||||
nextStateOnSuccess: ProcessState.CheckRadio),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The final parametrization, reboot process including the store all
|
||||
// configurations and the check of all setups survived the reboot have to be completed.
|
||||
// Radio signal level check, skipped on NA region or if skipping is required by special
|
||||
// approval
|
||||
new ProcessStateStruct(
|
||||
new CheckRadio(Resources.StrStateRadioCheck),
|
||||
ProcessState.CheckRadio,
|
||||
Resources.StrStateRadioCheck,
|
||||
10,
|
||||
ProcessState.CheckOrderNumber),
|
||||
productionProcess: new CheckRadio(Resources.StrStateRadioCheck),
|
||||
processState: ProcessState.CheckRadio,
|
||||
processInfo: Resources.StrStateRadioCheck,
|
||||
productionProcessNo:10,
|
||||
nextStateOnSuccess: ProcessState.CheckOrderNumber),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
ProcessState.CheckOrderNumber,
|
||||
Resources.StrStateCheckOrderNumber,
|
||||
11,
|
||||
ProcessState.CheckSerialNumber),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
ProcessState.CheckSerialNumber,
|
||||
Resources.StrStateCheckSerialNumber,
|
||||
12,
|
||||
ProcessState.CheckAttachments),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new CheckAttachments(Resources.StrStateCheckAttachments),
|
||||
ProcessState.CheckAttachments,
|
||||
Resources.StrStateCheckAttachments,
|
||||
13,
|
||||
ProcessState.ExecVisualInspection),
|
||||
productionProcess: new CheckAttachments(Resources.StrStateCheckAttachments),
|
||||
processState: ProcessState.CheckAttachments,
|
||||
processInfo: Resources.StrStateCheckAttachments,
|
||||
productionProcessNo:13,
|
||||
nextStateOnSuccess: ProcessState.ExecVisualInspection),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new VisualInspection(Resources.StrStateVisualInspection),
|
||||
ProcessState.ExecVisualInspection,
|
||||
Resources.StrStateVisualInspection,
|
||||
14,
|
||||
ProcessState.PrepareShippingMode),
|
||||
productionProcess: new VisualInspection(Resources.StrStateVisualInspection),
|
||||
processState: ProcessState.ExecVisualInspection,
|
||||
processInfo: Resources.StrStateVisualInspection,
|
||||
productionProcessNo:14,
|
||||
nextStateOnSuccess: ProcessState.PrepareShippingMode),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new PrepareShipping(Resources.StrStatePrepareShipping),
|
||||
ProcessState.PrepareShippingMode,
|
||||
Resources.StrStatePrepareShipping,
|
||||
15,
|
||||
ProcessState.ReadyForShipping),
|
||||
productionProcess: new PrepareShipping(Resources.StrStatePrepareShipping),
|
||||
processState: ProcessState.PrepareShippingMode,
|
||||
processInfo: Resources.StrStatePrepareShipping,
|
||||
productionProcessNo:15,
|
||||
nextStateOnSuccess: ProcessState.ReadyForShipping),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
new ProcessStateStruct(
|
||||
productionProcess: null,
|
||||
processState:ProcessState.ReadyForShipping,
|
||||
+11
-2
@@ -86,6 +86,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
|
||||
/// - CancellationToken.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Retries for installation of password file.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
// Uncheck executed process to leave the result open needed for retries
|
||||
@@ -184,8 +187,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
|
||||
if (!Meter.IsLoggedOn)
|
||||
Meter.Login();
|
||||
retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile();
|
||||
retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile();
|
||||
|
||||
// Install and check password file
|
||||
var retryCtr = 2;
|
||||
do
|
||||
{
|
||||
retValBol = _meterPwdFile.UnlockEraseWriteMeterPwdFile();
|
||||
retValBol &= _meterPwdFile.WriteMeterPwdFile() && _meterPwdFile.VerifyMeterPwdFile();
|
||||
} while (retryCtr-- > 0 && !retValBol);
|
||||
|
||||
ActualProcessProgress++;
|
||||
if (!retValBol)
|
||||
|
||||
-192
@@ -1,192 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionCheckShippingState : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionCheckShippingState()
|
||||
{
|
||||
name = "Prüfe versandbereitschaft des Zählers";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Hydraulisch geprüft? Batterie i.O?";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
|
||||
private void doStartProcessLoop()
|
||||
{
|
||||
var retriesRemaining = 1;
|
||||
while (retriesRemaining >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Progress = 0;
|
||||
//var url = $"http://localhost:56011/api/FinalCheck/GetProgrammingParameters?PcbID={Meter.PcbId}";
|
||||
var url = $"{ServiceUrls.MeterInfoForTestBench()}{Meter.PcbId}";
|
||||
var csdRet = LocalWebRequest.GetRequest(url);
|
||||
|
||||
var res = JsonConvert.DeserializeObject<String[]>(csdRet);
|
||||
|
||||
var CalibrationRun = res[4];
|
||||
var LastTestBechState = 0;
|
||||
Boolean? HyState;
|
||||
Boolean? preState = null;
|
||||
if (!string.IsNullOrEmpty(res[5]))
|
||||
{
|
||||
int.TryParse(res[5], out var tmp);
|
||||
LastTestBechState = tmp;
|
||||
}
|
||||
|
||||
if (LastTestBechState <= 20)
|
||||
{
|
||||
HyState = null;
|
||||
}
|
||||
else if (LastTestBechState <= 30)
|
||||
{
|
||||
HyState = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HyState = false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(CalibrationRun))
|
||||
{
|
||||
preState = true;
|
||||
}
|
||||
|
||||
|
||||
if (!HyState.HasValue || !HyState.Value)
|
||||
{
|
||||
UserControl.lblText.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
UserControl.lblText.Content = "Zähler nicht erfolgreich geprüft";
|
||||
}
|
||||
));
|
||||
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
if (!preState.HasValue || !preState.Value)
|
||||
{
|
||||
UserControl.lblText.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
UserControl.lblText.Content = "Zähler nicht erfolgreich vorbehandelt";
|
||||
}
|
||||
));
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
Progress = 50;
|
||||
|
||||
var genesisStatus = new GenesisStatus();
|
||||
|
||||
// this calculates all life time values
|
||||
if (!GenesisStatusHandler.BuildLifeTimeInformation(Meter, genesisStatus))
|
||||
{
|
||||
|
||||
UserControl.lblText.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
UserControl.lblText.Content = "Batterie nicht lesbar";
|
||||
}
|
||||
));
|
||||
Meter.WriteLog("Batterie nicht lesbar");
|
||||
break;
|
||||
}
|
||||
|
||||
//lastFrame
|
||||
Meter.WriteLog($"totalUsed at EOL {genesisStatus.DrainedBatteryLoadPercent:F2}");
|
||||
if (res[1] == "3212095")
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (genesisStatus.RemainingLifeTimeYears < 20)
|
||||
{
|
||||
if (genesisStatus.DrainedBatteryLoadPercent > 8)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
UserControl.lblText.Content = "Batterie über 10% entladen";
|
||||
Meter.WriteLog("Batterie über 10% entladen");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
//;
|
||||
if (Meter.LutCrc != $@"0x{int.Parse(res[8]):X4}")
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
UserControl.lblText.Content = "Lut not correct";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (currentProcessState != ProductionProcessState.Error)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
retriesRemaining -= 1;
|
||||
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Meter.WriteLog($"{ex}");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
retriesRemaining -= 1;
|
||||
}
|
||||
}
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
doStartProcessLoop();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessDone : BaseProductionProcess
|
||||
{
|
||||
public event EventHandler<Tuple<Boolean,Boolean, Boolean>> isDone;
|
||||
private UcDialog UserControl;
|
||||
public DialogResult Result = DialogResult.None;
|
||||
public enum DialogResult
|
||||
{
|
||||
None,
|
||||
Retry,
|
||||
Print,
|
||||
Abort
|
||||
}
|
||||
public Boolean DialogIsDone { get; }
|
||||
private Boolean Error;
|
||||
public ProductionProcessDone(Boolean error = false)
|
||||
{
|
||||
Error = error;
|
||||
DialogIsDone = false;
|
||||
name = "Fertig";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcDialog();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
var retry = false;
|
||||
var abort = false;
|
||||
var print = false;
|
||||
if (Error)
|
||||
{
|
||||
switch (Result)
|
||||
{
|
||||
|
||||
case DialogResult.Retry:
|
||||
retry = true;
|
||||
break;
|
||||
case DialogResult.Print:
|
||||
abort = true;
|
||||
print = true;
|
||||
break;
|
||||
case DialogResult.Abort:
|
||||
abort = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isDone?.Invoke(null, new Tuple<Boolean, Boolean,Boolean>(retry, abort, print));
|
||||
}
|
||||
|
||||
private void StepError(String ErrorText = "Ein Fehler ist aufgetreten")
|
||||
{
|
||||
|
||||
UserControl.SetDesc(ErrorText);
|
||||
var errorOptionList = new List<UcDialog.DialogOption>();
|
||||
var retry = new UcDialog.DialogOption("Wiederholen", "Alle Schritte werden wiederholt", () =>
|
||||
{
|
||||
Result = DialogResult.Retry;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var Abort = new UcDialog.DialogOption("Abbruch", "Diesen Zähler NICHT verpacken", () =>
|
||||
{
|
||||
Result = DialogResult.Abort;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
var print = new UcDialog.DialogOption("Rückläuferschein drucken", "Rückläuferschein beim Zähler lassen und auf Klärung durch QS warten", () =>
|
||||
{
|
||||
Result = DialogResult.Print;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
|
||||
errorOptionList.Add(retry);
|
||||
errorOptionList.Add(Abort);
|
||||
errorOptionList.Add(print);
|
||||
|
||||
UserControl.SetDialogOptions(errorOptionList);
|
||||
}
|
||||
|
||||
private void StepSuccsess()
|
||||
{
|
||||
|
||||
UserControl.SetDesc("Zähler verpacken");
|
||||
var OptionList = new List<UcDialog.DialogOption>();
|
||||
var retry = new UcDialog.DialogOption("Ok", "", () =>
|
||||
{
|
||||
Result = DialogResult.None;
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
|
||||
OptionList.Add(retry);
|
||||
|
||||
UserControl.SetDialogOptions(OptionList);
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
if (Error)
|
||||
{
|
||||
StepError();
|
||||
}
|
||||
else
|
||||
{
|
||||
StepSuccsess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-364
@@ -1,364 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParameterization : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessFinalParameterization()
|
||||
{
|
||||
name = "Final Parameterization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {this.GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, int addToCheck = 10, int addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var accucalValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (accucalValue >= (value + addFromCheck) && value <= accucalValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
|
||||
base.Progress = 0;
|
||||
|
||||
var useRadio = true;
|
||||
var radioParams = new RadioConfigurationParams();
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
|
||||
|
||||
var url = ServiceUrls.GenesisFinalCheckServiceUrl();
|
||||
url = url + $"GetRadioConfiguration?PcbId={Meter.PcbId}";
|
||||
|
||||
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
http.Method = "GET";
|
||||
http.Timeout = 2000;
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
radioParams = JsonConvert.DeserializeObject<RadioConfigurationParams>(responseJson);
|
||||
}
|
||||
}
|
||||
base.Progress = 20;
|
||||
|
||||
|
||||
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
|
||||
//Alarms
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_MainAlarmMask?
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_ExtendedAlarmMask ?
|
||||
//CUSTOMER_AlarmBroadcastMask?
|
||||
//CUSTOMER_AlarmEnableMask ?
|
||||
//CUSTOMER_AlarmVisualAutoClearMask?
|
||||
//CUSTOMER_AlarmVisualMask ?
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//Meter.SetLcdText(true, null);
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister(Register.Customer.TriggerAlarmCancel,
|
||||
// (new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_LeakFlowThreshold", 375, true, true, 1, -1));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_ExcessFlowVolumeThreshold", 25000, true, true, 1, -1));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ExcessFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_LeakTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x4E, 0xC0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_Locale",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xD0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x0B, 0x71, 0xB0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x75, 0x30 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ReverseFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x78 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0xF4 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x14 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ArrowThreshold",
|
||||
(new Byte[] { 0x00, 0x1E, 0x84, 0x80 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayPow10",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xFD }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ForwardArrow",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_HardErrorLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LedMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", (new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", 60 << 16, true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xC8 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MeterSize",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_PipeFillingDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1E }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SampleRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_UpdateThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_AdapterPresenceLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x60 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_PulseReportRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowPoint",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x03, 0xF5 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureRate",
|
||||
(new Byte[] { 0x00, 0x0D, 0xBB, 0xA0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseLength",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseWeight",
|
||||
(new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_TemperatureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_AverageFlowPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateDayOfMonth",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateReadingContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_PeriodicLogLifeTimeCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_BatterySelection",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_WarnFromClamp",
|
||||
(new Byte[] { 0x25, 0x89, 0x06, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_WakeupInterval",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_MbusState",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_UtcTimeOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
//// just read later //overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_FrequencyIndicator}).Reverse(), true, true);
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_HistoricalAlarmsDays",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1D }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
//Original
|
||||
//0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44
|
||||
//Write to register
|
||||
//0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42, 0x41
|
||||
|
||||
|
||||
//good one
|
||||
//E6-C8-88-00-DE-B8-68-C0-D6-A8-48-80-CE-98-28-40
|
||||
//0E-05-04-04-00-14-30-68-D0-14-0E-80-40-63-93-73-22
|
||||
|
||||
//&bad one
|
||||
//0E-05-04-05-00-00-88-C8-E6-C0-68-B8-DE-80-48-A8-D6-40-28-98-CE
|
||||
|
||||
|
||||
//0E-05-04-04-00-22-73-93-63-40-80-0E-14-D0-68-30-14
|
||||
|
||||
if (useRadio)
|
||||
{
|
||||
|
||||
|
||||
//var funkadresse = new List<byte>();
|
||||
//funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(),
|
||||
// true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey",
|
||||
(new Byte[]
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}).ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_RadioAddress", radioParams.RadioAddress, true, true));
|
||||
|
||||
if (radioParams.PowerLevel > 0 && radioParams.PowerLevelOption > 0 && radioParams.ImpedanceCodeNew > 0 && radioParams.ImpedanceCodeOption > 0)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevel", radioParams.PowerLevel, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevelOption", radioParams.PowerLevelOption, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeNew", radioParams.ImpedanceCodeNew, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeOption", radioParams.ImpedanceCodeOption, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_currentGenesis_WriteRegister("SENSUSRADIO_CustomerText",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
////radio end state!
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var ret = true;
|
||||
int done = 0;
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} succeed");
|
||||
}
|
||||
else
|
||||
{
|
||||
base.NewStatus($"set Parameter {cTask.Result.Item1} failed");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
base.Progress = 20 + ((Int32)Math.Round(((Double)done / (Double)overAllResult.Count) * 80, 0));
|
||||
done = done + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
base.currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-355
@@ -1,355 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParametrizationFix : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessFinalParametrizationFix()
|
||||
{
|
||||
name = "Final Parametrization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false, Int32 addToCheck = 10, Int32 addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var accucalValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (accucalValue >= (value + addFromCheck) && value <= accucalValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
Progress = 0;
|
||||
|
||||
RadioConfigurationParams radioParams;
|
||||
{
|
||||
var url = "http://localhost:56011/api/FinalCheck/";
|
||||
url += $"GetRadioConfiguration?PcbId={Meter.PcbId}&withPressure=false";
|
||||
|
||||
var http = (HttpWebRequest)WebRequest.Create(url);
|
||||
http.Method = "GET";
|
||||
http.Timeout = 20000;
|
||||
var response = (HttpWebResponse)http.GetResponse();
|
||||
var responseStream = response.GetResponseStream();
|
||||
if (responseStream == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
using (var sr = new StreamReader(responseStream))
|
||||
{
|
||||
var responseJson = sr.ReadToEnd();
|
||||
radioParams = JsonConvert.DeserializeObject<RadioConfigurationParams>(responseJson);
|
||||
}
|
||||
}
|
||||
Progress = 20;
|
||||
|
||||
|
||||
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
|
||||
//Alarms
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_MainAlarmMask?
|
||||
////_currentGenesis.WriteRegister("SENSUSRADIO_ExtendedAlarmMask ?
|
||||
//CUSTOMER_AlarmBroadcastMask?
|
||||
//CUSTOMER_AlarmEnableMask ?
|
||||
//CUSTOMER_AlarmVisualAutoClearMask?
|
||||
//CUSTOMER_AlarmVisualMask ?
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//Meter.SetLcdText(true, null);
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister(Register.Customer.TriggerAlarmCancel,
|
||||
// (new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_LeakFlowThreshold", 375, true, true, 1, -1));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("CUSTOMER_ExcessFlowVolumeThreshold", 25000, true, true, 1, -1));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ExcessFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_LeakTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x4E, 0xC0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_Locale",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xD0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x0B, 0x71, 0xB0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x02, 0x58 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_PressureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x75, 0x30 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_ReverseFlowTimeThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x78 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureHighThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0xF4 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x01, 0x2C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_TemperatureLowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x14 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ArrowThreshold",
|
||||
(new Byte[] { 0x00, 0x1E, 0x84, 0x80 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayPow10",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xFD }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_DisplayUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ForwardArrow",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_HardErrorLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LedMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", (new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowMaxPeriod", 60 << 16, true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_LowFlowThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0xC8 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MeterSize",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_PipeFillingDelay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1E }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SampleRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MinValidAmplitude",
|
||||
(new Byte[] { 0x25, 0x80, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_MaxValidDeltaToF",
|
||||
(new Byte[] { 0x00, 0x03, 0xC6, 0x5E }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_UpdateThreshold",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_AdapterPresenceLimit",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x60 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("IRDA_PulseReportRate",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowPoint",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_FlowUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x03, 0xF5 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressurePresent",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureRate",
|
||||
(new Byte[] { 0x00, 0x0D, 0xBB, 0xA0 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PressureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseLength",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseMode",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_PulseWeight",
|
||||
(new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("METROLOGYASST_TemperatureUnits",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_BatterySelection",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("POWERMON_WarnFromClamp",
|
||||
(new Byte[] { 0x25, 0x89, 0x06, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
//// just read later //overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_FrequencyIndicator}).Reverse(), true, true);
|
||||
|
||||
//Original
|
||||
//0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44
|
||||
//Write to register
|
||||
//0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42, 0x41
|
||||
|
||||
//good one
|
||||
//E6-C8-88-00-DE-B8-68-C0-D6-A8-48-80-CE-98-28-40
|
||||
//0E-05-04-04-00-14-30-68-D0-14-0E-80-40-63-93-73-22
|
||||
|
||||
//&bad one
|
||||
//0E-05-04-05-00-00-88-C8-E6-C0-68-B8-DE-80-48-A8-D6-40-28-98-CE
|
||||
|
||||
//0E-05-04-04-00-22-73-93-63-40-80-0E-14-D0-68-30-14
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_WakeupInterval",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_MbusState",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_UtcTimeOffset",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_HistoricalAlarmsDays",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x1D }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_AverageFlowPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x05 }).Reverse().ToArray(), true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_DataLogPeriod",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x3C }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateDayOfMonth",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_FixedDateReadingContents",
|
||||
(new Byte[] { 0x0C, 0x00, 0x24, 0x03 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_PeriodicLogLifeTimeCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x0 }).Reverse().ToArray(), true, true));
|
||||
|
||||
//var funkadresse = new List<byte>();
|
||||
//funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
//funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(),
|
||||
// true, true));
|
||||
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey",
|
||||
// (new Byte[]
|
||||
// {
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
// }).ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var funkadresse = new List<Byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0x0E, 0x9F, 0xAC, 0xC6 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xA0, 0xE1, 0xEF, 0x1C }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0x3B, 0x27, 0xA4, 0x9B }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xAC, 0x21, 0x65, 0x35 }).ToArray());
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_RadioAddress", radioParams.RadioAddress, true, true));
|
||||
|
||||
if (radioParams.PowerLevel > 0 && radioParams.PowerLevelOption > 0 && radioParams.ImpedanceCodeNew > 0 && radioParams.ImpedanceCodeOption > 0)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevel", radioParams.PowerLevel, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_PowerLevelOption", radioParams.PowerLevelOption, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeNew", radioParams.ImpedanceCodeNew, true, true));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_ImpedanceCodeOption", radioParams.ImpedanceCodeOption, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
//_currentGenesis_WriteRegister("SENSUSRADIO_CustomerText",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, false);
|
||||
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
////radio end state!
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0xFF }).Reverse().ToArray(), true, false));
|
||||
|
||||
//overAllResult.Add(_currentGenesis_WriteRegister("SENSUSRADIO_SystemState",
|
||||
// (new Byte[] { 0x00, 0x00, 0x00, 0x02 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
|
||||
var ret = true;
|
||||
Int32 done = 0;
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
NewStatus($"set Parameter {cTask.Result.Item1} succeed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NewStatus($"set Parameter {cTask.Result.Item1} failed");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Progress = 20 + ((Int32)Math.Round((done / (Double)overAllResult.Count) * 80, 0));
|
||||
done += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-273
@@ -1,273 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.ProductionOrderCore;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFinalParametrizationVakoCsd : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
private ProductionProcessConnect connectProcess;
|
||||
private Boolean hasRadio;
|
||||
|
||||
public ProductionProcessFinalParametrizationVakoCsd(ProductionProcessConnect connectProcess, Boolean registerHasRadio = true)
|
||||
{
|
||||
this.connectProcess = connectProcess;
|
||||
name = "Kunden Parametrierung";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
hasRadio = registerHasRadio;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain
|
||||
{
|
||||
lblHl =
|
||||
{
|
||||
Content = name
|
||||
},
|
||||
lblText =
|
||||
{
|
||||
Content = "Dieser Vorgang kann bis zu 1 Minute dauern!"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public Task<Tuple<String, Boolean>> _currentGenesis_WriteRegister<T>(String reg, T value, Boolean waitForResult = true,
|
||||
Boolean checkRegister = false)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Task.Delay(10).Wait();
|
||||
var ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
if (!ret)
|
||||
{
|
||||
ret = Meter.WriteRegister(reg, value, waitForResult, checkRegister);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, ret);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public Task<Tuple<String, Boolean>> wirteRegisterInBetweenCheck(String reg, Int32 value, Boolean waitForResult = true,
|
||||
Int32 addToCheck = 10, Int32 addFromCheck = 0)
|
||||
{
|
||||
return new Task<Tuple<String, Boolean>>(() =>
|
||||
{
|
||||
Meter.WriteRegister(reg, value, waitForResult);
|
||||
|
||||
var actualValue = RegisterConverter.ConvertTo<Int32>(Meter.ReadRegister(reg));
|
||||
if (actualValue >= (value + addFromCheck) && value <= actualValue + (addToCheck))
|
||||
{
|
||||
return new Tuple<String, Boolean>(reg, true);
|
||||
}
|
||||
return new Tuple<String, Boolean>(reg, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void doStartProcessLoop()
|
||||
{
|
||||
var remainingRetries = 4;
|
||||
while (remainingRetries >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (connectProcess.asyncProgrammingParametersTask.Status == TaskStatus.Running)
|
||||
{
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
if (connectProcess.asyncProgrammingParametersTask.Status == TaskStatus.RanToCompletion
|
||||
&& connectProcess.asyncProgrammingParametersTask.Result != null
|
||||
&& connectProcess.asyncProgrammingParametersTask.Result.Any())
|
||||
{
|
||||
var myJsonResponse = connectProcess.asyncProgrammingParametersTask.Result;
|
||||
|
||||
Progress = 15;
|
||||
|
||||
//fix
|
||||
// CUSTOMER_LeakFlowThreshold
|
||||
//CUSTOMER_ExcessFlowVolumeThreshold
|
||||
|
||||
var overAllResult = new List<Task<Tuple<String, Boolean>>>();
|
||||
//611.219.280
|
||||
//
|
||||
var ts = DateTimeOffset.UtcNow - new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(0));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true));
|
||||
|
||||
// keien frq aber radio parameter
|
||||
if (!Meter.RadioFrequencyMhz.HasValue && myJsonResponse.Any(a => a.RegisterName.Contains("RADIO")))
|
||||
{
|
||||
throw new ApplicationException("Radio inconsistent between meter and programmingparameters");
|
||||
}
|
||||
// eine frequen aber keine radio parameter
|
||||
if (Meter.RadioFrequencyMhz.HasValue && !myJsonResponse.Any(a => a.RegisterName.Contains("RADIO")))
|
||||
{
|
||||
throw new ApplicationException("Radio inconsistent between meter and programmingparameters");
|
||||
}
|
||||
foreach (var item in myJsonResponse.Where(m => m.Source == ProgrammingSource.Vako))
|
||||
{
|
||||
|
||||
if (item.RegisterName == "CUSTOMER_LeakFlowThreshold")
|
||||
{
|
||||
|
||||
}
|
||||
//todo: find a better sln for SENSUSRADIO_EncryptionKey
|
||||
//SENSUSRADIO_EncryptionKey dont reserve SENSUSRADIO_EncryptionKey!
|
||||
if (item.RegisterName.ToLower().Contains("displaypow".ToLower()) || item.RegisterName.ToLower().Contains("METROLOGYASST_FlowPoint".ToLower()))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, new[] { item.RegisterValue.ToArray()[0] }, true, true));
|
||||
}
|
||||
else if (item.RegisterName.ToLower().Contains("SENSUSRADIO_EncryptionKey".ToLower()))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.ToArray(), true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
|
||||
}
|
||||
|
||||
//else if (!item.RegisterName.ToLower().Contains("apparrangement"))
|
||||
//{
|
||||
// overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
//}
|
||||
}
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_AlarmEnableMask", new Byte[] { 0x00, 0x00, 0x80, 0x53 }.Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_AlarmBroadcastMask", new Byte[] { 0x00, 0x00, 0x1f, 0xdc }.Reverse().ToArray()));
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("CUSTOMER_AlarmVisualMask", new Byte[] { 0x00, 0x00, 0x1f, 0xdc }.Reverse().ToArray()));
|
||||
|
||||
foreach (var item in myJsonResponse.Where(m => m.Source == ProgrammingSource.Csd))
|
||||
{
|
||||
//todo: find a better sln for SENSUSRADIO_EncryptionKey
|
||||
//SENSUSRADIO_EncryptionKey dont reserve SENSUSRADIO_EncryptionKey!
|
||||
if (item.RegisterName.ToLower().Contains("SENSUSRADIO_EncryptionKey".ToLower()))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.ToArray(), true, true));
|
||||
}
|
||||
else if (!item.RegisterName.ToLower().Contains("apparrangement"))
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister(item.RegisterName, item.RegisterValue.Reverse().ToArray(), true, true));
|
||||
}
|
||||
}
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_ResetAccumulators",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray()));
|
||||
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("SYSTEM_CalendarSeconds", Convert.ToInt32(ts.TotalSeconds)));
|
||||
overAllResult.Add(wirteRegisterInBetweenCheck("IRDA_MfgDate", Convert.ToInt32(ts.TotalSeconds)));
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("NFC_EraseRMA",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray()));
|
||||
|
||||
if (Meter.RadioFrequencyMhz.HasValue)
|
||||
{
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("LOGGER_TriggerLogFlush",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray()));
|
||||
|
||||
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("PERIODICLOG_ResetCounter",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray()));
|
||||
}
|
||||
overAllResult.Add(_currentGenesis_WriteRegister("GENESISFLOW_SealDisplay",
|
||||
(new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true));
|
||||
|
||||
|
||||
var ret = true;
|
||||
Int32 done = 0;
|
||||
|
||||
foreach (var cTask in overAllResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
cTask.RunSynchronously();
|
||||
if (cTask.Result.Item2)
|
||||
{
|
||||
NewStatus($"Schreiben des Parameter {cTask.Result.Item1} war erfolgreich");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cTask.Result.Item1.ToLower().Contains("Metersize".ToLower()) || cTask.Result.Item1.ToLower().Contains("NFC_EraseRMA".ToLower()) || cTask.Result.Item1.ToLower().Contains("CUSTOMER_ExcessFlowVolumeThreshold".ToLower()) || cTask.Result.Item1.ToLower().Contains("CUSTOMER_LeakFlowThreshold".ToLower()) || cTask.Result.Item1.ToLower() == "SENSUSRADIO_MetroRadioLifeTimeCounter".ToLower())
|
||||
{
|
||||
NewStatus($"Warnung! Fehler beim Schreiben des Parameters {cTask.Result.Item1}");
|
||||
}
|
||||
else
|
||||
{
|
||||
NewStatus($"Warnung! Fehler beim Schreiben des Parameters {cTask.Result.Item1}");
|
||||
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (cTask.Result.Item1 != "GENESISFLOW_MaxDeltaToFRange")
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
Progress = 15 + ((Int32)Math.Round((done / (Double)overAllResult.Count) * 85, 0));
|
||||
done += 1;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
remainingRetries -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
remainingRetries = -1;
|
||||
NewStatus("Warnung! Fehler beim Laden des Parametersatzes");
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
NewStatus($"Warnung! Fehler beim Behandeln von {ex.Message}");
|
||||
remainingRetries = remainingRetries - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
doStartProcessLoop();
|
||||
}
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessFullReadOut : BaseProductionProcess
|
||||
{
|
||||
private UcFullReadOut UserControl;
|
||||
public ProductionProcessFullReadOut()
|
||||
{
|
||||
name = "Sicherung des Zählerzustandes";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcFullReadOut();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
try
|
||||
{
|
||||
UserControl.lblHl.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() => { UserControl.lblHl.Content = "Read out Registers"; }
|
||||
));
|
||||
var oldConfigEntry = Meter.Configuration.UseRegisterWatchService;
|
||||
if (oldConfigEntry)
|
||||
{
|
||||
Meter.Configuration.UseRegisterWatchService = false;
|
||||
}
|
||||
|
||||
var total = Meter.GetRegistersDic().Keys.ToList();
|
||||
var done = 0;
|
||||
foreach (var dic in total)
|
||||
{
|
||||
try
|
||||
{
|
||||
var done1 = done;
|
||||
UserControl.lblText.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
UserControl.lblText.Content = $"Read {dic.GetIdent()}({done1}/{total.Count})";
|
||||
}
|
||||
));
|
||||
if (dic.RegisterName.ToLower() != "password" && dic.RegisterDetail.Privilege.Lvl8 != Access.WO)
|
||||
{
|
||||
switch (dic.GetIdent().ToLower())
|
||||
{
|
||||
case "sensusradio_encryptionkey":
|
||||
Meter.ReadRegister(dic.GetIdent(), 32);
|
||||
break;
|
||||
default:
|
||||
if (dic.DataType == typeof(UInt64) || dic.DataType == typeof(Int64))
|
||||
{
|
||||
Meter.ReadRegister(dic.GetIdent(), 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.ReadRegister(dic.GetIdent());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
Progress = (Int32)Math.Round(((Double)done / total.Count) * 100, 0);
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
//todo: error logger
|
||||
}
|
||||
|
||||
done += 1;
|
||||
}
|
||||
|
||||
Meter.StoreCurrentRegisterDic();
|
||||
Meter.Configuration.UseRegisterWatchService = oldConfigEntry;
|
||||
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using Newtonsoft.Json;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Logic.ProductionOrderCore;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessGetFinalParametrizationVakoCsd : BaseProductionProcess
|
||||
{
|
||||
public IList<ProgrammingParameters> Result = new List<ProgrammingParameters>();
|
||||
private UcPlain UserControl;
|
||||
public ProductionProcessGetFinalParametrizationVakoCsd()
|
||||
{
|
||||
name = "Hole Kunden Parametrierung";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Kann bis zu 1 Minute dauern!";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
|
||||
private void doStartProcessLoop()
|
||||
{
|
||||
var retriesRemaining = 2;
|
||||
while (retriesRemaining >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Progress = 0;
|
||||
//var url = $"http://localhost:56011/api/FinalCheck/GetProgrammingParameters?PcbID={Meter.PcbId}";
|
||||
var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={Meter.PcbId}";
|
||||
var csdRet = LocalWebRequest.GetRequest(url, 60000);
|
||||
|
||||
Result = JsonConvert.DeserializeObject<IList<ProgrammingParameters>>(csdRet);
|
||||
|
||||
Progress = 100;
|
||||
|
||||
if (!Result.Any())
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
retriesRemaining -= 1;
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
retriesRemaining -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
doStartProcessLoop();
|
||||
}
|
||||
}
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessPasswordFile : BaseProductionProcess
|
||||
{
|
||||
private UcPasswordFile _userControl;
|
||||
private MeterPwdDb _pwdContainer = new MeterPwdDb();
|
||||
private MeterPwdFile _meterPwdFile;
|
||||
|
||||
public ProductionProcessPasswordFile()
|
||||
{
|
||||
name = "PasswordFile";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
_userControl = new UcPasswordFile();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (_userControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return _userControl;
|
||||
}
|
||||
|
||||
private void updateImage(Image ctlImage, Boolean? success = null)
|
||||
{
|
||||
if (success.HasValue)
|
||||
{
|
||||
if (success.Value)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
var ret = MeterPwdHandlerDb.RequestPwdFileFromDb(Meter.PcbId, out _pwdContainer);
|
||||
updateImage(_userControl.RequestPassword, ret);
|
||||
Progress += 16;
|
||||
Meter.Logout();
|
||||
ret = Meter.Login();
|
||||
|
||||
|
||||
//If the password file is written, the "Password" from _pwdContainer is overwritten from Skeleton-key
|
||||
//to the "level 8 password" form the LuDB server. The DB password column is the current login password
|
||||
//for production. Initially the "Password" is the Skeleton-key which can not be part of the list of
|
||||
//Passwords. The level 8 password is the last in the _pwdContainer list of passwords.
|
||||
if (Encoding.UTF8.GetString(_pwdContainer.ListOfPasswords.Last()) == _pwdContainer.Password)
|
||||
{
|
||||
NewStatus("Passwörter schon geschrieben. Prozess wird übersprungen");
|
||||
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Get the passwords from LuDB, insert the skeleton-kay and generate the password file
|
||||
if (ret)
|
||||
{
|
||||
ret = CreatePasswordFile();
|
||||
}
|
||||
|
||||
updateImage(_userControl.CreateFile, ret);
|
||||
Progress += 16;
|
||||
|
||||
//Write the password file to the Cordonel, read it back and make a binary verification
|
||||
if (ret)
|
||||
{
|
||||
ret = WriteAndVerifyPasswordFileToMeter();
|
||||
}
|
||||
|
||||
updateImage(_userControl.WriteToMeter, ret);
|
||||
Progress += 16;
|
||||
|
||||
//Check if new password is in the meter ... even if the file write wasn't successful
|
||||
if (ret)
|
||||
{
|
||||
Meter.Logout();
|
||||
ret = Meter.Login(Encoding.UTF8.GetString(_pwdContainer.ListOfPasswords.Last()));
|
||||
}
|
||||
|
||||
//Password in Production DB can be updated (overwrite Skeleton-key in Password column with
|
||||
//password level 8 from LuDB) because the login with installed password file succeeded,
|
||||
//this is the indicator, that the password file is valid.
|
||||
if (ret)
|
||||
{
|
||||
ret = MeterPwdHandlerDb.SetPwdFromSkeletonToLvl8inDd(Meter.PcbId, _pwdContainer);
|
||||
}
|
||||
updateImage(_userControl.UpdatePassword, ret);
|
||||
Progress += 16;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = Meter.Logout();
|
||||
}
|
||||
updateImage(_userControl.Logout, ret);
|
||||
Progress += 16;
|
||||
|
||||
//test the production database password
|
||||
if (ret)
|
||||
{
|
||||
Meter.ClearPassword();
|
||||
ret = Meter.Login();
|
||||
}
|
||||
updateImage(_userControl.CheckNewPassword, ret);
|
||||
Progress = 100;
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
}
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
#region realWork
|
||||
public Boolean CreatePasswordFile()
|
||||
{
|
||||
_meterPwdFile = new MeterPwdFile(Meter);
|
||||
return _meterPwdFile.BuildPwdFile(_pwdContainer.ListOfPasswords, 1, _pwdContainer.Skeleton);
|
||||
}
|
||||
public Boolean WriteAndVerifyPasswordFileToMeter()
|
||||
{
|
||||
if (_meterPwdFile.UnlockEraseWriteMeterPwdFile())
|
||||
{
|
||||
if (_meterPwdFile.WriteMeterPwdFile())
|
||||
{
|
||||
return _meterPwdFile.VerifyMeterPwdFile();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-473
@@ -1,473 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using SIRTCOM;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Button = System.Windows.Controls.Button;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessRadioCheck : BaseProductionProcess
|
||||
{
|
||||
private UcRadioCheck UserControl;
|
||||
public ProductionProcessRadioCheck()
|
||||
{
|
||||
|
||||
name = "Radio Check";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
|
||||
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcRadioCheck();
|
||||
|
||||
UserControl.OnRetryRequested += delegate { GetRssi(); };
|
||||
|
||||
|
||||
UserControl.OnResetRequested += delegate { Reset(); };
|
||||
UserControl.OnForceAPam += delegate { forcePush(); };
|
||||
UserControl.OnDoneRequested += delegate
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
if (SENSUSRADIO_WakeupInterval != null)
|
||||
{
|
||||
var ret = Meter.WriteRegister("SENSUSRADIO_WakeupInterval", SENSUSRADIO_WakeupInterval, true, true);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
//clear
|
||||
}
|
||||
|
||||
private Byte[] SENSUSRADIO_WakeupInterval;
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
//readout adress, freq,
|
||||
|
||||
if (Meter.RadioFrequencyMhz.HasValue)
|
||||
{
|
||||
|
||||
|
||||
var freq = RegisterConverter.ConvertTo<UInt32>(Meter.ReadRegister("SENSUSRADIO_FrequencyIndicator"));
|
||||
RadioAdress = RegisterConverter.ConvertTo<UInt32>(Meter.ReadRegister("SENSUSRADIO_RadioAddress"));
|
||||
|
||||
|
||||
Comport = Convert.ToByte(ConfigurationManager.AppSettings[$"SirtComport{freq}"]);
|
||||
var enc = Meter.ReadRegister("SENSUSRADIO_EncryptionKey", 16);
|
||||
|
||||
EncyptionKey = LocalWebRequest.GetRequest($"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetEncryptionKey?PcbID={Meter.PcbId}", 80000).ToUpper().Trim('\"');
|
||||
if (!EncyptionKey.Equals(BitConverter.ToString(enc.ToArray()).Replace("-", "")))
|
||||
{
|
||||
MessageBox.Show("Funkschlüssel überprüfen!");
|
||||
}
|
||||
|
||||
EncyptionKey = BitConverter.ToString(enc.ToArray()).Replace("-", "");
|
||||
|
||||
//if (freq == 868)
|
||||
//{
|
||||
// Comport = 8;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Comport = 7;
|
||||
//}
|
||||
BoxNr = Convert.ToByte(ConfigurationManager.AppSettings["SirtBoxNr"]);
|
||||
|
||||
DebugMessage($"Start RadioCheck Comport:{Comport} ,BoxNr:{BoxNr}, freq: {freq}, RadioAddress:{RadioAdress}s\r\n");
|
||||
|
||||
Meter.WriteRegister("SENSUSRADIO_IrDAModulePresent", 1, true, true);
|
||||
|
||||
|
||||
SENSUSRADIO_WakeupInterval = Meter.ReadRegister("SENSUSRADIO_WakeupInterval");
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", 0);
|
||||
|
||||
|
||||
GetRssi();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
}
|
||||
|
||||
#region FormerForm
|
||||
|
||||
private SaveData saveData;
|
||||
private Statemashine stm;
|
||||
private static HttpClient httpclient;
|
||||
|
||||
private Byte? RSSI_PAM_Min;
|
||||
private Byte? RSSI_PAM_Max;
|
||||
private Byte? RSSI_PAM;
|
||||
private Byte? RSSI_SEMI_Min;
|
||||
private Byte? RSSI_SEMI_Max;
|
||||
private Byte? RSSI_SEMI;
|
||||
|
||||
public Byte BoxNr;
|
||||
|
||||
public Int32 Ordernumber;
|
||||
public UInt32 RadioAdress;
|
||||
|
||||
public Byte Comport;
|
||||
|
||||
public String EncyptionKey = "";
|
||||
|
||||
|
||||
private void enableBtn(Button btn, Boolean enable)
|
||||
{
|
||||
btn.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() =>
|
||||
{
|
||||
btn.IsEnabled = enable;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
private void SetUi()
|
||||
{
|
||||
UserControl.SetUi(new UcRadioCheck.UIContainer(RSSI_PAM_Min, RSSI_SEMI_Min, RSSI_PAM, RSSI_SEMI, RSSI_PAM_Max, RSSI_SEMI_Max));
|
||||
}
|
||||
|
||||
private async void GetRssi()
|
||||
{
|
||||
|
||||
//StartProcess();
|
||||
enableBtn(UserControl.btnGetRssi, false);
|
||||
|
||||
DebugMessage("");
|
||||
|
||||
|
||||
saveData = new SaveData();
|
||||
|
||||
SetUi();
|
||||
|
||||
|
||||
|
||||
//Meter.WriteRegister("SENSUSRADIO_PowerLevel", 67, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_PowerLevelOption", 59, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeNew", 2992, true, true);
|
||||
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeOption", 2936, true, true);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
await GetRssiMinMaxAsync(BoxNr, Ordernumber);
|
||||
SetUi();
|
||||
GetRSSI((Int32)RadioAdress, Comport, EncyptionKey);
|
||||
SetUi();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugMessage($"Fehler in buttonSende_Click():\r\n{ex.Message}\r\n{ex.InnerException}", true);
|
||||
}
|
||||
enableBtn(UserControl.btnGetRssi, true);
|
||||
|
||||
}
|
||||
|
||||
private void clearRssi()
|
||||
{
|
||||
RSSI_PAM_Min = null;
|
||||
RSSI_PAM_Max = null;
|
||||
RSSI_PAM = null;
|
||||
RSSI_SEMI_Min = null;
|
||||
RSSI_SEMI_Max = null;
|
||||
RSSI_SEMI = null;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
if (!(stm == null))
|
||||
{
|
||||
stm.ClearPam();
|
||||
stm.Stop();
|
||||
}
|
||||
DebugMessage("Reset\r\n");
|
||||
clearRssi();
|
||||
SetUi();
|
||||
StartProcess();
|
||||
}
|
||||
|
||||
private class SaveData
|
||||
{
|
||||
public Int32 RadioAdress { get; set; }
|
||||
public Byte RSSI_PAM { get; set; }
|
||||
public Byte RSSI_SEMI { get; set; }
|
||||
public Int32 LimitId { get; set; }
|
||||
public Byte Result { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Speichert das gefüllte saveData Objekt via SaveRSSI Webservice
|
||||
/// </summary>
|
||||
private async void SaveDataToDB()
|
||||
{
|
||||
DebugMessage("Calling SaveRSSI Webservice...", true);
|
||||
try
|
||||
{
|
||||
saveData.RadioAdress = (Int32)RadioAdress; // 0-4294967295
|
||||
String url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}SaveRSSI";
|
||||
String body = JsonConvert.SerializeObject(saveData);
|
||||
await PostDataAsync(url, body);
|
||||
DebugMessage(" Ready\r\n", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugMessage($"Fehler in SaveDataToDB():\r\n{ex.Message}\r\n{ex.InnerException}", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task GetRssiMinMaxAsync(Byte BoxNr, Int32 FaNr)
|
||||
{
|
||||
//DebugMessage("Calling GetLimits Webservice...", true);
|
||||
try
|
||||
{
|
||||
// TODO anpassen
|
||||
String url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}GetLimits/{BoxNr}/{FaNr}";
|
||||
String body = await GetResponseAsync(url);
|
||||
JObject o = JObject.Parse(body);
|
||||
|
||||
saveData.LimitId = Convert.ToInt32(o.SelectToken("LimitId").ToString());
|
||||
RSSI_PAM_Min = Convert.ToByte(o.SelectToken("RSSI_PAM_Min").ToString());
|
||||
RSSI_PAM_Max = Convert.ToByte(o.SelectToken("RSSI_PAM_Max").ToString());
|
||||
RSSI_SEMI_Min = Convert.ToByte(o.SelectToken("RSSI_SEMI_Min").ToString());
|
||||
RSSI_SEMI_Max = Convert.ToByte(o.SelectToken("RSSI_SEMI_Max").ToString());
|
||||
DebugMessage(" Ready\r\n", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
saveData.LimitId = 0;
|
||||
RSSI_PAM_Min = 100;
|
||||
|
||||
RSSI_PAM_Max = 200;
|
||||
RSSI_SEMI_Min = 100;
|
||||
RSSI_SEMI_Max = 200;
|
||||
// RSSI_PAM_Min RSSI_PAM_Max RSSI_SEMI_Min RSSI_SEMI_Max
|
||||
//145 164 182
|
||||
|
||||
// throw new Exception("Fehler in GetRssiMinMax()", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetRSSI(Int32 RadioAdress, Int32 ByteCOMPort, String strKey)
|
||||
{
|
||||
|
||||
RSSI_PAM = null;
|
||||
RSSI_SEMI = null;
|
||||
|
||||
stm = new Statemashine();
|
||||
|
||||
Byte P81_1 = 0;
|
||||
|
||||
saveData.RadioAdress = RadioAdress;
|
||||
|
||||
stm.initialise((Byte)ByteCOMPort);
|
||||
Wrapper wrp = new Wrapper();
|
||||
stm.StartLoggin("C:\\GenesisLog\\log.txt");
|
||||
|
||||
// ist wohl nicht nötig da der SIRT richtig konfiguroert ist:
|
||||
// wrp.ActivateSirt(byte modul1, byte modul2, byte actTimeout, out byte outP12_01, out byte outP12_02);
|
||||
|
||||
DebugMessage($"Sending PAM to {RadioAdress.ToString()} ...", true);
|
||||
stm.ClearPam();
|
||||
stm.Timeout_s = 60;
|
||||
|
||||
if (strKey == "")
|
||||
{
|
||||
// Dummy PAM 00 OHNE Funkschlüssel
|
||||
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, "", "0", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dummy PAM 00 mit Funkschlüssel
|
||||
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, strKey, "0", true);
|
||||
}
|
||||
|
||||
stm.OnStateChanged += Stm_OnStateChanged;
|
||||
stm.Start(); // Start polling
|
||||
|
||||
DebugMessage(" OK\r\n", true);
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE);
|
||||
Thread.Sleep(5000);
|
||||
//Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x01, true, false);
|
||||
forcePush();
|
||||
if (false)
|
||||
{
|
||||
GotRSSICallback(1, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void forcePush()
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x55);
|
||||
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x02);
|
||||
}
|
||||
|
||||
|
||||
public void DebugMessage(String value, Boolean Append = false)
|
||||
{
|
||||
NewStatus(value);
|
||||
}
|
||||
|
||||
private void GotRSSICallback(Byte Rssi_Semi_Sirt, Byte Rssi_Pam_Cord)
|
||||
{
|
||||
// RSSI beim Empfangen der PAM gemessen vom Cordonel (Sendestärke des SIRT verpackt in SEMI, byte 20)
|
||||
DebugMessage($"RSSI Cord of PAM (Sirt => Cord):{Rssi_Pam_Cord}\r\n", true);
|
||||
RSSI_PAM = Rssi_Pam_Cord;
|
||||
RSSI_SEMI = Rssi_Semi_Sirt;
|
||||
|
||||
// RSSI beim Empfangen der SEMI gemessen vom SIRT (Sendestärke des Cordonel in byte 4)
|
||||
DebugMessage($"RSSI Sirt of SEMI (Cord => Sirt):{Rssi_Semi_Sirt}\r\n", true);
|
||||
saveData.RSSI_PAM = Rssi_Pam_Cord;
|
||||
saveData.RSSI_SEMI = Rssi_Semi_Sirt;
|
||||
|
||||
saveData.Result = 1;
|
||||
|
||||
if (RSSI_PAM < RSSI_PAM_Min)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_SEMI < RSSI_SEMI_Min)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_PAM > RSSI_PAM_Max)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
if (RSSI_SEMI > RSSI_SEMI_Max)
|
||||
{
|
||||
saveData.Result = 0;
|
||||
}
|
||||
|
||||
|
||||
SaveDataToDB();
|
||||
SetUi();
|
||||
if (saveData.Result == 1)
|
||||
{
|
||||
UserControl.ViewResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void Stm_OnStateChanged(Object sender, MyEventArgs e)
|
||||
{
|
||||
// our Pam
|
||||
PAM Pam = stm.GetPAM(1);
|
||||
|
||||
if (Pam.State == PAM.PAMStates.Timeout)
|
||||
{
|
||||
DebugMessage($"Timeout nach {Pam.GetTime()} s\r\n");
|
||||
}
|
||||
|
||||
if (Pam.CountSemi > 0)
|
||||
{
|
||||
// we recieved the SEMI
|
||||
|
||||
//btnGetRssi.IsEnabled = true;
|
||||
stm.Stop();
|
||||
stm.ClearPam();
|
||||
|
||||
String HexbytesSEMI = Pam.Semi.HexData.Replace(" ", "");
|
||||
Byte[] SEMI_bytes = new Byte[HexbytesSEMI.Length / 2];
|
||||
|
||||
for (Int32 i = 0; i < HexbytesSEMI.Length; i += 2)
|
||||
{
|
||||
SEMI_bytes[i / 2] = Convert.ToByte(HexbytesSEMI.Substring(i, 2), 16);
|
||||
}
|
||||
|
||||
// SEMI Status
|
||||
if (SEMI_bytes[19] == 0)
|
||||
{
|
||||
// RSSI beim Empfangen der SEMI gemessen vom Sirt
|
||||
Byte Semi_Rssi_Sirt = SEMI_bytes[2];
|
||||
|
||||
// RSSI beim Empfangen der PAM gemessen vom Cordonel
|
||||
Byte Pam_Rssi_Cord = SEMI_bytes[20];
|
||||
|
||||
GotRSSICallback(Semi_Rssi_Sirt, Pam_Rssi_Cord);
|
||||
}
|
||||
else
|
||||
{
|
||||
// SEMI Status ist nicht 0.
|
||||
DebugMessage(Pam.Semi.GetPamErrorMessage(), true);
|
||||
}
|
||||
stm.ClearPam();
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage($"BUPS:{Pam.CountBup}\r\n", true);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<String> PostDataAsync(String url, String data)
|
||||
{
|
||||
httpclient = new HttpClient();
|
||||
// 20 Sekunden Timeout
|
||||
httpclient.Timeout = new TimeSpan(0, 0, 20);
|
||||
|
||||
StringContent queryString = new StringContent(data, Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage response = await httpclient.PostAsync(url, queryString);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
String content = await response.Content.ReadAsStringAsync();
|
||||
return content;
|
||||
}
|
||||
|
||||
private static async Task<String> GetResponseAsync(String url)
|
||||
{
|
||||
httpclient = new HttpClient();
|
||||
// 20 Sekunden Timeout
|
||||
httpclient.Timeout = new TimeSpan(0, 0, 20);
|
||||
|
||||
HttpResponseMessage response = httpclient.GetAsync(url).Result;
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
String content = await response.Content.ReadAsStringAsync();
|
||||
return content;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessRegisterWatch : BaseProductionProcess
|
||||
{
|
||||
private UcFullReadOut UserControl;
|
||||
public ProductionProcessRegisterWatch()
|
||||
{
|
||||
name = "Sicherung des Zählerzustandes";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcFullReadOut();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
UserControl.lblHl.Dispatcher.Invoke(DispatcherPriority.Send,
|
||||
new Action(() => { UserControl.lblHl.Content = "Read out Registers"; }
|
||||
));
|
||||
|
||||
var total = Meter.GetRegistersDic().Keys.Where(n => n.RegisterName == "TemperatureMeasurePeriod" || n.RegisterName == "PressureMeasurePeriod" || n.RegisterName == "METROLOGYASST_PressureRate").ToList();
|
||||
var done = 0;
|
||||
foreach (var dic in total)
|
||||
{
|
||||
var ret = Meter.ReadRegister(dic.GetIdent());
|
||||
|
||||
if (dic.AppName == "SENSUSRADIO")
|
||||
{
|
||||
Meter.WriteLog($"Register Watch: {dic.RegisterName} = { RegisterConverter.ConvertTo<UInt16>(ret)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.WriteLog($"Register Watch: {dic.RegisterName} = { RegisterConverter.ConvertTo<UInt32>(ret)}");
|
||||
}
|
||||
}
|
||||
done += 1;
|
||||
|
||||
|
||||
//Meter.StoreCurrentRegisterDic();
|
||||
//Meter.Configuration.UseRegisterWatchService = oldConfigEntry;
|
||||
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-258
@@ -1,258 +0,0 @@
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Controls;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessShippingMode : BaseProductionProcess
|
||||
{
|
||||
private UcPlain UserControl;
|
||||
private Boolean doRestart;
|
||||
private Boolean hasRadio;
|
||||
public ProductionProcessShippingMode(Boolean restart = false, Boolean registerHasRadio = true)
|
||||
{
|
||||
name = "Versandbereitschaft herstellen";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
doRestart = restart;
|
||||
hasRadio = registerHasRadio;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcPlain();
|
||||
UserControl.lblHl.Content = name;
|
||||
UserControl.lblText.Content = "Display und Alarme für den Kunden einstellen.";
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
|
||||
|
||||
hasRadio = Meter.RadioFrequencyMhz.HasValue;
|
||||
|
||||
|
||||
|
||||
if (hasRadio)
|
||||
{
|
||||
if (Meter.StoreAllConfigurations())
|
||||
{
|
||||
if (doRestart)
|
||||
{
|
||||
var CheckValuesAfterBoot = new List<Tuple<String, Byte[]>>
|
||||
{
|
||||
new Tuple<String, Byte[]>("METROLOGYASST_PulseLength",
|
||||
Meter.ReadRegister("METROLOGYASST_PulseLength")),
|
||||
new Tuple<String, Byte[]>("POWERMON_BatteryQuantity",
|
||||
Meter.ReadRegister("POWERMON_BatteryQuantity")),
|
||||
new Tuple<String, Byte[]>("GENESISFLOW_MeterSize", Meter.ReadRegister("GENESISFLOW_MeterSize")),
|
||||
new Tuple<String, Byte[]>("GENESISFLOW_CalFactor1", Meter.ReadRegister("GENESISFLOW_CalFactor1")),
|
||||
new Tuple<String, Byte[]>("SENSUSRADIO_RadioAddress", Meter.ReadRegister("SENSUSRADIO_RadioAddress"))
|
||||
};
|
||||
var _meterResetPsu = new MeterResetPsu(Meter)
|
||||
{
|
||||
StoreConfigEnable = true
|
||||
};
|
||||
var rebootSucceeded = _meterResetPsu.MeterResetPsuExecute();
|
||||
|
||||
Thread.Sleep(10000);
|
||||
if (!Meter.Login())
|
||||
|
||||
{
|
||||
Meter.WriteLog("relogin first attempt Failed");
|
||||
Thread.Sleep(5000);
|
||||
if (!Meter.Login())
|
||||
{
|
||||
Meter.WriteLog("relogins Failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Boolean? hasDiffrences = null;
|
||||
foreach (var item in CheckValuesAfterBoot)
|
||||
{
|
||||
if (!item.Item2.SequenceEqual(Meter.ReadRegister(item.Item1)))
|
||||
{
|
||||
hasDiffrences = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!hasDiffrences.HasValue)
|
||||
{
|
||||
hasDiffrences = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootSucceeded && hasDiffrences.HasValue && !hasDiffrences.Value)
|
||||
{
|
||||
|
||||
Meter.WriteRegister("SENSUSRADIO_SystemState", 0xFF);
|
||||
Meter.Logout();
|
||||
Thread.Sleep(5000);
|
||||
if (!Meter.Login())
|
||||
{
|
||||
Meter.WriteLog("relogin first attempt Failed");
|
||||
Thread.Sleep(5000);
|
||||
|
||||
if (!Meter.Login())
|
||||
{
|
||||
Meter.WriteLog("relogin Failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
var SENSUSRADIO_MainAlarmMask = Meter.ReadRegister("SENSUSRADIO_MainAlarmMask");
|
||||
var SENSUSRADIO_ExtendedAlarmMask = Meter.ReadRegister("SENSUSRADIO_ExtendedAlarmMask");
|
||||
var SENSUSRADIO_SystemState = Meter.ReadRegister("SENSUSRADIO_SystemState");
|
||||
if (SENSUSRADIO_SystemState[0] == 0x02 && SENSUSRADIO_MainAlarmMask[0] != 0)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.WriteLog("resetRadio Failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.WriteLog("reboot compare failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.ALL);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.SetLcdText(true, new Byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.WriteRegister("SENSUSRADIO_SystemState", 0xFF);
|
||||
Meter.Logout();
|
||||
Thread.Sleep(5000);
|
||||
if (!Meter.Login())
|
||||
{
|
||||
Thread.Sleep(5000);
|
||||
if (!Meter.Login())
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var SENSUSRADIO_MainAlarmMask = Meter.ReadRegister("SENSUSRADIO_MainAlarmMask");
|
||||
var SENSUSRADIO_ExtendedAlarmMask = Meter.ReadRegister("SENSUSRADIO_ExtendedAlarmMask");
|
||||
var SENSUSRADIO_SystemState = Meter.ReadRegister("SENSUSRADIO_SystemState");
|
||||
if (SENSUSRADIO_SystemState[0] == 0x02 && SENSUSRADIO_MainAlarmMask[0] != 0)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.WriteLog("resetRadio Failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Meter.StoreAllConfigurations())
|
||||
{
|
||||
if (doRestart)
|
||||
{
|
||||
var CheckValuesAufterBoot = new List<Tuple<String, Byte[]>>();
|
||||
CheckValuesAufterBoot.Add(new Tuple<String, Byte[]>("METROLOGYASST_PulseLength", Meter.ReadRegister("METROLOGYASST_PulseLength")));
|
||||
CheckValuesAufterBoot.Add(new Tuple<String, Byte[]>("POWERMON_BatteryQuantity", Meter.ReadRegister("POWERMON_BatteryQuantity")));
|
||||
CheckValuesAufterBoot.Add(new Tuple<String, Byte[]>("GENESISFLOW_MeterSize", Meter.ReadRegister("GENESISFLOW_MeterSize")));
|
||||
CheckValuesAufterBoot.Add(new Tuple<String, Byte[]>("GENESISFLOW_CalFactor1", Meter.ReadRegister("GENESISFLOW_CalFactor1")));
|
||||
|
||||
var _meterResetPsu = new MeterResetPsu(Meter)
|
||||
{
|
||||
StoreConfigEnable = true
|
||||
};
|
||||
var rebootSucceeded = _meterResetPsu.MeterResetPsuExecute();
|
||||
|
||||
Thread.Sleep(10000);
|
||||
Meter.Login();
|
||||
|
||||
|
||||
Boolean? hasDiffrences = null;
|
||||
foreach (var item in CheckValuesAufterBoot)
|
||||
{
|
||||
if (!item.Item2.SequenceEqual(Meter.ReadRegister(item.Item1)))
|
||||
{
|
||||
hasDiffrences = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!hasDiffrences.HasValue)
|
||||
{
|
||||
hasDiffrences = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.ALL);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.SetLcdText(true, new Byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
Meter.ResetAlarm(GenesisMeter.Alarm.EMPTY_PIPE);//(true, new byte[] { 0x00, 0x00, 0x00, 0x01 });
|
||||
|
||||
if (rebootSucceeded && hasDiffrences.HasValue && !hasDiffrences.Value)
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
Meter.WriteLog("reboot compare failed");
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentProcessState = ProductionProcessState.Error;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-162
@@ -1,162 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using ProductionUiCordonel.UserControls.FinalTest;
|
||||
|
||||
namespace ProductionUiCordonel.ProductionProcesses.Actions
|
||||
{
|
||||
public class ProductionProcessSpecialConfig : BaseProductionProcess
|
||||
{
|
||||
private UcDialog UserControl;
|
||||
|
||||
public Boolean DialogIsDone { get; }
|
||||
|
||||
public ProductionProcessSpecialConfig()
|
||||
{
|
||||
DialogIsDone = false;
|
||||
name = "Customer Parameterization";
|
||||
currentProcessState = ProductionProcessState.Waiting;
|
||||
}
|
||||
public override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcDialog();
|
||||
}
|
||||
|
||||
public override UserControl GetControl()
|
||||
{
|
||||
if (UserControl == null)
|
||||
{
|
||||
throw new Exception($"UserControl {GetType()} not Ready");
|
||||
}
|
||||
return UserControl;
|
||||
}
|
||||
|
||||
|
||||
public override void ProcessDone()
|
||||
{
|
||||
//clear
|
||||
}
|
||||
|
||||
private void StepDone()
|
||||
{
|
||||
currentProcessState = ProductionProcessState.Done;
|
||||
}
|
||||
|
||||
private void StepRadio()
|
||||
{
|
||||
|
||||
UserControl.SetDesc("Set EncryptionKey");
|
||||
var radioOptionList = new List<UcDialog.DialogOption>();
|
||||
var radioDefault = new UcDialog.DialogOption("old default", "same as iperl", () =>
|
||||
{
|
||||
|
||||
var funkadresse = new List<Byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0xE6, 0xC8, 0x88, 0x00 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xDE, 0xB8, 0x68, 0xC0 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xD6, 0xA8, 0x48, 0x80 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xCE, 0x98, 0x28, 0x40 }).ToArray());
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true);
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var upRadioOnly = new UcDialog.DialogOption("alpha", "000...", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", (new Byte[]
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}).ToArray(), true, true);
|
||||
StepDone();
|
||||
|
||||
});
|
||||
|
||||
var optOneLiter = new UcDialog.DialogOption("new default", "new default key", () =>
|
||||
{
|
||||
var funkadresse = new List<Byte>();
|
||||
funkadresse.AddRange((new Byte[] { 0x0E, 0x9F, 0xAC, 0xC6 }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xA0, 0xE1, 0xEF, 0x1C }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0x3B, 0x27, 0xA4, 0x9B }).ToArray());
|
||||
funkadresse.AddRange((new Byte[] { 0xAC, 0x21, 0x65, 0x35 }).ToArray());
|
||||
Meter.WriteRegister("SENSUSRADIO_EncryptionKey", funkadresse.ToArray(), true, true);
|
||||
StepDone();
|
||||
});
|
||||
|
||||
radioOptionList.Add(radioDefault);
|
||||
radioOptionList.Add(upRadioOnly);
|
||||
radioOptionList.Add(optOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(radioOptionList);
|
||||
}
|
||||
private void StepWakeUp()
|
||||
{
|
||||
UserControl.SetDesc("Set Radio WakeUp");
|
||||
var wakeupOptionList = new List<UcDialog.DialogOption>();
|
||||
var wakeUpDefault = new UcDialog.DialogOption("wakeup Water and Radio", "Default for nearly all", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x03 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
var wakeUpRadioOnly = new UcDialog.DialogOption("wakeup only Radio", "WakeupInterval to 6 (only radio)", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x06 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
var pulseOptOneLiter = new UcDialog.DialogOption("wakeup off", "WakeupInterval to 0, no Radio active (e.g. USA))", () =>
|
||||
{
|
||||
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true);
|
||||
StepRadio();
|
||||
});
|
||||
|
||||
wakeupOptionList.Add(wakeUpDefault);
|
||||
wakeupOptionList.Add(wakeUpRadioOnly);
|
||||
wakeupOptionList.Add(pulseOptOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(wakeupOptionList);
|
||||
}
|
||||
|
||||
private void StepPulse()
|
||||
{
|
||||
UserControl.SetDesc("Set Pulse Configuration");
|
||||
var pulseOptionList = new List<UcDialog.DialogOption>();
|
||||
var pulseOptOff = new UcDialog.DialogOption("Pulse off", "set pulsemode to off", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x00 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
var pulseOptDefault = new UcDialog.DialogOption("Pulse Default", "1 pulse per 10 l, pulse mode a4 and 200ms pulse length", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x07 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x27, 0x10 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
var pulseOptOneLiter = new UcDialog.DialogOption("One Liter Pulse", "1 pulse per 1l, pulse mode a4 and 20ms pulse length", () =>
|
||||
{
|
||||
Meter.WriteRegister("METROLOGYASST_PulseLength", (new Byte[] { 0x00, 0x00, 0x00, 0x04 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseMode", (new Byte[] { 0x00, 0x00, 0x00, 0x01 }).Reverse().ToArray(), true, true);
|
||||
Meter.WriteRegister("METROLOGYASST_PulseWeight", (new Byte[] { 0x00, 0x00, 0x03, 0xE8 }).Reverse().ToArray(), true, true);
|
||||
StepWakeUp();
|
||||
});
|
||||
|
||||
pulseOptionList.Add(pulseOptOff);
|
||||
pulseOptionList.Add(pulseOptDefault);
|
||||
pulseOptionList.Add(pulseOptOneLiter);
|
||||
|
||||
UserControl.SetDialogOptions(pulseOptionList);
|
||||
}
|
||||
|
||||
public override void StartProcess()
|
||||
{
|
||||
StepPulse();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
public interface IProcessStateDef
|
||||
{
|
||||
/// <summary>
|
||||
/// Collection of state information
|
||||
/// </summary>
|
||||
List<ProcessStateStruct> StateContainer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the process start struct linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process state struct of the attached state</returns>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
ProcessStateStruct GetProcessStateStructOfState(ProcessState stateMachineState);
|
||||
|
||||
/// <summary>
|
||||
/// Get the process linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process attached to the state</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
IProductionProcess GetProcessOfState(ProcessState stateMachineState);
|
||||
|
||||
/// <summary>
|
||||
/// Get the current information of the state machine state
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>information attached to state depending on region</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Mar-18" author="Thomas Wiedebusch">
|
||||
/// - If state == null return error message.
|
||||
/// </remarks>
|
||||
String GetStateInfoOfState(ProcessState? stateMachineState);
|
||||
|
||||
/// <summary>
|
||||
/// Get the info text from production process
|
||||
/// </summary>
|
||||
/// <param name="process">process to look for state info text</param>
|
||||
/// <returns>information attached to process depending on region</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
String GetStateInfoOfProcess(IProductionProcess process);
|
||||
|
||||
/// <summary>
|
||||
/// Get the state machine state of the text
|
||||
/// </summary>
|
||||
/// <param name="text">information text to search if state is assigned</param>
|
||||
/// <returns>state attached to information text</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
ProcessState GetStateOfInfoText(String text);
|
||||
|
||||
/// <summary>
|
||||
/// Get the state machine state from for the process
|
||||
/// </summary>
|
||||
/// <param name="process">process to look for state info text</param>
|
||||
/// <returns>state attached to process</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
ProcessState GetStateOfProcess(IProductionProcess process);
|
||||
|
||||
/// <summary>
|
||||
/// Get number of EOL relevant processes for statistic e.g. progress bar
|
||||
/// </summary>
|
||||
/// <returns>number of initialized processes</returns>
|
||||
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Used marker for production relevant processes
|
||||
/// </remarks>
|
||||
Int32 GetNumberOfInitializedProcesses();
|
||||
|
||||
/// <summary>
|
||||
/// Get a sorted list of all production processes in order of the execution sequence
|
||||
/// </summary>
|
||||
/// <returns>list of initialized processes</returns>
|
||||
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Used marker for production relevant processes
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
|
||||
/// - Changed to sorted list by production process number
|
||||
/// </remarks>
|
||||
List<IProductionProcess> GetAllEolRelevantProcesses();
|
||||
}
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.PickingProcesses
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation for all production process states to feed the state machine:
|
||||
/// - Production process class (representing a production process step), null if hidden process,
|
||||
/// - attached state,
|
||||
/// - state information to display a text message,
|
||||
/// - production process number to define where to display in the overview,
|
||||
/// - next state which should be executed after this succeeded,
|
||||
/// [optional]:
|
||||
/// - own error state,
|
||||
/// - own break state,
|
||||
/// - kick off state for parallel execution after starting this process in a separate task,
|
||||
/// - wait for single process to finish successfully,
|
||||
/// - wait for all processes to finish successfully,
|
||||
/// - start always independent of any result, e.g. the error state needs to be started if called!
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public class PickingProcessStateDef : BaseProcessStatesDef
|
||||
{
|
||||
/// <summary>
|
||||
/// State-machine definitions of production-processes which feeds the state-machine.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR PREPARATION:
|
||||
/// -----------------------------
|
||||
/// STEP 1: Define some states for your processes <see cref="ProcessState"/>
|
||||
/// STEP 2: Implement your processes like <see cref="DetectCordonel"/>
|
||||
/// STEP 3: Register and chain your states here
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR NORMAL USAGE:
|
||||
/// -----------------------------
|
||||
/// Means one state automatically switched on successfully execution to the next required state.
|
||||
///
|
||||
/// Define the (e.g.):
|
||||
/// productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
|
||||
/// processState: ProcessState.DetectCordonel,
|
||||
/// processInfo: Resources.StrStateDetectCordonel,
|
||||
/// productionProcessNo: 0,
|
||||
/// nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
///
|
||||
/// If a special state is needed on errorExitState or breakExitState these can be assigned. Otherwise, the
|
||||
/// "errorExitState" is linked to the generic-error-state, the "breakExitState" to the abort-test-state.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR NON-BLOCKING MULTIPLE PROCESSES SIMULTANEOUSLY ACTIVITIES:
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Sometimes production processes may be able to be executed simultaneously as they are independent of each
|
||||
/// other. One example is a database access for data collection from different tables.
|
||||
///
|
||||
/// This is needed for non-blocking immediately new state change (not waiting for the successful execution of
|
||||
/// the actual new assigned process).
|
||||
///
|
||||
/// Define the (e.g.):
|
||||
///
|
||||
/// productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
/// processState: ProcessState.ConnectCordonel,
|
||||
/// processInfo: Resources.StrStateConnectCordonel,
|
||||
/// productionProcessNo: 1,
|
||||
/// // Avoid automatic change after completion as parallel process is active
|
||||
/// nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
/// // Kick off parallel process execution after starting the "ConnectCordonel() task"
|
||||
/// kickOffParallelState: ProcessState.GetSerialNumberAndRadioAddress),
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION TO DELAY THE START OF A PROCESS AND WAIT ON RESULTS OF OTHER PROCESS(ES):
|
||||
/// -------------------------------------------------------------------------------------
|
||||
/// Each new process execution can be delayed as it may need the result of another process which is active.
|
||||
///
|
||||
/// Wait for a single process to complete:
|
||||
/// Set the "waitForSingleProcess" to the state of the process needed to wait for (e.g.):
|
||||
///
|
||||
/// productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
/// processState: ProcessState.CheckProductionState,
|
||||
/// processInfo: Resources.StrStateCheckProductionState,
|
||||
/// productionProcessNo: 4,
|
||||
/// // Avoid automatic change after completion as parallel process is active
|
||||
/// nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
/// // Kick off parallel process execution after starting
|
||||
/// kickOffParallelState: ProcessState.ProcessPasswordFile,
|
||||
/// // Wait until this process has been successfully completed
|
||||
/// waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
///
|
||||
/// Wait for all preceding processes to complete to be sure to get all data and all processed are succeeded:
|
||||
/// Set the "waitForAllProcesses" to true (e.g.):
|
||||
/// productionProcess: new ExecPasswordFile(Resources.StrStatePasswordFile),
|
||||
/// processState: ProcessState.ProcessPasswordFile,
|
||||
/// processInfo: Resources.StrStatePasswordFile,
|
||||
/// productionProcessNo: 5,
|
||||
/// nextStateOnSuccess: ProcessState.ExecFinalParametrization,
|
||||
/// waitForAllProcesses: true),
|
||||
///
|
||||
/// </summary>
|
||||
public PickingProcessStateDef()
|
||||
{
|
||||
var stateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
#region ----------------------------------- GENERIC-STATES---------------------------------------------
|
||||
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
|
||||
// to change the state after successfully execution. The detection is the base for all others.
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
|
||||
processState: ProcessState.DetectCordonel,
|
||||
processInfo: Resources.StrStateDetectCordonel,
|
||||
productionProcessNo: 0,
|
||||
nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
|
||||
// Detection of Cordonel has to be completed before assigning next state. It has to be checked if
|
||||
// the meter changed to clear all collected contents of previous run. To UPDATE ALL INFORMATION after
|
||||
// new meter assignment the "DetectCordonel" has to be repeated to return here "Old Meter" and then
|
||||
// enter the "ConnectCordonel"!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: null,
|
||||
processState: ProcessState.CheckNewMeter,
|
||||
processInfo: Resources.StrProcessStateCheckNewMeter,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: ProcessState.DetectCordonel,
|
||||
errorExitState: ProcessState.ConnectCordonel),
|
||||
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
processState: ProcessState.ConnectCordonel,
|
||||
processInfo: Resources.StrStateConnectCordonel,
|
||||
productionProcessNo: 1,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetSerialNumberAndRadioAddress),
|
||||
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
|
||||
processState: ProcessState.GetSerialNumberAndRadioAddress,
|
||||
processInfo: Resources.StrStateGetSerialAndRadioAddress,
|
||||
productionProcessNo: 2,
|
||||
nextStateOnSuccess: ProcessState.CheckOrderNumber,
|
||||
waitForAllProcesses: true),
|
||||
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
processState: ProcessState.CheckOrderNumber,
|
||||
processInfo: Resources.StrStateCheckOrderNumber,
|
||||
productionProcessNo:3,
|
||||
nextStateOnSuccess: ProcessState.Idle),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- PICKING-STATES --------------------------------------------
|
||||
//TODO Roland: implement your states here
|
||||
#endregion -------------------------------- PICKING-STATES --------------------------------------------
|
||||
|
||||
};
|
||||
StateContainer.AddRange(stateContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Timer = System.Threading.Timer;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
@@ -44,7 +44,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
}
|
||||
|
||||
// Container for production process states
|
||||
private BaseProcessStates _processStateDef;
|
||||
private IProcessStateDef _processStateDef;
|
||||
|
||||
// Container for production status information, a list is used to keep the content over all classes of production
|
||||
// processes as a reference seems not to return their value (always reset to the initial value)
|
||||
@@ -113,6 +113,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// - Create and setup Cordonel.
|
||||
/// </summary>
|
||||
/// <param name="slot">physical slot for this meter</param>
|
||||
/// <param name="processSateDef"></param>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
@@ -121,12 +122,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// - Always RegisterWatchService on,
|
||||
/// - Always MinMaxCHeck on.
|
||||
/// </remarks>
|
||||
public ProcessController(Int32 slot)
|
||||
public ProcessController(Int32 slot, IProcessStateDef processSateDef)
|
||||
{
|
||||
_processCtrlTimer = new Timer(TmrProcessCtrlCycle_Elapsed, null, ProcessTimerCycleMs, ProcessTimerCycleMs);
|
||||
_slot = slot;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationToken = _cancellationTokenSource.Token;
|
||||
_processStateDef = processSateDef;
|
||||
InitNewMeter();
|
||||
InitProcesses();
|
||||
// program start with idle process
|
||||
@@ -598,8 +600,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
if (Processes == null)
|
||||
Processes = new List<IProductionProcess>();
|
||||
if (_processStateDef == null)
|
||||
_processStateDef = new EolStateMachineDef();
|
||||
|
||||
// get all processes relevant for EOL from table which has to be sorted
|
||||
var processes = _processStateDef.GetAllEolRelevantProcesses();
|
||||
|
||||
@@ -283,13 +283,11 @@
|
||||
<Compile Include="ctls\ctlMultiModePressure.xaml.cs">
|
||||
<DependentUpon>ctlMultiModePressure.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Picking.xaml.cs">
|
||||
<DependentUpon>Picking.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Model\EOLHandler.cs" />
|
||||
<Compile Include="ProductionProcesses\Enum\PickingProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\VisualInspection.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericStateMachineDef.cs" />
|
||||
<Compile Include="ProductionProcesses\IProcessStateDef.cs" />
|
||||
<Compile Include="ProductionProcesses\BaseProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\ErrorHandler.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\ExecStoreConfiguration.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\GetSerialNumberAndRadioAddress.cs" />
|
||||
@@ -300,7 +298,8 @@
|
||||
<Compile Include="ProductionProcesses\Enum\ImgState.cs" />
|
||||
<Compile Include="ProductionProcesses\Enum\ProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EventArgs\SingleProcessStateArgs.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolStateMachineDef.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\PickingProcesses\PickingProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\ProcessStateStruct.cs" />
|
||||
<Compile Include="Data\PickingResultData.cs" />
|
||||
<Compile Include="Data\PressureResultDataNotifyable.cs" />
|
||||
@@ -311,12 +310,6 @@
|
||||
<Compile Include="Model\MarriageMultiModeViewModel.cs" />
|
||||
<Compile Include="Model\PickingMultiModeViewModel.cs" />
|
||||
<Compile Include="Model\PickingViewModel.cs" />
|
||||
<Compile Include="MultiMode.xaml.cs">
|
||||
<DependentUpon>MultiMode.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MultiModeChild.xaml.cs">
|
||||
<DependentUpon>MultiModeChild.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Model\IMultiModeChildViewModel.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\CheckSerialNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\CheckOrderNumber.cs" />
|
||||
@@ -376,37 +369,17 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Picking.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="FinalTest.xaml">
|
||||
<Page Include="ProductionWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FinalTest.xaml.cs">
|
||||
<DependentUpon>FinalTest.xaml</DependentUpon>
|
||||
<Compile Include="ProductionWindow.xaml.cs">
|
||||
<DependentUpon>ProductionWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="MultiMode.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MultiModeChild.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UserAccessWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -620,7 +593,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Enum\" />
|
||||
<Folder Include="ProductionProcesses\PickingProcesses\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Class="Xylem.Common.Production.ProductionUiCordonel.FinalTest"
|
||||
x:Class="Xylem.Common.Production.ProductionUiCordonel.ProductionWindow"
|
||||
mc:Ignorable="d"
|
||||
Title="FinalTest" MinHeight="730" MinWidth="820" Height="730" Width="820" Initialized="Window_Initialized" Closing="Window_Closing" ResizeMode="CanMinimize" HorizontalAlignment="Right" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
|
||||
<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="2,2,2,2">
|
||||
+8
-6
@@ -21,6 +21,7 @@ using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
|
||||
using Xylem.Common.Utils.Logging;
|
||||
using Xylem.Common.Utils.UserAccessCtrl;
|
||||
@@ -33,7 +34,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
/// <summary>
|
||||
/// Interaction logic for FinalTest.xaml
|
||||
/// </summary>
|
||||
public sealed partial class FinalTest
|
||||
public sealed partial class ProductionWindow
|
||||
{
|
||||
#region variables and properties
|
||||
private readonly ILogger _logger;
|
||||
@@ -59,13 +60,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
private String _lastLoggingTextToAvoidRepetition;
|
||||
private CordonelRequirements _productionRequirements;
|
||||
private UserAccessWindow _userAccessWindow;
|
||||
private IProcessStateDef _processStateDef;
|
||||
|
||||
#endregion
|
||||
|
||||
public FinalTest()
|
||||
public ProductionWindow(String softwareName, String projectName, IProcessStateDef processStateDef)
|
||||
{
|
||||
_logger = NLogHelper.CreateOrGetLogger("ProductionUiCordonel");
|
||||
|
||||
_logger = NLogHelper.CreateOrGetLogger(projectName);
|
||||
_processStateDef = processStateDef;
|
||||
String msg;
|
||||
try
|
||||
{
|
||||
@@ -93,7 +95,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
|
||||
InitializeComponent();
|
||||
// Log version to files for debug purposes
|
||||
_strSoftwareNameVersion = $"{Properties.Resources.StrSoftwareNameVersion} {_version}";
|
||||
_strSoftwareNameVersion = $"{softwareName} {_version}";
|
||||
_logger.Info(_strSoftwareNameVersion);
|
||||
|
||||
Title = _strSoftwareNameVersion;
|
||||
@@ -177,7 +179,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
|
||||
try
|
||||
{
|
||||
_processCtrl = new ProcessController(Slot);
|
||||
_processCtrl = new ProcessController(Slot, _processStateDef);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -19,7 +19,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
@@ -285,6 +285,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cordonel - Shipping Preparation - Version.
|
||||
/// </summary>
|
||||
internal static string StrEolSoftwareNameVersion {
|
||||
get {
|
||||
return ResourceManager.GetString("StrEolSoftwareNameVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR.
|
||||
/// </summary>
|
||||
@@ -1392,6 +1401,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cordonel - Picking - Version.
|
||||
/// </summary>
|
||||
internal static string StrPickingSoftwareNameVersion {
|
||||
get {
|
||||
return ResourceManager.GetString("StrPickingSoftwareNameVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Production Order Number .
|
||||
/// </summary>
|
||||
@@ -1518,15 +1536,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cordonel - Shipping Preparation - Version.
|
||||
/// </summary>
|
||||
internal static string StrSoftwareNameVersion {
|
||||
get {
|
||||
return ResourceManager.GetString("StrSoftwareNameVersion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New Cordonel EOL Software available! The software is going to exit! This version:.
|
||||
/// </summary>
|
||||
|
||||
@@ -733,9 +733,12 @@
|
||||
<data name="StrMsgYears" xml:space="preserve">
|
||||
<value>Jahre</value>
|
||||
</data>
|
||||
<data name="StrSoftwareNameVersion" xml:space="preserve">
|
||||
<data name="StrEolSoftwareNameVersion" xml:space="preserve">
|
||||
<value>Cordonel - Versandfertigmachen - Version</value>
|
||||
</data>
|
||||
<data name="StrPickingSoftwareNameVersion" xml:space="preserve">
|
||||
<value>Cordonel - Montage - Version</value>
|
||||
</data>
|
||||
<data name="StrInstructionScanHousing" xml:space="preserve">
|
||||
<value>Deckel scannen</value>
|
||||
</data>
|
||||
|
||||
@@ -733,9 +733,12 @@
|
||||
<data name="StrMsgYears" xml:space="preserve">
|
||||
<value>years</value>
|
||||
</data>
|
||||
<data name="StrSoftwareNameVersion" xml:space="preserve">
|
||||
<data name="StrEolSoftwareNameVersion" xml:space="preserve">
|
||||
<value>Cordonel - Shipping Preparation - Version</value>
|
||||
</data>
|
||||
<data name="StrPickingSoftwareNameVersion" xml:space="preserve">
|
||||
<value>Cordonel - Picking - Version</value>
|
||||
</data>
|
||||
<data name="StrInstructionScanHousing" xml:space="preserve">
|
||||
<value>Scan housing</value>
|
||||
</data>
|
||||
|
||||
Reference in New Issue
Block a user