using FrontendWorkerService.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.FrontendRepository.Interface;
using Repository.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace FrontendWorkerService.Quartz.Jobs
{
    /// <summary>
    /// 透過obix API向Niagara取得所有設備的最新的即時資料
    /// </summary>
    [DisallowConcurrentExecution]
    class OnTimeDeviceRawDataJob : IJob
    {
        private readonly ILogger<OnTimeDeviceRawDataJob> logger;
        private readonly IFrontendRepository frontendRepository;

        public OnTimeDeviceRawDataJob(
            ILogger<OnTimeDeviceRawDataJob> logger,
            IFrontendRepository frontendRepository)
        {
            this.logger = logger;
            this.frontendRepository = frontendRepository;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                logger.LogInformation("【OnTimeDeviceRawDataJob】【任務開始】");

                EDFunction ed = new EDFunction();
                var obixApiConfig = new ObixApiConfig();

                var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";

                var variable = await frontendRepository.GetAllAsync<KeyValue>(sqlObix);
                obixApiConfig.ApiBase = variable.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
                obixApiConfig.UserName = ed.AESDecrypt(variable.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
                obixApiConfig.Password = ed.AESDecrypt(variable.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault());

                String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));

                var sWhere = @$"deleted = 0 AND system_type = @system_type AND system_key = @system_key";
                var watch = await frontendRepository.GetOneAsync<Variable>("variable", sWhere, new { system_type = "obixConfig", system_key = "watch_id" });

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch.system_value}/pollChanges/");
                request.Method = "POST";
                request.Headers.Add("Authorization", "Basic " + encoded);
                request.PreAuthenticate = true;

                //Stopwatch stopWatch = new Stopwatch();
                //stopWatch.Start();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();

                //stopWatch.Stop();
                //logger.LogInformation("【OnTimeDeviceRawDataJob】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);

                //stopWatch.Reset();
                //stopWatch.Start();
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(responseContent);
                string json = JsonConvert.SerializeXmlNode(xmlDocument);
                JObject jsonResult = (JObject)JsonConvert.DeserializeObject(json);

                if (jsonResult.ContainsKey("err")) //抓取錯誤
                {
                    logger.LogError("【OnTimeDeviceRawDataJob】【API回傳錯誤資訊】");
                    logger.LogError("【OnTimeDeviceRawDataJob】【API回傳錯誤資訊】[錯誤內容]:{0}", json);

                    #region 刪除舊有watch service
                    logger.LogInformation("【OnTimeDeviceRawDataJob】【開始刪除該watch service】[編號:{0}]", watch.system_value);

                    HttpWebRequest deleteWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch.system_value}/delete/");
                    deleteWatchServiceRequest.Method = "POST";
                    deleteWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
                    deleteWatchServiceRequest.PreAuthenticate = true;

                    HttpWebResponse deleteWatchServiceResponse = (HttpWebResponse)deleteWatchServiceRequest.GetResponse();
                    var deleteWatchServiceResponseContent = new StreamReader(deleteWatchServiceResponse.GetResponseStream()).ReadToEnd();

                    xmlDocument.LoadXml(deleteWatchServiceResponseContent);
                    string deleteWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
                    JObject deleteWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(deleteWatchServiceJson);

                    if (deleteWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
                    {
                        logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service失敗】[編號:{0}]");
                        logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service失敗】[錯誤內容]:{0}", deleteWatchServiceJson);
                    }
                    else if (deleteWatchServiceJsonResult.ContainsKey("obj"))
                    {
                        var deleteResult = deleteWatchServiceJsonResult["obj"]["@null"].ToString();

                        if (deleteResult == "true")
                        {
                            logger.LogInformation("【OnTimeDeviceRawDataJob】【刪除舊有watch service成功】[編號:{0}]", watch.system_value);
                        }
                        else
                        {
                            logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service失敗】[編號:{0}]", watch.system_value);
                            logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service失敗】[錯誤內容]:{0}", deleteWatchServiceJson);
                        }
                    }
                    else //未知錯誤
                    {
                        logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service未知錯誤】[編號:{0}]", watch.system_value);
                        logger.LogError("【OnTimeDeviceRawDataJob】【刪除舊有watch service未知錯誤】[錯誤內容]:{0}", deleteWatchServiceJson);
                    }
                    #endregion

                    #region 重新建立watch service
                    logger.LogInformation("【OnTimeDeviceRawDataJob】【開始重新建立watch service】");

                    string watch_id = string.Empty; //紀錄watch id的編號
                    //重新建立watch service
                    HttpWebRequest makeWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/make/");
                    makeWatchServiceRequest.Method = "POST";
                    makeWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
                    makeWatchServiceRequest.PreAuthenticate = true;

                    HttpWebResponse makeWatchServiceResponse = (HttpWebResponse)makeWatchServiceRequest.GetResponse();
                    var makeWatchServiceResponseContent = new StreamReader(makeWatchServiceResponse.GetResponseStream()).ReadToEnd();

                    xmlDocument.LoadXml(makeWatchServiceResponseContent);
                    string makeWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
                    JObject makeWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(makeWatchServiceJson);

                    if (makeWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
                    {
                        logger.LogError("【OnTimeDeviceRawDataJob】【重新建立watch service失敗】");
                        logger.LogError("【OnTimeDeviceRawDataJob】【重新建立watch service失敗】[錯誤內容]:{0}", makeWatchServiceJson);
                        return;
                    }

                    if (makeWatchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                    {
                        var makeSplit = makeWatchServiceJsonResult["obj"]["@href"].ToString().Split("/");
                        watch_id = makeSplit[makeSplit.Length - 2].Replace("watch", "");
                    }

                    if (!string.IsNullOrEmpty(watch_id))
                    {
                        logger.LogInformation("【OnTimeDeviceRawDataJob】【重新建立watch service的編號】[編號:{0}]", watch_id);

                        //儲存至variable
                        Dictionary<string, object> updateWatchId = new Dictionary<string, object>()
                        {
                            { "@system_value", watch_id}
                        };

                        await frontendRepository.UpdateOneByCustomTable(updateWatchId, "variable", "system_type = 'obixConfig' AND system_key = 'watch_id'");

                        //修改watch service 存活時間
                        HttpWebRequest changeWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch_id}/lease/");
                        changeWatchServiceRequest.Method = "PUT";
                        changeWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
                        changeWatchServiceRequest.PreAuthenticate = true;

                        var realTime = $@"<reltime val='PT24H0S' />";
                        byte[] realTimeByteArray = Encoding.UTF8.GetBytes(realTime);
                        using (Stream reqStream = changeWatchServiceRequest.GetRequestStream())
                        {
                            reqStream.Write(realTimeByteArray, 0, realTimeByteArray.Length);
                        }

                        HttpWebResponse changeWatchServiceResponse = (HttpWebResponse)changeWatchServiceRequest.GetResponse();
                        var changeWatchServiceResponseContent = new StreamReader(changeWatchServiceResponse.GetResponseStream()).ReadToEnd();

                        xmlDocument.LoadXml(changeWatchServiceResponseContent);
                        string changeWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
                        JObject changeWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(changeWatchServiceJson);

                        if (changeWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
                        {
                            logger.LogError("【OnTimeDeviceRawDataJob】【修改watch service存活時間失敗】");
                            logger.LogError("【OnTimeDeviceRawDataJob】【修改watch service存活時間失敗】[錯誤內容]:{0}", changeWatchServiceJsonResult);
                            return;
                        }
                    }
                    #endregion

                    #region 設定要訂閱的設備點位
                    var deviceSubscrips = await frontendRepository.GetAllAsync<OntimeSubscrip>("ontime_device_subscription", string.Empty);
                    var subscripUriFormat = @" <uri val='/obix/config/Arena/{0}/{1}/{2}/{3}/' />";

                    List<string> subscripStrings = new List<string>();

                    foreach (var deviceSubscrip in deviceSubscrips)
                    {
                        List<string> devicePaths = new List<string>();
                        //拆解設備編號來組出路徑
                        var deviceSubscripSplit = deviceSubscrip.device_number.Split("_");
                        foreach (var temp in deviceSubscripSplit)
                        {
                            if (temp[0].ToString().All(char.IsDigit))
                            {
                                devicePaths.Add($"$3{temp}");
                            }
                            else
                            {
                                devicePaths.Add(temp);
                            }
                        }

                        //剔除最後一個,因為是設備名稱
                        devicePaths.RemoveAt(devicePaths.Count() - 1);

                        //查詢是否有做為狀態設定(device_kind)
                        var sql_device_kind = $@"SELECT dk.* FROM device d
                                                        JOIN device_kind dk ON 
                                                         d.device_building_tag = dk.device_building_tag
                                                         AND d.device_system_tag = dk.device_system_tag
                                                         AND d.device_name_tag = dk.device_name_tag
                                                        WHERE d.deleted = 0
                                                        AND d.device_number = @device_number";

                        var deviceKind = await frontendRepository.GetOneAsync<DeviceKind>(sql_device_kind, new { device_number = deviceSubscrip.device_number });

                        if (deviceKind != null)
                        {   //表示該設備有特別設定點位
                            if ((deviceSubscrip.name == deviceKind.Device_normal_point_name ||
                                deviceSubscrip.name == deviceKind.Device_close_point_name ||
                                deviceSubscrip.name == deviceKind.Device_error_point_name) &&
                                deviceSubscrip.name != "ER")
                            {
                                subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), deviceSubscrip.device_number, deviceSubscrip.name, "facets"));
                                subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), deviceSubscrip.device_number, deviceSubscrip.name, "out"));
                            }
                            else
                            {   //並未符合指定的點位
                                subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), deviceSubscrip.device_number, deviceSubscrip.name, "out"));
                            }
                        }
                        else
                        {
                            subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), deviceSubscrip.device_number, deviceSubscrip.name, "out"));
                        }

                    }

                    #endregion 設定要訂閱的設備點位

                    #region 訂閱設備點位
                    HttpWebRequest addWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch_id}/add/");
                    addWatchServiceRequest.Method = "POST";
                    addWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
                    addWatchServiceRequest.PreAuthenticate = true;

                    var subscripFullString = $@"<obj is='obix: WatchIn'>
                                                <list names = 'hrefs'>
                                                    {string.Join(null, subscripStrings)}
                                                </list>
                                            </obj>";
                    byte[] byteArray = Encoding.UTF8.GetBytes(subscripFullString);
                    using (Stream reqStream = addWatchServiceRequest.GetRequestStream())
                    {
                        reqStream.Write(byteArray, 0, byteArray.Length);
                    }

                    HttpWebResponse addWatchServiceResponse = (HttpWebResponse)addWatchServiceRequest.GetResponse();
                    var addWatchServiceResponseContent = new StreamReader(addWatchServiceResponse.GetResponseStream()).ReadToEnd();

                    xmlDocument.LoadXml(addWatchServiceResponseContent);
                    string addWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
                    JObject addWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(addWatchServiceJson);

                    if (addWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
                    {
                        logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】");
                        logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】[錯誤內容]:{0}", addWatchServiceJsonResult);
                        return;
                    }
                    else
                    {
                        logger.LogInformation("【OnTimeDeviceRawDataJob】【設備點位訂閱成功】");
                    }
                    #endregion 訂閱設備點位
                }
                else
                {
                    if (jsonResult.ContainsKey("obj")) //表示可以讀取到內容
                    {
                        List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();

                        var ontimeList = jsonResult["obj"]["list"];
                        if (ontimeList["real"] != null && ontimeList["real"].HasValues)
                        {   //讀取數值型

                            //判斷是否為多筆數值資料
                            var temp_real_count = 0; //用來計算總共有幾個name
                            foreach (var realVal in ontimeList["real"].Children())
                            {
                                var tempKeyValue = realVal.ToString();
                                if (tempKeyValue.Contains("@displayName"))
                                {
                                    temp_real_count++;
                                }
                            }

                            if(temp_real_count > 1)
                            {   //多筆情況
                                foreach (var real in ontimeList["real"])
                                {
                                    var valueSplit = real["@display"].ToString().Split();
                                    var value = valueSplit[0];
                                    var href = real["@href"].ToString();
                                    var hrefSplit = href.Split("/");
                                    var findOutIndex = 0;
                                    var outIndex = 0;
                                    foreach (var tempHref in hrefSplit) //找出out的Index
                                    {
                                        if (tempHref == "out")
                                        {
                                            outIndex = findOutIndex;
                                        }
                                        findOutIndex++;
                                    }

                                    var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
                                    var name = hrefSplit[outIndex - 1];//透過outIndex找出點位

                                    Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
                                    {
                                        { "device_number", device_number},
                                        { "name", name},
                                        { "@value", value},
                                        { "@is_bool", 0},
                                    };

                                    ontimeRawDatas.Add(ontimeRawData);
                                }
                            }
                            else
                            {   //單筆情況
                                var valueSplit = ontimeList["real"]["@display"].ToString().Split();
                                var value = valueSplit[0];
                                var href = ontimeList["real"]["@href"].ToString();
                                var hrefSplit = href.Split("/");
                                var findOutIndex = 0;
                                var outIndex = 0;
                                foreach (var tempHref in hrefSplit) //找出out的Index
                                {
                                    if (tempHref == "out")
                                    {
                                        outIndex = findOutIndex;
                                    }
                                    findOutIndex++;
                                }

                                var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
                                var name = hrefSplit[outIndex - 1];//透過outIndex找出點位

                                Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
                                    {
                                        { "device_number", device_number},
                                        { "name", name},
                                        { "@value", value},
                                        { "@is_bool", 0},
                                    };

                                ontimeRawDatas.Add(ontimeRawData);
                            }
                        }

                        if (ontimeList["bool"] != null && ontimeList["bool"].HasValues)
                        {   //讀取布林型

                            //判斷是否為多筆bool資料
                            var temp_bool_count = 0; //用來計算總共有幾個name
                            foreach (var boolVal in ontimeList["bool"].Children())
                            {
                                var tempKeyValue = boolVal.ToString();
                                if (tempKeyValue.Contains("@displayName"))
                                {
                                    temp_bool_count++;
                                }
                            }
                            if (temp_bool_count > 1)
                            {   //多筆情況
                                foreach (var real in ontimeList["bool"])
                                {
                                    var valueSplit = real["@display"].ToString().Split();
                                    var value = valueSplit[0];
                                    var href = real["@href"].ToString();
                                    var hrefSplit = href.Split("/");
                                    var findOutIndex = 0;
                                    var outIndex = 0;
                                    foreach (var tempHref in hrefSplit) //找出out的Index
                                    {
                                        if (tempHref == "out")
                                        {
                                            outIndex = findOutIndex;
                                        }
                                        findOutIndex++;
                                    }

                                    var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
                                    var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
                                    string finalFacetsValue = null;

                                    //判斷是否有facets
                                    if (ontimeList["str"] != null && ontimeList["str"].HasValues)
                                    {
                                        var has_find = false;
                                        foreach (var facet in ontimeList["str"])
                                        {
                                            var facet_href = facet["@href"].ToString();
                                            var facet_href_split = facet_href.Split("/");
                                            if (facet_href.Contains(device_number) && facet_href_split[facet_href_split.Length - 3] == name)
                                            {   //表示有找到
                                                finalFacetsValue = facet["@display"].ToString();
                                                var facetValueSplit = facet["@display"].ToString().Split(",");
                                                foreach (var facetValue in facetValueSplit)
                                                {
                                                    if (facetValue.Contains(value))
                                                    {
                                                        var tempTextValue = facetValue.Split("=");
                                                        value = tempTextValue[0];

                                                        has_find = true;
                                                        break;
                                                    }
                                                }

                                                if (has_find)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //找出是否有存在facets,如果有則須多加判斷
                                        var sql = $@"SELECT facets FROM ontime_device_rawdata WHERE device_number = @device_number AND name = @name";
                                        var facets = await frontendRepository.GetOneAsync<string>(sql, new { device_number = device_number, name = name });
                                        finalFacetsValue = facets;

                                        if (!string.IsNullOrEmpty(facets))
                                        {
                                            var facetValueSplit = facets.Split(",");
                                            foreach (var facetValue in facetValueSplit)
                                            {
                                                if (facetValue.Contains(value))
                                                {
                                                    var tempTextValue = facetValue.Split("=");
                                                    value = tempTextValue[0];
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
                                    {
                                        { "device_number", device_number},
                                        { "name", name},
                                        { "@value", value},
                                        { "@is_bool", 1},
                                        { "@facets", finalFacetsValue},
                                    };

                                    ontimeRawDatas.Add(ontimeRawData);
                                }
                            }
                            else
                            {   //單筆情況

                                var valueSplit = ontimeList["bool"]["@display"].ToString().Split();
                                var value = valueSplit[0];
                                var href = ontimeList["bool"]["@href"].ToString();
                                var hrefSplit = href.Split("/");
                                var findOutIndex = 0;
                                var outIndex = 0;
                                foreach (var tempHref in hrefSplit) //找出out的Index
                                {
                                    if (tempHref == "out")
                                    {
                                        outIndex = findOutIndex;
                                    }
                                    findOutIndex++;
                                }

                                var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
                                var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
                                string finalFacetsValue = null;

                                //判斷是否有facets
                                if (ontimeList["str"] != null && ontimeList["str"].HasValues)
                                {
                                    var has_find = false;
                                    foreach (var facet in ontimeList["str"])
                                    {
                                        var facet_href = facet["@href"].ToString();
                                        var facet_href_split = facet_href.Split("/");
                                        if (facet_href.Contains(device_number) && facet_href_split[facet_href_split.Length - 3] == name)
                                        {   //表示有找到
                                            finalFacetsValue = facet["@display"].ToString();
                                            var facetValueSplit = facet["@display"].ToString().Split(",");
                                            foreach (var facetValue in facetValueSplit)
                                            {
                                                if (facetValue.Contains(value))
                                                {
                                                    var tempTextValue = facetValue.Split("=");
                                                    value = tempTextValue[0];

                                                    has_find = true;
                                                    break;
                                                }
                                            }

                                            if (has_find)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    //找出是否有存在facets,如果有則須多加判斷
                                    var sql = $@"SELECT facets FROM ontime_device_rawdata WHERE device_number = @device_number AND name = @name";
                                    var facets = await frontendRepository.GetOneAsync<string>(sql, new { device_number = device_number, name = name });
                                    finalFacetsValue = facets;

                                    if (!string.IsNullOrEmpty(facets))
                                    {
                                        var facetValueSplit = facets.Split(",");
                                        foreach (var facetValue in facetValueSplit)
                                        {
                                            if (facetValue.Contains(value))
                                            {
                                                var tempTextValue = facetValue.Split("=");
                                                value = tempTextValue[0];
                                                break;
                                            }
                                        }
                                    }
                                }

                                Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
                                    {
                                        { "device_number", device_number},
                                        { "name", name},
                                        { "@value", value},
                                        { "@is_bool", 1},
                                        { "@facets", finalFacetsValue},
                                    };

                                ontimeRawDatas.Add(ontimeRawData);

                            }
                        }
                        //stopWatch.Stop();
                        //logger.LogInformation("【OnTimeDeviceRawDataJob】【效能檢驗】[解析資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);

                        if (ontimeRawDatas.Count() > 0)
                        {
                            //stopWatch.Reset();
                            //stopWatch.Start();
                            await frontendRepository.UpdateListByCustomTable(ontimeRawDatas, "ontime_device_rawdata", "device_number = @device_number AND name = @name");

                            //stopWatch.Stop();
                            //logger.LogInformation("【OnTimeDeviceRawDataJob】【效能檢驗】[資料存入資料庫花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
                        }
                    }
                }

                logger.LogInformation("【OnTimeDeviceRawDataJob】【任務完成】");
            }
            catch (Exception exception)
            {
                logger.LogError("【OnTimeDeviceRawDataJob】【任務失敗】");
                logger.LogError("【OnTimeDeviceRawDataJob】【任務失敗】[Exception]:{0}", exception.ToString());
            }

        }
    }
}