shayne_lo пре 4 месеци
родитељ
комит
46e8af23f7

+ 25 - 0
ConsoleApp1.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32819.101
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{32D6705F-003A-488D-8146-12DF5ED30428}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{32D6705F-003A-488D-8146-12DF5ED30428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{32D6705F-003A-488D-8146-12DF5ED30428}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{32D6705F-003A-488D-8146-12DF5ED30428}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{32D6705F-003A-488D-8146-12DF5ED30428}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {1F7D751B-807B-4E7E-9F79-256989E854F0}
+	EndGlobalSection
+EndGlobal

Разлика између датотеке није приказан због своје велике величине
+ 15 - 0
ConsoleApp1/CertificateTest/CertificateRequestTest.cs


+ 23 - 0
ConsoleApp1/ConsoleApp1.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net7.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <FrameworkReference Include="Microsoft.AspNetCore.App" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
+    <PackageReference Include="Dapper" Version="2.1.21" />
+    <PackageReference Include="FluentFTP" Version="48.0.3" />
+    <PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.2" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+    <PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
+  </ItemGroup>
+
+</Project>

+ 38 - 0
ConsoleApp1/DI/CricularDependency.cs

@@ -0,0 +1,38 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.DI;
+
+interface IClassA { }
+interface IClassB { }
+
+class ClassA : IClassA
+{
+    public ClassA(IClassB classB) { }
+}
+class ClassB : IClassB
+{
+    public ClassB(IClassA classB) { }
+}
+
+internal class CricularDependency
+{
+    public static void Test()
+    {
+        var builder = WebApplication.CreateBuilder();
+
+        builder.Services.AddSingleton<IClassA, ClassA>();
+        builder.Services.AddSingleton<IClassB, ClassB>();
+
+        var app = builder.Build();
+
+        app.MapGet("/", (IClassA classA) => "test");
+
+        app.Run();
+    }
+}

+ 33 - 0
ConsoleApp1/Else/EnumerableSequenceEqualTest.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.Else
+{
+    internal class EnumerableSequenceEqualTest
+    {
+        public static void Test()
+        {
+            var a = new Dictionary<string, string>() {
+                { "0", "1" },
+                { "2", "3" }
+            };
+            var b = new Dictionary<string, string>() {
+                { "2", "3" },
+                { "0", "1" }
+            };
+            var equl = CheckIsEqual(a, b);
+        }
+
+        private static bool CheckIsEqual(Dictionary<string, string> d1, Dictionary<string, string> d2)
+        {
+            return d1.Count == d2.Count && d1.All(
+                 (d1KV) => d2.TryGetValue(d1KV.Key, out var d2Value) && (
+                      d1KV.Value == d2Value ||
+                      d1KV.Value?.Equals(d2Value) == true)
+            );
+        }
+    }
+}

+ 76 - 0
ConsoleApp1/Else/EvHttpClientLogger.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.Else
+{
+    public static class EvHttpClientLoggerTest
+    {
+        public static async Task Test()
+        {
+            int file_cnt = 0;
+            while (true)
+            {
+                EvHttpClientLogger.Instance.StartNewLog(file_cnt.ToString());
+                for (int i = 0; i < 10; i++)
+                {
+                    EvHttpClientLogger.Instance.Log(i.ToString());
+                    await Task.Delay(1000);
+                }
+                file_cnt++;
+            }
+        }
+    }
+
+    public class EvHttpClientLogger
+    {
+        public static EvHttpClientLogger Instance => _Instance;
+
+        private static EvHttpClientLogger _Instance = new EvHttpClientLogger();
+
+        private EvHttpClientLogger()
+        {
+            if (!Directory.Exists(FolderName))
+            {
+                Directory.CreateDirectory(FolderName);
+            }
+        }
+        private const string FolderName = "ApiLog";
+        private const int MaxLogCnt = 10;
+        private string LogFileName = null;
+
+        internal void StartNewLog(string name)
+        {
+            TryRemoveOneLog();
+            LogFileName = name + DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".txt";
+        }
+
+        internal void Log(string mesasage)
+        {
+            if (string.IsNullOrEmpty(LogFileName))
+            {
+                return;
+            }
+            File.AppendAllText(Path.Combine(FolderName, LogFileName), mesasage + Environment.NewLine);
+        }
+
+        private void TryRemoveOneLog()
+        {
+            var files = Directory.GetFiles(FolderName).ToList();
+            if (files.Count < MaxLogCnt)
+            {
+                return;
+            }
+
+            List<FileInfo> fileInfos = new List<FileInfo>();
+            foreach (var file in files)
+            {
+                fileInfos.Add(new FileInfo(file));
+            }
+            var candidateFile = fileInfos.OrderBy(x => x.LastWriteTimeUtc).First();
+            candidateFile.Delete();
+        }
+    }
+}

+ 14 - 0
ConsoleApp1/EvAuthMsg.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1
+{
+    public class EvAuthMsg
+    {
+        public string result { get; set; }
+        public object message { get; set; }
+    }
+}

+ 19 - 0
ConsoleApp1/InterfaceTest.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1;
+
+public interface IT1
+{
+    public void F1(DateTime? dateTime = null);
+}
+internal class InterfaceTest : IT1
+{
+    public void F1(DateTime? dateTime = null)
+    {
+        
+    }
+}

+ 47 - 0
ConsoleApp1/Mile/BaoruhMile.cs

@@ -0,0 +1,47 @@
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.Mile;
+
+internal class BaoruhMile
+{
+    const string urlFormat = "https://e-bus.baoruh.com/carno/{0}";
+
+    public static async Task<decimal?> GetMile(string carNumber, ILogger? logger = null)
+    {
+        try
+        {
+            HttpClient client = new HttpClient();
+            string url = string.Format(urlFormat, carNumber);
+            var result = await client.GetAsync(url);
+            if (result.IsSuccessStatusCode)
+            {
+                //Stream contentStream = await result.Content.ReadAsStreamAsync();
+                //var body = await new StreamReader(contentStream).ReadToEndAsync();
+                var body = await result.Content.ReadAsStringAsync();
+
+                JObject jo = JObject.Parse(body);
+
+                string checkKey = jo.Value<string>("CarNumber");// jo["State"].Value<int>();
+                if (checkKey == carNumber &&
+                    jo.ContainsKey("DR_MILE"))
+                {
+                    decimal mileage = jo.Value<decimal>("DR_MILE");
+                    return mileage;
+                }
+
+                return 1;
+            }
+        }
+        catch (Exception e)
+        {
+
+        }
+        return -1;
+    }
+}

+ 78 - 0
ConsoleApp1/Mile/CapitalbusMile.cs

@@ -0,0 +1,78 @@
+using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http.Json;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+
+internal class CapitalbusMile
+{
+    const string urlFormat = "http://ecar.capitalbusgroup.com.tw:8081/GetLastKM/{0}/{1}";
+    const string key = "35505603";
+
+    public static async Task<decimal?> GetMile(string carNumber, ILogger? logger = null)
+    {
+        try
+        {
+            HttpClient client = new HttpClient();
+            string token = GetToken();
+            string url = string.Format(urlFormat, carNumber, token);
+            var result = await client.GetAsync(url);
+            if (result.IsSuccessStatusCode)
+            {
+                Stream contentStream = await result.Content.ReadAsStreamAsync();
+                var body = await new StreamReader(contentStream).ReadToEndAsync();
+                //result.Headers.Add("Content-Type");
+                //var body = await result.Content.ReadAsStringAsync();
+
+                JObject jo = JObject.Parse(body);
+
+                string resultString = jo.Value<string>("Result");// jo["State"].Value<int>();
+                if (resultString == "Success" &&
+                    jo.ContainsKey("DR_MILE"))
+                {
+                    decimal mileage = jo.Value<decimal>("DR_MILE");
+                    return mileage;
+                }
+
+                return 1;
+            }
+        }
+        catch(Exception e)
+        {
+
+        }
+        return -1;
+    }
+
+    private static string GetToken()
+    {
+        return GetToken(DateTime.UtcNow, key);
+    }
+
+    private static string GetToken(DateTime DateTimeNow, string key)
+    {
+        DateTime baseTime = DateTime.Parse("1970/01/01 00:00:00Z").ToUniversalTime();
+        TimeSpan time = DateTimeNow - baseTime;
+        return GetToken((decimal)time.TotalSeconds, key);
+    }
+
+    private static string GetToken(decimal seconds, string key)
+    {
+        var ts_str = (seconds + 3600).ToString("0.0000000");
+        var ts_byte = Encoding.UTF8.GetBytes(ts_str);
+
+        var hasher = new HMACSHA1(Encoding.UTF8.GetBytes(key));
+        var hashResult = hasher.ComputeHash(ts_byte);
+        var sha1_tshexstr = BitConverter.ToString(hashResult).Replace("-", "").ToLower();
+
+        var token = string.Format("{0}:{1}", ts_str, sha1_tshexstr);
+        var b64_token = Base64UrlTextEncoder.Encode(Encoding.UTF8.GetBytes(token));
+        return b64_token + '=';
+    }
+}

+ 169 - 0
ConsoleApp1/Mile/FuntoroMile.cs

@@ -0,0 +1,169 @@
+using ConsoleApp1.Mile;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http.Headers;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+
+namespace ConsoleApp1.Mile
+{
+    internal class FuntoroMile
+    {
+        public static void Test()
+        {
+            var license = "EAA-127";
+            var apiUrl = "http://cloud.funtoro.com/twchannel1/api/index.php/ebus";
+            var apiKey = "FUN2yOf05bUS";
+            new FuntoroMile().GetVehicleMileage(license, apiUrl, apiKey);
+        }
+
+        public double GetVehicleMileage(string VehicleLicense, string apiUrl, string apiKey)
+        {
+            double mileage = 0;
+            var dt = DateTime.Now;
+            var dto = new { Code = 106, VehicleLicense };
+
+            var sJ = JsonConvert.SerializeObject(dto);
+
+            var sign = GetSignature(apiKey, dt, sJ);
+
+            var signedDto = new { Data = sJ, Ts = GetUnixTimeSeconds(dt), Signature = sign };
+
+            var vvJ = JsonConvert.SerializeObject(signedDto);
+
+            try
+            {
+                var client = new HttpClient() { Timeout = TimeSpan.FromMilliseconds(60000) };
+                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+
+                var response = client.PostAsync(apiUrl, new StringContent(vvJ, Encoding.UTF8, "application/json")).Result;
+                string responseBody = response.Content.ReadAsStringAsync().Result;
+
+                Console.WriteLine(responseBody);
+
+                if (response.IsSuccessStatusCode)
+                {
+                    JObject jo = JObject.Parse(responseBody);
+
+                    int state = jo["State"].Value<int>();
+                    if (state == 1)
+                    {
+                        mileage = jo["Mileage"].Value<double>();
+
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(string.Format(" {0} 呼叫 里程數API 發生問題 {1}", VehicleLicense, e.ToString()));
+            }
+
+            return mileage;
+        }
+
+        private string GetSignature(string apikey, DateTime dt, string requestBody)
+        {
+            long ts = 0;
+            ts = GetUnixTimeSeconds(dt);
+
+            //取得簽章
+            var str = string.Format("{0}{1}{2}"
+                 , ts
+                , requestBody
+                 , apikey);
+            return BackendCrytography.MD5ToHex_UTF8(str);
+        }
+
+        private static long GetUnixTimeSeconds(DateTime dt)
+        {
+            DateTimeOffset _offset = new DateTimeOffset(dt);
+            return DateTimeToUnixTimestamp(_offset.DateTime);
+        }
+
+        private static long DateTimeToUnixTimestamp(DateTime dateTime)
+        {
+            var start = new DateTime(1970, 1, 1, 0, 0, 0, dateTime.Kind);
+            return Convert.ToInt64((dateTime - start).TotalSeconds);
+        }
+    }
+
+    public class BackendCrytography
+    {
+        /// <summary>
+        /// Returns a MD5 hash as a string
+        /// </summary>
+        /// <param name="TextToHash">String to be hashed.</param>
+        /// <returns>Hash as string.</returns>
+        public static String MD5ToHex_UTF8(String TextToHash)
+        {
+            if ((TextToHash == null) || (TextToHash.Length == 0))
+            {
+                return String.Empty;
+            }
+
+            MD5 md5 = new MD5CryptoServiceProvider();
+            byte[] textToHash = Encoding.UTF8.GetBytes(TextToHash);
+            byte[] result = md5.ComputeHash(textToHash);
+            return BitConverter.ToString(result).Replace("-", "").ToLower();
+        }
+
+        /// <summary>
+        /// Returns a MD5 hash as a string
+        /// </summary>
+        /// <param name="TextToHash">String to be hashed.</param>
+        /// <returns>Hash as string.</returns>
+        public static String GetMD5Hash(String TextToHash)
+        {
+            if ((TextToHash == null) || (TextToHash.Length == 0))
+            {
+                return String.Empty;
+            }
+
+            MD5 md5 = new MD5CryptoServiceProvider();
+            //MD5 md5 = MD5.Create();
+            //byte[] textToHash = Encoding.Default.GetBytes(TextToHash);
+            byte[] textToHash = Encoding.UTF8.GetBytes(TextToHash);
+            byte[] result = md5.ComputeHash(textToHash);
+            var b64 = Convert.ToBase64String(result);
+
+            return b64;
+        }
+
+        public static String GetSHA256Hash(String TextToHash)
+        {
+            if ((TextToHash == null) || (TextToHash.Length == 0))
+            {
+                return String.Empty;
+            }
+            SHA256 sha256 = new SHA256CryptoServiceProvider();//建立一個SHA256
+            byte[] source = Encoding.Default.GetBytes(TextToHash);//將字串轉為Byte[]
+            byte[] crypto = sha256.ComputeHash(source);//進行SHA256加密
+            return Convert.ToBase64String(crypto);
+        }
+
+
+        public static string GetFileMD5Hash(string filePath)
+        {
+            using (var md5 = MD5.Create())
+            {
+                using (var stream = File.OpenRead(filePath))
+                {
+                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
+                }
+            }
+        }
+
+        public static string GetFileMD5Hash(Stream stream)
+        {
+            using (var md5 = MD5.Create())
+            {
+                return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToUpper();
+            }
+        }
+    }
+}

+ 15 - 0
ConsoleApp1/NewWebApi/ButtonStatus.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.Model
+{
+    public class ButtonStatus
+    {
+        public int Button1 { get; set; }
+        public int Button2 { get; set; }
+        public int EmergencyButton { get; set; }
+    }
+}

+ 449 - 0
ConsoleApp1/NewWebApi/EvApi.cs

@@ -0,0 +1,449 @@
+using AwInitilizer.Model;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.Assist
+{
+    public class EvApiResult<T>
+    {
+        public T Result { get; set; }
+        public string Response { get; set; }
+    }
+
+    public class EvApiWifiResult
+    {
+        public int Rssi { get; set; }
+        public int ErrorCode { get; set; }
+    }
+
+    public static class EvApi
+    {
+        internal static async Task<EvApiResult<bool>> ChekCsuBootCompelete()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt2String();
+            if (!getResult.IsSuccess ||
+                string.IsNullOrEmpty(getResult.Msg))
+            {
+                return new EvApiResult<bool>() { Response = getResult.Msg, Result = false };
+            }
+
+            Regex rx = new Regex("(SystemStatus)\\\": ([0-9]*)");
+            var matches = rx.Matches(getResult.Msg);
+            if (matches.Count == 0)
+            {
+                return new EvApiResult<bool>() { 
+                    Result = false,
+                    Response = getResult.Msg
+                };
+            }
+            bool isAllPassed = true;
+            for (int matchIndex = 0; matchIndex < matches.Count; matchIndex++)
+            {
+                var match = matches[matchIndex];
+                if (match.Groups.Count != 3)
+                {
+                    isAllPassed = false;
+                    break;
+                }
+                else
+                {
+                    if (match.Groups[2].Value != "1")
+                    {
+                        isAllPassed = false;
+                        break;
+                    }
+                }
+            }
+
+            return new EvApiResult<bool>()
+            {
+                Result = isAllPassed,
+                Response = getResult.Msg,
+            };
+        }
+
+        internal static async Task<EvApiResult<bool>> CheckGetQueryAction()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt2String();
+            if (!getResult.IsSuccess ||
+                string.IsNullOrEmpty(getResult.Msg))
+            {
+                return new EvApiResult<bool>() { Response = getResult.Msg, Result = false };
+            }
+
+            return new EvApiResult<bool>()
+            {
+                Result = !string.IsNullOrEmpty(getResult.Msg),
+                Response = getResult.Msg
+            };
+        }
+
+        internal static async Task<EvApiResult<ButtonStatus>> GetButtonStatus()
+        {
+            var getResult = await EvHttpClient.GetButtonStatusString();
+            var result = getResult.Msg;
+
+            if(!getResult.IsSuccess)
+            {
+                return new EvApiResult<ButtonStatus>()
+                {
+                    Result = null,
+                    Response = getResult.Msg
+                };
+            }
+
+            if (!result.Contains("Button1") ||
+                !result.Contains("Button2") ||
+                !result.Contains("EmergencyButton"))
+            {
+                return new EvApiResult<ButtonStatus>()
+                {
+                    Result = null,
+                    Response = result
+                };
+            }
+            var values = JsonConvert.DeserializeObject<ButtonStatus>(result);
+            return new EvApiResult<ButtonStatus>()
+            {
+                Result = values,
+                Response = result,
+            };
+        }
+
+        internal static async Task<EvApiResult<Dictionary<string, string>>> GetVersion()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt1String();
+            var toReturn = new Dictionary<string, string>();
+
+            string result = getResult.Msg;
+            if (!getResult.IsSuccess)
+            {
+                return new EvApiResult<Dictionary<string, string>>()
+                {
+                    Result = null,
+                    Response = getResult.Msg,
+                };
+            }
+
+            var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
+
+            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 new EvApiResult<Dictionary<string, string>>()
+            {
+                Result = toReturn,
+                Response = result
+            };
+        }
+
+        internal static async Task<EvApiResult<string>> GetTelcomModemImei()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt3String();
+            string result = getResult.Msg;
+            if (!getResult.IsSuccess)
+            {
+                return new EvApiResult<string>()
+                {
+                    Result = string.Empty,
+                    Response = getResult.Msg,
+                };
+            }
+
+            Regex rx = new Regex("(TelcomModemImei)\\\": \"([0-9]*)\"");
+            var matches = rx.Matches(result);
+            string imeiString = string.Empty;
+
+            if (matches.Count != 0)
+            {
+                var match = matches[0];
+                if (match.Groups.Count != 3)
+                {
+                    imeiString = string.Empty;
+                }
+                else
+                {
+                    if (match.Groups[2].Value is string imei)
+                    {
+                        imeiString = imei;
+                    }
+                    else
+                    {
+                        imeiString = "";
+                    }
+                }
+            }
+            else
+            {
+                imeiString = "";
+            }
+
+            return new EvApiResult<string>()
+            {
+                Result = imeiString,
+                Response = result
+            };
+        }
+
+        internal static async Task<EvApiResult<EvApiWifiResult>> GetWifiRssi()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt3String();
+            string result = getResult.Msg;
+            if (!getResult.IsSuccess)
+            {
+                return new EvApiResult<EvApiWifiResult>() { 
+                    Result = new EvApiWifiResult() { 
+                        Rssi = 0,
+                        ErrorCode = 0
+                    },
+                    Response = getResult.Msg,
+                };
+            }
+
+            Regex rx_mode = new Regex("(WifiMode)\\\": ([0-9]*)");
+            var matches_mode = rx_mode.Matches(result);
+            int rssi = 0;
+            int errorCode = -1;
+
+            if (matches_mode.Count != 0)
+            {
+                var match = matches_mode[0];
+                if (match.Groups.Count != 3)
+                {
+                    errorCode = 0;
+                }
+                else
+                {
+                    if (int.TryParse(match.Groups[2].Value, out var wifiMode))
+                    {
+                        if (wifiMode != 1)
+                        {
+                            errorCode = 1;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                errorCode = 2;
+            }
+
+            if (errorCode != -1)
+            {
+                return new EvApiResult<EvApiWifiResult>()
+                {
+                    Result = new EvApiWifiResult()
+                    {
+                        Rssi = rssi,
+                        ErrorCode = errorCode
+                    },
+                    Response = result
+                };
+            }
+
+            Regex rx = new Regex("(WifiRssi)\\\": (-?[0-9]*)");
+            var matches = rx.Matches(result);
+
+            if (matches.Count != 0)
+            {
+                var match = matches[0];
+                if (match.Groups.Count != 3)
+                {
+                    errorCode = 3;
+                }
+                else
+                {
+                    if (int.TryParse(match.Groups[2].Value, out var rssiSignal))
+                    {
+                        rssi = rssiSignal;
+                    }
+                    else
+                    {
+                        errorCode = 4;
+                    }
+                }
+            }
+            else
+            {
+                errorCode = 5;
+            }
+
+            return new EvApiResult<EvApiWifiResult>()
+            {
+                Result = new EvApiWifiResult()
+                {
+                    Rssi = rssi,
+                    ErrorCode = errorCode
+                },
+                Response = result
+            };
+        }
+
+        internal static async Task<EvApiResult<Dictionary<int, string>>> GetConnectorStatus()
+        {
+            var getResult = await EvHttpClient.GetQueryActionOpt2String();
+            Dictionary<int, string> connectorStatusPair = new Dictionary<int, string>();
+
+            string result = getResult.Msg;
+            if (!getResult.IsSuccess)
+            {
+                return new EvApiResult<Dictionary<int, string>>() { 
+                    Result = connectorStatusPair,
+                    Response = getResult.Msg
+                };
+            }
+
+            Regex rx = new Regex("(SystemStatus)\\\": (\\d)");
+            var matches = rx.Matches(result);
+            for (int matchIndex = 0; matchIndex < matches.Count; matchIndex++)
+            {
+                var match = matches[matchIndex];
+                if (match.Groups.Count != 3)
+                {
+                    //LogWriter.Log($"Connector {matchIndex} status string mismatched");
+                    return new EvApiResult<Dictionary<int, string>>()
+                    {
+                        Result = null,
+                        Response = result
+                    };
+                    //InfoLog += $"Connector {matchIndex} status string mismatched\n";
+                    //Logger.Print($"Connector {matchIndex} status string mismatched", isError:true);
+                }
+                else
+                {
+                    connectorStatusPair.Add(matchIndex, match.Groups[2].Value);
+                }
+            }
+
+            return new EvApiResult<Dictionary<int, string>>()
+            {
+                Result = connectorStatusPair,
+                Response = result,
+            };
+        }
+
+        internal static async Task<EvApiResult<bool>> FactorySet()
+        {
+            var getResult = await EvHttpClient.GetFactorySetResultString();
+            var result = getResult.Msg;
+            if (!getResult.IsSuccess)
+            {
+                return new EvApiResult<bool>() { 
+                    Result = false,
+                    Response = getResult.Msg
+                };
+            }
+
+            Regex rx = new Regex("(result)\":\"([a-zA-Z]*)\"");
+            var matches = rx.Matches(result);
+            if (matches.Count > 0 &&
+                matches[0].Success &&
+                matches[0].Groups.Count == 3 &&
+                matches[0].Groups[2].Value.ToLower() == "success")
+            {
+                return new EvApiResult<bool>()
+                {
+                    Result = true,
+                    Response = result
+                };
+            }
+            return new EvApiResult<bool>()
+            {
+                Result = false,
+                Response = result
+            };
+        }
+
+        internal static async Task<EvApiResult<bool>> SignalUpdateFirmware()
+        {
+            var result = await EvHttpClient.GetSignalUpdateFirmwareResultString();
+            if (!result.IsSuccess)
+            {
+                return new EvApiResult<bool>() { 
+                    Result = false,
+                    Response = result.Msg
+                };
+            }
+
+            return new EvApiResult<bool>()
+            {
+                Result = !string.IsNullOrEmpty(result.Msg),
+                Response = result.Msg,
+            };
+        }
+
+        /// <summary>
+        /// Not Tested
+        /// </summary>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        [Obsolete]
+        internal static async Task<EvApiResult<bool>> Uploadfirmware(string fileName)
+        {
+            var result = await EvHttpClient.GetUploadfirmwareResultString(new List<string> { fileName });
+            if (!result.IsSuccess)
+            {
+                return new EvApiResult<bool>()
+                {
+                    Result = false,
+                    Response = result.Msg
+                };
+            }
+
+            return new EvApiResult<bool>() { 
+                Result = !string.IsNullOrEmpty(result.Msg),
+                Response = result.Msg,
+            };
+        }
+
+        /// <summary>
+        /// Not tested
+        /// </summary>
+        /// <param name="fileNames"></param>
+        /// <returns></returns>
+        [Obsolete]
+        internal static async Task<EvApiResult<bool>> Uploadfirmware(List<string> fileNames)
+        {
+            var result = await EvHttpClient.GetUploadfirmwareResultString(fileNames);
+            if (!result.IsSuccess)
+            {
+                return new EvApiResult<bool>()
+                {
+                    Result = false,
+                    Response = result.Msg
+                };
+            }
+
+            return new EvApiResult<bool>()
+            {
+                Result = !string.IsNullOrEmpty(result.Msg),
+                Response = result.Msg,
+            };
+        }
+    }
+}

+ 272 - 0
ConsoleApp1/NewWebApi/EvHttpClient.cs

@@ -0,0 +1,272 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.Assist
+{
+    public class EvHttpClientResult
+    {
+        public bool IsSuccess { get; set; }
+        public string Msg { get; set; }
+    }
+
+    public class EvAuthMsg
+    {
+        public string result { get; set; }
+        public object message { get; set; }
+    }
+
+    public static class EvHttpClient
+    {
+        private static string account = "adminf";
+        private static string pass = "1231231238";
+        //internal static string ServerIpAddress = "192.168.1.10";
+        //internal static string ServerUrl = "https://192.168.1.10";
+        //updated EV
+        internal static string ServerIpAddress = "192.168.80.179";
+        internal static string ServerUrl = "https://192.168.80.179";
+        //original EV
+        //internal static string ServerIpAddress = "192.168.80.199";
+        //internal static string ServerUrl = "https://192.168.80.199";
+
+        internal static Task<EvHttpClientResult> GetQueryActionOpt1String()
+        {
+            string api = "get_query_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>() {
+                {"opt","1"}
+            };
+            return CallBase(api, param);
+        }
+
+        internal static Task<EvHttpClientResult> GetQueryActionOpt2String()
+        {
+            string api = "get_query_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>() {
+                {"opt","2"}
+            };
+            return CallBase(api, param);
+        }
+
+        internal static Task<EvHttpClientResult> GetQueryActionOpt3String()
+        {
+            string api = "get_query_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>() {
+                {"opt","3"}
+            };
+            return CallBase(api, param);
+        }
+
+        internal static Task<EvHttpClientResult> GetButtonStatusString()
+        {
+            string api = "get_button_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>()
+            {
+            };
+            return CallBase(api, param);
+        }
+
+        internal static Task<EvHttpClientResult> GetFactorySetResultString()
+        {
+            string api = "set_system_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>();
+            param.Add("SystemId", "");
+            param.Add("SystemDateTime", "");
+            param.Add("PhaseLossPolicy", "");
+            param.Add("FactoryConfiguration", "1");
+            param.Add("AuthorisationMode", "");
+            param.Add("isAPP", "");
+            param.Add("isQRCode", "");
+            param.Add("isRFID", "");
+            param.Add("QRCodeMadeMode", "");
+            param.Add("QRCodeContent", "");
+            param.Add("Intensity", "");
+            param.Add("RfidCardNumEndian", "");
+            param.Add("PsuAcInputType", "");
+            return CallBase(api, param);
+        }
+
+        internal static Task<EvHttpClientResult> GetUploadfirmwareResultString(List<string> fileNames)
+        {
+            string api = "upgrade_iso_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>(){
+                {"fw_tag","iso"}
+            };
+            return CallBase(api, param, firmwareNames: fileNames);
+        }
+
+        internal static Task<EvHttpClientResult> GetSignalUpdateFirmwareResultString()
+        {
+            string api = "upgrade_iso_action.php";
+            Dictionary<string, string> param = new Dictionary<string, string>(){
+                {"fw_tag","iso"},
+            };
+            var dummyFileCotent = new ByteArrayContent(new byte[0]);
+            dummyFileCotent.Headers.ContentDisposition
+              = new ContentDispositionHeaderValue("attachment")
+              {
+                  FileName = "temp.txt",
+                  Size = 0,
+                  CreationDate = DateTime.Now,
+                  ModificationDate = DateTime.Now,
+                  ReadDate = DateTime.Now,
+                  Name = "files[]"
+              };
+
+            return CallBase(api, param, customContents: new List<HttpContent>() { dummyFileCotent });
+        }
+
+        private static async Task<EvHttpClientResult> CallBase(
+            string api,
+            Dictionary<string, string> param,
+            List<string> firmwareNames = null,
+            List<HttpContent> customContents = null)
+        {
+            try
+            {
+                var url = string.Format("{0}/{1}", ServerUrl, api);
+                Dictionary<string, string> pams = new Dictionary<string, string>
+                {
+                    { "account", account },
+                    { "password", pass }
+                };
+                foreach (var pam in param)
+                {
+                    pams.Add(pam.Key, pam.Value);
+                }
+
+
+                var formContent = new MultipartFormDataContent();
+                foreach (var pam in pams)
+                {
+                    formContent.Add(new StringContent(pam.Value), pam.Key);
+                }
+
+                if (firmwareNames != null)
+                {
+                    if (firmwareNames.Count == 1)
+                    {
+                        var fileName = firmwareNames[0];
+                        formContent.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(fileName)), "file");
+                    }
+                    else
+                    {
+                        foreach (var fileName in firmwareNames)
+                        {
+                            formContent.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(fileName)), "file[]");
+                        }
+                    }
+                }
+
+                if (customContents != null)
+                {
+                    foreach (var content in customContents)
+                    {
+                        formContent.Add(content);
+                    }
+                }
+
+                HttpResponseMessage postResult;
+                string result = null;
+
+
+                var handler = new HttpClientHandler();
+                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
+                handler.ServerCertificateCustomValidationCallback =
+                    (httpRequestMessage, cert, cetChain, policyErrors) =>
+                    {
+                        return true;
+                    };
+
+                using (HttpClient evClient = new HttpClient(handler))
+                {
+                    evClient.Timeout = TimeSpan.FromSeconds(5);
+
+                    try
+                    {
+                        postResult = await evClient.PostAsync(url, formContent);
+                        if (postResult == null || !postResult.IsSuccessStatusCode)
+                        {
+                            throw new Exception("Post fail");
+                        }
+                        result = await postResult.Content.ReadAsStringAsync();
+
+                        if (result.Contains("File is uploaded, please wait a moment to upgrade"))
+                        {
+                            return new EvHttpClientResult()
+                            {
+                                IsSuccess = true,
+                                Msg = result,
+                            };
+                        }
+
+                        var check = JsonConvert.DeserializeObject<EvAuthMsg>(result);
+                        if (check != null &&
+                            check.result != null &&
+                            check.result.ToLower() == "fail")
+                        {
+                            return new EvHttpClientResult() { 
+                                IsSuccess = false,
+                                Msg = result,
+                            };
+                        }
+
+                        return new EvHttpClientResult()
+                        {
+                            IsSuccess = true,
+                            Msg = result,
+                        };
+                    }
+                    catch
+                    {
+                        //post fail
+                    }
+                }
+
+                using (WebClientTimeout webClient = new WebClientTimeout())
+                {
+                    NameValueCollection parameters = new NameValueCollection();
+                    foreach (var inpam in param)
+                    {
+                        parameters.Add(inpam.Key, inpam.Value);
+                    }
+                    webClient.QueryString = parameters;
+
+                    using (Stream stream = webClient.OpenRead(url))
+                    // 使用 StreamReader 讀取 stream 內的字元
+                    using (StreamReader reader = new StreamReader(stream))
+                    {
+                        // 將 StreamReader 所讀到的字元轉為 string
+                        result = await reader.ReadToEndAsync();
+                    }
+
+                    var check = JsonConvert.DeserializeObject<EvAuthMsg>(result);
+                    if (check != null &&
+                        check.result != null &&
+                        check.result.ToLower() == "fail")
+                    {
+                        return new EvHttpClientResult()
+                        {
+                            IsSuccess = false,
+                            Msg = result,
+                        };
+                    }
+                }
+                return new EvHttpClientResult() { IsSuccess = true, Msg = result };
+
+            }
+            catch (Exception e)
+            {
+                return new EvHttpClientResult() { IsSuccess = false, Msg = e.Message }; ;
+            }
+        }
+    }
+}

