Browse Source

wait csu boot check complete

Robert 4 years ago
parent
commit
976b019e9c

+ 12 - 0
AwInitilizer/App.config

@@ -1,6 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="AwInitilizer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
     <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
     </startup>
+    <userSettings>
+        <AwInitilizer.Properties.Settings>
+            <setting name="FirmwareRoot" serializeAs="String">
+                <value>./</value>
+            </setting>
+        </AwInitilizer.Properties.Settings>
+    </userSettings>
 </configuration>

+ 17 - 1
AwInitilizer/App.xaml.cs

@@ -1,9 +1,11 @@
-using System;
+using AwInitilizer.DLL;
+using System;
 using System.Collections.Generic;
 using System.Configuration;
 using System.Data;
 using System.IO;
 using System.Linq;
+using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 
@@ -19,6 +21,13 @@ namespace AwInitilizer
             DispatcherUnhandledException += App_DispatcherUnhandledException;
         }
 
+        protected override void OnActivated(EventArgs e)
+        {
+            base.OnActivated(e);
+
+            var startResult = SajetConnect.SajetTransStart();
+        }
+
         private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
         {
             var fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
@@ -27,5 +36,12 @@ namespace AwInitilizer
             MessageBox.Show($"App crashed,Please report error and send back {fileName}");
             Application.Current.Shutdown();
         }
+
+        protected override void OnExit(ExitEventArgs e)
+        {
+            base.OnExit(e);
+
+            var stopResult = SajetConnect.SajetTransClose();
+        }
     }
 }

+ 26 - 3
AwInitilizer/Assist/SerialPortocol.cs

@@ -16,6 +16,8 @@ namespace AwInitilizer.Assist
         public event EventHandler<EvseSerialResponseModel> OnMsgReceived;
         public event PropertyChangedEventHandler PropertyChanged;
 
+        public string LatestNullMessage { get; private set; }
+
         private Interface.ISerialPort _serialPort;
 
         private SemaphoreQueue receivedBufferLock = new SemaphoreQueue(1, 1);
@@ -175,6 +177,11 @@ namespace AwInitilizer.Assist
             }
             OnMsgReceived -= EvseSerialProtocal_OnMsgReceived;
 
+            if (signal.CurrentCount == 0)
+            {
+                //timeout
+                LatestNullMessage = "Serial portocol timeout";
+            }
             return result;
 
             void EvseSerialProtocal_OnMsgReceived(object sender, EvseSerialResponseModel e)
