using Backend.Models;
using BackendWorkerService.Services.Implement;
using Dapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Quartz;
using Repository.BackendRepository.Interface;
using Repository.Helper;
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 BackendWorkerService.Quartz.Jobs
{
    [DisallowConcurrentExecution]
    class ArchiveElectricMeterDayJob : IJob
    {
        private readonly ILogger<ArchiveElectricMeterDayJob> logger;
        private readonly IBackgroundServiceRepository backgroundServiceRepository;
        private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
        protected readonly IDatabaseHelper _databaseHelper;
        private readonly ILogger<Task_Detail> loggers;


        public ArchiveElectricMeterDayJob(
            ILogger<ArchiveElectricMeterDayJob> logger,
            IBackgroundServiceRepository backgroundServiceRepository,
            IBackgroundServiceMsSqlRepository backgroundServiceMySqlRepository,
            IDatabaseHelper databaseHelper, ILogger<Task_Detail> loggers, IBackendRepository backendRepository)
        {
            this.logger = logger;
            this.backgroundServiceRepository = backgroundServiceRepository;
            this.backgroundServiceMsSqlRepository = backgroundServiceMySqlRepository;
            this._databaseHelper = databaseHelper;
            this.loggers = loggers;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            Task_Detail task_Detail = new Task_Detail(loggers, backgroundServiceRepository);
            string device_number = string.Empty;
            try
            {
                if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "All"))
                {
                    await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "All", "任務開始");
                    EDFunction ed = new EDFunction();
                    XmlDocument xmlDocument = new XmlDocument();

                    ServicePointManager.DefaultConnectionLimit = 10;
                    var sqlArchive = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'archiveConfig'";
                    var saveToMSDB = await backgroundServiceRepository.GetOneAsync<string>("select system_value from variable where system_type = 'save_to_ms_db' and deleted = 0");
                    var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
                    var electricMeterGuid = variableArchive.Where(x => x.Name == "ElectricMeterGuid").Select(x => x.Value).FirstOrDefault();
                    var waterMeterGuid = variableArchive.Where(x => x.Name == "WaterMeterGuid").Select(x => x.Value).FirstOrDefault();
                    string station = string.Empty;
                    string tagQuantity = await backgroundServiceRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0;");

                    #region http variable 
                    HttpWebRequest archiveRequest = null;
                    HttpWebResponse archiveResponse = null;
                    string archiveResponseContent = null;
                    string archiveJson = null;
                    JObject archiveJsonResult = new JObject();
                    #endregion
                    #region 找出所有電錶設備
                    var sWhere = "deleted = 0 AND device_name_tag = @sub_system_guid";
                    var electricMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = electricMeterGuid });
                    var waterMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = waterMeterGuid });
                    #endregion 找出所有電錶設備

                    #region 找出所有電錶系統的點位
                    var sPointWhere = "is_needArchive = 1 and deleted = 0 AND device_name_tag = @sub_system_guid";
                    var electricPoints = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = electricMeterGuid });
                    var waterPoints = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = waterMeterGuid });
                    #endregion 找出所有電錶系統的點位

                    #region 組合出所有電錶設備點位
                    List<DeviceNumberPoint> electricDeviceNumberPoints = new List<DeviceNumberPoint>();
                    foreach (var electricMeter in electricMeters)
                    {
                        foreach (var point in electricPoints)
                        {
                            if (electricMeter.device_building_tag == point.device_building_tag)
                            {
                                DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
                                deviceNumberPoint.DeviceNumber = electricMeter.Device_number;
                                deviceNumberPoint.Point = point.points;
                                deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points);
                                deviceNumberPoint.archive_lastDate = electricMeter.archive_lastDate;
                                deviceNumberPoint.created_at = electricMeter.created_at;
                                electricDeviceNumberPoints.Add(deviceNumberPoint);
                            }
                        }
                    }
                    #endregion 組合出所有電錶設備點位
                    #region 組合出所有水錶設備點位
                    List<DeviceNumberPoint> waterDeviceNumberPoints = new List<DeviceNumberPoint>();
                    foreach (var waterMeter in waterMeters)
                    {
                        foreach (var point in waterPoints)
                        {
                            if (waterMeter.device_building_tag == point.device_building_tag)
                            {
                                DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
                                deviceNumberPoint.DeviceNumber = waterMeter.Device_number;
                                deviceNumberPoint.Point = point.points;
                                deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", waterMeter.Device_number, point.points);
                                deviceNumberPoint.archive_lastDate = waterMeter.archive_lastDate;
                                deviceNumberPoint.created_at = waterMeter.created_at;
                                waterDeviceNumberPoints.Add(deviceNumberPoint);
                            }
                        }
                    }
                    #endregion 組合出所有電錶設備點位

                    #region 取得obix 設定
                    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 variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
                    obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
                    obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
                    obixApiConfig.Password = ed.AESDecrypt(variableObix.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));
                    #endregion 取得obix 設定

                    var now = DateTime.Now;
                    #region 天歸檔
                    if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Day"))
                    {
                        try
                        {

                            await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "水電表天任務開始");
                            var preDay = now.AddDays(-1); //取得前一天
                            var dbDateName = preDay.Year.ToString().PadLeft(4, '0') + preDay.Month.ToString().PadLeft(2, '0');

                            //var startTimestamp = string.Format("{0}T00:00:00.000+08:00", preDay.ToString("yyyy-MM-dd"));
                            //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", preDay.ToString("yyyy-MM-dd"));

                            //var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                            //                        <abstime name='start' val='{startTimestamp}' />
                            //                        <abstime name='end' val='{endTimestamp}' />
                            //                        <reltime name='interval' val = 'PT1D' />
                            //                    </obj>";

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

                            #region 從前次 成功日期到昨天為止

                            //抓取每個設備的資料
                            List<Dictionary<string, object>> electericArchiveDayRawDatas = new List<Dictionary<string, object>>();
                            List<Dictionary<string, object>> waterArchiveDayRawDatas = new List<Dictionary<string, object>>();
                            foreach (var deviceNumberPoint in electricDeviceNumberPoints)
                            {
                                var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");
                                var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
                                if (startDay == "0001-01-01") // 假設archive_lastDate為null
                                {
                                    startDay = deviceNumberPoint.created_at.ToString("yyyy-MM-dd");
                                }
                                foreach (DateTime day in EachDay(startDay, endDay))
                                {
                                    var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:15:00的資料
                                    //var sDay = string.Format("{0}T23:59:59.000+08:00", day.AddDays(-1).ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:00:00的資料

                                    var eDay = string.Format("{0}T00:15:00.000+08:00", day.AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T"));


                                    string historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                <abstime name='start' val='{sDay}' />
                                                <abstime name='end' val='{eDay}' />
                                                <reltime name='interval' val = 'PT2D' /> 
                                            </obj>";
                                    device_number = deviceNumberPoint.FullDeviceNumberPoint;
                                    if (tagQuantity.Equals("5"))
                                        station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                                                where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                                                and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                                    else
                                        station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                                                where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                                                device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                                                and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                                                and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                                                and device_point_name = '{device_number.Split("_")[8]}'").Result;
                                    archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                                    //HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                                    archiveRequest.Method = "POST";
                                    archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                                    archiveRequest.PreAuthenticate = true;

                                    byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                                    using (Stream reqStream = archiveRequest.GetRequestStream())
                                    {
                                        reqStream.Write(byteArray, 0, byteArray.Length);
                                    }

                                    archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                                    archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                                    archiveResponse.Dispose();
                                    archiveResponse.Close();

                                    xmlDocument.LoadXml(archiveResponseContent);
                                    archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                                    archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                                    if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                                    {
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);

                                        Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
                                        archiveDayRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                                        archiveDayRawData.Add("@point", deviceNumberPoint.Point);
                                        archiveDayRawData.Add("@start_timestamp", sDay.Replace("T", " ").Substring(0, 19));
                                        archiveDayRawData.Add("@end_timestamp", eDay.Replace("T", " ").Substring(0, 19));
                                        archiveDayRawData.Add("@is_complete", 0);
                                        archiveDayRawData.Add("@repeat_times", 0);
                                        archiveDayRawData.Add("@fail_reason", archiveJson);

                                        archiveDayRawData.Add("@count_rawdata", 0);
                                        archiveDayRawData.Add("@min_rawdata", 0);
                                        archiveDayRawData.Add("@max_rawdata", 0);
                                        archiveDayRawData.Add("@avg_rawdata", 0);
                                        archiveDayRawData.Add("@sum_rawdata", 0);
                                        archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                        electericArchiveDayRawDatas.Add(archiveDayRawData);
                                    }

                                    if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                                    {
                                        var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                                        if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                                        {
                                            electericArchiveDayRawDatas.AddRange(ArrangeRawDatas);
                                        }
                                    }
                                }
                            }
                            foreach (var deviceNumberPoint in waterDeviceNumberPoints)
                            {
                                var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");
                                var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
                                if (startDay == "0001-01-01") // 假設archive_lastDate為null
                                {
                                    startDay = deviceNumberPoint.created_at.ToString("yyyy-MM-dd");
                                }
                                foreach (DateTime day in EachDay(startDay, endDay))
                                {
                                    var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:15:00的資料
                                    //var sDay = string.Format("{0}T23:59:59.000+08:00", day.AddDays(-1).ToString("yyyy-MM-dd").Replace(" ", "T")); // 巨蛋用此時間抓到的實際是T00:00:00的資料

                                    var eDay = string.Format("{0}T00:15:00.000+08:00", day.AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T"));


                                    string historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                <abstime name='start' val='{sDay}' />
                                                <abstime name='end' val='{eDay}' />
                                                <reltime name='interval' val = 'PT2D' /> 
                                            </obj>";

                                    device_number = deviceNumberPoint.FullDeviceNumberPoint;
                                    if (tagQuantity.Equals("5"))
                                        station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                                            where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                                            and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                                    else
                                        station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history 
                                                where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                                                device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                                                and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                                                and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                                                and device_point_name = '{device_number.Split("_")[8]}'").Result;
                                    archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                                    //HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                                    archiveRequest.Method = "POST";
                                    archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                                    archiveRequest.PreAuthenticate = true;


                                    byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                                    using (Stream reqStream = archiveRequest.GetRequestStream())
                                    {
                                        reqStream.Write(byteArray, 0, byteArray.Length);
                                    }

                                    archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                                    archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                                    archiveResponse.Dispose();
                                    archiveResponse.Close();

                                    xmlDocument.LoadXml(archiveResponseContent);
                                    archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                                    archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                                    if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                                    {
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);

                                        Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
                                        archiveDayRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                                        archiveDayRawData.Add("@point", deviceNumberPoint.Point);
                                        archiveDayRawData.Add("@start_timestamp", sDay.Replace("T", " ").Substring(0, 19));
                                        archiveDayRawData.Add("@end_timestamp", eDay.Replace("T", " ").Substring(0, 19));
                                        archiveDayRawData.Add("@is_complete", 0);
                                        archiveDayRawData.Add("@repeat_times", 0);
                                        archiveDayRawData.Add("@fail_reason", archiveJson);

                                        archiveDayRawData.Add("@count_rawdata", 0);
                                        archiveDayRawData.Add("@min_rawdata", 0);
                                        archiveDayRawData.Add("@max_rawdata", 0);
                                        archiveDayRawData.Add("@avg_rawdata", 0);
                                        archiveDayRawData.Add("@sum_rawdata", 0);
                                        archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                        waterArchiveDayRawDatas.Add(archiveDayRawData);
                                    }

                                    if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                                    {
                                        var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                                        if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                                        {
                                            waterArchiveDayRawDatas.AddRange(ArrangeRawDatas);
                                        }
                                    }
                                }
                            }

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

                            if (electericArchiveDayRawDatas.Count() > 0)
                            {
                                foreach (var row in electericArchiveDayRawDatas)
                                {
                                    row.TryGetValue("@start_timestamp", out var yyyymmData);
                                    dbDateName = System.DateTime.Parse(yyyymmData.ToString()).ToString("yyyyMM");
                                    var sql = $@"CREATE TABLE IF NOT EXISTS `archive_electric_water_meter_day_{dbDateName}`  (
                                                     `device_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                                     `point` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                                     `start_timestamp` datetime(6) NOT NULL,
                                                     `end_timestamp` datetime(6) NULL DEFAULT NULL,
                                                     `count_rawdata` int(11) NULL DEFAULT NULL,
                                                     `min_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                                     `max_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                                     `sub_result` decimal(15, 3) NULL DEFAULT NULL,
                                                     `avg_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                                     `sum_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                                     `is_complete` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '是否完成,0:未完成 1:完成',
                                                     `repeat_times` int(11) NULL DEFAULT 0 COMMENT '重複次數',
                                                     `fail_reason` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '失敗原因',
                                                     `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                                                     `updated_at` datetime(6) NULL DEFAULT NULL,
                                                     PRIMARY KEY (`device_number`, `point`, `start_timestamp`) USING BTREE
                                                   ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

                                                   SET FOREIGN_KEY_CHECKS = 1;
                                                   UPDATE archive_electric_water_meter_day_{dbDateName} SET 
                                                           count_rawdata = @count_rawdata,
                                                           min_rawdata = @min_rawdata,
                                                           max_rawdata = @max_rawdata,
                                                           sub_result = @max_rawdata - @min_rawdata,
                                                           avg_rawdata = @avg_rawdata,
                                                           sum_rawdata = @sum_rawdata,
                                                           is_complete = @is_complete,
                                                           repeat_times = @repeat_times,
                                                           fail_reason = @fail_reason,
                                                           updated_at = @updated_at
                                                        WHERE device_number = @device_number
                                                           AND point = @point
                                                           AND start_timestamp = @start_timestamp;

                                                   INSERT INTO archive_electric_water_meter_day_{dbDateName} (
                                                       device_number,
                                                       point,
                                                       start_timestamp,
                                                       end_timestamp,
                                                       count_rawdata,
                                                       min_rawdata,
                                                       max_rawdata,
                                                       sub_result,
                                                       avg_rawdata,
                                                       sum_rawdata,
                                                       is_complete,
                                                       repeat_times,
                                                       fail_reason)
                                                   SELECT 
                                                       @device_number,
                                                       @point,
                                                       @start_timestamp,
                                                       @end_timestamp,
                                                       @count_rawdata,
                                                       @min_rawdata,
                                                       @max_rawdata,
                                                       @max_rawdata - @min_rawdata,
                                                       @avg_rawdata,
                                                       @sum_rawdata,
                                                       @is_complete,
                                                       @repeat_times,
                                                       @fail_reason
                                                   WHERE ROW_COUNT() = 0;
                            update device set archive_lastDate = @start_timestamp, archive_lastActionDate = @updated_at 
                            where device_number = @device_number;";      //archive_lastDate 前次完成時間 ,archive_lastActionDate 本次作業時間

                                    var mySql = $@"BEGIN TRANSACTION;
                                                   IF OBJECT_ID(N'dbo.archive_electric_water_meter_day_{dbDateName}', N'U') is null
                                                   BEGIN
                                                       CREATE TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}](
                                                        [device_number] [varchar](50) NOT NULL,
                                                        [point] [varchar](20) NOT NULL,
                                                        [start_timestamp] [datetime] NOT NULL,
                                                        [end_timestamp] [datetime] NULL,
                                                        [count_rawdata] [int] NULL,
                                                        [min_rawdata] [decimal](15, 3) NULL,
                                                        [max_rawdata] [decimal](15, 3) NULL,
                                                           [sub_result] [decimal](15, 3) NULL,
                                                        [avg_rawdata] [decimal](15, 3) NULL,
                                                        [sum_rawdata] [decimal](15, 3) NULL,
                                                        [is_complete] [tinyint] NULL,
                                                        [repeat_times] [int] NULL,
                                                        [fail_reason] [nvarchar](max) NULL,
                                                        [created_at] [datetime] NULL,
                                                        [updated_at] [datetime] NULL,
                                                        CONSTRAINT [PK_archive_electric_water_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED 
                                                       (
                                                        [device_number] ASC,
                                                        [point] ASC,
                                                        [start_timestamp] ASC
                                                       )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                                                       ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

                                                       ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_repeat_times]  DEFAULT ((0)) FOR [repeat_times]

                                                       ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_created_at]  DEFAULT (getdate()) FOR [created_at]

                                                       ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_updated_at]  DEFAULT (NULL) FOR [updated_at]

                                                       EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete'

                                                       EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times'

                                                       EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason'
                                                   END

                                                   UPDATE archive_electric_water_meter_day_{dbDateName} SET 
                                                           count_rawdata = @count_rawdata,
                                                           min_rawdata = @min_rawdata,
                                                           max_rawdata = @max_rawdata,
                                                           sub_result = @max_rawdata - @min_rawdata,
                                                           avg_rawdata = @avg_rawdata,
                                                           sum_rawdata = @sum_rawdata,
                                                           is_complete = @is_complete,
                                                           repeat_times = @repeat_times,
                                                           fail_reason = @fail_reason,
                                                           updated_at = @updated_at
                                                        WHERE device_number = @device_number
                                                           AND point = @point
                                                           AND start_timestamp = @start_timestamp;

                                                   IF @@ROWCOUNT = 0
                                                   BEGIN
                                                       INSERT INTO archive_electric_water_meter_day_{dbDateName} (
                                                           device_number,
                                                           point,
                                                           start_timestamp,
                                                           end_timestamp,
                                                           count_rawdata,
                                                           min_rawdata,
                                                           max_rawdata,
                                                           sub_result,
                                                           avg_rawdata,
                                                           sum_rawdata,
                                                           is_complete,
                                                           repeat_times,
                                                           fail_reason)
                                                       VALUES (
                                                           @device_number,
                                                           @point,
                                                           @start_timestamp,
                                                           @end_timestamp,
                                                           @count_rawdata,
                                                           @min_rawdata,
                                                           @max_rawdata,
                                                           @max_rawdata - @min_rawdata,
                                                           @avg_rawdata,
                                                           @sum_rawdata,
                                                           @is_complete,
                                                           @repeat_times,
                                                           @fail_reason)
                                                   END

                                               COMMIT TRANSACTION;";
                                    await backgroundServiceRepository.ExecuteSql(sql, row);
                                    if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                                    {
                                        await backgroundServiceMsSqlRepository.ExecuteSql(mySql, row);
                                    }
                                }
                            }
                            if (waterArchiveDayRawDatas.Count() > 0)
                            {
                                foreach (var row in waterArchiveDayRawDatas)
                                {
                                    row.TryGetValue("@start_timestamp", out var yyyymmData);
                                    dbDateName = System.DateTime.Parse(yyyymmData.ToString()).ToString("yyyyMM");
                                    var sql = $@"
                                            CREATE TABLE IF NOT EXISTS `archive_electric_water_meter_day_{dbDateName}`  (
                                              `device_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `point` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `start_timestamp` datetime(6) NOT NULL,
                                              `end_timestamp` datetime(6) NULL DEFAULT NULL,
                                              `count_rawdata` int(11) NULL DEFAULT NULL,
                                              `min_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `max_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sub_result` decimal(15, 3) NULL DEFAULT NULL,
                                              `avg_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sum_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `is_complete` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '是否完成,0:未完成 1:完成',
                                              `repeat_times` int(11) NULL DEFAULT 0 COMMENT '重複次數',
                                              `fail_reason` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '失敗原因',
                                              `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                                              `updated_at` datetime(6) NULL DEFAULT NULL,
                                              PRIMARY KEY (`device_number`, `point`, `start_timestamp`) USING BTREE
                                            ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

                                            UPDATE archive_electric_water_meter_day_{dbDateName} SET 
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;


                                            INSERT INTO archive_electric_water_meter_day_{dbDateName} (
                                                device_number,
                                                point,
                                                start_timestamp,
                                                end_timestamp,
                                                count_rawdata,
                                                min_rawdata,
                                                max_rawdata,
                                                sub_result,
                                                avg_rawdata,
                                                sum_rawdata,
                                                is_complete,
                                                repeat_times,
                                                fail_reason)
                                            SELECT 
                                                @device_number,
                                                @point,
                                                @start_timestamp,
                                                @end_timestamp,
                                                @count_rawdata,
                                                @min_rawdata,
                                                @max_rawdata,
                                                @max_rawdata - @min_rawdata,
                                                @avg_rawdata,
                                                @sum_rawdata,
                                                @is_complete,
                                                @repeat_times,
                                                @fail_reason
                                            WHERE ROW_COUNT() = 0;
                     update device set archive_lastDate = @start_timestamp, archive_lastActionDate = @updated_at 
                     where device_number = @device_number;";   //archive_lastDate 前次完成時間 ,archive_lastActionDate 本次作業時間

                                    var mySql = $@"BEGIN TRANSACTION;
                                            IF OBJECT_ID(N'dbo.archive_electric_water_meter_day_{dbDateName}', N'U') is null
                                            BEGIN
                                                CREATE TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}](
                                                 [device_number] [varchar](50) NOT NULL,
                                                 [point] [varchar](20) NOT NULL,
                                                 [start_timestamp] [datetime] NOT NULL,
                                                 [end_timestamp] [datetime] NULL,
                                                 [count_rawdata] [int] NULL,
                                                 [min_rawdata] [decimal](15, 3) NULL,
                                                 [max_rawdata] [decimal](15, 3) NULL,
                                                    [sub_result] [decimal](15, 3) NULL,
                                                 [avg_rawdata] [decimal](15, 3) NULL,
                                                 [sum_rawdata] [decimal](15, 3) NULL,
                                                 [is_complete] [tinyint] NULL,
                                                 [repeat_times] [int] NULL,
                                                 [fail_reason] [nvarchar](max) NULL,
                                                 [created_at] [datetime] NULL,
                                                 [updated_at] [datetime] NULL,
                                                 CONSTRAINT [PK_archive_electric_water_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED 
                                                (
                                                 [device_number] ASC,
                                                 [point] ASC,
                                                 [start_timestamp] ASC
                                                )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                                                ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_repeat_times]  DEFAULT ((0)) FOR [repeat_times]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_created_at]  DEFAULT (getdate()) FOR [created_at]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_day_{dbDateName}] ADD  CONSTRAINT [DF_archive_electric_water_meter_day_{dbDateName}_updated_at]  DEFAULT (NULL) FOR [updated_at]

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason'
                                            END

                                            UPDATE archive_electric_water_meter_day_{dbDateName} SET 
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;

                                            IF @@ROWCOUNT = 0
                                            BEGIN
                                                INSERT INTO archive_electric_water_meter_day_{dbDateName} (
                                                    device_number,
                                                    point,
                                                    start_timestamp,
                                                    end_timestamp,
                                                    count_rawdata,
                                                    min_rawdata,
                                                    max_rawdata,
                                                    sub_result,
                                                    avg_rawdata,
                                                    sum_rawdata,
                                                    is_complete,
                                                    repeat_times,
                                                    fail_reason)
                                                VALUES (
                                                    @device_number,
                                                    @point,
                                                    @start_timestamp,
                                                    @end_timestamp,
                                                    @count_rawdata,
                                                    @min_rawdata,
                                                    @max_rawdata,
                                                    @max_rawdata - @min_rawdata,
                                                    @avg_rawdata,
                                                    @sum_rawdata,
                                                    @is_complete,
                                                    @repeat_times,
                                                    @fail_reason)
                                            END

                                        COMMIT TRANSACTION;";
                                    await backgroundServiceRepository.ExecuteSql(sql, row);
                                    if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                                    {
                                        await backgroundServiceMsSqlRepository.ExecuteSql(mySql, row);
                                    }
                                }
                            }
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Day", "水電表天任務完成");
                        }
                        catch (Exception exception)
                        {
                            await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Day", exception.ToString());
                            logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】");
                            logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】[Exception]:{0}, {1}", exception.ToString(), "device_number = " + device_number);
                            logger.LogError(await backgroundServiceMsSqlRepository.GetDbAllString());
                        }
                        finally
                        {
                            if (archiveResponse != null)
                            {
                                archiveResponse.Dispose();
                                archiveResponse.Close();
                            }
                        }
                    }
                    #endregion 天歸檔

                    #region 週歸檔
                    //if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Week"))
                    //{
                    //    try
                    //    {
                    //        await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Week", "水電表周任務開始");
                    //        int week = Convert.ToInt32(now.DayOfWeek);
                    //        week = week == 0 ? 7 : week;

                    //        var startTimestamp = string.Format("{0}T00:00:00.000+08:00", now.AddDays(1 - week).ToString("yyyy-MM-dd"));
                    //        var endTimestamp = string.Format("{0}T23:59:59.000+08:00", now.AddDays(7 - week).ToString("yyyy-MM-dd"));

                    //        var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                    //                                <abstime name='start' val='{startTimestamp}' />
                    //                                <abstime name='end' val='{endTimestamp}' />
                    //                                <reltime name='interval' val = 'PT7D' />
                    //                            </obj>";

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

                    //        //抓取每個設備的資料
                    //        List<Dictionary<string, object>> electricArchiveWeekRawDatas = new List<Dictionary<string, object>>();
                    //        List<Dictionary<string, object>> waterArchiveWeekRawDatas = new List<Dictionary<string, object>>();
                    //        foreach (var deviceNumberPoint in electricDeviceNumberPoints)
                    //        {
                    //            if (tagQuantity.Equals("5"))
                    //                station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                    //                            where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                    //                            and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                    //            else
                    //                station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history 
                    //                            where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                    //                            device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                    //                            and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                    //                            and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                    //                            and device_point_name = '{device_number.Split("_")[8]}'").Result;
                    //            device_number = deviceNumberPoint.FullDeviceNumberPoint;
                    //            archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                    //            //HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                    //            archiveRequest.Method = "POST";
                    //            archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                    //            archiveRequest.PreAuthenticate = true;


                    //            byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                    //            using (Stream reqStream = archiveRequest.GetRequestStream())
                    //            {
                    //                reqStream.Write(byteArray, 0, byteArray.Length);
                    //            }

                    //            archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                    //            archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                    //            archiveResponse.Dispose();
                    //            archiveResponse.Close();

                    //            xmlDocument.LoadXml(archiveResponseContent);
                    //            archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                    //            archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                    //            if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                    //            {
                    //                //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
                    //                //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);

                    //                Dictionary<string, object> archiveWeekRawData = new Dictionary<string, object>();
                    //                archiveWeekRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                    //                archiveWeekRawData.Add("@point", deviceNumberPoint.Point);
                    //                archiveWeekRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
                    //                archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
                    //                archiveWeekRawData.Add("@is_complete", 0);
                    //                archiveWeekRawData.Add("@repeat_times", 0);
                    //                archiveWeekRawData.Add("@fail_reason", archiveJson);

                    //                archiveWeekRawData.Add("@count_rawdata", 0);
                    //                archiveWeekRawData.Add("@min_rawdata", 0);
                    //                archiveWeekRawData.Add("@max_rawdata", 0);
                    //                archiveWeekRawData.Add("@avg_rawdata", 0);
                    //                archiveWeekRawData.Add("@sum_rawdata", 0);
                    //                archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                    //                electricArchiveWeekRawDatas.Add(archiveWeekRawData);
                    //            }

                    //            if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                    //            {
                    //                var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                    //                if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                    //                {
                    //                    electricArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
                    //                }
                    //            }
                    //        }
                    //        foreach (var deviceNumberPoint in waterDeviceNumberPoints)
                    //        {
                    //            device_number = deviceNumberPoint.FullDeviceNumberPoint;
                    //            if (tagQuantity.Equals("5"))
                    //                station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                    //                            where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                    //                            and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                    //            else
                    //                station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                    //                            where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                    //                            device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                    //                            and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                    //                            and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                    //                            and device_point_name = '{device_number.Split("_")[8]}'").Result;
                    //            archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                    //            //HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                    //            archiveRequest.Method = "POST";
                    //            archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                    //            archiveRequest.PreAuthenticate = true;

                    //            byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                    //            using (Stream reqStream = archiveRequest.GetRequestStream())
                    //            {
                    //                reqStream.Write(byteArray, 0, byteArray.Length);
                    //            }

                    //            archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                    //            archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                    //            archiveResponse.Dispose();
                    //            archiveResponse.Close();

                    //            xmlDocument.LoadXml(archiveResponseContent);
                    //            archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                    //            archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                    //            if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                    //            {
                    //                //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
                    //                //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);

                    //                Dictionary<string, object> archiveWeekRawData = new Dictionary<string, object>();
                    //                archiveWeekRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                    //                archiveWeekRawData.Add("@point", deviceNumberPoint.Point);
                    //                archiveWeekRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
                    //                archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
                    //                archiveWeekRawData.Add("@is_complete", 0);
                    //                archiveWeekRawData.Add("@repeat_times", 0);
                    //                archiveWeekRawData.Add("@fail_reason", archiveJson);

                    //                archiveWeekRawData.Add("@count_rawdata", 0);
                    //                archiveWeekRawData.Add("@min_rawdata", 0);
                    //                archiveWeekRawData.Add("@max_rawdata", 0);
                    //                archiveWeekRawData.Add("@avg_rawdata", 0);
                    //                archiveWeekRawData.Add("@sum_rawdata", 0);
                    //                archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                    //                waterArchiveWeekRawDatas.Add(archiveWeekRawData);
                    //            }

                    //            if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                    //            {
                    //                var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                    //                if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                    //                {
                    //                    waterArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
                    //                }
                    //            }
                    //        }

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

                    //        if (electricArchiveWeekRawDatas.Count() > 0)
                    //        {
                    //            var sql = $@"

                    //                        UPDATE archive_electric_water_meter_week SET 
                    //                                count_rawdata = @count_rawdata,
                    //                                min_rawdata = @min_rawdata,
                    //                                max_rawdata = @max_rawdata,
                    //                                sub_result = @max_rawdata - @min_rawdata,
                    //                                avg_rawdata = @avg_rawdata,
                    //                                sum_rawdata = @sum_rawdata,
                    //                                is_complete = @is_complete,
                    //                                repeat_times = @repeat_times,
                    //                                fail_reason = @fail_reason,
                    //                                updated_at = @updated_at
                    //                             WHERE device_number = @device_number
                    //                                AND point = @point
                    //                                AND start_timestamp = @start_timestamp;


                    //                            INSERT INTO archive_electric_water_meter_week (
                    //                                device_number,
                    //                                point,
                    //                                start_timestamp,
                    //                                end_timestamp,
                    //                                count_rawdata,
                    //                                min_rawdata,
                    //                                max_rawdata,
                    //                                sub_result,
                    //                                avg_rawdata,
                    //                                sum_rawdata,
                    //                                is_complete,
                    //                                repeat_times,
                    //                                fail_reason)
                    //                            SELECT 
                    //                                @device_number,
                    //                                @point,
                    //                                @start_timestamp,
                    //                                @end_timestamp,
                    //                                @count_rawdata,
                    //                                @min_rawdata,
                    //                                @max_rawdata,
                    //                                @max_rawdata - @min_rawdata,
                    //                                @avg_rawdata,
                    //                                @sum_rawdata,
                    //                                @is_complete,
                    //                                @repeat_times,
                    //                                @fail_reason
                    //                            WHERE ROW_COUNT() = 0;
                    //                            ";

                    //            var mySql = $@"BEGIN TRANSACTION;

                    //                        UPDATE archive_electric_water_meter_week SET 
                    //                                count_rawdata = @count_rawdata,
                    //                                min_rawdata = @min_rawdata,
                    //                                max_rawdata = @max_rawdata,
                    //                                sub_result = @max_rawdata - @min_rawdata,
                    //                                avg_rawdata = @avg_rawdata,
                    //                                sum_rawdata = @sum_rawdata,
                    //                                is_complete = @is_complete,
                    //                                repeat_times = @repeat_times,
                    //                                fail_reason = @fail_reason,
                    //                                updated_at = @updated_at
                    //                             WHERE device_number = @device_number
                    //                                AND point = @point
                    //                                AND start_timestamp = @start_timestamp;

                    //                        IF @@ROWCOUNT = 0
                    //                        BEGIN
                    //                            INSERT INTO archive_electric_water_meter_week (
                    //                                device_number,
                    //                                point,
                    //                                start_timestamp,
                    //                                end_timestamp,
                    //                                count_rawdata,
                    //                                min_rawdata,
                    //                                max_rawdata,
                    //                                sub_result,
                    //                                avg_rawdata,
                    //                                sum_rawdata,
                    //                                is_complete,
                    //                                repeat_times,
                    //                                fail_reason)
                    //                            VALUES (
                    //                                @device_number,
                    //                                @point,
                    //                                @start_timestamp,
                    //                                @end_timestamp,
                    //                                @count_rawdata,
                    //                                @min_rawdata,
                    //                                @max_rawdata,
                    //                                @max_rawdata - @min_rawdata,
                    //                                @avg_rawdata,
                    //                                @sum_rawdata,
                    //                                @is_complete,
                    //                                @repeat_times,
                    //                                @fail_reason)
                    //                        END

                    //                    COMMIT TRANSACTION;";
                    //            await backgroundServiceRepository.ExecuteSql(sql, electricArchiveWeekRawDatas);
                    //            if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                    //            {
                    //                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electricArchiveWeekRawDatas);
                    //            }

                    //        }
                    //        if (waterArchiveWeekRawDatas.Count() > 0)
                    //        {
                    //            var sql = $@"

                    //                        UPDATE archive_electric_water_meter_week SET 
                    //                                count_rawdata = @count_rawdata,
                    //                                min_rawdata = @min_rawdata,
                    //                                max_rawdata = @max_rawdata,
                    //                                sub_result = @max_rawdata - @min_rawdata,
                    //                                avg_rawdata = @avg_rawdata,
                    //                                sum_rawdata = @sum_rawdata,
                    //                                is_complete = @is_complete,
                    //                                repeat_times = @repeat_times,
                    //                                fail_reason = @fail_reason,
                    //                                updated_at = @updated_at
                    //                             WHERE device_number = @device_number
                    //                                AND point = @point
                    //                                AND start_timestamp = @start_timestamp;


                    //                            INSERT INTO archive_electric_water_meter_week (
                    //                                device_number,
                    //                                point,
                    //                                start_timestamp,
                    //                                end_timestamp,
                    //                                count_rawdata,
                    //                                min_rawdata,
                    //                                max_rawdata,
                    //                                sub_result,
                    //                                avg_rawdata,
                    //                                sum_rawdata,
                    //                                is_complete,
                    //                                repeat_times,
                    //                                fail_reason)
                    //                            SELECT 
                    //                                @device_number,
                    //                                @point,
                    //                                @start_timestamp,
                    //                                @end_timestamp,
                    //                                @count_rawdata,
                    //                                @min_rawdata,
                    //                                @max_rawdata,
                    //                                @max_rawdata - @min_rawdata,
                    //                                @avg_rawdata,
                    //                                @sum_rawdata,
                    //                                @is_complete,
                    //                                @repeat_times,
                    //                                @fail_reason
                    //                            WHERE ROW_COUNT() = 0;
                    //                            ";

                    //            var mySql = $@"BEGIN TRANSACTION;

                    //                        UPDATE archive_electric_water_meter_week SET 
                    //                                count_rawdata = @count_rawdata,
                    //                                min_rawdata = @min_rawdata,
                    //                                max_rawdata = @max_rawdata,
                    //                                sub_result = @max_rawdata - @min_rawdata,
                    //                                avg_rawdata = @avg_rawdata,
                    //                                sum_rawdata = @sum_rawdata,
                    //                                is_complete = @is_complete,
                    //                                repeat_times = @repeat_times,
                    //                                fail_reason = @fail_reason,
                    //                                updated_at = @updated_at
                    //                             WHERE device_number = @device_number
                    //                                AND point = @point
                    //                                AND start_timestamp = @start_timestamp;

                    //                        IF @@ROWCOUNT = 0
                    //                        BEGIN
                    //                            INSERT INTO archive_electric_water_meter_week (
                    //                                device_number,
                    //                                point,
                    //                                start_timestamp,
                    //                                end_timestamp,
                    //                                count_rawdata,
                    //                                min_rawdata,
                    //                                max_rawdata,
                    //                                sub_result,
                    //                                avg_rawdata,
                    //                                sum_rawdata,
                    //                                is_complete,
                    //                                repeat_times,
                    //                                fail_reason)
                    //                            VALUES (
                    //                                @device_number,
                    //                                @point,
                    //                                @start_timestamp,
                    //                                @end_timestamp,
                    //                                @count_rawdata,
                    //                                @min_rawdata,
                    //                                @max_rawdata,
                    //                                @max_rawdata - @min_rawdata,
                    //                                @avg_rawdata,
                    //                                @sum_rawdata,
                    //                                @is_complete,
                    //                                @repeat_times,
                    //                                @fail_reason)
                    //                        END

                    //                    COMMIT TRANSACTION;";
                    //            await backgroundServiceRepository.ExecuteSql(sql, waterArchiveWeekRawDatas);
                    //            if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                    //            {
                    //                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveWeekRawDatas);
                    //            }
                    //        }
                    //        await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Week", "任務完成");
                    //    }
                    //    catch (Exception exception)
                    //    {
                    //        await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Week", exception.ToString());
                    //        logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】");
                    //        logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
                    //    }
                    //    finally
                    //    {
                    //        if (archiveResponse != null)
                    //        {
                    //            archiveResponse.Dispose();
                    //            archiveResponse.Close();
                    //        }
                    //    }
                    //}
                    #endregion 週歸檔

                    #region 月歸檔
                    if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Month"))
                    {
                        try
                        {
                            await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "水電表月任務開始");

                            string startTimestamp = "";
                            string endTimestamp = "";
                            string historyQueryFilter = "";

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

                            //抓取每個設備的資料
                            List<Dictionary<string, object>> electricArchiveMonthRawDatas = new List<Dictionary<string, object>>();
                            List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
                            foreach (var deviceNumberPoint in electricDeviceNumberPoints)
                            {
                                var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");

                                var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");

                                foreach (DateTime day in EachMonth(startDay, endDay))
                                {
                                    if (day.ToString("yyyy-MM") == System.DateTime.Now.AddDays(-1).ToString("yyyy-MM"))
                                    {
                                        var preDay = now.AddDays(-1); //取得前一天

                                        var dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month);
                                        var FirstDay = new DateTime(preDay.Year, preDay.Month, 1);
                                        //var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day);  // 這是抓到該月最後一天
                                        var LastDay = now;

                                        //var startTimestamp = string.Format("{0}T23:59:59.000+08:00", FirstDay.AddDays(-1).ToString("yyyy-MM-dd")); // 巨蛋要這樣抓數據才是對的
                                        startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));

                                        //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd"));
                                        endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); // 240131 jay for dome


                                        historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                    <abstime name='start' val='{startTimestamp}' />
                                                    <abstime name='end' val='{endTimestamp}' />
                                                    <reltime name='interval' val = 'PT{dayInMonth + 1}D' />
                                                </obj>";

                                    }
                                    else
                                    {
                                        var dayInMonth = DateTime.DaysInMonth(day.Year, day.Month);
                                        var FirstDay = new DateTime(day.Year, day.Month, 1);
                                        var LastDay = new DateTime(day.Year, day.Month, dayInMonth);

                                        startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));

                                        endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd"));
                                        historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                    <abstime name='start' val='{startTimestamp}' />
                                                    <abstime name='end' val='{endTimestamp}' />
                                                    <reltime name='interval' val = 'PT{dayInMonth + 1}D' />
                                                </obj>";
                                    }

                                    device_number = deviceNumberPoint.FullDeviceNumberPoint;
                                    if (tagQuantity.Equals("5"))
                                        station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                                                where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                                                and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                                    else
                                        station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history 
                                                where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                                                device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                                                and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                                                and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                                                and device_point_name = '{device_number.Split("_")[8]}'").Result;
                                    archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                                    //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                                    archiveRequest.Method = "POST";
                                    archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                                    archiveRequest.PreAuthenticate = true;

                                    byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                                    using (Stream reqStream = archiveRequest.GetRequestStream())
                                    {
                                        reqStream.Write(byteArray, 0, byteArray.Length);
                                    }

                                    archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                                    archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                                    archiveResponse.Dispose();
                                    archiveResponse.Close();

                                    xmlDocument.LoadXml(archiveResponseContent);
                                    archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                                    archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                                    if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                                    {
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);

                                        Dictionary<string, object> archiveMonthRawData = new Dictionary<string, object>();
                                        archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                                        archiveMonthRawData.Add("@point", deviceNumberPoint.Point);
                                        archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
                                        archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
                                        archiveMonthRawData.Add("@is_complete", 0);
                                        archiveMonthRawData.Add("@repeat_times", 0);
                                        archiveMonthRawData.Add("@fail_reason", archiveJson);

                                        archiveMonthRawData.Add("@count_rawdata", 0);
                                        archiveMonthRawData.Add("@min_rawdata", 0);
                                        archiveMonthRawData.Add("@max_rawdata", 0);
                                        archiveMonthRawData.Add("@avg_rawdata", 0);
                                        archiveMonthRawData.Add("@sum_rawdata", 0);
                                        archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                        electricArchiveMonthRawDatas.Add(archiveMonthRawData);
                                    }

                                    if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                                    {
                                        var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                                        if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                                        {
                                            electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
                                        }
                                    }
                                }
                            }
                            foreach (var deviceNumberPoint in waterDeviceNumberPoints)
                            {
                                var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");

                                var endDay = System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");

                                foreach (DateTime day in EachMonth(startDay, endDay))
                                {
                                    if (day.ToString("yyyy-MM") == System.DateTime.Now.AddDays(-1).ToString("yyyy-MM"))
                                    {
                                        var preDay = now.AddDays(-1); //取得前一天

                                        var dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month);
                                        var FirstDay = new DateTime(preDay.Year, preDay.Month, 1);
                                        //var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day);  // 這是抓到該月最後一天
                                        var LastDay = now;

                                        //var startTimestamp = string.Format("{0}T23:59:59.000+08:00", FirstDay.AddDays(-1).ToString("yyyy-MM-dd")); // 巨蛋要這樣抓數據才是對的
                                        startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));

                                        //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd"));
                                        endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd")); // 240131 jay for dome


                                        historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                    <abstime name='start' val='{startTimestamp}' />
                                                    <abstime name='end' val='{endTimestamp}' />
                                                    <reltime name='interval' val = 'PT{dayInMonth + 1}D' />
                                                </obj>";

                                    }
                                    else
                                    {
                                        var dayInMonth = DateTime.DaysInMonth(day.Year, day.Month);
                                        var FirstDay = new DateTime(day.Year, day.Month, 1);
                                        var LastDay = new DateTime(day.Year, day.Month, dayInMonth);

                                        startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));

                                        endTimestamp = string.Format("{0}T00:15:00.000+08:00", LastDay.ToString("yyyy-MM-dd"));
                                        historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
                                                    <abstime name='start' val='{startTimestamp}' />
                                                    <abstime name='end' val='{endTimestamp}' />
                                                    <reltime name='interval' val = 'PT{dayInMonth + 1}D' />
                                                </obj>";
                                    }
                                    device_number = deviceNumberPoint.FullDeviceNumberPoint;
                                    if (tagQuantity.Equals("5"))
                                        station = await backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history
                                                where device_building_tag = '{device_number.Split("_")[0]}' and device_floor_tag = '{device_number.Split("_")[2]}' 
                                                and device_name_tag = '{device_number.Split("_")[1]}' and device_point_name = '{device_number.Split("_")[5]}'");
                                    else
                                        station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history 
                                                where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and 
                                                device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}' 
                                                and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}' 
                                                and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
                                                and device_point_name = '{device_number.Split("_")[8]}'").Result;
                                    archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
                                    //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
                                    archiveRequest.Method = "POST";
                                    archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
                                    archiveRequest.PreAuthenticate = true;


                                    byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
                                    using (Stream reqStream = archiveRequest.GetRequestStream())
                                    {
                                        reqStream.Write(byteArray, 0, byteArray.Length);
                                    }

                                    archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
                                    archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
                                    archiveResponse.Dispose();
                                    archiveResponse.Close();

                                    xmlDocument.LoadXml(archiveResponseContent);
                                    archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
                                    archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);

                                    if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
                                    {
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
                                        //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);

                                        Dictionary<string, object> archiveMonthRawData = new Dictionary<string, object>();
                                        archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                                        archiveMonthRawData.Add("@point", deviceNumberPoint.Point);
                                        archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
                                        archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
                                        archiveMonthRawData.Add("@is_complete", 0);
                                        archiveMonthRawData.Add("@repeat_times", 0);
                                        archiveMonthRawData.Add("@fail_reason", archiveJson);

                                        archiveMonthRawData.Add("@count_rawdata", 0);
                                        archiveMonthRawData.Add("@min_rawdata", 0);
                                        archiveMonthRawData.Add("@max_rawdata", 0);
                                        archiveMonthRawData.Add("@avg_rawdata", 0);
                                        archiveMonthRawData.Add("@sum_rawdata", 0);
                                        archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                                        waterArchiveMonthRawDatas.Add(archiveMonthRawData);
                                    }

                                    if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
                                    {
                                        var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
                                        if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
                                        {
                                            waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
                                        }
                                    }
                                }
                            }

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

                            if (electricArchiveMonthRawDatas.Count() > 0)
                            {
                                var sql = $@"
                                               CREATE TABLE IF NOT EXISTS `archive_electric_water_meter_month`  (
                                              `device_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `point` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `start_timestamp` datetime(6) NOT NULL,
                                              `end_timestamp` datetime(6) NULL DEFAULT NULL,
                                              `count_rawdata` int(11) NULL DEFAULT NULL,
                                              `min_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `max_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sub_result` decimal(15, 3) NULL DEFAULT NULL,
                                              `avg_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sum_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `is_complete` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '是否完成,0:未完成 1:完成',
                                              `repeat_times` int(11) NULL DEFAULT 0 COMMENT '重複次數',
                                              `fail_reason` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '失敗原因',
                                              `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                                              `updated_at` datetime(6) NULL DEFAULT NULL,
                                              PRIMARY KEY (`device_number`, `point`, `start_timestamp`) USING BTREE
                                            ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

                                            SET FOREIGN_KEY_CHECKS = 1;
                                            UPDATE archive_electric_water_meter_month SET 
                                                    start_timestamp = @start_timestamp,
                                                    end_timestamp = @end_timestamp,
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;

                                                INSERT INTO archive_electric_water_meter_month (
                                                    device_number,
                                                    point,
                                                    start_timestamp,
                                                    end_timestamp,
                                                    count_rawdata,
                                                    min_rawdata,
                                                    max_rawdata,
                                                    sub_result,
                                                    avg_rawdata,
                                                    sum_rawdata,
                                                    is_complete,
                                                    repeat_times,
                                                    fail_reason)
                                                SELECT
                                                    @device_number,
                                                    @point,
                                                    @start_timestamp,
                                                    @end_timestamp,
                                                    @count_rawdata,
                                                    @min_rawdata,
                                                    @max_rawdata,
                                                    @max_rawdata - @min_rawdata,
                                                    @avg_rawdata,
                                                    @sum_rawdata,
                                                    @is_complete,
                                                    @repeat_times,
                                                    @fail_reason
                                                WHERE ROW_COUNT() = 0;";

                                var mySql = $@"BEGIN TRANSACTION;
                                            IF OBJECT_ID(N'dbo.archive_electric_water_meter_month', N'U') is null
                                            BEGIN
                                                CREATE TABLE [dbo].[archive_electric_water_meter_month](
                                                 [device_number] [varchar](50) NOT NULL,
                                                 [point] [varchar](20) NOT NULL,
                                                 [start_timestamp] [datetime] NOT NULL,
                                                 [end_timestamp] [datetime] NULL,
                                                 [count_rawdata] [int] NULL,
                                                 [min_rawdata] [decimal](15, 3) NULL,
                                                 [max_rawdata] [decimal](15, 3) NULL,
                                                    [sub_result] [decimal](15, 3) NULL,
                                                 [avg_rawdata] [decimal](15, 3) NULL,
                                                 [sum_rawdata] [decimal](15, 3) NULL,
                                                 [is_complete] [tinyint] NULL,
                                                 [repeat_times] [int] NULL,
                                                 [fail_reason] [nvarchar](max) NULL,
                                                 [created_at] [datetime] NULL,
                                                 [updated_at] [datetime] NULL,
                                                 CONSTRAINT [PK_archive_electric_water_meter_month] PRIMARY KEY CLUSTERED 
                                                (
                                                 [device_number] ASC,
                                                 [point] ASC,
                                                 [start_timestamp] ASC
                                                )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                                                ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_repeat_times]  DEFAULT ((0)) FOR [repeat_times]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_created_at]  DEFAULT (getdate()) FOR [created_at]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_updated_at]  DEFAULT (NULL) FOR [updated_at]

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'is_complete'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'repeat_times'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'fail_reason'
                                            END

                                            UPDATE archive_electric_water_meter_month SET 
                                                    start_timestamp = @start_timestamp,
                                                    end_timestamp = @end_timestamp,
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;

                                            IF @@ROWCOUNT = 0
                                            BEGIN
                                                INSERT INTO archive_electric_water_meter_month (
                                                    device_number,
                                                    point,
                                                    start_timestamp,
                                                    end_timestamp,
                                                    count_rawdata,
                                                    min_rawdata,
                                                    max_rawdata,
                                                    sub_result,
                                                    avg_rawdata,
                                                    sum_rawdata,
                                                    is_complete,
                                                    repeat_times,
                                                    fail_reason)
                                                VALUES (
                                                    @device_number,
                                                    @point,
                                                    @start_timestamp,
                                                    @end_timestamp,
                                                    @count_rawdata,
                                                    @min_rawdata,
                                                    @max_rawdata,
                                                    @max_rawdata - @min_rawdata,
                                                    @avg_rawdata,
                                                    @sum_rawdata,
                                                    @is_complete,
                                                    @repeat_times,
                                                    @fail_reason)
                                            END

                                        COMMIT TRANSACTION;";
                                await backgroundServiceRepository.ExecuteSql(sql, electricArchiveMonthRawDatas);
                                if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                                {
                                    await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electricArchiveMonthRawDatas);
                                }
                            }
                            if (waterArchiveMonthRawDatas.Count() > 0)
                            {
                                var sql = $@"
                                               CREATE TABLE IF NOT EXISTS `archive_electric_water_meter_month`  (
                                              `device_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `point` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
                                              `start_timestamp` datetime(6) NOT NULL,
                                              `end_timestamp` datetime(6) NULL DEFAULT NULL,
                                              `count_rawdata` int(11) NULL DEFAULT NULL,
                                              `min_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `max_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sub_result` decimal(15, 3) NULL DEFAULT NULL,
                                              `avg_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `sum_rawdata` decimal(15, 3) NULL DEFAULT NULL,
                                              `is_complete` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '是否完成,0:未完成 1:完成',
                                              `repeat_times` int(11) NULL DEFAULT 0 COMMENT '重複次數',
                                              `fail_reason` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '失敗原因',
                                              `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                                              `updated_at` datetime(6) NULL DEFAULT NULL,
                                              PRIMARY KEY (`device_number`, `point`, `start_timestamp`) USING BTREE
                                            ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

                                            SET FOREIGN_KEY_CHECKS = 1;
                                            UPDATE archive_electric_water_meter_month SET 
                                                    start_timestamp = @start_timestamp,
                                                    end_timestamp = @end_timestamp,
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;

                                                INSERT INTO archive_electric_water_meter_month (
                                                    device_number,
                                                    point,
                                                    start_timestamp,
                                                    end_timestamp,
                                                    count_rawdata,
                                                    min_rawdata,
                                                    max_rawdata,
                                                    sub_result,
                                                    avg_rawdata,
                                                    sum_rawdata,
                                                    is_complete,
                                                    repeat_times,
                                                    fail_reason)
                                                SELECT
                                                    @device_number,
                                                    @point,
                                                    @start_timestamp,
                                                    @end_timestamp,
                                                    @count_rawdata,
                                                    @min_rawdata,
                                                    @max_rawdata,
                                                    @max_rawdata - @min_rawdata,
                                                    @avg_rawdata,
                                                    @sum_rawdata,
                                                    @is_complete,
                                                    @repeat_times,
                                                    @fail_reason
                                                WHERE ROW_COUNT() = 0;";

                                var mySql = $@"BEGIN TRANSACTION;
                                            IF OBJECT_ID(N'dbo.archive_electric_water_meter_month', N'U') is null
                                            BEGIN
                                                CREATE TABLE [dbo].[archive_electric_water_meter_month](
                                                 [device_number] [varchar](50) NOT NULL,
                                                 [point] [varchar](20) NOT NULL,
                                                 [start_timestamp] [datetime] NOT NULL,
                                                 [end_timestamp] [datetime] NULL,
                                                 [count_rawdata] [int] NULL,
                                                 [min_rawdata] [decimal](15, 3) NULL,
                                                 [max_rawdata] [decimal](15, 3) NULL,
                                                    [sub_result] [decimal](15, 3) NULL,
                                                 [avg_rawdata] [decimal](15, 3) NULL,
                                                 [sum_rawdata] [decimal](15, 3) NULL,
                                                 [is_complete] [tinyint] NULL,
                                                 [repeat_times] [int] NULL,
                                                 [fail_reason] [nvarchar](max) NULL,
                                                 [created_at] [datetime] NULL,
                                                 [updated_at] [datetime] NULL,
                                                 CONSTRAINT [PK_archive_electric_water_meter_month] PRIMARY KEY CLUSTERED 
                                                (
                                                 [device_number] ASC,
                                                 [point] ASC,
                                                 [start_timestamp] ASC
                                                )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                                                ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_repeat_times]  DEFAULT ((0)) FOR [repeat_times]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_created_at]  DEFAULT (getdate()) FOR [created_at]

                                                ALTER TABLE [dbo].[archive_electric_water_meter_month] ADD  CONSTRAINT [DF_archive_electric_water_meter_month_updated_at]  DEFAULT (NULL) FOR [updated_at]

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'is_complete'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'repeat_times'

                                                EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_water_meter_month', @level2type=N'COLUMN',@level2name=N'fail_reason'
                                            END

                                            UPDATE archive_electric_water_meter_month SET 
                                                    start_timestamp = @start_timestamp,
                                                    end_timestamp = @end_timestamp,
                                                    count_rawdata = @count_rawdata,
                                                    min_rawdata = @min_rawdata,
                                                    max_rawdata = @max_rawdata,
                                                    sub_result = @max_rawdata - @min_rawdata,
                                                    avg_rawdata = @avg_rawdata,
                                                    sum_rawdata = @sum_rawdata,
                                                    is_complete = @is_complete,
                                                    repeat_times = @repeat_times,
                                                    fail_reason = @fail_reason,
                                                    updated_at = @updated_at
                                                 WHERE device_number = @device_number
                                                    AND point = @point
                                                    AND start_timestamp = @start_timestamp;

                                            IF @@ROWCOUNT = 0
                                            BEGIN
                                                INSERT INTO archive_electric_water_meter_month (
                                                    device_number,
                                                    point,
                                                    start_timestamp,
                                                    end_timestamp,
                                                    count_rawdata,
                                                    min_rawdata,
                                                    max_rawdata,
                                                    sub_result,
                                                    avg_rawdata,
                                                    sum_rawdata,
                                                    is_complete,
                                                    repeat_times,
                                                    fail_reason)
                                                VALUES (
                                                    @device_number,
                                                    @point,
                                                    @start_timestamp,
                                                    @end_timestamp,
                                                    @count_rawdata,
                                                    @min_rawdata,
                                                    @max_rawdata,
                                                    @max_rawdata - @min_rawdata,
                                                    @avg_rawdata,
                                                    @sum_rawdata,
                                                    @is_complete,
                                                    @repeat_times,
                                                    @fail_reason)
                                            END

                                        COMMIT TRANSACTION;";
                                await backgroundServiceRepository.ExecuteSql(sql, waterArchiveMonthRawDatas);
                                if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
                                {
                                    await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveMonthRawDatas);
                                }
                            }
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Month", "水電表月任務完成");
                        }
                        catch (Exception exception)
                        {
                            await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Month", exception.ToString());
                            logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】");
                            logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】[Exception]:{0}, {1}", exception.ToString(), "device_number = " + device_number);
                        }
                        finally
                        {
                            if (archiveResponse != null)
                            {
                                archiveResponse.Dispose();
                                archiveResponse.Close();
                            }
                        }
                    }
                    #endregion 月歸檔

                    #region 補償機制
                    ////取得連線字串
                    //if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Compensate"))
                    //{
                    //    try
                    //    {
                    //        await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Compensate", "補償機制任務開始");
                    //        ProcEletricMeterService procEletricMeterService = new ProcEletricMeterService(backgroundServiceRepository, backgroundServiceMsSqlRepository);
                    //        await procEletricMeterService.ArchiveData();
                    //        await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Compensate", "任務完成");
                    //    }
                    //    catch (Exception ex)
                    //    {
                    //        await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Compensate", ex.ToString());
                    //    }
                    //}
                    #endregion 補償機制

                    await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "All", "任務完成");
                }

            }
            catch (Exception exception)
            {
                await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "All", exception.ToString());
                logger.LogError("【ArchiveElectricMeterDayJob】【任務失敗】");
                logger.LogError("【ArchiveElectricMeterDayJob】【任務失敗】[Exception]:{0}, {1}", exception.ToString(), "device_number = " + device_number);
            }
        }


        public IEnumerable<DateTime> EachDay(string from, string thru)
        {
            var strtday = DateTime.Parse(from).AddDays(-1); //每次重做 2天
            var endday = DateTime.Parse(thru);
            for (var day = strtday.Date; day.Date <= endday.Date; day = day.AddDays(1))
                yield return day;
        }
        public IEnumerable<DateTime> EachMonth(string from, string thru)
        {
            var strtday = DateTime.Parse(from);
            var endday = DateTime.Parse(thru);
            for (var _month = strtday.Date; _month.Month <= endday.Month; _month = _month.AddMonths(1))
                yield return _month;

        }
        private List<Dictionary<string, object>> ArrangeRawData(DeviceNumberPoint deviceNumberPoint, JObject jsonResult)
        {
            List<Dictionary<string, object>> arrangeRawDatas = new List<Dictionary<string, object>>();
            try
            {
                var histories = jsonResult["obj"]["list"];
                var rawdateCount = Convert.ToInt32(jsonResult["obj"]["int"]["@val"].ToString());

                if (rawdateCount == 0)
                {
                    return null;
                }

                if (histories != null && histories.HasValues)
                {
                    if (rawdateCount > 1)
                    {   //多筆資料
                        foreach (var history in histories)
                        {
                            Dictionary<string, object> arrangeRawData = new Dictionary<string, object>();
                            arrangeRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                            arrangeRawData.Add("@point", deviceNumberPoint.Point);

                            //時間
                            if (history["abstime"] != null && history["abstime"].HasValues)
                            {
                                foreach (var abstime in history["abstime"])
                                {
                                    var name = abstime["@name"].ToString();
                                    switch (name)
                                    {
                                        case "start":
                                            var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                                            arrangeRawData.Add("@start_timestamp", startTimstamp);
                                            break;
                                        case "end":
                                            var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                                            arrangeRawData.Add("@end_timestamp", endTimstamp);
                                            break;
                                    }
                                }
                            }

                            //區間內資料筆數
                            if (history["int"] != null && history["int"].HasValues)
                            {
                                var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
                                arrangeRawData.Add("@count_rawdata", count);
                            }

                            //整合數值(最大、最小、平均、總和)
                            if (history["real"] != null && history["real"].HasValues)
                            {
                                foreach (var real in history["real"])
                                {
                                    var name = real["@name"].ToString();
                                    switch (name)
                                    {
                                        case "min":
                                            var min = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                            arrangeRawData.Add("@min_rawdata", min);
                                            break;
                                        case "max":
                                            var max = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                            arrangeRawData.Add("@max_rawdata", max);
                                            break;
                                        case "avg":
                                            var avg = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                            arrangeRawData.Add("@avg_rawdata", avg);
                                            break;
                                        case "sum":
                                            var sum = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                            arrangeRawData.Add("@sum_rawdata", sum);
                                            break;
                                    }
                                }
                            }
                            arrangeRawData.Add("@is_complete", 1);
                            arrangeRawData.Add("@repeat_times", 0);
                            arrangeRawData.Add("@fail_reason", null);
                            arrangeRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                            arrangeRawDatas.Add(arrangeRawData);
                        }
                    }
                    else
                    {   //單筆資料
                        Dictionary<string, object> arrangeRawData = new Dictionary<string, object>();
                        arrangeRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
                        arrangeRawData.Add("@point", deviceNumberPoint.Point);

                        //時間
                        if (histories["obj"]["abstime"] != null && histories["obj"]["abstime"].HasValues)
                        {
                            foreach (var abstime in histories["obj"]["abstime"])
                            {
                                var name = abstime["@name"].ToString();
                                switch (name)
                                {
                                    case "start":
                                        var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                                        arrangeRawData.Add("@start_timestamp", startTimstamp);
                                        break;
                                    case "end":
                                        var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                                        arrangeRawData.Add("@end_timestamp", endTimstamp);
                                        break;
                                }
                            }
                        }

                        //區間內資料筆數
                        if (histories["obj"]["int"] != null && histories["obj"]["int"].HasValues)
                        {
                            var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
                            arrangeRawData.Add("@count_rawdata", count);
                        }

                        //整合數值(最大、最小、平均、總和)
                        if (histories["obj"]["real"] != null && histories["obj"]["real"].HasValues)
                        {
                            foreach (var real in histories["obj"]["real"])
                            {
                                var name = real["@name"].ToString();
                                switch (name)
                                {
                                    case "min":
                                        var min = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                        arrangeRawData.Add("@min_rawdata", min);
                                        break;
                                    case "max":
                                        var max = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                        arrangeRawData.Add("@max_rawdata", max);
                                        break;
                                    case "avg":
                                        var avg = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                        arrangeRawData.Add("@avg_rawdata", avg);
                                        break;
                                    case "sum":
                                        var sum = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
                                        arrangeRawData.Add("@sum_rawdata", sum);
                                        break;
                                }
                            }
                        }
                        arrangeRawData.Add("@is_complete", 1);
                        arrangeRawData.Add("@repeat_times", 0);
                        arrangeRawData.Add("@fail_reason", null);
                        arrangeRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

                        arrangeRawDatas.Add(arrangeRawData);
                    }
                }

                return arrangeRawDatas;
            }
            catch (Exception ex)
            {
                return arrangeRawDatas;
            }
        }
    }
}