+ 19 - 0
ConsoleApp1/NewWebApi/WebClientTimeout.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AwInitilizer.Assist
+{
+    public class WebClientTimeout : WebClient
+    {
+        protected override WebRequest GetWebRequest(Uri uri)
+        {
+            WebRequest w = base.GetWebRequest(uri);
+            w.Timeout = 2 * 1000;
+            return w;
+        }
+    }
+}

+ 69 - 0
ConsoleApp1/OCPPAuth/Ebus_capital.cs

@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.OCPPAuth
+{
+    internal static class Ebus_capital
+    {
+        public static void Test()
+        {
+            //var url = "https://buscharge.zerovatech.com/service/api/v1/cpo/station";
+            //var _body = "";
+            //var timestamp = "";
+            //string signature = GetSignature(GetUnencodeText(url, _body, timestamp, headers["PartnerId"], saltkey));
+            var result = IsExpiryTime("1712031689");
+            Console.WriteLine(result);
+        }
+
+        private static bool IsExpiryTime(string timestamp)
+        {
+            bool result = true;
+            long minTime = DateTimeOffset.UtcNow.AddSeconds(-300).ToUnixTimeSeconds();
+            long maxTime = DateTimeOffset.UtcNow.AddSeconds(300).ToUnixTimeSeconds();
+            long requestTime = 0;
+
+            if (long.TryParse(timestamp, out requestTime))
+            {
+                if (minTime < requestTime && maxTime > requestTime)
+                {
+                    result = false;
+                }
+            }
+
+            DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+            dateTime = dateTime.AddSeconds(requestTime).ToLocalTime();
+            return result;
+        }
+
+
+        private static string GetUnencodeText(string url, string body, string timestamp, string partnerId, string saltkey)
+        {
+
+            string tempText = url.Substring(url.IndexOf('?') + 1).ToLower();
+            tempText = tempText.StartsWith("http") ? string.Empty : tempText;
+            body = tempText + body;
+            string unencodeText = string.Format("{0}{1}{2}{3}", body, timestamp, partnerId, saltkey).ToLower();
+
+            return unencodeText;
+        }
+
+        private static string GetSignature(string unencodeText)
+        {
+            if ((unencodeText == null) || (unencodeText.Length == 0))
+            {
+                return String.Empty;
+            }
+            unencodeText = unencodeText.ToLower();
+
+            MD5 md5 = MD5.Create();// new MD5CryptoServiceProvider();
+            byte[] textToHash = Encoding.UTF8.GetBytes(unencodeText);
+            byte[] result = md5.ComputeHash(textToHash);
+            return BitConverter.ToString(result).Replace("-", "").ToLower();
+        }
+    }
+}