@@ -246,8 +253,16 @@ namespace AwInitilizer.Assist
 
         private string SimpleStringParser(byte[] parameter)
         {
-            if (parameter == null || parameter.Length <= 1)
+            if(parameter == null)
+            {
+                LatestNullMessage = "parameter null exception";
+                return string.Empty;
+            }
+            if (parameter.Length <= 1)
+            {
+                LatestNullMessage = $"parameter legnth {parameter.Length} error";
                 return string.Empty;
+            }
             if(parameter.ToList().Contains(0x00))
             {
                 int endIndex = Array.FindIndex(parameter, (x) => { return x == 0x00; });
@@ -261,8 +276,16 @@ namespace AwInitilizer.Assist
             {
                 parameter = parameter.Take(parameter.Length - 1).ToArray();
             }
-            var result = Encoding.ASCII.GetString(parameter);
-            return result;
+            try
+            {
+                var result = Encoding.ASCII.GetString(parameter);
+                return result;
+            }
+            catch(Exception e)
+            {
+                LatestNullMessage = $"string parse exception : {e.Message}";
+                return string.Empty;
+            }
         }
 
         private byte[] ParseReceive(byte[] parseData, out List<EvseSerialResponseModel> reponseModels)

+ 257 - 0
AwInitilizer/DLL/SajetConnect.cs

@@ -0,0 +1,257 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.DLL
+{
+    public class SajetConnect
+    {
+        public enum CMD
+        {
+            Signin = 1, 
+            SnCheck = 15,
+            WoCheck = 14,
+            Report = 16,
+            Log = 4,
+            HeaderRegister = 8,
+            ValueReport = 5
+        }
+
+
+        [DllImport("SajetConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
+        public static extern bool SajetTransStart();
+
+        [DllImport("SajetConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
+        public static extern bool SajetTransClose();
+
+        //[DllImport("SajetConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
+        //public static extern bool SajetTransData(int command, IntPtr data, IntPtr length);
+
+        [DllImport("SajetConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
+        public static extern bool SajetTransData(int command, IntPtr data, IntPtr length);
+
+        [DllImport("SajetConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
+        public static extern bool SajetTransData_C(int command, out string data);
+
+        private static string userId = "";
+        public static bool SajetTransSignIn(ref string data)
+        {
+            var attemptId = data;
+            if(SajetTransData(CMD.Signin, ref data))
+            {
+                if(string.IsNullOrEmpty(data) || data.StartsWith("NG"))
+                {
+                    userId = "";
+                    return false;
+                }
+                else
+                {
+                    userId = attemptId;
+                    return true;
+                }
+            }
+            userId = "";
+            return false;
+        }
+
+        private static string WorkOrder = "";
+        public static bool SajetTransWoCheck(ref string workOrder)
+        {
+            if (string.IsNullOrEmpty(userId))
+                return false;
+            if (workOrder == null)
+                workOrder = "";
+            var msg = userId + "," + workOrder + ",";
+
+            if (SajetTransData(CMD.WoCheck, ref msg))
+            {
+                if (string.IsNullOrEmpty(msg) || msg.StartsWith("NG"))
+                {
+                    WorkOrder = "";
+                    return false;
+                }
+                else
+                {
+                    WorkOrder = workOrder;
+                    return true;
+                }
+            }
+            WorkOrder = "";
+            return false;
+        }
+        
+        private static string SN;
+        public static bool SajetTransSnCheck(ref string serialNumber)
+        {
+            var attemptSN = serialNumber;
+            if (string.IsNullOrEmpty(userId))
+                return false;
+            if (WorkOrder == null)
+                WorkOrder = "";
+            var msg = userId + "," + WorkOrder + "," + serialNumber + ",";
+
+            if (SajetTransData(CMD.SnCheck, ref msg))
+            {
+                if (string.IsNullOrEmpty(msg) || msg.StartsWith("NG"))
+                {
+                    SN = "";
+                    return false;
+                }
+                else
+                {
+                    SN = attemptSN;
+                    return true;
+                }
+            }
+            SN = "";
+            return false;
+        }
+
+        public static bool SajetTranFinish(bool Result)
+        {
+            if (string.IsNullOrEmpty(userId))
+                return false;
+            if (string.IsNullOrEmpty(WorkOrder))
+                return false;
+            if (string.IsNullOrEmpty(SN))
+                return false;
+            string msg = userId +"," + WorkOrder + "," + SN + ",";
+
+            if (string.IsNullOrEmpty(msg))
+                return false;
+            Result = false;
+            if (Result)
+            {
+                msg += "OK,";
+            }
+            else
+            {
+                msg += "NG,";
+            }
+            return SajetTransData(CMD.Report, ref msg);
+        }
+
+        public static string SajetTransRegisterHeader(string model, string header)
+        {
+            if (string.IsNullOrEmpty(userId))
+                return "";
+            var msg = userId + ",";
+            msg += model + "," + header;
+            if (SajetTransData(CMD.HeaderRegister,ref msg))
+            {
+                if(msg.StartsWith("OK"))
+                {
+                    //get codename
+                    msg = msg.Substring(3);
+                    var spaceIndex = msg.IndexOf(",");
+                    if (spaceIndex > 0)
+                    {
+                        msg = msg.Substring(0, spaceIndex);
+                    }
+                    return msg;
+                }
+                return null;
+            }
+            return null;
+        }
+
+        public static bool SajetTransReport(Dictionary<string,int> resultPair,Dictionary<string,string> codePair)
+        {
+            if (string.IsNullOrEmpty(userId))
+                return false;
+            if (string.IsNullOrEmpty(SN))
+                return false;
+            string msg = userId + "," + SN + ",";
+            foreach(var result in resultPair)
+            {
+                if(codePair.Keys.Contains(result.Key))
+                {
+                    msg += string.Format("{0}:{1},", codePair[result.Key],string.Format("{0}.00", result.Value) );
+                }
+            }
+            return SajetTransData(CMD.ValueReport,ref msg);
+        }
+
+        public static bool SajetTransLog (string data,bool isError)
+        {
+            if (string.IsNullOrEmpty(userId))
+                return false;
+            if (string.IsNullOrEmpty(SN))
+                return false;
+            string prefix = userId + "," + SN + ",";
+            while (data.Length > 0)
+            {
+                var msg = prefix;
+                int sendLength = Math.Min(250 - msg.Length, data.Length);
+                var sendString = data.Substring(0, sendLength);
+                msg += sendString;
+                if (!SajetTransData(CMD.Log, ref msg))
+                {
+                    break;
+                }
+                data = data.Substring(sendLength);
+            }
+            return data.Length == 0;
+        }
+
+        private static bool SajetTransData(CMD command, ref string data)
+        {
+            return SajetTransData((int)command,ref data);
+        }
+
+        private static string GetSendPrefix()
+        {
+            string msg = "";
+            if (string.IsNullOrEmpty(userId))
+            {
+                return null;
+            }
+            msg = userId + ",";
+            if (string.IsNullOrEmpty(WorkOrder))
+            {
+                return null;
+            }
+            msg += WorkOrder + ",";
+            return msg;
+        }
+
+        private static bool SajetTransData(int command,ref string data)
+        {
+            return true;
+            if(!data.EndsWith(","))
+            {
+                data = data + ",";
+            }
+
+            var idByte = Encoding.ASCII.GetBytes(data);
+            var length = idByte.Length;
+
+            var dataArray = new byte[100];
+            Array.Copy(idByte, 0, dataArray, 0, Math.Min(dataArray.Length, idByte.Length));
+
+            IntPtr dataIntPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(100);
+            System.Runtime.InteropServices.Marshal.Copy(idByte, 0, dataIntPtr, idByte.Length);
+
+            IntPtr lengthIntPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(10);
+            System.Runtime.InteropServices.Marshal.WriteInt32(lengthIntPtr, length);
+
+            var sendResult = SajetConnect.SajetTransData(command, dataIntPtr, lengthIntPtr);
+
+            var resultString1 = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(dataIntPtr);
+
+            System.Runtime.InteropServices.Marshal.Copy(dataIntPtr, dataArray, 0, 100);
+            System.Runtime.InteropServices.Marshal.Release(dataIntPtr);
+
+            var readLength = System.Runtime.InteropServices.Marshal.ReadInt32(lengthIntPtr);
+            System.Runtime.InteropServices.Marshal.Release(lengthIntPtr);
+
+            var resultString = Encoding.ASCII.GetString(dataArray);
+
+            data = resultString1.Substring(0, Math.Min(readLength, resultString1.Length));
+            return sendResult;
+        }
+    }
+}

BIN
AwInitilizer/DLL/SajetConnect.dll


+ 37 - 0
AwInitilizer/HintDialog.xaml

@@ -0,0 +1,37 @@
+<Window x:Class="AwInitilizer.HintDialog"
+        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:local="clr-namespace:AwInitilizer"
+        mc:Ignorable="d"
+        Title="HintDialog" Height="270" Width="600"
+        WindowStyle="None"
+        ResizeMode="NoResize"
+        WindowStartupLocation="CenterOwner"
+        Topmost="True">
+    <Border BorderBrush="Gray" BorderThickness="2">
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="30"/>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="auto"/>
+            </Grid.RowDefinitions>
+
+            <Grid Grid.Row="0" Background="Gray">
+                <Label x:Name="uxTitle" Content="Message" Foreground="White"/>
+            </Grid>
+
+            <Grid x:Name="uxCancelContainer" Grid.Row="2" Height="70">
+                <Button  HorizontalAlignment="Center" VerticalAlignment="Center" Height="50" Width="100" Click="Button_Click">
+                    <Label x:Name="uxBtnText" Content="Cancel"/>
+                </Button>
+            </Grid>
+
+            <StackPanel Orientation="Vertical" VerticalAlignment="Center" Grid.Row="1">
+                <Image x:Name="uxImage" Width="100" Height="100" Visibility="Collapsed"/>
+                <Label x:Name="uxConentText" FontSize="24" Foreground="Black" Content="Test Messge" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+            </StackPanel>
+        </Grid>
+    </Border>
+</Window>

+ 102 - 0
AwInitilizer/HintDialog.xaml.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace AwInitilizer
+{
+    /// <summary>
+    /// Interaction logic for HintDialog.xaml
+    /// </summary>
+    public partial class HintDialog : Window
+    {
+        public string Message
+        {
+            get => (string) uxConentText.Content;
+            set => uxConentText.Content = value;
+        }
+
+        public string BtnText
+        {
+            get => (string)uxBtnText.Content;
+            set => uxBtnText.Content = value;
+        }
+
+        public string Caption
+        {
+            get => (string)uxTitle.Content;
+            set => uxTitle.Content = value;
+        }
+
+        private string _ImgPath;
+        public string ImgPath
+        {
+            get => _ImgPath;
+            set
+            {
+                if(_ImgPath!=value)
+                {
+                    _ImgPath = value;
+
+                    if(string.IsNullOrEmpty(_ImgPath))
+                    {
+                        uxImage.Visibility = Visibility.Collapsed;
+                    }
+                    else
+                    {
+                        uxImage.Visibility = Visibility.Visible;
+                        uxImage.Source = new BitmapImage(new Uri(_ImgPath)) { };
+                    }
+                }
+            }
+        }
+
+        public bool IsCancelAble
+        {
+            get => uxCancelContainer.Visibility == Visibility.Visible;
+            set
+            {
+                uxCancelContainer.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+            }
+        }
+
+        public HintDialog()
+        {
+            InitializeComponent();
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+        }
+
+        private static ImageSource GetBitMap(string imgpath)
+        {
+            try
+            {
+                BitmapImage bitmapImg = new BitmapImage();
+                bitmapImg.BeginInit();
+                bitmapImg.UriSource = new Uri(imgpath, UriKind.RelativeOrAbsolute);
+                bitmapImg.CreateOptions = BitmapCreateOptions.IgnoreColorProfile | BitmapCreateOptions.IgnoreImageCache;
+                bitmapImg.CacheOption = BitmapCacheOption.OnLoad;
+                bitmapImg.EndInit();
+                bitmapImg.Freeze();
+                return bitmapImg;
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+                return null;
+            }
+        }
+    }
+}

BIN
AwInitilizer/Image/Blue.png


BIN
AwInitilizer/Image/Emergency.png


BIN
AwInitilizer/Image/Green.png


+ 26 - 0
AwInitilizer/Initilizer.csproj

@@ -25,6 +25,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -34,6 +35,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup>
     <ApplicationManifest>app.manifest</ApplicationManifest>
@@ -63,6 +65,14 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </ApplicationDefinition>
+    <Compile Include="Procedure\VersionLogProcedure.cs" />
+    <Compile Include="SigninDialog.xaml.cs">
+      <DependentUpon>SigninDialog.xaml</DependentUpon>
+    </Compile>
+    <Page Include="HintDialog.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="MainWindow.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
@@ -78,6 +88,10 @@
       <SubType>Component</SubType>
     </Compile>
     <Compile Include="Converter\BooleanAndConverter.cs" />
+    <Compile Include="DLL\SajetConnect.cs" />
+    <Compile Include="HintDialog.xaml.cs">
+      <DependentUpon>HintDialog.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Interface\IIogger.cs" />
     <Compile Include="Interface\ISerialPort.cs" />
     <Compile Include="MainViewModel.cs" />
@@ -85,6 +99,10 @@
       <DependentUpon>MainWindow.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Page Include="SigninDialog.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Model\ButtonStatus.cs" />
@@ -128,6 +146,14 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <Content Include="DLL\SajetConnect.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Resource Include="Image\Blue.png" />
+    <Resource Include="Image\Emergency.png" />
+    <Resource Include="Image\Green.png" />
+  </ItemGroup>
   <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 42 - 0
AwInitilizer/MainViewModel.cs

@@ -11,6 +11,34 @@ namespace AwInitilizer
 {
     public class MainViewModel : Model.UpdateData,INotifyPropertyChanged
     {
+        private string _UserID;
+        public string UserID
+        {
+            get => _UserID;
+            set
+            {
+                if(_UserID!=value)
+                {
+                    _UserID = value;
+                    RaisePropertyChanged(nameof(UserID));
+                }
+            }
+        }
+
+        private string _WorkOrder;
+        public string WorkOrder
+        {
+            get => _WorkOrder;
+            set
+            {
+                if (_WorkOrder != value)
+                {
+                    _WorkOrder = value;
+                    RaisePropertyChanged(nameof(WorkOrder));
+                }
+            }
+        }
+
         private bool _IsUdatIng = false;
         public bool IsUdatIng
         {
@@ -26,6 +54,20 @@ namespace AwInitilizer
             }
         }
 
+        private bool _IsInputCheckpassed = false;
+        public bool IsInputCheckpassed
+        {
+            get => _IsInputCheckpassed;
+            set
+            {
+                if(_IsInputCheckpassed != value)
+                {
+                    _IsInputCheckpassed = value;
+                    RaisePropertyChanged(nameof(IsInputCheckpassed));
+                }
+            }
+        }
+
         public bool IsInputLock => !IsUdatIng;
 
         private string _SettingFileName;

+ 148 - 114
AwInitilizer/MainWindow.xaml

@@ -3,142 +3,176 @@
         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:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
         xmlns:local="clr-namespace:AwInitilizer"
         mc:Ignorable="d"
-        Title="Initlizer" Height="1023" Width="789.5" Background="#FF363535" >
+        Title="Initlizer" Height="590" Width="790" Background="#FF363535"
+        input:InputMethod.IsInputMethodEnabled="False"
+        x:Name="uxManinWindow">
     <Window.Resources>
     </Window.Resources>
     <Viewbox>
-        <StackPanel Orientation="Vertical" Margin="10">
-            <GroupBox>
-                <GroupBox.Header>
-                    <Label Content="Barcode Setting" Foreground="White" FontSize="16"/>
-                </GroupBox.Header>
-                <StackPanel Orientation="Vertical">
-                    <StackPanel Orientation="Horizontal">
-                        <StackPanel Orientation="Horizontal" Height="30">
+        <StackPanel Orientation="Horizontal">
+            <StackPanel Orientation="Vertical" Width="790">
+                <GroupBox>
+                    <GroupBox.Header>
+                        <Label Content="Account" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
+                    <StackPanel Orientation="Vertical">
+                        <StackPanel Orientation="Horizontal" Height="30" Margin="0,0,0,10">
                             <Grid Width="200">
-                                <Label Content="Model Name" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                                <Label Content="User Id" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
                             </Grid>
-                            <TextBox x:Name="uxModelName" Text="{Binding ModelName}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="170" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                            <TextBox Text="{Binding UserID}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="440" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                            <Button Width="100" Click="Logout_Click" IsEnabled="{Binding IsInputLock}">
+                                <Label Content="Logout"/>
+                            </Button>
                         </StackPanel>
-                        <StackPanel Orientation="Horizontal" Height="30">
+                        <StackPanel Orientation="Horizontal" Height="30" Margin="0,0,0,10">
                             <Grid Width="200">
-                                <Label Content="Serial Number" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                                <Label Content="Work Order" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
                             </Grid>
-                            <TextBox x:Name="uxSerialNumber" Text="{Binding SerialNumber}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="170" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                            <TextBox Text="{Binding WorkOrder}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="540" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"
+                                     TextChanged="WorkOrder_TextChanged" KeyDown="WorkOrder_KeyDown"/>
                         </StackPanel>
                     </StackPanel>
-                    <Frame Height="10"/>
-                </StackPanel>
-            </GroupBox>
-            <GroupBox>
-                <GroupBox.Header>
-                    <Label Content="Config Setting" Foreground="White" FontSize="16"/>
-                </GroupBox.Header>
-                <StackPanel Orientation="Vertical">
-                    <StackPanel Orientation="Horizontal" Height="30">
-                        <Grid Width="200">
-                            <Label Content="Setting File" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
-                        </Grid>
-                        <TextBox x:Name="uxSettingFile" Text="{Binding SettingFileName}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="510" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
-                        <Button Width="30" Click="SettingFileSelect_Click" IsEnabled="{Binding IsInputLock}">
-                            <Label Content="..."/>
-                        </Button>
+                </GroupBox>
+                <GroupBox>
+                    <GroupBox.Header>
+                        <Label Content="Barcode Setting" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
+                    <StackPanel Orientation="Vertical">
+                        <StackPanel Orientation="Horizontal">
+                            <StackPanel Orientation="Horizontal" Height="30">
+                                <Grid Width="200">
+                                    <Label Content="Model Name" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                                </Grid>
+                                <TextBox x:Name="uxModelName" Text="{Binding ModelName}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="170" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                            </StackPanel>
+                            <StackPanel Orientation="Horizontal" Height="30">
+                                <Grid Width="200">
+                                    <Label Content="Serial Number" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                                </Grid>
+                                <TextBox x:Name="uxSerialNumber" Text="{Binding SerialNumber}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="170" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                            </StackPanel>
+                        </StackPanel>
+                        <Frame Height="10"/>
                     </StackPanel>
-                    <Frame Height="10"/>
-                    <StackPanel Orientation="Horizontal" Height="30">
-                        <Grid Width="200">
-                            <Label Content="4G Module Reversiion" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
-                        </Grid>
-                        <TextBox x:Name="uxFourGModuleVer" Text="{Binding FourGenModuleVersion}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="540" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                </GroupBox>
+                <GroupBox>
+                    <GroupBox.Header>
+                        <Label Content="Config Setting" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
+                    <StackPanel Orientation="Vertical">
+                        <StackPanel Orientation="Horizontal" Height="30">
+                            <Grid Width="200">
+                                <Label Content="Setting File" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                            </Grid>
+                            <TextBox x:Name="uxSettingFile" Text="{Binding SettingFileName}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="540" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                        </StackPanel>
+                        <Frame Height="10"/>
+                        <StackPanel Orientation="Horizontal" Height="30">
+                            <Grid Width="200">
+                                <Label Content="4G Module Reversiion" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                            </Grid>
+                            <TextBox x:Name="uxFourGModuleVer" Text="{Binding FourGenModuleVersion}" IsEnabled="{Binding IsInputLock}" IsReadOnly="True" Width="540" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center"/>
+                        </StackPanel>
+                        <Frame Height="10"/>
+                        <StackPanel Orientation="Horizontal" Height="30">
+                            <Grid Width="200">
+                                <Label Content="4G Sim Card Information" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                            </Grid>
+                            <CheckBox x:Name="uxIsSimCheckEnabled" IsChecked="{Binding IsSimInsert}" IsEnabled="{Binding IsInputLock}" IsHitTestVisible="False" VerticalAlignment="Center" />
+                            <Grid Width="10"/>
+                            <Grid Width="70">
+                                <Label Content="ICCID" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                            </Grid>
+                            <Grid Width="10"/>
+                            <TextBox x:Name="uxICCID" Text="{Binding ICCID}" IsReadOnly="True" Width="176" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center">
+                                <TextBox.IsEnabled>
+                                    <MultiBinding Converter="{StaticResource booleanAndConverter}">
+                                        <Binding Path="IsSimInsert" />
+                                        <Binding Path="IsInputLock" />
+                                    </MultiBinding>
+                                </TextBox.IsEnabled>
+                            </TextBox>
+                            <Grid Width="70">
+                                <Label Content="IMSI" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
+                            </Grid>
+                            <Grid Width="10"/>
+                            <TextBox x:Name="uxIMSI" Text="{Binding IMSI}" IsReadOnly="True" Width="176" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center">
+                                <TextBox.IsEnabled>
+                                    <MultiBinding Converter="{StaticResource booleanAndConverter}">
+                                        <Binding Path="IsSimInsert" />
+                                        <Binding Path="IsInputLock" />
+                                    </MultiBinding>
+                                </TextBox.IsEnabled>
+                            </TextBox>
+                            <Grid Width="10"/>
+                        </StackPanel>
+                        <Frame Height="10"/>
                     </StackPanel>
-                    <Frame Height="10"/>
-                    <StackPanel Orientation="Horizontal" Height="30">
-                        <Grid Width="200">
-                            <Label Content="4G Sim Card Information" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
-                        </Grid>
-                        <CheckBox x:Name="uxIsSimCheckEnabled" IsChecked="{Binding IsSimInsert}" IsEnabled="{Binding IsInputLock}" IsHitTestVisible="False" VerticalAlignment="Center" />
-                        <Grid Width="10"/>
-                        <Grid Width="70">
-                            <Label Content="ICCID" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
-                        </Grid>
-                        <Grid Width="10"/>
-                        <TextBox x:Name="uxICCID" Text="{Binding ICCID}" IsReadOnly="True" Width="176" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center">
-                            <TextBox.IsEnabled>
-                                <MultiBinding Converter="{StaticResource booleanAndConverter}">
-                                    <Binding Path="IsSimInsert" />
-                                    <Binding Path="IsInputLock" />
-                                </MultiBinding>
-                            </TextBox.IsEnabled>
-                        </TextBox>
-                        <Grid Width="70">
-                            <Label Content="IMSI" Foreground="White" FontSize="16" HorizontalAlignment="Center"/>
-                        </Grid>
+                </GroupBox>
+
+                <GroupBox>
+                    <GroupBox.Header>
+                        <Label Content="Firmware version" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
+
+                    <DataGrid AutoGenerateColumns="False" Margin="10" Height="150" CanUserSortColumns="False" IsEnabled="{Binding IsInputLock}" ItemsSource="{Binding FirmwareUpdateModels}">
+                        <DataGrid.Columns>
+                            <DataGridTextColumn Header="Module" Width="150" MinWidth="50" Binding="{Binding Path=Module}" IsReadOnly="True"/>
+                            <DataGridTextColumn Header="Version" Width="150" MinWidth="70" Binding="{Binding Path=Version}" IsReadOnly="True"/>
+                            <DataGridTextColumn Header="File name" Binding="{Binding Path=FirmwareFileName}" IsReadOnly="False"/>
+                        </DataGrid.Columns>
+                    </DataGrid>
+                </GroupBox>
+
+                <Grid Height="50">
+                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
+                        <ProgressBar Minimum="0" Maximum="100" x:Name="uxProgress" VerticalAlignment="Center" Height="10" Width="250"/>
+                        <Label x:Name="uxProgressRate" Content="0%" Foreground="White" FontSize="16"/>
                         <Grid Width="10"/>
-                        <TextBox x:Name="uxIMSI" Text="{Binding IMSI}" IsReadOnly="True" Width="176" FontSize="16" TextAlignment="Center" VerticalContentAlignment="Center">
-                            <TextBox.IsEnabled>
+                        <Button x:Name="uxStartBtn" Click="StartInit_Click">
+                            <Button.IsEnabled>
                                 <MultiBinding Converter="{StaticResource booleanAndConverter}">
-                                    <Binding Path="IsSimInsert" />
                                     <Binding Path="IsInputLock" />
+                                    <Binding Path="IsInputCheckpassed" />
                                 </MultiBinding>
-                            </TextBox.IsEnabled>
-                        </TextBox>
-                        <Grid Width="10"/>
+                            </Button.IsEnabled>
+                            
+                            <Label Content="Start DC Initialize"/>
+                        </Button>
                     </StackPanel>
-                    <Frame Height="10"/>
-                </StackPanel>
-            </GroupBox>
-
-            <GroupBox>
-                <GroupBox.Header>
-                    <Label Content="Firmware version" Foreground="White" FontSize="16"/>
-                </GroupBox.Header>
-
-                <DataGrid AutoGenerateColumns="False" Margin="10" Height="150" CanUserSortColumns="False" IsEnabled="{Binding IsInputLock}" ItemsSource="{Binding FirmwareUpdateModels}">
-                    <DataGrid.Columns>
-                        <DataGridTextColumn Header="Module" Width="150" MinWidth="50" Binding="{Binding Path=Module}" IsReadOnly="True"/>
-                        <DataGridTextColumn Header="Version" Width="150" MinWidth="70" Binding="{Binding Path=Version}" IsReadOnly="True"/>
-                        <DataGridTextColumn Header="File name" Binding="{Binding Path=FirmwareFileName}" IsReadOnly="False"/>
-                    </DataGrid.Columns>
-                </DataGrid>
-            </GroupBox>
-
-            <Grid Height="50">
-                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
-                    <ProgressBar Minimum="0" Maximum="100" x:Name="uxProgress" VerticalAlignment="Center" Height="10" Width="250"/>
-                    <Label x:Name="uxProgressRate" Content="0%" Foreground="White" FontSize="16"/>
-                    <Grid Width="10"/>
-                    <Button x:Name="uxStartBtn" Click="StartInit_Click" IsEnabled="{Binding IsInputLock}">
-                        <Label Content="Start DC Initialize"/>
-                    </Button>
-                </StackPanel>
-            </Grid>
-
-            <GroupBox Height="280" >
-                <GroupBox.Header>
-                    <Label Content="Init Procedure" Foreground="White" FontSize="16"/>
-                </GroupBox.Header>
+                </Grid>
 
-                <DataGrid AutoGenerateColumns="False" Margin="10" x:Name="uxProcedureDataGrid" CanUserSortColumns="False" IsEnabled="{Binding IsInputLock}" ItemsSource="{Binding UpdateProcedure}">
-                    <DataGrid.Columns>
-                        <DataGridTextColumn Header="Name" Width="150" MinWidth="50" Binding="{Binding Path=Name}" IsReadOnly="True"/>
-                        <DataGridTextColumn Header="Content" Width="500" MinWidth="70" Binding="{Binding Path=Content}" IsReadOnly="True"/>
-                        <DataGridCheckBoxColumn Header="Action" Binding="{Binding Path=IsActivated}" IsReadOnly="False"/>
-                    </DataGrid.Columns>
-                </DataGrid>
-            </GroupBox>
+                <GroupBox Height="280" >
+                    <GroupBox.Header>
+                        <Label Content="Init Procedure" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
 
-            <GroupBox Height="200">
-                <GroupBox.Header>
-                    <Label Content="Terminal" Foreground="White" FontSize="16"/>
-                </GroupBox.Header>
+                    <DataGrid AutoGenerateColumns="False" Margin="10" x:Name="uxProcedureDataGrid" CanUserSortColumns="False" IsEnabled="{Binding IsInputLock}" ItemsSource="{Binding UpdateProcedure}">
+                        <DataGrid.Columns>
+                            <DataGridTextColumn Header="Name" Width="150" MinWidth="50" Binding="{Binding Path=Name}" IsReadOnly="True"/>
+                            <DataGridTextColumn Header="Content" Width="500" MinWidth="70" Binding="{Binding Path=Content}" IsReadOnly="True"/>
+                            <DataGridCheckBoxColumn Header="Action" Binding="{Binding Path=IsActivated}" IsReadOnly="False"/>
+                        </DataGrid.Columns>
+                    </DataGrid>
+                </GroupBox>
+            </StackPanel>
+            <Grid Width="10"/>
+            <StackPanel Orientation="Vertical" Width="400">
+                <GroupBox Height="885">
+                    <GroupBox.Header>
+                        <Label Content="Terminal" Foreground="White" FontSize="16"/>
+                    </GroupBox.Header>
 
-                <ScrollViewer x:Name="uxTerminalScroller">
-                    <TextBlock x:Name="uxTerminal" Background="Black" Margin="10" Foreground="Green">
-                    </TextBlock>
-                </ScrollViewer>
-            </GroupBox>
+                    <ScrollViewer x:Name="uxTerminalScroller">
+                        <TextBlock x:Name="uxTerminal" Background="Black" Margin="10" Foreground="Green">
+                        </TextBlock>
+                    </ScrollViewer>
+                </GroupBox>
+            </StackPanel>
         </StackPanel>
     </Viewbox>
 </Window>

+ 322 - 87
AwInitilizer/MainWindow.xaml.cs

@@ -29,6 +29,7 @@ namespace AwInitilizer
     {
         private string barCode = string.Empty;
         private DispatcherTimer CleanInputTimer;
+        private DispatcherTimer LogoutTimer;
 
         private bool IsInitilizing = false;
 
@@ -47,22 +48,33 @@ namespace AwInitilizer
             System.Net.ServicePointManager.Expect100Continue = false;
 
             CleanInputTimer = new DispatcherTimer();
-            CleanInputTimer.Interval = TimeSpan.FromSeconds(2);
+            CleanInputTimer.Interval = TimeSpan.FromSeconds(1);
             CleanInputTimer.Tick += CleanInputTimer_Tick;
 
+            LogoutTimer = new DispatcherTimer();
+            LogoutTimer.Interval = TimeSpan.FromMinutes(1);
+            LogoutTimer.Tick += LogoutTimer_Tick;
+
             Loaded += MainWindow_Loaded;
             PreviewKeyDown += MainWindow_PreviewKeyDown;
+            PreviewKeyUp += MainWindow_PreviewKeyUp;
 
+            SystemID.TryParse("AWLU770001W1P0D2045A001A0", out var systemID);
             //this.DataContext = new MainViewModel();
             this.DataContext = new MainViewModel() {
-                //ModelName = "DSYE601E0ED2PH",
-                //SerialNumber = "NeedSetupSN",
-                //FourGenModuleVersion = "EC25AFFAR07A08M4G",
+                //SystemID = systemID,
+                //ModelName = "AWLU770001W1P0",
+                //SettingModelName = "AWLU770001W1P0",
+                //SerialNumber = "D2045A001A0",
+                ////FourGenModuleVersion = "EC25AFFAR07A08M4G",
                 //IsSimInsert = false,
-                //ICCID = "12345678901234567890",
-                //IMSI = "123456789012345",
-                //CSUVersion = "V1.01.01.0601.00",
-                //MCUVersion = "D0.52.40.1770.P0"
+                ////ICCID = "12345678901234567890",
+                ////IMSI = "123456789012345",
+                ////CSUVersion = "V1.01.01.0601.00",
+                ////MCUVersion = "D0.52.40.1770.P0",
+                //IsInputCheckpassed = true,
+                //FirmwareUpdateModels = new List<FirmwareUpdateModel>(),
+
             };
             this.DataContextChanged += MainWindow_DataContextChanged;
         }
@@ -75,29 +87,82 @@ namespace AwInitilizer
         private void CleanInputTimer_Tick(object sender, EventArgs e)
         {
             CleanInputTimer.Stop();
+
+            Console.WriteLine(barCode);
+
+            if (SystemID.TryParse(barCode, out SystemID systemID))
+            {
+                SystemIDScanReseived(systemID);
+            }
+
             barCode = string.Empty;
         }
 
+        bool shiftPressed = false;
         private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
         {
-            barCode += e.Key;
+            ResetLogoutTimer();
+
+            if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
+            {
+                shiftPressed = true;
+                return;
+            }
+            else if (e.Key == Key.Enter)
+            {
+                e.Handled = true;
+                return;
+            }
+            else
+            {
+                if (e.Key >= Key.D0 && e.Key <= Key.D9)
+                {
+                    // Number keys pressed so need to so special processing
+                    // also check if shift pressed
+                    var input = e.Key.ToString();
+                    input = input.Remove(0, 1);
+                    barCode += input;
+                }
+                else if (e.Key == Key.OemMinus)
+                {
+                    barCode += "-";
+                }
+                else if (e.Key == Key.Return)
+                {
+                    return;
+                }
+                else
+                {
+                    var input = e.Key.ToString();
+                    if (shiftPressed)
+                        input = input.ToUpper();
+                    barCode += input;
+                }
+            }
 
             CleanInputTimer.Stop();
             CleanInputTimer.Start();
+        }
 
-            if (SystemID.TryParse(barCode,out SystemID systemID))
+        private void SystemIDScanReseived(SystemID systemID)
+        {
+            ViewModel.IsInputCheckpassed = false;
+            inputSystemID = systemID;
+            var serialNumber = inputSystemID.SerialNumber;
+            if (!DLL.SajetConnect.SajetTransSnCheck(ref serialNumber))
             {
-                inputSystemID = systemID;
-                uxModelName.Text = systemID.ModelName.ToString();
-                uxSerialNumber.Text = systemID.SerialNumber;
+                MessageBox.Show("Serial Number or WorkOrder Error");
+                return;
+            }
 
-                if(ViewModel!=null && !string.IsNullOrEmpty(ViewModel.ModelName))
-                {
-                    if (systemID.ModelName.ToString() != ViewModel.ModelName)
-                    {
-                        MessageBox.Show("Model Name Mismatch");
-                    }
-                }
+            LoadConfigBySystemID(systemID);
+        }
+
+        private void MainWindow_PreviewKeyUp(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
+            {
+                shiftPressed = false;
             }
         }
 
@@ -113,12 +178,32 @@ namespace AwInitilizer
             //procedures.Add(new ButtonStatusCheckPorcedure());
             //procedures.Add(new RestarttoIdelProcedure());
 
-            //uxProcedureDataGrid.ItemsSource = procedures;
+            //ViewModel.UpdateProcedure.Add(new VersionLogProcedure());
+
+            //uxProcedureDataGrid.ItemsSource = procedures;\
+
+//            var test = new HintDialog();
+//            test.ImgPath = "pack://application:,,,/AwInitilizer;component/Image/Blue.png";
+//            test.Message = "BLUE BOTTON"
+//;           test.ShowDialog();
+
+            DisplayLogin();
         }
 
         private void StartInit_Click(object sender, RoutedEventArgs e)
         {
-            if(CheckInputData())
+            //check again
+            ViewModel.IsInputCheckpassed = false;
+            inputSystemID = ViewModel.SystemID;
+            var serialNumber = inputSystemID.SerialNumber;
+            if (!DLL.SajetConnect.SajetTransSnCheck(ref serialNumber))
+            {
+                MessageBox.Show("Serial Number or WorkOrder Error");
+                return;
+            }
+
+            ViewModel.IsInputCheckpassed = CheckInputData();
+            if (ViewModel.IsInputCheckpassed)
             {
                 ViewModel.IsUdatIng = true;
                 _ = UpdateTask();
@@ -150,7 +235,7 @@ namespace AwInitilizer
             bool isAvaliable = true;
             string alertMsg = string.Empty;
             UpdateData updateData;
-            if(DataContext is MainViewModel viewModel)
+            if (DataContext is MainViewModel viewModel)
             {
                 updateData = viewModel;
             }
@@ -160,12 +245,12 @@ namespace AwInitilizer
             }
 
 
-            if(string.IsNullOrEmpty(updateData.ModelName))
+            if (string.IsNullOrEmpty(updateData.ModelName))
             {
                 alertMsg += "Model Name is Required\n";
                 isAvaliable = false;
             }
-            else if(ViewModel.SettingModelName!= updateData.ModelName)
+            else if (ViewModel.SettingModelName != updateData.ModelName)
             {
                 alertMsg += "Model Name setting is Mismathed\n";
                 isAvaliable = false;
@@ -178,9 +263,9 @@ namespace AwInitilizer
             }
 
             var systemIDString = updateData.ModelName + updateData.SerialNumber;
-            if(!string.IsNullOrEmpty(systemIDString))
+            if (!string.IsNullOrEmpty(systemIDString))
             {
-                if(SystemID.TryParse(systemIDString,out SystemID systemID))
+                if (SystemID.TryParse(systemIDString, out SystemID systemID))
                 {
                     updateData.SystemID = systemID;
                 }
@@ -191,7 +276,7 @@ namespace AwInitilizer
                 }
             }
 
-            if (updateData.SystemID!=null &&
+            if (updateData.SystemID != null &&
                 updateData.SystemID.ModelName.Network.ToString().Contains("4G"))
             {
                 if (string.IsNullOrEmpty(updateData.FourGenModuleVersion))
@@ -245,7 +330,7 @@ namespace AwInitilizer
                 }
             }
 
-            if(!isAvaliable)
+            if (!isAvaliable)
             {
                 MessageBox.Show(alertMsg);
             }
@@ -258,11 +343,16 @@ namespace AwInitilizer
             ProcedureBase.Logger = this;
             uxTerminal.Inlines.Clear();
 
+            Dictionary<string, string> logPairs = new Dictionary<string, string>();
+            //logPairs.Add("ModelName", ViewModel.SystemID.ModelName.ToString());
+            //logPairs.Add("SerialNumber", ViewModel.SystemID.SerialNumber);
+
             ViewModel.IsUdatIng = true;
             var procedureList = ViewModel.UpdateProcedure.Where(x => x.IsActivated).ToList();
             int procedureIndex;
             for (procedureIndex = 0; procedureIndex < procedureList.Count; procedureIndex++)
             {
+                procedureList[procedureIndex].LogPair.Clear();
                 procedureList[procedureIndex].Reset();
             }
 
@@ -271,31 +361,77 @@ namespace AwInitilizer
                 uxProgress.Value = (procedureIndex * 100 / procedureList.Count);
                 uxProgressRate.Content = ((int)(procedureIndex * 100 / procedureList.Count)) + "%";
                 var result = await procedureList[procedureIndex].DoWork();
+
+                foreach(var procedureLog in procedureList[procedureIndex].LogPair)
+                {
+                    logPairs.Add(procedureLog.Key, procedureLog.Value);
+                }
+
                 if (!result)
                     break;
             }
 
+
+            //report MES result
+            ReportMESLog(logPairs);
+
             if (procedureIndex == procedureList.Count)
             {
                 uxProgress.Value = 100;
                 uxProgressRate.Content = "100%";
+                //report Success
+                DLL.SajetConnect.SajetTranFinish(true);
             }
             CreateLogFile();
             ViewModel.IsUdatIng = false;
         }
 
+        private void ReportMESLog(Dictionary<string, string> logPairs)
+        {
+            //build header
+            Dictionary<string, int> valuePairs = new Dictionary<string, int>();
+            foreach (var pair in logPairs)
+            {
+                if(int.TryParse(pair.Value,out int val))
+                {
+                    valuePairs.Add(pair.Key,val);
+                }
+                else
+                {
+                    valuePairs.Add(string.Format("{0}:{1}", pair.Key, pair.Value),1);
+                }
+            }
+            //register Header
+            var codePair = new Dictionary<string, string>();
+            var model = ViewModel.SystemID.ModelName.ToString();
+            foreach(var key in valuePairs.Keys)
+            {
+                var code = DLL.SajetConnect.SajetTransRegisterHeader(model,key);
+                if (string.IsNullOrEmpty(code))
+                    continue;
+                codePair.Add(key, code);
+            }
+            //report value
+            var reportResult = DLL.SajetConnect.SajetTransReport(valuePairs, codePair);
+        }
+
         private void CreateLogFile()
         {
             var fileName = ViewModel.SystemID + ViewModel.SerialNumber + DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".txt";
             var folderName = "Log";
             var filePath = Path.Combine(folderName, fileName);
             string content = "";
-            
-            if(File.Exists(fileName))
+
+            if (File.Exists(fileName))
             {
                 File.Delete(fileName);
             }
 
+            if (!Directory.Exists("Log"))
+            {
+                Directory.CreateDirectory("Log");
+            }
+
             FileStream fileStream = new FileStream(filePath, FileMode.Create);
             StreamWriter fileWriter = new StreamWriter(fileStream);
 
@@ -310,7 +446,7 @@ namespace AwInitilizer
             fileWriter.WriteLine($"sim ICCID:{ ViewModel.ICCID}");
             fileWriter.WriteLine($"sim IMSI:{ ViewModel.IMSI}");
 
-            foreach(var model in ViewModel.FirmwareUpdateModels)
+            foreach (var model in ViewModel.FirmwareUpdateModels)
             {
                 fileWriter.WriteLine($"{model.Module} version:{ model.Version}");
             }
@@ -328,14 +464,15 @@ namespace AwInitilizer
 
             fileWriter.WriteLine("==========================");
             fileWriter.Close();
-            //fileStream.Close();
+            fileStream.Close();
         }
 
         public void Print(string msg, bool isError = false)
         {
-            Dispatcher.Invoke(()=> {
+            DLL.SajetConnect.SajetTransLog(msg, isError);
+            Dispatcher.Invoke(() => {
                 Span line = new Span();
-                line.Inlines.Add(msg+"\n");
+                line.Inlines.Add(msg + "\n");
                 Span.SetForeground(line, isError ? Brushes.Red : Brushes.Green);
 
                 uxTerminal.Inlines.Add(line);
@@ -344,45 +481,75 @@ namespace AwInitilizer
         }
         #endregion
 
-        private void SettingFileSelect_Click(object sender, RoutedEventArgs e)
+        private void LoadConfigBySystemID(SystemID systemID)
         {
-            OpenFileDialog openFileDialog = new OpenFileDialog();
-            openFileDialog.Filter = "Setting file|*.ini";
-            openFileDialog.Multiselect = false;
-            if (openFileDialog.ShowDialog() == true)
-            {
-                //check format
-                var filePath = openFileDialog.FileName;
-                if (!string.IsNullOrEmpty(filePath) &&
-                    File.Exists(filePath))
+            string settingRootFolder;
+            try
+            {
+                var defaultPath = Properties.Settings.Default.FirmwareRoot;
+                if(string.IsNullOrEmpty(defaultPath))
                 {
-                    var settingString = File.ReadAllText(filePath);
-                    SettingConfig setting;
-                    try
-                    {
-                         setting = JsonConvert.DeserializeObject<SettingConfig>(settingString);
-                    }
-                    catch
-                    {
-                        MessageBox.Show("Setting file ERROR");
-                        return;
-                    }
-
-                    if(CheckSettingConfig(System.IO.Path.GetDirectoryName(filePath),ref setting))
-                    {
-                        ViewModel.SettingModelName = setting.ModelName;
-                        ViewModel.SettingFileName = Path.GetFileName(filePath);
-                        ViewModel.FourGenModuleVersion = setting.FourGenModuleVersion;
-                        ViewModel.IsSimInsert = setting.IsSimInsert;
-                        ViewModel.ICCID = setting.ICCID;
-                        ViewModel.IMSI = setting.IMSI;
-                        ViewModel.FirmwareUpdateModels = setting.FirmwareUpdateList
-                            .Where(x => !string.IsNullOrEmpty(x.Module) && !string.IsNullOrEmpty(x.Version) && !string.IsNullOrEmpty(x.FirmwareFileName)
-                            ).ToList() ;
-
-                        UpdateProcedure();
-                    }
+                    defaultPath = ".\\";
                 }
+                settingRootFolder = Path.GetFullPath(defaultPath);
+            }
+            catch
+            {
+                MessageBox.Show("Firmware root path ERROR");
+                return;
+            }
+
+            if (!Directory.Exists(settingRootFolder))
+            {
+                MessageBox.Show("Firmware root path not exist");
+                return;
+            }
+
+            string modelDirectoy = Path.Combine(settingRootFolder, systemID.ModelName.ToString());
+            if (!Directory.Exists(modelDirectoy))
+            {
+                MessageBox.Show("Model firmware root path not exist");
+                return;
+            }
+
+            string modelSeettingFilePath = Path.Combine(modelDirectoy, systemID.ModelName.ToString() + ".ini");
+            if (!File.Exists(modelSeettingFilePath))
+            {
+                MessageBox.Show("Model firmware setting not exist");
+                return;
+            }
+
+            //check format
+            var settingString = File.ReadAllText(modelSeettingFilePath);
+            SettingConfig setting;
+            try
+            {
+                setting = JsonConvert.DeserializeObject<SettingConfig>(settingString);
+            }
+            catch
+            {
+                MessageBox.Show("Setting file ERROR");
+                return;
+            }
+
+            if (CheckSettingConfig(System.IO.Path.GetDirectoryName(modelSeettingFilePath), ref setting))
+            {
+                ViewModel.SystemID = systemID;
+                ViewModel.ModelName = systemID.ModelName.ToString();
+                ViewModel.SerialNumber = systemID.SerialNumber;
+
+                ViewModel.SettingModelName = setting.ModelName;
+                ViewModel.SettingFileName = Path.GetFileName(modelSeettingFilePath);
+                ViewModel.FourGenModuleVersion = setting.FourGenModuleVersion;
+                ViewModel.IsSimInsert = setting.IsSimInsert;
+                ViewModel.ICCID = setting.ICCID;
+                ViewModel.IMSI = setting.IMSI;
+                ViewModel.FirmwareUpdateModels = setting.FirmwareUpdateList
+                    .Where(x => !string.IsNullOrEmpty(x.Module) && !string.IsNullOrEmpty(x.Version) && !string.IsNullOrEmpty(x.FirmwareFileName)
+                    ).ToList();
+
+                UpdateProcedure();
+                ViewModel.IsInputCheckpassed = CheckInputData();
             }
         }
 
@@ -391,15 +558,15 @@ namespace AwInitilizer
             List<ProcedureBase> procedures = new List<ProcedureBase>();
 
             //init intilize procedure list
+            procedures.Add(new ButtonStatusCheckPorcedure());
             procedures.Add(new BasicInfoUpdateProcedure());
             procedures.Add(new FourGenModuleCheckProcedure());
             for (int firemwareIndex = 0; firemwareIndex < ViewModel.FirmwareUpdateModels.Count ; firemwareIndex++)
             {
                 procedures.Add(new FirmwareUpdateProcedure(ViewModel.FirmwareUpdateModels[firemwareIndex]));
             }
-
-            procedures.Add(new ButtonStatusCheckPorcedure());
             procedures.Add(new RestarttoIdelProcedure());
+            procedures.Add(new VersionLogProcedure());
 
             ViewModel.UpdateProcedure.Clear();
 
@@ -519,20 +686,20 @@ namespace AwInitilizer
                                             isCheckPassed = false;
                                         }
 
-                                        byte[] imgType = new byte[4];
-                                        if (fs.Read(imgType, 0, 4) == 4)
-                                        {
-                                            if (!imgType.SequenceEqual(new byte[] { 0x10, 0x00, 0x00, 0x04, }))
-                                            {
-                                                MessageBox.Show($"{model.Module} Firemware type ERROR");
-                                                isCheckPassed = false;
-                                            }
-                                        }
-                                        else
-                                        {
-                                            MessageBox.Show($"{model.Module} Firemware header ERROR");
-                                            isCheckPassed = false;
-                                        }
+                                        //byte[] imgType = new byte[4];
+                                        //if (fs.Read(imgType, 0, 4) == 4)
+                                        //{
+                                        //    if (!imgType.SequenceEqual(new byte[] { 0x10, 0x00, 0x00, 0x04, }))
+                                        //    {
+                                        //        MessageBox.Show($"{model.Module} Firemware type ERROR");
+                                        //        isCheckPassed = false;
+                                        //    }
+                                        //}
+                                        //else
+                                        //{
+                                        //    MessageBox.Show($"{model.Module} Firemware header ERROR");
+                                        //    isCheckPassed = false;
+                                        //}
                                     }
                                 }
                                 catch
@@ -550,5 +717,73 @@ namespace AwInitilizer
 
             return isCheckPassed;
         }
+
+        private void ResetLogoutTimer()
+        {
+            if(LogoutTimer!=null)
+            {
+                logoutCheckCnt = 0;
+                LogoutTimer.Stop();
+                LogoutTimer.Start();
+            }
+        }
+
+        private void DisplayLogin()
+        {
+            LogoutTimer?.Stop();
+            var signinDialog = new SigninDialog();
+            signinDialog.Owner = this;
+            signinDialog.ShowDialog();
+            if (signinDialog.DialogResult != true)
+            {
+                App.Current.Shutdown();
+            }
+            else
+            {
+                ViewModel.UserID = signinDialog.UserId;
+                ViewModel.WorkOrder = signinDialog.WorkOrder;
+                LogoutTimer?.Start();
+            }
+        }
+
+        private int logoutCheckCnt = 0;
+        private void LogoutTimer_Tick(object sender, EventArgs e)
+        {
+            LogoutTimer.Stop();
+
+            if (ViewModel.IsUdatIng)
+            {
+                logoutCheckCnt = 0;
+                return;
+            }
+            if (++logoutCheckCnt > 10)
+            {
+                logoutCheckCnt = 0;
+                DisplayLogin();
+            }
+            else
+            {
+                LogoutTimer.Start();
+            }
+        }
+
+        private void Logout_Click(object sender, RoutedEventArgs e)
+        {
+            DisplayLogin();
+        }
+
+        private void WorkOrder_TextChanged(object sender, TextChangedEventArgs e)
+        {
+            ViewModel.IsInputCheckpassed = false;
+        }
+
+        private void WorkOrder_KeyDown(object sender, KeyEventArgs e)
+        {
+            //ViewModel.IsInputCheckpassed = true;
+            if (e.Key == Key.Enter && ViewModel.SystemID != null)
+            {
+                SystemIDScanReseived(ViewModel.SystemID);
+            }
+        }
     }
 }

+ 1 - 1
AwInitilizer/Model/SystemID.cs

@@ -217,7 +217,7 @@ namespace AwInitilizer.Model
                 return false;
             }
 
-            if (modelNameString.Length != 14)
+            if (modelNameString.Length != 14 && modelNameString.Length != 12)
                 return false;
             return TryParse(modelNameString, out modelName);
         }

+ 15 - 0
AwInitilizer/Procedure/BasicInfoUpdateProcedure.cs

@@ -19,6 +19,7 @@ namespace AwInitilizer.Procedure
         {
             if (!await base.CheckAndCreateSocket())
             {
+                LogPair.Add("BaseUpdateSocketConnect","0");
                 InfoLog += "EVSE connect failed\n";
                 return false;
             }
@@ -28,22 +29,26 @@ namespace AwInitilizer.Procedure
             {
                 InfoLog += "Model Name update failed\n";
                 Logger.Print("Model Name update Failed", isError: true);
+                LogPair.Add("ModelNameWrite", "0");
                 return false;
             }
             else
             {
                 Logger.Print("Model Name write Success");
+                LogPair.Add("ModelNameWrite", "1");
             }
 
             if (!await serialPortocol.SetSerialNumber(UpdateData.SerialNumber))
             {
                 InfoLog += "Serial Number update failed\n";
                 Logger.Print("Serial Number update Failed", isError: true);
+                LogPair.Add("SerialNumberWrite", "0");
                 return false;
             }
             else
             {
                 Logger.Print("Serial Number write Success");
+                LogPair.Add("SerialNumberWrite", "1");
             }
 
             var setDateTime = DateTime.Now.ToUniversalTime();
@@ -52,22 +57,26 @@ namespace AwInitilizer.Procedure
             {
                 InfoLog += "RTC update failed\n";
                 Logger.Print("RTC update Failed", isError: true);
+                LogPair.Add("RtcUpdate", "0");
                 return false;
             }
             else
             {
                 Logger.Print("RTC update write Success");
+                LogPair.Add("RtcUpdate", "1");
             }
 
             if (!await serialPortocol.SettingChangeConfirm())
             {
                 InfoLog += "Setting save request failed\n";
                 Logger.Print("Setting save Failed", isError: true);
+                LogPair.Add("SettingSave", "0");
                 return false;
             }
             else
             {
                 Logger.Print("Setting save Success");
+                LogPair.Add("SettingSave", "1");
             }
 
             Logger.Print("Waiting EVSE reboot...");
@@ -78,10 +87,12 @@ namespace AwInitilizer.Procedure
             {
                 InfoLog += "EVSE not found after reboot\n";
                 Logger.Print("EVSE reboot timeout", isError: true);
+                LogPair.Add("BaseUpdateSocketReConnect", "0");
                 return false;
             }
 
             var receivedModelName = await serialPortocol.GetModelName();
+            LogPair.Add("ModelNameRead", receivedModelName);
             if (string.IsNullOrEmpty(receivedModelName))
             {
                 InfoLog += "Model name get failed after reboot\n";
@@ -101,10 +112,13 @@ namespace AwInitilizer.Procedure
             }
 
             var receivedSeerialNumber = await serialPortocol.GetSerialNumber();
+            LogPair.Add("SerialNumberRead", receivedSeerialNumber);
             if (string.IsNullOrEmpty(receivedSeerialNumber))
             {
                 InfoLog += "Serial number get failed after reboot\n";
+                InfoLog += serialPortocol.LatestNullMessage +"\n";
                 Logger.Print("Stored Serial read Failed", isError: true);
+                Logger.Print(serialPortocol.LatestNullMessage);
                 return false;
             }
             else
@@ -120,6 +134,7 @@ namespace AwInitilizer.Procedure
             }
 
             var receivedDateTime = await serialPortocol.GetUTCTime();
+            LogPair.Add("RtcRead", receivedDateTime?.ToString("yyyyMMddHHmmss"));
             if (string.IsNullOrEmpty(receivedModelName))
             {
                 InfoLog += "UTC Time receive failed after reboot\n";

+ 168 - 43
AwInitilizer/Procedure/ButtonStatusCheckPorcedure.cs

@@ -9,6 +9,7 @@ using System.Linq;
 using System.Net;
 using System.Security.AccessControl;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Windows;
 
@@ -16,17 +17,39 @@ namespace AwInitilizer.Procedure
 {
     public class ButtonStatusCheckPorcedure : ProcedureBase
     {
+        private HintDialog hintDialog = new HintDialog();
         public ButtonStatusCheckPorcedure() : base()
         {
-            Name = "Button press test";
+            Name = "Button Press Test";
             Content = "Interaction to test button status";
         }
 
         internal override async Task<bool> Run()
         {
             Logger.Print("Button Unpress Status check Start");
+            //stage 0 - wait system ready
+            //wait restart
+            Logger.Print("Waiting response..");
+
+            bool response = false;
+            int pollinfCnt = 0;
+            for (pollinfCnt = 0; pollinfCnt < 14; pollinfCnt++)
+            {
+                await Task.Delay(TimeSpan.FromSeconds(30));
+                response = await CheckAllIdel();
+                if (response)
+                    break;
+            }
+
+            //timeout
+            if (pollinfCnt >= 14)
+            {
+                Logger.Print("Wait EVSE timeout", isError: true);
+                return false;
+            }
+
             //stage 1 - unpress all
-            MessageBox.Show("Please make sure All button is Unpressed\nPress Ok while complete", "Starting Button test");
+            ShowDialog("Please make sure All button is Unpressed\nPress Ok while complete", "Starting Button test", "OK","", cancelAble: true);
             ButtonStatus status = await GetButtonStatus();
 
             if (status == null)
@@ -38,22 +61,23 @@ namespace AwInitilizer.Procedure
 
             InfoLog += "Unpress check result\n";
             InfoLog += $"Button1:{status.Button1},Button2:{status.Button2},EmgerncyButton:{status.EmergencyButton}\n";
+            LogPair.Add("UnpressButtonTest", string.Format("{0}{1}{2}", status.Button1, status.Button2, status.EmergencyButton));
 
             bool isAllMatched = true;
             if (status != null)
             {
                 isAllMatched = true;
-                if (status.Button1 != 1)
+                if (status.Button1 != 0)
                 {
                     Logger.Print("Button1 status ERROR, unpress is ecpected", isError: true);
                     isAllMatched = false;
                 }
-                if (status.Button2 != 1)
+                if (status.Button2 != 0)
                 {
                     Logger.Print("Button3 status ERROR, unpress is ecpected", isError: true);
                     isAllMatched = false;
                 }
-                if (status.EmergencyButton != 1)
+                if (status.EmergencyButton != 0)
                 {
                     Logger.Print("EmergencyButton status ERROR, unpress is ecpected", isError: true);
                     isAllMatched = false;
@@ -76,13 +100,37 @@ namespace AwInitilizer.Procedure
 
             //stage 2 - check press sequence
             Logger.Print("Button Unpress Status check Start");
-            MessageBox.Show("Press Button1,Button2,EmergencyButton in order\neach press continuous 2 secondes\nPress Ok to start", "Starting Button test");
+            //MessageBox.Show("Press Button1,Button2,EmergencyButton in order\neach press continuous 2 secondes\nPress Ok to start", "Starting Button test");
 
             bool isError = false;
             //Button1,Button2,EmergencyButton in order 0,1,2
             ButtonStatus pressStatus = null;
             for (int testType = 0; testType < 3; testType++)
             {
+                string btn,imgUrl;
+                switch (testType)
+                {
+                    case 0:
+                        btn = "Green Button";
+                        imgUrl = "pack://application:,,,/AwInitilizer;component/Image/Green.png";
+                        break;
+                    case 1:
+                        btn = "Blue Button";
+                        imgUrl = "pack://application:,,,/AwInitilizer;component/Image/Blue.png";
+                        break;
+                    case 2:
+                        btn = "EmergencyButton";
+                        imgUrl = "pack://application:,,,/AwInitilizer;component/Image/Emergency.png";
+                        break;
+                    default:
+                        btn = "";
+                        imgUrl = null;
+                        break;
+                };
+
+                //MessageBox.Show($"press {btn}");
+                ShowDialog($"PRESS {btn.ToUpper()}", "Button press test", "", imgUrl, cancelAble: false);
+
                 //retry 20 times, 20*0.5 = 10 seconds 
                 int testCnt;
                 for (testCnt = 0; testCnt < 20; testCnt++)
@@ -101,62 +149,55 @@ namespace AwInitilizer.Procedure
                         pressStatus.Button2 != 0 ||
                         pressStatus.EmergencyButton != 0)
                     {
+                        bool success = false;
                         if (pressStatus.Button1 == (testType == 0 ? 1 : 0) &&
                             pressStatus.Button2 == (testType == 1 ? 1 : 0) &&
                             pressStatus.EmergencyButton == (testType == 2 ? 1 : 0))
                         {
                             //Status correct
+                            success = true;
                         }
                         else
                         {
                             //Status error
                             isError = true;
+                            success = false;
                             break;
                         }
 
-                        //wait release
-                        for (testCnt = 0; testCnt < 20; testCnt++)
+                        if (success)
                         {
-                            await Task.Delay(500);
-                            status = await GetButtonStatus();
-                            if (status == null)
+                            //wait release
+                            for (var releaseCnt = 0; releaseCnt < 20; releaseCnt++)
                             {
-                                InfoLog += "Get Butoon state failed\n";
-                                Logger.Print("Get Butoon state failed");
-                                return false;
-                            }
-                            if (status.Button1 == 0 &&
-                                status.Button2 == 0 &&
-                                status.EmergencyButton == 0)
-                            {
-                                break;
+                                await Task.Delay(500);
+                                status = await GetButtonStatus();
+                                if (status == null)
+                                {
+                                    InfoLog += "Get Butoon state failed\n";
+                                    Logger.Print("Get Butoon state failed");
+                                    return false;
+                                }
+                                if (status.Button1 == 0 &&
+                                    status.Button2 == 0 &&
+                                    status.EmergencyButton == 0)
+                                {
+                                    break;
+                                }
                             }
+                            break;
                         }
                     }
                 }
 
-                string btn;
-                switch (testType)
-                {
-                    case 0:
-                        btn = "Button1";
-                        break;
-                    case 1:
-                        btn = "Button2";
-                        break;
-                    case 2:
-                        btn = "EmergencyButton";
-                        break;
-                    default:
-                        btn = "";
-                        break;
-                };
-
+                DismisDialog();
                 InfoLog += $"Press check stage {btn} result\n";
                 InfoLog += $"Button1:{pressStatus.Button1},Button2:{pressStatus.Button2},EmgerncyButton:{pressStatus.EmergencyButton}\n";
+                LogPair.Add($"{btn}PressTest", string.Format("{0}{1}{2}", status.Button1, status.Button2, status.EmergencyButton));
 
                 if (testCnt >= 20)
                 {
+                    isError = true;
                     Logger.Print($"{btn} press TIMEOUT", isError: true);
                     break;
                 }
@@ -177,7 +218,7 @@ namespace AwInitilizer.Procedure
             return true;
         }
 
-        internal async Task<ButtonStatus> GetButtonStatus()
+        internal async Task<ButtonStatus> GetButtonStatus(bool isConnectTest = false)
         {
             try
             {
@@ -198,17 +239,72 @@ namespace AwInitilizer.Procedure
             }
             catch (Exception e)
             {
-                InfoLog += "Get Button Status Failed\n";
-                InfoLog += e.Message;
-                InfoLog += "\n";
+                if (!isConnectTest)
+                {
+                    InfoLog += "Get Button Status Failed\n";
+                    InfoLog += e.Message;
+                    InfoLog += "\n";
 
-                Logger.Print("Get Button Status Failed", isError: true);
-                Logger.Print(e.Message + "", isError: true);
+                    Logger.Print("Get Button Status Failed", isError: true);
+                    Logger.Print(e.Message + "", isError: true);
+                }
             }
 
             return null;
         }
 
+        private async Task<bool> CheckAllIdel()
+        {
+            try
+            {
+                using (Assist.WebClientTimeout webClient = new Assist.WebClientTimeout())
+                {
+                    NameValueCollection parameters = new NameValueCollection();
+                    parameters.Add("opt", "2");
+                    webClient.QueryString = parameters;
+
+                    using (Stream stream = await webClient.OpenReadTaskAsync($"https://{ServerIpAddress}/get_query_action.php"))
+                    // 使用 StreamReader 讀取 stream 內的字元
+                    using (StreamReader reader = new StreamReader(stream))
+                    {
+                        // 將 StreamReader 所讀到的字元轉為 string
+                        string request = reader.ReadToEnd();
+                        InfoLog += $"get status respons:\n{request}\n";
+                        LogPair.Add($"EvseStatus", request);
+                        Regex rx = new Regex("(SystemStatus)\\\": (\\d)");
+                        var matches = rx.Matches(request);
+                        bool isAllPassed = true;
+                        for (int matchIndex = 0; matchIndex < matches.Count; matchIndex++)
+                        {
+                            var match = matches[matchIndex];
+                            if (match.Groups.Count != 3)
+                            {
+                                InfoLog += $"Connector {matchIndex} status string mismatched\n";
+                                Logger.Print($"Connector {matchIndex} status string mismatched", isError: true);
+                                isAllPassed = false;
+                            }
+                            else
+                            {
+                                if (match.Groups[2].Value != "1")
+                                {
+                                    InfoLog += $"Connector {matchIndex} status not Idel\n";
+                                    Logger.Print($"Connector {matchIndex} status not Idel", isError: true);
+                                    isAllPassed = false;
+                                }
+                            }
+                        }
+
+                        return isAllPassed;
+                    }
+                }
+                return true;
+            }
+            catch (Exception e)
+            {
+                return false;
+            }
+        }
+
         private string GetBtnStatusString(int status)
         {
             if (status == 1)
@@ -218,5 +314,34 @@ namespace AwInitilizer.Procedure
             else
                 return status.ToString();
         }
+
+        private void ShowDialog(string msg,string title, string btnText,string imgUrl, bool cancelAble)
+        {
+            hintDialog = new HintDialog();
+
+            hintDialog.Owner = Application.Current.MainWindow;
+
+            hintDialog.Message = msg;
+            hintDialog.Title = title;
+            hintDialog.IsCancelAble = cancelAble;
+            hintDialog.BtnText = btnText;
+            hintDialog.ImgPath = imgUrl;
+
+            if (cancelAble)
+            {
+                hintDialog.ShowDialog();
+            }
+            else
+            {
+                hintDialog.Show();
+            }
+        }
+
+        private void DismisDialog()
+        {
+            if (hintDialog == null)
+                return;
+            hintDialog.Close();
+        }
     }
 }

+ 86 - 10
AwInitilizer/Procedure/FirmwareUpdateProcedure.cs

@@ -1,4 +1,5 @@
-using AwInitilizer.Model;
+using AwInitilizer.Assist;
+using AwInitilizer.Model;
 using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
@@ -9,6 +10,7 @@ using System.IO;
 using System.Linq;
 using System.Net;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Web;
 using System.Windows.Ink;
@@ -20,7 +22,7 @@ namespace AwInitilizer.Procedure
         internal string Version;
         internal string fileName;
         internal string module;
-        internal int SleepMinuts = 6;
+        //internal int SleepMinuts = 6;
 
         private FirmwareUpdateModel _model;
 
@@ -39,6 +41,7 @@ namespace AwInitilizer.Procedure
         internal override async Task<bool> Run()
         {
             var oldVersion = await GetSpecificVersion();
+            LogPair.Add($"{module}OldVersion", oldVersion);
             if (string.IsNullOrEmpty(oldVersion))
             {
                 InfoLog += $"Get {Name} version failed\n";
@@ -52,11 +55,28 @@ namespace AwInitilizer.Procedure
             }
             Logger.Print("Firmware Uploading...");
             var uploadResult = await Uploadfiremware(fileName);
+            LogPair.Add($"{module}Upload", uploadResult.ToString());
             if (uploadResult)
             {
                 //wait restart
                 Logger.Print("Waiting restart..");
-                await Task.Delay(TimeSpan.FromMinutes(SleepMinuts));
+
+                bool response = false;
+                int pollinfCnt = 0;
+                for (pollinfCnt = 0; pollinfCnt < 14; pollinfCnt++)
+                {
+                    await Task.Delay(TimeSpan.FromSeconds(30));
+                    response = await CheckAllIdel();
+                    if (response)
+                        break;
+                }
+
+                //timeout
+                if(pollinfCnt>=14)
+                {
+                    Logger.Print("Wait restart timeout",isError:true);
+                    return false;
+                }
             }
             else
             {
@@ -65,6 +85,7 @@ namespace AwInitilizer.Procedure
                 return false;
             }
             var updatedVersion = await GetSpecificVersion();
+            LogPair.Add($"{module}NewVersion", updatedVersion);
             if (string.IsNullOrEmpty(updatedVersion))
             {
                 InfoLog += $"Get updated {Name} version failed\n";
@@ -96,11 +117,11 @@ namespace AwInitilizer.Procedure
             return versions[module];
         }
 
-        internal async Task<Dictionary<string,string>> GetVersion()
+        internal async Task<Dictionary<string,string>> GetVersion(bool isConnectTest = false)
         {
             try
             {
-                using (WebClient webClient = new WebClient())
+                using (WebClientTimeout webClient = new WebClientTimeout())
                 {
                     NameValueCollection parameters = new NameValueCollection();
                     parameters.Add("opt", "1");
@@ -145,17 +166,72 @@ namespace AwInitilizer.Procedure
             }
             catch(Exception e)
             {
-                Logger.Print("Get Version Failed", isError: true);
-                Logger.Print(e.Message+"", isError: true);
+                if (!isConnectTest)
+                {
+                    Logger.Print("Get Version Failed", isError: true);
+                    Logger.Print(e.Message + "", isError: true);
 
-                InfoLog += "Get Version Failed\n";
-                InfoLog += e.Message;
-                InfoLog += "\n";
+                    InfoLog += "Get Version Failed\n";
+                    InfoLog += e.Message;
+                    InfoLog += "\n";
+                }
 
                 return null;
             }
         }
 
+        private async Task<bool> CheckAllIdel()
+        {
+            try
+            {
+                using (WebClient webClient = new WebClient())
+                {
+                    NameValueCollection parameters = new NameValueCollection();
+                    parameters.Add("opt", "2");
+                    webClient.QueryString = parameters;
+
+                    using (Stream stream = await webClient.OpenReadTaskAsync($"https://{ServerIpAddress}/get_query_action.php"))
+                    // 使用 StreamReader 讀取 stream 內的字元
+                    using (StreamReader reader = new StreamReader(stream))
+                    {
+                        // 將 StreamReader 所讀到的字元轉為 string
+                        string request = reader.ReadToEnd();
+                        InfoLog += $"get status respons:\n{request}\n";
+                        LogPair.Add($"EvseStatus", request);
+                        Regex rx = new Regex("(SystemStatus)\\\": (\\d)");
+                        var matches = rx.Matches(request);
+                        bool isAllPassed = true;
+                        for (int matchIndex = 0; matchIndex < matches.Count; matchIndex++)
+                        {
+                            var match = matches[matchIndex];
+                            if (match.Groups.Count != 3)
+                            {
+                                InfoLog += $"Connector {matchIndex} status string mismatched\n";
+                                Logger.Print($"Connector {matchIndex} status string mismatched", isError: true);
+                                isAllPassed = false;
+                            }
+                            else
+                            {
+                                if (match.Groups[2].Value != "1")
+                                {
+                                    InfoLog += $"Connector {matchIndex} status not Idel\n";
+                                    Logger.Print($"Connector {matchIndex} status not Idel", isError: true);
+                                    isAllPassed = false;
+                                }
+                            }
+                        }
+
+                        return isAllPassed;
+                    }
+                }
+                return true;
+            }
+            catch (Exception e)
+            {
+                return false;
+            }
+        }
+
         internal async Task<bool> Uploadfiremware(string fileName)
         {
             try

+ 7 - 0
AwInitilizer/Procedure/FourGenModuleCheckProcedure.cs

@@ -20,6 +20,7 @@ namespace AwInitilizer.Procedure
             if (!await base.CheckAndCreateSocket())
             {
                 InfoLog += "EVSE connect failed\n";
+                LogPair.Add("FourgenSocketConnect", "0");
                 return false;
             }
 
@@ -31,6 +32,7 @@ namespace AwInitilizer.Procedure
             }
 
             var fourthGenModuleVersion = await serialPortocol.GetFourGenModuleVersion();
+            LogPair.Add("FourgenModuleVersion", fourthGenModuleVersion);
             if (string.IsNullOrEmpty(fourthGenModuleVersion))
             {
                 InfoLog += "4G module version read error\n";
@@ -53,10 +55,12 @@ namespace AwInitilizer.Procedure
             {
                 InfoLog += "Get sim status failed\n";
                 Logger.Print("Get sim status failed", isError: true);
+                LogPair.Add("SimStatus", "ReadFail");
                 return false;
             }
             else
             {
+                LogPair.Add("SimStatus", simstatus.IsInstalled? "1":"0");
                 if (simstatus.IsInstalled != UpdateData.IsSimInsert)
                 {
                     Logger.Print("sim install status not matched", isError: true);
@@ -69,6 +73,9 @@ namespace AwInitilizer.Procedure
                         var ICCIDstring = Encoding.ASCII.GetString(simstatus.ICCID);
                         var IMSIstring = Encoding.ASCII.GetString(simstatus.IMSI);
 
+                        LogPair.Add("SimICCID", ICCIDstring);
+                        LogPair.Add("SimIMSI", IMSIstring);
+
                         InfoLog += $"Get sim info, inserted:{simstatus.IsInstalled},ICCID:{ICCIDstring},IMSI:{IMSIstring}\n";
 
                         if (ICCIDstring != UpdateData.ICCID)

+ 2 - 0
AwInitilizer/Procedure/ProcedureBase.cs

@@ -27,6 +27,8 @@ namespace AwInitilizer.Procedure
         public static UpdateData UpdateData { get; set; }
         public static IIogger Logger { get; set; }
 
+        public Dictionary<string, string> LogPair { get; private set; } = new Dictionary<string, string>();
+
         internal SerialPortocol serialPortocol { get; private set; }
 
         internal static string ServerIpAddress = "192.168.1.10";

+ 2 - 1
AwInitilizer/Procedure/RestarttoIdelProcedure.cs

@@ -16,7 +16,7 @@ namespace AwInitilizer.Procedure
     {
         public RestarttoIdelProcedure() : base()
         {
-            Name = "Restart to Idel";
+            Name = "Restart To Idel";
             Content = "Restart EVSSE and check status back to Idel";
         }
 
@@ -107,6 +107,7 @@ namespace AwInitilizer.Procedure
                         // 將 StreamReader 所讀到的字元轉為 string
                         string request = reader.ReadToEnd();
                         InfoLog += $"get status respons:\n{request}\n";
+                        LogPair.Add($"EvseStatus", request);
                         Regex rx = new Regex("(SystemStatus)\\\": (\\d)");
                         var matches = rx.Matches(request);
                         bool isAllPassed = true;

+ 98 - 0
AwInitilizer/Procedure/VersionLogProcedure.cs

@@ -0,0 +1,98 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.Procedure
+{
+    public class VersionLogProcedure : ProcedureBase
+    {
+        public VersionLogProcedure() : base()
+        {
+            Name = "Version Logger";
+            Content = "Report version back to MES";
+        }
+
+        internal override async Task<bool> Run()
+        {
+            var versionPair = await GetVersion();
+            if (versionPair != null)
+            {
+                foreach (var infoPair in versionPair)
+                {
+                    LogPair.Add(infoPair.Key, infoPair.Value);
+                }
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        internal async Task<Dictionary<string, string>> GetVersion()
+        {
+            try
+            {
+                using (WebClient webClient = new WebClient())
+                {
+                    NameValueCollection parameters = new NameValueCollection();
+                    parameters.Add("opt", "1");
+                    webClient.QueryString = parameters;
+
+                    using (Stream stream = await webClient.OpenReadTaskAsync($"https://{ServerIpAddress}/get_query_action.php"))
+                    // 使用 StreamReader 讀取 stream 內的字元
+                    using (StreamReader reader = new StreamReader(stream))
+                    {
+                        // 將 StreamReader 所讀到的字元轉為 string
+                        string request = reader.ReadToEnd();
+                        InfoLog += $"get version response:{request}\n";
+                        var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(request);
+
+                        var toReturn = new Dictionary<string, string>();
+                        foreach (var pair in values)
+                        {
+                            if (pair.Value is string v)
+                            {
+                                toReturn.Add(pair.Key, v);
+                            }
+                            else if (pair.Value is Newtonsoft.Json.Linq.JArray a)
+                            {
+                                try
+                                {
+                                    var versionList = JsonConvert.DeserializeObject<List<string>>(a.ToString());
+                                    for (int index = 0; index < versionList.Count; index++)
+                                    {
+                                        toReturn.Add(string.Format("{0}{1}", pair.Key, index), versionList[index]);
+                                    }
+                                }
+                                catch
+                                {
+
+                                }
+                            }
+                        }
+
+                        return toReturn;
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Logger.Print("Get Version Failed", isError: true);
+                Logger.Print(e.Message + "", isError: true);
+
+                InfoLog += "Get Version Failed\n";
+                InfoLog += e.Message;
+                InfoLog += "\n";
+
+                return null;
+            }
+        }
+    }
+}

+ 12 - 0
AwInitilizer/Properties/Settings.Designer.cs

@@ -22,5 +22,17 @@ namespace AwInitilizer.Properties {
                 return defaultInstance;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("./")]
+        public string FirmwareRoot {
+            get {
+                return ((string)(this["FirmwareRoot"]));
+            }
+            set {
+                this["FirmwareRoot"] = value;
+            }
+        }
     }
 }

+ 7 - 5
AwInitilizer/Properties/Settings.settings

@@ -1,7 +1,9 @@
 <?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
-  <Profiles>
-    <Profile Name="(Default)" />
-  </Profiles>
-  <Settings />
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AwInitilizer.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="FirmwareRoot" Type="System.String" Scope="User">
+      <Value Profile="(Default)">./</Value>
+    </Setting>
+  </Settings>
 </SettingsFile>

+ 48 - 0
AwInitilizer/SigninDialog.xaml

@@ -0,0 +1,48 @@
+<Window x:Class="AwInitilizer.SigninDialog"
+        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:local="clr-namespace:AwInitilizer"
+        mc:Ignorable="d"
+        Title="Signin" Height="300" Width="400"
+        WindowStyle="None"
+        ResizeMode="NoResize"
+        WindowStartupLocation="CenterOwner"
+        Topmost="True">
+    <Border BorderBrush="Gray" BorderThickness="2">
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="30"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+
+            <Grid Grid.Row="0" Background="Gray">
+                <Label x:Name="uxTitle" Content="Message" Foreground="White"/>
+            </Grid>
+
+            <Grid Grid.Row="1">
+                <StackPanel Orientation="Vertical" VerticalAlignment="Center" >
+                    <StackPanel Orientation="Vertical" VerticalAlignment="Center" >
+                        <Label Foreground="Black" Content="Enter ID" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+                        <Rectangle Height="10"/>
+                        <TextBox x:Name="uxIdBox" Margin="10" Height="20" TextAlignment="Center"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical" VerticalAlignment="Center" >
+                        <Label Foreground="Black" Content="Enter WorkOrder" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+                        <Rectangle Height="10"/>
+                        <TextBox x:Name="uxWorkOrderBox" Margin="10" Height="20" TextAlignment="Center"/>
+                    </StackPanel>
+
+                    <Label x:Name="uxErrmsg" Content="error" Foreground="Red" Visibility="Hidden" HorizontalAlignment="Center"/>
+                    <Rectangle Height="10"/>
+                    <Grid x:Name="uxCancelContainer" Grid.Row="2" Height="30">
+                        <Button  HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="100" Click="OK_Pressed">
+                            <Label x:Name="uxBtnText" Content="OK"/>
+                        </Button>
+                    </Grid>
+                </StackPanel>
+            </Grid>
+        </Grid>
+    </Border>
+</Window>

+ 85 - 0
AwInitilizer/SigninDialog.xaml.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace AwInitilizer
+{
+    /// <summary>
+    /// Interaction logic for SigninDialog.xaml
+    /// </summary>
+    public partial class SigninDialog : Window
+    {
+        public string UserId { get; private set; } = "";
+        public string WorkOrder { get; private set; } = "";
+
+        public SigninDialog()
+        {
+            InitializeComponent();
+        }
+
+        private void OK_Pressed(object sender, RoutedEventArgs e)
+        {
+            if(string.IsNullOrEmpty(uxIdBox.Text))
+            {
+                uxErrmsg.Visibility = Visibility.Visible;
+                return;
+            }
+
+            string id = uxIdBox.Text;
+            string idBackup = id;
+            if (DLL.SajetConnect.SajetTransSignIn(ref id))
+            {
+                if (string.IsNullOrEmpty(id) || id.StartsWith("NG"))
+                {
+                    uxErrmsg.Content = "ID Error";
+                    uxErrmsg.Visibility = Visibility.Visible;
+                    return;
+                }
+
+                UserId = idBackup;
+            }
+            else
+            {
+                uxErrmsg.Content = "ID Error";
+                uxErrmsg.Visibility = Visibility.Visible;
+                return;
+            }
+
+            if (!string.IsNullOrEmpty(uxWorkOrderBox.Text))
+            {
+                string workOrder = uxWorkOrderBox.Text;
+                if (DLL.SajetConnect.SajetTransWoCheck(ref workOrder))
+                {
+                    if (string.IsNullOrEmpty(workOrder) || workOrder.StartsWith("NG"))
+                    {
+                        uxErrmsg.Content = "WorkOrder Error";
+                        uxErrmsg.Visibility = Visibility.Visible;
+                        return;
+                    }
+
+                    WorkOrder = workOrder;
+                }
+                else
+                {
+                    uxErrmsg.Content = "WorkOrder Error";
+                    uxErrmsg.Visibility = Visibility.Visible;
+                    return;
+                }
+            }
+
+            DialogResult = true;
+            this.Close();
+            return;
+        }
+    }
+}