+ 41 - 0
ConsoleApp1/OCPPAuth/Signature.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.OCPPAuth
+{
+    internal static class Signature
+    {
+        public static void Test()
+        {
+            string signature = GetSignature(
+                timestamp: "1731483946",
+                partnerid: "523E6CE1-8BA4-4D88-8895-AC05F5B3AE8F",
+                saltkey: "L^u9d2Rt@C");
+        }
+
+        private static string GetSignature(string timestamp, string partnerid, string saltkey)
+        {
+            var unencodeText = $"{timestamp}{partnerid}{saltkey}".ToLower();
+            var signature = GetSignature(unencodeText);
+            return signature;
+        }
+
+        private static string GetSignature(string unencodeText)
+        {
+            if ((unencodeText == null) || (unencodeText.Length == 0))
+            {
+                return String.Empty;
+            }
+            unencodeText = unencodeText.ToLower();
+
+            MD5 md5 = MD5.Create();// new MD5CryptoServiceProvider();
+            byte[] textToHash = Encoding.UTF8.GetBytes(unencodeText);
+            byte[] result = md5.ComputeHash(textToHash);
+            return BitConverter.ToString(result).Replace("-", "").ToLower();
+        }
+    }
+}

+ 238 - 0
ConsoleApp1/Program.cs

@@ -0,0 +1,238 @@
+
+using AwInitilizer.Assist;
+using Azure;
+using ConsoleApp1.CertificateTest;
+using ConsoleApp1.Else;
+using ConsoleApp1.Mile;
+using ConsoleApp1.OCPPAuth;
+using ConsoleApp1.RegexTest;
+using ConsoleApp1.StringCheck;
+using ConsoleApp1.WebSocketClient;
+using FluentFTP;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+
+Signature.Test();
+return;
+
+StringCheck1.Run();
+return;
+
+var value = "{\"result\":\"Success\",\"message\":{\"SystemId\":\"\",\"SystemDateTime\":\"\",\"FactoryConfiguration\":\"1\",\"RfidCardNumEndian\":\"\",\"PsuAcInputType\":\"\",\"PhaseLossPolicy\":0,\"AuthorisationMode\":0,\"isAPP\":0,\"isQRCode\":0,\"isRFID\":0,\"QRCodeMadeMode\":0,\"Intensity\":0,\"QRCodeContent\":\"\"}}";
+var test = JsonConvert.DeserializeObject<EvAuthMsg>(value);
+var msg = test.message;
+var type = test.message.GetType();
+
+if (type == typeof(JObject))
+{
+    var msgText = JsonConvert.SerializeObject(msg);
+}
+
+if (type == typeof(System.String))
+{
+
+}
+
+//var result0 = await CapitalbusMile.GetMile("EAL-1093");
+var result0 = await BaoruhMile.GetMile("SYV-0001");
+var a = 1;
+
+Ebus_capital.Test();
+
+var test1 = "123abcABC";
+var result1 = GetIntStringFromString(test1);
+
+string GetIntStringFromString(string s)
+{
+    string toReturn = string.Empty;
+    var array = Encoding.ASCII.GetBytes(s);
+    if (array.Length == 0)
+    {
+        return toReturn;
+    }
+    toReturn = GetString(GetInt(array[0]));
+    for (int index = 1 ; index < array.Length; index ++)
+    {
+        toReturn = $"{toReturn}{GetString(GetInt(array[index]))}";
+    }
+    return toReturn;
+}
+
+string GetString(int i)
+{
+    return i.ToString("00");
+}
+
+int GetInt(byte c)
+{
+    if (c < 32 || c > 126)
+    {
+        return 0;
+    }
+    return c - 32;
+}
+
+//var dic = new Dictionary<string, int?>();
+//dic["test"] = null;
+
+//var test1 = "sftp://charger:1@qAAtrE6och@104.41.191.35/home/charger/V0.67_ramdisk_AXLU111001D1P1_CSU30_RootFileSystem_1832C5CF_FTPs.gz";
+//var test2 = "sftp://charger:1@qAAtrE6och@evscket.phihong.com/home/charger/V0.67_ramdisk_AXLU111001D1P1_CSU30_RootFileSystem_1832C5CF_FTPs.gz";
+
+//var result3 = new Uri(test2);
+
+var temp = await EvApi.GetVersion();
+Console.WriteLine(JsonConvert.SerializeObject(temp));
+Console.ReadKey();
+
+return;
+
+ConsoleApp1.DI.CricularDependency.Test();
+
+RegexTest.Test3();
+
+EnumerableSequenceEqualTest.Test();
+
+await EvHttpClientLoggerTest.Test();
+
+RegexTest.Test();
+
+CertificateRequestTest.Test2();
+
+await WebSocketClientTest.Test();
+
+string uidString1 = "BB51A7D9-1F69-415C-94C0-AC6DE76A70D9";
+Guid uid = Guid.Parse(uidString1);
+var uidRestored =  uid.ToString();
+
+ServicePointManager.ServerCertificateValidationCallback +=
+    (sender, cert, chain, sslPolicyErrors) => true;
+System.Net.ServicePointManager.Expect100Continue = false;
+
+IPAddress ipAddress = IPAddress.Parse("192.168.80.179");
+Ping pingSender = new Ping();
+PingReply pingReply = pingSender.Send(ipAddress, 50);
+pingSender.Dispose();
+
+Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+await CapitalbusMile.GetMile("EAL-1095");
+
+var cards = await TTIA_API.GetCards();
+var mappedTrasactions = await TTIA_API.GetTrasactions(cards);
+
+var ftp = await GetFtpClient();
+try
+{
+    var list = await ftp.GetListing("/");
+}
+catch(Exception e)
+{
+
+}
+
+
+long secs = 1587362347;
+var baseTime = DateTime.Parse("1970-01-01 00:00:00 Z").ToUniversalTime();
+var addedTime = baseTime.AddSeconds(secs);
+Console.WriteLine(addedTime);
+
+
+string data = """
+    1587362347{"code":106,"vehiclelicense":"ea-123"}zv1234
+    """;
+var result = MD5ToHex_UTF8(data);
+
+var appBuilder = WebApplication.CreateBuilder();
+var app = appBuilder.Build();
+
+app.UseWebSockets();
+
+app.MapGet("/test", () =>
+{
+    return "hello!";
+});
+
+app.Use(async (context, next) =>
+{
+    if (context.Request.Path == "/ws")
+    {
+        if (context.WebSockets.IsWebSocketRequest)
+        {
+            using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
+        }
+        else
+        {
+            context.Response.StatusCode = StatusCodes.Status400BadRequest;
+        }
+    }
+    else
+    {
+        await next(context);
+    }
+
+});
+
+app.Urls.Add("http://*:80");
+
+app.Run();
+
+ String MD5ToHex_UTF8(String TextToHash)
+{
+    if ((TextToHash == null) || (TextToHash.Length == 0))
+    {
+        return String.Empty;
+    }
+
+    MD5 md5 = new MD5CryptoServiceProvider();
+    byte[] textToHash = Encoding.UTF8.GetBytes(TextToHash);
+    byte[] result = md5.ComputeHash(textToHash);
+    return BitConverter.ToString(result).Replace("-", "").ToLower();
+}
+
+
+static async Task<IAsyncFtpClient> GetFtpClient()
+{
+    IAsyncFtpClient toReturn = null;
+    try
+    {
+        
+        //var token = new CancellationToken();
+        toReturn = new AsyncFtpClient("ecar.capitalbusgroup.com.tw", new NetworkCredential("eCarCharge", "aBcd@0505"), port: 2121);
+        toReturn.Config.LogUserName = false;
+        toReturn.Config.LogPassword = false;
+        toReturn.Config.LogHost = false;
+        toReturn.Config.ConnectTimeout = 30_000;
+
+        // conn.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
+        //toReturn.Config.DataConnectionType = FtpDataConnectionType.PASV;
+        toReturn.Config.DataConnectionType = FtpDataConnectionType.PASV;
+        toReturn.Config.EncryptionMode = FtpEncryptionMode.None;
+        //toReturn.Config.EncryptionMode = FtpEncryptionMode.None;
+        toReturn.ValidateCertificate += (control, e) =>
+        {
+            e.PolicyErrors = System.Net.Security.SslPolicyErrors.None;
+            e.Accept = true;
+        };
+
+        await toReturn.Connect();
+        return toReturn;
+    }
+    catch (Exception ex)
+    {
+        if (toReturn is not null)
+        {
+            toReturn.Dispose();
+        }
+
+        return null;
+    }
+}

+ 117 - 0
ConsoleApp1/RSA/ChatgpetSuggest.cs

@@ -0,0 +1,117 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using Org.BouncyCastle.OpenSsl;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto.Parameters;
+using System.Text;
+
+public class RSAExample
+{
+    public static void Main()
+    {
+        // 讀取並載入私鑰和公鑰
+        RSA rsaGen = RSA.Create();
+        RSAParameters privateKeyParameters = rsaGen.ExportParameters(true);
+        RSAParameters publicKeyParameters = rsaGen.ExportParameters(false);
+        //RSAParameters privateKeyParameters = LoadPrivateKey("private_key.pem");
+        //RSAParameters publicKeyParameters = LoadPublicKey("public_key.pem");
+
+        var aes = Aes.Create();
+        var buffer = new MemoryStream();
+        CryptoStream cryptoStream = new CryptoStream(
+                buffer,
+                aes.CreateEncryptor(),
+                CryptoStreamMode.Write);
+        StreamWriter sw = new StreamWriter(cryptoStream);
+        sw.Write("this is the message");
+        sw.Close();
+        var key = aes.Key;
+        var iv = aes.IV;
+        var encoded = buffer.ToArray();
+
+        var aesDecrept = Aes.Create();
+        aesDecrept.Key = key;
+        aesDecrept.IV = iv;
+        var toDecryptStream = new MemoryStream(encoded);
+        CryptoStream deCryptoStream = new CryptoStream(
+               toDecryptStream,
+               aesDecrept.CreateDecryptor(),
+               CryptoStreamMode.Read);
+        StreamReader sr = new StreamReader(deCryptoStream);
+        var deceypedString = sr.ReadToEnd();
+
+        // 創建 RSA 實例
+        using (RSA rsa = RSA.Create())
+        {
+            rsa.ImportParameters(privateKeyParameters);
+
+            // 用私鑰加密數據
+            byte[] dataToEncrypt = System.Text.Encoding.UTF8.GetBytes("This is a secret message");
+            byte[] encryptedData = rsa.Encrypt(dataToEncrypt, RSAEncryptionPadding.OaepSHA256);
+
+            Console.WriteLine("Encrypted Data (Base64): " + Convert.ToBase64String(encryptedData));
+
+            rsa.ImportParameters(publicKeyParameters);
+
+            // 用公鑰解密數據
+            byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
+            string decryptedMessage = System.Text.Encoding.UTF8.GetString(decryptedData);
+
+            Console.WriteLine("Decrypted Message: " + decryptedMessage);
+        }
+    }
+
+    private static RSAParameters LoadPrivateKey(string filePath)
+    {
+        using (StreamReader reader = new StreamReader(filePath))
+        {
+            PemReader pemReader = new PemReader(reader);
+            AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
+            RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)keyPair.Private;
+
+            return DotNetUtilities.ToRSAParameters(privateKey);
+        }
+    }
+
+    private static RSAParameters LoadPublicKey(string filePath)
+    {
+        using (StreamReader reader = new StreamReader(filePath))
+        {
+            PemReader pemReader = new PemReader(reader);
+            RsaKeyParameters publicKey = (RsaKeyParameters)pemReader.ReadObject();
+
+            return DotNetUtilities.ToRSAParameters(publicKey);
+        }
+    }
+}
+
+public static class DotNetUtilities
+{
+    public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privateKey)
+    {
+        return new RSAParameters
+        {
+            Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
+            Exponent = privateKey.PublicExponent.ToByteArrayUnsigned(),
+            D = privateKey.Exponent.ToByteArrayUnsigned(),
+            P = privateKey.P.ToByteArrayUnsigned(),
+            Q = privateKey.Q.ToByteArrayUnsigned(),
+            DP = privateKey.DP.ToByteArrayUnsigned(),
+            DQ = privateKey.DQ.ToByteArrayUnsigned(),
+            InverseQ = privateKey.QInv.ToByteArrayUnsigned()
+        };
+    }
+
+    public static RSAParameters ToRSAParameters(RsaKeyParameters publicKey)
+    {
+        return new RSAParameters
+        {
+            Modulus = publicKey.Modulus.ToByteArrayUnsigned(),
+            Exponent = publicKey.Exponent.ToByteArrayUnsigned()
+        };
+    }
+}

+ 47 - 0
ConsoleApp1/RegexTest/RegexTest.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.RegexTest
+{
+    internal partial class RegexTest
+    {
+        public static void Test3()
+        {
+            var msg = "      Checksum = 0x002D11B8";
+            Regex checksumRegex = new Regex("^(.*)Checksum = (0x.*)$");
+            var match = checksumRegex.Match(msg);
+            if (match.Success &&
+                match.Groups.Count > 2 &&
+                match.Groups[2].Value.StartsWith("0x"))
+            {
+
+            }
+        }
+
+        public static void Test2()
+        {
+            var msg = "Memory [0x08000000 : 0x08010000] - Checksum : 0x00AA2428";
+            Regex checksumRegex = new Regex("^(.*)Checksum : (0x.*)$");
+            var match = checksumRegex.Match(msg);
+            if (match.Success &&
+                match.Groups.Count > 2 &&
+                match.Groups[2].Value.StartsWith("0x"))
+            {
+
+            }
+        }
+
+        public static void Test()
+        {
+            var input = "adcGH01@%!";
+            var result = SlugRegex().Replace(input, "test");
+        }
+
+        [GeneratedRegex("[^0-9A-Za-z _-]", RegexOptions.NonBacktracking, 5)]
+        private static partial Regex SlugRegex();
+    }
+}

+ 24 - 0
ConsoleApp1/StringCheck/StringCheck1.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.StringCheck
+{
+    public static class StringCheck1
+    {
+        public static void Run()
+        {
+            var strings = File.ReadAllLines("2024-08-27.log");
+            foreach (var s in strings) { 
+                if (s.Contains("completed_session") && !s.Contains("PeriodEnergy"))
+                {
+                    Console.WriteLine(s);
+                }
+            }
+        }
+
+        public static string log = "";
+    }
+}

+ 48 - 0
ConsoleApp1/TTIA_API.cs

@@ -0,0 +1,48 @@
+using Dapper;
+using Microsoft.Data.SqlClient;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+public static class TTIA_API
+{
+    public static string webDbString = "data source=prd-ebus.database.windows.net;initial catalog=StandardOCPP_Web;;persist security info=True;user id=ebus_user;password=R859tdk%az;MultipleActiveResultSets=True;App=EntityFramework;TrustServerCertificate=true;Max Pool Size=200;Connection Lifetime=0;Pooling=true;";
+    public static string mainDbString = "data source=prd-ebus.database.windows.net;initial catalog=StandardOCPP_Main;;persist security info=True;user id=ebus_user;password=R859tdk%az;MultipleActiveResultSets=True;App=EntityFramework;TrustServerCertificate=true;Max Pool Size=1024;Connection Lifetime=0;Pooling=true;Min Pool Size=150;";
+
+    public static async Task<List<string>> GetCards()
+    {
+        string cmd = """
+            SELECT [IdTag]
+            FROM [dbo].[VehicleCustomer]
+            """;
+        using var webconn = new SqlConnection(webDbString);
+        webconn.Open();
+        var quesryResult = await webconn.QueryAsync<string>(cmd);
+        return quesryResult.ToList();
+    }
+
+    internal static async Task<List<string>> GetTrasactions(List<string> cards)
+    {
+        try
+        {
+
+            string cmd = """
+            SELECT [Id]
+            FROM [dbo].[TransactionRecord]
+            WHERE StartIdTag in @StartIdTag
+            """;
+            var param = new DynamicParameters();
+            param.Add("@StartIdTag", cards);
+            using var mainconn = new SqlConnection(mainDbString);
+            mainconn.Open();
+            var quesryResult = await mainconn.QueryAsync<string>(cmd, param);
+            return quesryResult.ToList();
+        }
+        catch(Exception e)
+        {
+            throw;
+        }
+    }
+}

+ 43 - 0
ConsoleApp1/UDP/UdpClientTest.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.UDP;
+
+class UdpClientTest
+{
+    public static void Test()
+    {
+        Socket socket = new Socket(socketType: SocketType.Dgram, protocolType: ProtocolType.Udp);
+        EndPoint endPoint = new DnsEndPoint("ChargingVerify01.taiwanebus.net", 14011);
+        socket.Connect(endPoint);
+        var sendResult = socket.Send(
+            buffer: new byte[] { 1, 2, 3 },
+            size: 3,
+            socketFlags: SocketFlags.None
+            );
+        var buffer = new byte[100];
+        var receivedData = socket.Receive(buffer);
+        Console.WriteLine(receivedData);
+
+
+        UdpClient udpClient = new UdpClient();
+        udpClient.Connect("ChargingVerify01.taiwanebus.net", 14011);
+        udpClient.ReceiveAsync().ContinueWith(UdpClientResultHandler);
+        var tt = udpClient.Send(
+            dgram: new byte[] { 1, 2, 3 },
+            bytes: 3
+            );
+        Console.WriteLine(tt);
+        Task.Delay(30_000).Wait();
+    }
+
+    private static void UdpClientResultHandler(Task<UdpReceiveResult> task)
+    {
+
+    }
+}

+ 35 - 0
ConsoleApp1/WebSocketClient/WebSocketClientTest.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Security;
+using System.Net.WebSockets;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.WebSocketClient
+{
+    internal static class WebSocketClientTest
+    {
+        public static async Task Test()
+        {
+            var url = new Uri("wss://localhost/PHSimulator006501");
+            var clientCertificate = X509Certificate2.CreateFromPemFile("crt.cert.pem", "key.key.pem");
+            var tmpCert = new X509Certificate2(clientCertificate.Export(X509ContentType.Pfx));
+            //var clientCertificate = new X509Certificate2("PHSimulator006501.pfx", "test");
+            //var clienCertificateRoot = X509Certificate2.CreateFromPemFile("rca.crt");
+            var client = new ClientWebSocket();
+            client.Options.AddSubProtocol("ocpp1.6");
+            client.Options.ClientCertificates.Add(tmpCert);
+            client.Options.RemoteCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
+            //client.Options.ClientCertificates.Add(clienCertificateRoot);
+            await client.ConnectAsync(url, default);
+        }
+
+        private static bool ValidateRemoteCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
+        {
+            return true;
+        }
+    }
+}

+ 41 - 0
ConsoleApp1/bellwether/BellwetherTest.cs

@@ -0,0 +1,41 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace ConsoleApp1.bellwether
+{
+    internal class BellwetherTest
+    {
+        static void test3()
+        {
+            var url = "http://plm.bellwether-corp.com:8081/BW_Service.asmx/ExportSolarenergy_All_1";
+            //RestClient client = new RestClient(url);
+            //RestRequest restRequest = new RestRequest() { Method = Method.GET };
+            //var requestResult = client.Execute(restRequest);
+            //var gettask = client.GetStringAsync(url);
+            //var result = gettask.Result;
+            //var result = requestResult.Content;
+            var result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<string xmlns=\"http://tempuri.org\">{\"code\":200,\"status\":\"success\",\"data\":[{\"Area\":\"集團\",\"Unit\":\"年\",\"Energy\":\"865576\",\"CO2EmissionSaved\":\"419766\",\"EquivalentTreesPlanted\":\"15321447\"},{\"Area\":\"\",\"Unit\":\"日\",\"Energy\":\"1590\",\"CO2EmissionSaved\":\"784\",\"EquivalentTreesPlanted\":\"28607\"},{\"Area\":\"平鎮\",\"Unit\":\"日\",\"Energy\":\"842\",\"CO2EmissionSaved\":\"428\",\"EquivalentTreesPlanted\":\"15640\"},{\"Area\":\"昆山\",\"Unit\":\"日\",\"Energy\":\"748\",\"CO2EmissionSaved\":\"355\",\"EquivalentTreesPlanted\":\"12968\"},{\"Area\":\"越南\",\"Unit\":\"日\",\"Energy\":\"---\",\"CO2EmissionSaved\":\"---\",\"EquivalentTreesPlanted\":\"---\"},{\"Area\":\"美洲\",\"Unit\":\"日\",\"Energy\":\"---\",\"CO2EmissionSaved\":\"---\",\"EquivalentTreesPlanted\":\"---\"},{\"Area\":\"\",\"Unit\":\"\",\"Energy\":\"---\",\"CO2EmissionSaved\":\"---\",\"EquivalentTreesPlanted\":\"---\"}],\"message\":\"\"}</string>";
+            //result = result.Replace('\n',' ').Replace('\r',' ');
+            Regex regex = new Regex(".*\"data\":(\\[.*\\]).*");
+            var matchResult = regex.Match(result);
+            if (matchResult != null && matchResult.Success && matchResult.Groups.Count > 1)
+            {
+                result = matchResult.Groups[1].Value;
+            }
+            var solarEnergyModels = JsonConvert.DeserializeObject<SolarEnergyModel[]>(result);
+        }
+
+        class SolarEnergyModel
+        {
+            public string Area { get; set; }
+            public string Energy { get; set; }
+            public string CO2EmissionSaved { get; set; }
+            public string EquivalentTreesPlanted { get; set; }
+        }
+    }
+}

Неке датотеке нису приказане због велике количине промена