[BGService]將部分obix定時任務改成批次撈取
This commit is contained in:
		
							parent
							
								
									e2f3992b9c
								
							
						
					
					
						commit
						b60530974f
					
				@ -45,7 +45,6 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
            this.backendRepository = backendRepository;
 | 
			
		||||
            this.loggers = loggers;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Execute(IJobExecutionContext context)
 | 
			
		||||
        {
 | 
			
		||||
            Task_Detail task_Detail = new Task_Detail(loggers, backendRepository);
 | 
			
		||||
@ -58,33 +57,13 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                        await task_Detail.InsertWorkTime("LightScheduleJob", "light_schedule");
 | 
			
		||||
 | 
			
		||||
                        var TimeNow = DateTime.Now.ToString("dddd HH:mm");
 | 
			
		||||
                        var schedule = await backendRepository.GetAllAsync<Schedule>("light_schedule","deleted = 0 and status = 1");
 | 
			
		||||
                        var schedule = await backendRepository.GetAllAsync<Schedule>("light_schedule", "deleted = 0 and status = 1");
 | 
			
		||||
 | 
			
		||||
                        string date = DateTime.Now.ToString("yyyy-MM-dd");
 | 
			
		||||
 | 
			
		||||
                        foreach (var oneSchedule in schedule)
 | 
			
		||||
                        {
 | 
			
		||||
                            // 檢查執行log
 | 
			
		||||
                            string light_schedule_guid = oneSchedule.light_schedule_guid;
 | 
			
		||||
                            string sWhere = @$"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'";
 | 
			
		||||
                            var schedule_log = await backendRepository.GetOneAsync<ScheduleLog>("light_schedule_log", sWhere);
 | 
			
		||||
                            string start_time = null;
 | 
			
		||||
                            string end_time = null;
 | 
			
		||||
                            if (schedule_log != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                start_time = schedule_log.start_time;
 | 
			
		||||
                                end_time = schedule_log.end_time;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (schedule_log == null)
 | 
			
		||||
                            {
 | 
			
		||||
                                Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
                                {
 | 
			
		||||
                                    { "@light_schedule_guid", light_schedule_guid},
 | 
			
		||||
                                    { "@date", date},
 | 
			
		||||
                                };
 | 
			
		||||
                                await backendRepository.AddOneByCustomTable(log, "light_schedule_log");
 | 
			
		||||
                            }
 | 
			
		||||
                            // 如果log有紀錄
 | 
			
		||||
 | 
			
		||||
                            // 先檢查今日否需執行
 | 
			
		||||
                            var weeklistN = oneSchedule.week.Split(',');
 | 
			
		||||
                            List<string> weeklist = new List<string>();
 | 
			
		||||
                            foreach (var weekN in weeklistN)
 | 
			
		||||
@ -102,34 +81,52 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                };
 | 
			
		||||
                                weeklist.Add(week);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            var Time = TimeNow.Split(" ");
 | 
			
		||||
                            string check = string.Empty;
 | 
			
		||||
                            // 檢查起始執行
 | 
			
		||||
                            if (start_time == null && DateTime.Parse(Time[1]) >= DateTime.Parse(oneSchedule.start_time))
 | 
			
		||||
                            if (!weeklist.Contains(Time[0])) { continue; }
 | 
			
		||||
 | 
			
		||||
                            // 檢查執行log
 | 
			
		||||
                            string light_schedule_guid = oneSchedule.light_schedule_guid;
 | 
			
		||||
                            string sWhere = @$"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'";
 | 
			
		||||
                            var schedule_log = await backendRepository.GetOneAsync<ScheduleLog>("light_schedule_log", sWhere);
 | 
			
		||||
                            string start_time = null;
 | 
			
		||||
                            string end_time = null;
 | 
			
		||||
                            if (schedule_log != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                start_time = schedule_log.start_time;
 | 
			
		||||
                                end_time = schedule_log.end_time;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (schedule_log == null)
 | 
			
		||||
                            {
 | 
			
		||||
                                check = "<real val='true' />";
 | 
			
		||||
                                UpdatedNiagara(oneSchedule, check);
 | 
			
		||||
                                Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                                    { "@start_time", Time[1]},
 | 
			
		||||
                            { "@light_schedule_guid", light_schedule_guid },
 | 
			
		||||
                            { "@date", date },
 | 
			
		||||
                        };
 | 
			
		||||
                                await backendRepository.UpdateOneByCustomTable(log, "light_schedule_log", $"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'");
 | 
			
		||||
                                logger.LogInformation($"【LightScheduleJob】【燈控排程開啟成功】排程名稱 :{oneSchedule.full_name}");
 | 
			
		||||
                                await backendRepository.AddOneByCustomTable(log, "light_schedule_log");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                            string check = string.Empty;
 | 
			
		||||
 | 
			
		||||
                            // 檢查起始執行
 | 
			
		||||
                            if (start_time == null && end_time == null && DateTime.Parse(Time[1]) >= DateTime.Parse(oneSchedule.start_time))
 | 
			
		||||
                            {
 | 
			
		||||
                                check = "true";  // 開啟
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // 檢查結束執行
 | 
			
		||||
                            if (end_time == null && DateTime.Parse(Time[1]) >= DateTime.Parse(oneSchedule.end_time))
 | 
			
		||||
                            {
 | 
			
		||||
                                check = "<real val='false' />";
 | 
			
		||||
                                UpdatedNiagara(oneSchedule, check);
 | 
			
		||||
                                Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
                                {
 | 
			
		||||
                                    { "@end_time", Time[1]},
 | 
			
		||||
                                };
 | 
			
		||||
                                await backendRepository.UpdateOneByCustomTable(log, "light_schedule_log", $"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'");
 | 
			
		||||
                                logger.LogInformation($"【LightScheduleJob】【燈控排程關閉成功】排程名稱 :{oneSchedule.full_name}");
 | 
			
		||||
                            }
 | 
			
		||||
                                check = "false";  // 關閉
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (!string.IsNullOrEmpty(check))
 | 
			
		||||
                            {
 | 
			
		||||
                                bool requestSuccess = await UpdatedNiagara(oneSchedule, check);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        await task_Detail.InsertWorkTime_End("LightScheduleJob", "light_schedule");
 | 
			
		||||
                    }
 | 
			
		||||
@ -146,52 +143,279 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                logger.LogError("【LightScheduleJob】【任務失敗】[Exception]:{0}", exception.ToString());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        public async void UpdatedNiagara(Schedule oneSchedule, string check)
 | 
			
		||||
 | 
			
		||||
        public async Task<bool> UpdatedNiagara(Schedule oneSchedule, string check)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var deviceNumList = await backendRepository.GetAllAsync<string>(@$"select d.device_number from schedule_device sd join device d on sd.device_guid = d.device_guid
 | 
			
		||||
                                                                                where light_schedule_guid = '{oneSchedule.light_schedule_guid}' and is_link = 1");
 | 
			
		||||
                // 取得排程所對應的設備號碼列表
 | 
			
		||||
                var deviceNumList = await backendRepository.GetAllAsync<string>(@$"SELECT d.device_number 
 | 
			
		||||
                                                                          FROM schedule_device sd 
 | 
			
		||||
                                                                          JOIN device d ON sd.device_guid = d.device_guid
 | 
			
		||||
                                                                          WHERE light_schedule_guid = '{oneSchedule.light_schedule_guid}' AND is_link = 1");
 | 
			
		||||
 | 
			
		||||
                // 取得obix配置
 | 
			
		||||
                var variableObix = await backendRepository.GetAllAsync<Backend.Models.KeyValue>(@$"SELECT system_value as Value, system_key as Name 
 | 
			
		||||
                                                                                         FROM variable 
 | 
			
		||||
                                                                                         WHERE deleted = 0 AND system_type = 'obixConfig'");
 | 
			
		||||
 | 
			
		||||
                // 取得obix相關配置參數
 | 
			
		||||
                string url = variableObix.FirstOrDefault(x => x.Name == "ApiBase")?.Value;
 | 
			
		||||
                string account = variableObix.FirstOrDefault(x => x.Name == "UserName")?.Value;
 | 
			
		||||
                string pass = variableObix.FirstOrDefault(x => x.Name == "Password")?.Value;
 | 
			
		||||
 | 
			
		||||
                // 檢查是否有配置缺失
 | 
			
		||||
                if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(account) || string.IsNullOrEmpty(pass))
 | 
			
		||||
                {
 | 
			
		||||
                    logger.LogWarning("【LightScheduleJob】【obix配置缺失】請檢查obix配置");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 準備HTTP請求的基本資訊
 | 
			
		||||
                string authInfo = Convert.ToBase64String(Encoding.Default.GetBytes($"{account}:{pass}"));
 | 
			
		||||
 | 
			
		||||
                // 構建每個設備的請求
 | 
			
		||||
                List<string> batchRequests = new List<string>();
 | 
			
		||||
                TagChangeFunction tagChange = new TagChangeFunction();
 | 
			
		||||
 | 
			
		||||
                var variableObix = await backendRepository.GetAllAsync<Backend.Models.KeyValue>("SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'");
 | 
			
		||||
                string url = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                string account = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                string pass = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                foreach (var deviceNum in deviceNumList)
 | 
			
		||||
                {
 | 
			
		||||
                    TagChangeFunction tagChange = new TagChangeFunction();
 | 
			
		||||
                    // 處理設備號碼,分解到URL中
 | 
			
		||||
                    var d = tagChange.AddStringIfStartsWithDigit(deviceNum, "$3");
 | 
			
		||||
                    var html = $"{url}obix/config/Arena/" + $"{d[0]}/{d[1]}/{d[2]}/{d[3]}/{deviceNum}/SSC/set";
 | 
			
		||||
                    string authInfo = account + ":" + pass;
 | 
			
		||||
                    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
 | 
			
		||||
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(html);
 | 
			
		||||
                    var uri = $"{url}obix/config/Arena/{d[0]}/{d[1]}/{d[2]}/{d[3]}/{deviceNum}/SSC/set";
 | 
			
		||||
 | 
			
		||||
                    // 構建要發送的實體資料
 | 
			
		||||
                    string realData = $"<real name='in' val='{check}' />";
 | 
			
		||||
 | 
			
		||||
                    // 建立批次請求
 | 
			
		||||
                    batchRequests.Add($"<uri is='obix:Invoke' val='{uri}'>" + realData + "</uri>");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 構建整體批次請求
 | 
			
		||||
                var batchRequestData = $@"<list is='obix:BatchIn'>
 | 
			
		||||
                                    {string.Join("", batchRequests)}
 | 
			
		||||
                                  </list>";
 | 
			
		||||
 | 
			
		||||
                // 發送批次請求
 | 
			
		||||
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "obix/batch");
 | 
			
		||||
                request.Method = "POST";
 | 
			
		||||
                request.Accept = "application/json; charset=utf-8";
 | 
			
		||||
                request.Headers["Authorization"] = "Basic " + authInfo;
 | 
			
		||||
                    byte[] byteArray = Encoding.UTF8.GetBytes(check);
 | 
			
		||||
 | 
			
		||||
                // 將所有設備的請求內容合併成一個批次請求
 | 
			
		||||
                byte[] byteArray = Encoding.UTF8.GetBytes(batchRequestData);
 | 
			
		||||
                using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
                {
 | 
			
		||||
                    reqStream.Write(byteArray, 0, byteArray.Length);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 發送請求並處理回應
 | 
			
		||||
                var response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
                    string strResponse = "";
 | 
			
		||||
                string responseContent = string.Empty;
 | 
			
		||||
 | 
			
		||||
                using (var sr = new StreamReader(response.GetResponseStream()))
 | 
			
		||||
                {
 | 
			
		||||
                        strResponse = sr.ReadToEnd();
 | 
			
		||||
                    responseContent = sr.ReadToEnd();
 | 
			
		||||
                }
 | 
			
		||||
                    // 只取err會取到override
 | 
			
		||||
                    if (strResponse.Contains("<err"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                // 檢查回應中是否有錯誤
 | 
			
		||||
                if (responseContent.Contains("<err"))
 | 
			
		||||
                {
 | 
			
		||||
                        logger.LogWarning($"【LightScheduleJob 】【set niagara light value fail】[排程 名稱]:{oneSchedule.full_name},[設備 名稱]:{deviceNum}");
 | 
			
		||||
                    XmlDocument xmlDocument = new XmlDocument();
 | 
			
		||||
                    xmlDocument.LoadXml(responseContent);
 | 
			
		||||
 | 
			
		||||
                    // 找到所有的 err 節點
 | 
			
		||||
                    XmlNodeList errNodes = xmlDocument.GetElementsByTagName("err");
 | 
			
		||||
 | 
			
		||||
                    // 如果有錯誤節點,進行處理
 | 
			
		||||
                    foreach (XmlNode errNode in errNodes)
 | 
			
		||||
                    {
 | 
			
		||||
                        logger.LogWarning($"【LightScheduleJob】【Niagara燈控設置失敗】排程名稱 :{oneSchedule.full_name} 顯示錯誤: {errNode}");
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return false; // 如果有錯誤,返回 false
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 成功後記錄並更新結束時間
 | 
			
		||||
                Dictionary<string, object> log = new Dictionary<string, object>();
 | 
			
		||||
 | 
			
		||||
                string time = DateTime.Now.ToString("HH:mm");
 | 
			
		||||
                if (check == "true")
 | 
			
		||||
                {
 | 
			
		||||
                    log.Add("@start_time", time);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    log.Add("@end_time", time);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                await backendRepository.UpdateOneByCustomTable(log, "light_schedule_log", $"light_schedule_guid = '{oneSchedule.light_schedule_guid}' and date = '{DateTime.Now:yyyy-MM-dd}'");
 | 
			
		||||
 | 
			
		||||
                logger.LogInformation($"【LightScheduleJob】【Niagara燈控設置成功】排程名稱 :{oneSchedule.full_name}");
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                logger.LogError("【LightScheduleJob】" + "UpdatedNiagaraFail:" + ex.ToString());
 | 
			
		||||
                throw ex;
 | 
			
		||||
                logger.LogError("【LightScheduleJob】批次請求發送失敗:" + ex.ToString());
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //public async Task Execute(IJobExecutionContext context)
 | 
			
		||||
        //{
 | 
			
		||||
        //    Task_Detail task_Detail = new Task_Detail(loggers, backendRepository);
 | 
			
		||||
        //    try
 | 
			
		||||
        //    {
 | 
			
		||||
        //        if (await task_Detail.GetNeedWorkTask("LightScheduleJob", "light_schedule"))
 | 
			
		||||
        //        {
 | 
			
		||||
        //            try
 | 
			
		||||
        //            {
 | 
			
		||||
        //                await task_Detail.InsertWorkTime("LightScheduleJob", "light_schedule");
 | 
			
		||||
 | 
			
		||||
        //                var TimeNow = DateTime.Now.ToString("dddd HH:mm");
 | 
			
		||||
        //                var schedule = await backendRepository.GetAllAsync<Schedule>("light_schedule","deleted = 0 and status = 1");
 | 
			
		||||
        //                string date = DateTime.Now.ToString("yyyy-MM-dd");
 | 
			
		||||
 | 
			
		||||
        //                foreach (var oneSchedule in schedule)
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    // 檢查執行log
 | 
			
		||||
        //                    string light_schedule_guid = oneSchedule.light_schedule_guid;
 | 
			
		||||
        //                    string sWhere = @$"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'";
 | 
			
		||||
        //                    var schedule_log = await backendRepository.GetOneAsync<ScheduleLog>("light_schedule_log", sWhere);
 | 
			
		||||
        //                    string start_time = null;
 | 
			
		||||
        //                    string end_time = null;
 | 
			
		||||
        //                    if (schedule_log != null)
 | 
			
		||||
        //                    {
 | 
			
		||||
        //                        start_time = schedule_log.start_time;
 | 
			
		||||
        //                        end_time = schedule_log.end_time;
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                    if (schedule_log == null)
 | 
			
		||||
        //                    {
 | 
			
		||||
        //                        Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
        //                        {
 | 
			
		||||
        //                            { "@light_schedule_guid", light_schedule_guid},
 | 
			
		||||
        //                            { "@date", date},
 | 
			
		||||
        //                        };
 | 
			
		||||
        //                        await backendRepository.AddOneByCustomTable(log, "light_schedule_log");
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                    // 如果log有紀錄
 | 
			
		||||
 | 
			
		||||
        //                    var weeklistN = oneSchedule.week.Split(',');
 | 
			
		||||
        //                    List<string> weeklist = new List<string>();
 | 
			
		||||
        //                    foreach (var weekN in weeklistN)
 | 
			
		||||
        //                    {
 | 
			
		||||
        //                        var week = weekN switch
 | 
			
		||||
        //                        {
 | 
			
		||||
        //                            "0" => "星期日",
 | 
			
		||||
        //                            "1" => "星期一",
 | 
			
		||||
        //                            "2" => "星期二",
 | 
			
		||||
        //                            "3" => "星期三",
 | 
			
		||||
        //                            "4" => "星期四",
 | 
			
		||||
        //                            "5" => "星期五",
 | 
			
		||||
        //                            "6" => "星期六",
 | 
			
		||||
        //                            _ => ""
 | 
			
		||||
        //                        };
 | 
			
		||||
        //                        weeklist.Add(week);
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                    var Time = TimeNow.Split(" ");
 | 
			
		||||
        //                    string check = string.Empty;
 | 
			
		||||
        //                    // 檢查起始執行
 | 
			
		||||
        //                    if (start_time == null && DateTime.Parse(Time[1]) >= DateTime.Parse(oneSchedule.start_time))
 | 
			
		||||
        //                    { 
 | 
			
		||||
        //                        check = "<real val='true' />";
 | 
			
		||||
        //                        UpdatedNiagara(oneSchedule, check);
 | 
			
		||||
        //                        Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
        //                        {
 | 
			
		||||
        //                            { "@start_time", Time[1]},
 | 
			
		||||
        //                        };
 | 
			
		||||
        //                        await backendRepository.UpdateOneByCustomTable(log, "light_schedule_log", $"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'");
 | 
			
		||||
        //                        logger.LogInformation($"【LightScheduleJob】【燈控排程開啟成功】排程名稱 :{oneSchedule.full_name}");
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                    // 檢查結束執行
 | 
			
		||||
        //                    if (end_time == null && DateTime.Parse(Time[1]) >= DateTime.Parse(oneSchedule.end_time))
 | 
			
		||||
        //                    {
 | 
			
		||||
        //                        check = "<real val='false' />";
 | 
			
		||||
        //                        UpdatedNiagara(oneSchedule, check);
 | 
			
		||||
        //                        Dictionary<string, object> log = new Dictionary<string, object>()
 | 
			
		||||
        //                        {
 | 
			
		||||
        //                            { "@end_time", Time[1]},
 | 
			
		||||
        //                        };
 | 
			
		||||
        //                        await backendRepository.UpdateOneByCustomTable(log, "light_schedule_log", $"light_schedule_guid = '{light_schedule_guid}' and date = '{date}'");
 | 
			
		||||
        //                        logger.LogInformation($"【LightScheduleJob】【燈控排程關閉成功】排程名稱 :{oneSchedule.full_name}");
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //                await task_Detail.InsertWorkTime_End("LightScheduleJob", "light_schedule");
 | 
			
		||||
        //            }
 | 
			
		||||
        //            catch (Exception ex)
 | 
			
		||||
        //            {
 | 
			
		||||
        //                logger.LogInformation($"LightScheduleJob fail");
 | 
			
		||||
        //                await task_Detail.WorkFail("LightScheduleJob", "light_schedule", ex.Message.ToString());
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        //    }
 | 
			
		||||
        //    catch (Exception exception)
 | 
			
		||||
        //    {
 | 
			
		||||
        //        logger.LogError("【LightScheduleJob】【任務失敗】");
 | 
			
		||||
        //        logger.LogError("【LightScheduleJob】【任務失敗】[Exception]:{0}", exception.ToString());
 | 
			
		||||
        //    }
 | 
			
		||||
        //}
 | 
			
		||||
        //public async void UpdatedNiagara(Schedule oneSchedule, string check)
 | 
			
		||||
        //{
 | 
			
		||||
        //    try
 | 
			
		||||
        //    {
 | 
			
		||||
        //        var deviceNumList = await backendRepository.GetAllAsync<string>(@$"select d.device_number from schedule_device sd join device d on sd.device_guid = d.device_guid
 | 
			
		||||
        //                                                                        where light_schedule_guid = '{oneSchedule.light_schedule_guid}' and is_link = 1");
 | 
			
		||||
 | 
			
		||||
        //        var variableObix = await backendRepository.GetAllAsync<Backend.Models.KeyValue>("SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'");
 | 
			
		||||
        //        string url = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
        //        string account = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
        //        string pass = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
        //        foreach (var deviceNum in deviceNumList)
 | 
			
		||||
        //        {
 | 
			
		||||
        //            TagChangeFunction tagChange = new TagChangeFunction();
 | 
			
		||||
        //            var d = tagChange.AddStringIfStartsWithDigit(deviceNum, "$3");
 | 
			
		||||
        //            var html = $"{url}obix/config/Arena/" + $"{d[0]}/{d[1]}/{d[2]}/{d[3]}/{deviceNum}/SSC/set";
 | 
			
		||||
        //            string authInfo = account + ":" + pass;
 | 
			
		||||
        //            authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
 | 
			
		||||
        //            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(html);
 | 
			
		||||
        //            request.Method = "POST";
 | 
			
		||||
        //            request.Accept = "application/json; charset=utf-8";
 | 
			
		||||
        //            request.Headers["Authorization"] = "Basic " + authInfo;
 | 
			
		||||
        //            byte[] byteArray = Encoding.UTF8.GetBytes(check);
 | 
			
		||||
        //            using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
        //            {
 | 
			
		||||
        //                reqStream.Write(byteArray, 0, byteArray.Length);
 | 
			
		||||
        //            }
 | 
			
		||||
        //            var response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
        //            string strResponse = "";
 | 
			
		||||
 | 
			
		||||
        //            using (var sr = new StreamReader(response.GetResponseStream()))
 | 
			
		||||
        //            {
 | 
			
		||||
        //                strResponse = sr.ReadToEnd();
 | 
			
		||||
        //            }
 | 
			
		||||
        //            // 只取err會取到override
 | 
			
		||||
        //            if (strResponse.Contains("<err"))
 | 
			
		||||
        //            {
 | 
			
		||||
        //                logger.LogWarning($"【LightScheduleJob 】【set niagara light value fail】[排程 名稱]:{oneSchedule.full_name},[設備 名稱]:{deviceNum}");
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        //    }
 | 
			
		||||
        //    catch (Exception ex)
 | 
			
		||||
        //    {
 | 
			
		||||
        //        logger.LogError("【LightScheduleJob】" + "UpdatedNiagaraFail:" + ex.ToString());
 | 
			
		||||
        //        throw ex;
 | 
			
		||||
        //    }
 | 
			
		||||
        //}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -95,79 +95,33 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
 | 
			
		||||
                            if (spaceResponseResult != null && spaceResponseResult.Code == "20000")
 | 
			
		||||
                            {
 | 
			
		||||
                                List<string> batchRequests = new List<string>();  // 用來存儲批次請求的列表
 | 
			
		||||
 | 
			
		||||
                                foreach (var area in spaceResponseResult.Payload.Areas)
 | 
			
		||||
                                {
 | 
			
		||||
                                    //找出對定的設備代碼
 | 
			
		||||
                                    var selectedMapping = parkingSapceMapping.Where(x => x.System_key == area.Name).FirstOrDefault();
 | 
			
		||||
                                    // 找出對應的設備代碼
 | 
			
		||||
                                    var selectedMapping = parkingSapceMapping.FirstOrDefault(x => x.System_key == area.Name);
 | 
			
		||||
                                    if (selectedMapping != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        item = area.Name;
 | 
			
		||||
                                        var name = area.Name;  // 保存設備名稱
 | 
			
		||||
                                        var tagName = selectedMapping.system_value;
 | 
			
		||||
                                        var apiFormat = @"{0}obix/config/Arena/{1}/{2}/{3}/{4}/{5}/CV/set";
 | 
			
		||||
                                        var tagNameSplit = tagName.Split("_");
 | 
			
		||||
 | 
			
		||||
                                        var parames = new List<object>();
 | 
			
		||||
                                        parames.Add(parkingConfig.ApiBase);
 | 
			
		||||
                                        for (var i = 0; i < tagNameSplit.Length; i++)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            if (i != tagNameSplit.Length - 1)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                parames.Add(tagNameSplit[i]); // tag 前 4段
 | 
			
		||||
                                            }
 | 
			
		||||
                                            else
 | 
			
		||||
                                            {
 | 
			
		||||
                                                parames.Add(tagName); // 第五段 完整 tag
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        //logger.LogError(@$"【ParkingJob】【停車場剩餘車位】{apiFormat}");
 | 
			
		||||
                                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(apiFormat, parames.ToArray()));
 | 
			
		||||
                                        request.Method = "POST";
 | 
			
		||||
                                        request.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                        request.PreAuthenticate = true;
 | 
			
		||||
                                        request.Timeout = System.Threading.Timeout.Infinite;
 | 
			
		||||
                                        var parames = new List<object> { parkingConfig.ApiBase };
 | 
			
		||||
                                        parames.AddRange(tagNameSplit.Take(tagNameSplit.Length - 1));  // tag 前 4段
 | 
			
		||||
                                        parames.Add(tagName);  // 最後一段 完整 tag
 | 
			
		||||
 | 
			
		||||
                                        string requestUri = string.Format(apiFormat, parames.ToArray());
 | 
			
		||||
 | 
			
		||||
                                        // 構建要發送的實體資料
 | 
			
		||||
                                        var real = $@"<real val='{area.Remain}' />";
 | 
			
		||||
                                        byte[] realByteArray = Encoding.UTF8.GetBytes(real);
 | 
			
		||||
                                        using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
                                        {
 | 
			
		||||
                                            reqStream.Write(realByteArray, 0, realByteArray.Length);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
                                        var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
 | 
			
		||||
                                        batchRequests.Add($"<uri is='obix:Invoke' val='{requestUri}'>" +
 | 
			
		||||
                                                          $"<real name='in' val='{area.Remain}' />" +
 | 
			
		||||
                                                          $"</uri>");
 | 
			
		||||
 | 
			
		||||
                                        XmlDocument xmlDocument = new XmlDocument();
 | 
			
		||||
                                        xmlDocument.LoadXml(responseContent);
 | 
			
		||||
                                        string json = JsonConvert.SerializeXmlNode(xmlDocument);
 | 
			
		||||
                                        JObject jsonResult = (JObject)JsonConvert.DeserializeObject(json);
 | 
			
		||||
 | 
			
		||||
                                        if (jsonResult.ContainsKey("err")) //抓取錯誤
 | 
			
		||||
                                        {
 | 
			
		||||
                                            logger.LogError("【ParkingJob】【停車場剩餘車位資訊】");
 | 
			
		||||
                                            logger.LogError("【ParkingJob】【停車場剩餘車位資訊】[錯誤內容]:{0}", json);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else
 | 
			
		||||
                                        {
 | 
			
		||||
                                            if (jsonResult.ContainsKey("real")) //表示可以讀取到內容
 | 
			
		||||
                                            {
 | 
			
		||||
                                                List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
 | 
			
		||||
                                                var realList = jsonResult["real"];
 | 
			
		||||
                                                var display = realList["@display"];
 | 
			
		||||
                                                if (display != null)
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    var tempStrSplit = display.ToString().Split(" ");
 | 
			
		||||
                                                    if (tempStrSplit[0] != area.Remain.ToString())
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        logger.LogError("【ParkingJob】【停車場剩餘車位資訊】[修改失敗]:{0}", display.ToString());
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                    else
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        logger.LogInformation("【ParkingJob】【停車場剩餘車位資訊】[修改成功]:{0}", display.ToString());
 | 
			
		||||
                                                        logger.LogInformation("【ParkingJob】【停車場剩餘車位資訊】[停車場資訊]:{0}", item);
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        // 進行日誌記錄
 | 
			
		||||
                                        logger.LogInformation("【ParkingJob】【停車場剩餘車位】準備更新設備:{0},剩餘車位數:{1}", name, area.Remain);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
@ -175,11 +129,59 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (batchRequests.Any())
 | 
			
		||||
                                {
 | 
			
		||||
                                    // 建立批次請求 XML
 | 
			
		||||
                                    var batchRequestXml = $@"<list is='obix:BatchIn'>
 | 
			
		||||
                                    {string.Join("", batchRequests)}
 | 
			
		||||
                                  </list>";
 | 
			
		||||
 | 
			
		||||
                                    // 發送批次請求
 | 
			
		||||
                                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(parkingConfig.ApiBase + "obix/batch");
 | 
			
		||||
                                    request.Method = "POST";
 | 
			
		||||
                                    request.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                    request.PreAuthenticate = true;
 | 
			
		||||
                                    request.Timeout = System.Threading.Timeout.Infinite;
 | 
			
		||||
 | 
			
		||||
                                    byte[] requestData = Encoding.UTF8.GetBytes(batchRequestXml);
 | 
			
		||||
                                    using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
                                    {
 | 
			
		||||
                                        reqStream.Write(requestData, 0, requestData.Length);
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
                                    var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
 | 
			
		||||
                                    // 檢查回應中是否有錯誤
 | 
			
		||||
                                    if (responseContent.Contains("<err"))
 | 
			
		||||
                                    {
 | 
			
		||||
                                        XmlDocument xmlDocument = new XmlDocument();
 | 
			
		||||
                                        xmlDocument.LoadXml(responseContent);
 | 
			
		||||
 | 
			
		||||
                                        // 找到所有的 err 節點
 | 
			
		||||
                                        XmlNodeList errNodes = xmlDocument.GetElementsByTagName("err");
 | 
			
		||||
 | 
			
		||||
                                        // 如果有錯誤節點,進行處理
 | 
			
		||||
                                        foreach (XmlNode errNode in errNodes)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            logger.LogWarning($"【ParkingJob】【停車場剩餘車位資訊】[錯誤內容]:{errNode}");
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        logger.LogInformation("【ParkingJob】【停車場剩餘車位資訊】[批次請求成功]");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    logger.LogWarning("【ParkingJob】【停車場剩餘車位資訊】[沒有需要發送的請求]");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                logger.LogWarning("【ParkingJob】【停車場剩餘車位資訊】 - [查無資料]");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ParkingJob", "Parking", "執行成功停車場剩餘車位Job");
 | 
			
		||||
                            //logger.LogInformation("【ParkingJob】【執行成功停車場剩餘車位Job】");
 | 
			
		||||
                        }
 | 
			
		||||
@ -233,91 +235,92 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
 | 
			
		||||
                            if (equipmentResponseResult != null && equipmentResponseResult.Code == "20000")
 | 
			
		||||
                            {
 | 
			
		||||
                                List<string> batchRequests = new List<string>();  // 用來存儲批次請求的列表
 | 
			
		||||
 | 
			
		||||
                                foreach (var equipment in equipmentResponseResult.Payload)
 | 
			
		||||
                                {
 | 
			
		||||
                                    //找出對定的設備代碼
 | 
			
		||||
                                    var selectedMapping = parkingEquipmentMapping.Where(x => x.System_key == equipment.Id).FirstOrDefault();
 | 
			
		||||
                                    // 找出對應的設備代碼
 | 
			
		||||
                                    var selectedMapping = parkingEquipmentMapping.FirstOrDefault(x => x.System_key == equipment.Id);
 | 
			
		||||
                                    if (selectedMapping != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        item = equipment.Id;
 | 
			
		||||
                                        var name = equipment.Id;  // 保存設備ID
 | 
			
		||||
                                        var tagName = selectedMapping.system_value;
 | 
			
		||||
                                        var apiFormat = @"{0}obix/config/Arena/{1}/{2}/{3}/{4}/{5}/ST/set";
 | 
			
		||||
 | 
			
		||||
                                        var tagNameSplit = tagName.Split("_");
 | 
			
		||||
 | 
			
		||||
                                        var parames = new List<object>();
 | 
			
		||||
                                        parames.Add(parkingConfig.ApiBase);
 | 
			
		||||
                                        for (var i = 0; i < tagNameSplit.Length; i++)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            if (i != tagNameSplit.Length - 1)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                parames.Add(tagNameSplit[i]);
 | 
			
		||||
                                            }
 | 
			
		||||
                                            else
 | 
			
		||||
                                            {
 | 
			
		||||
                                                parames.Add(tagName);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        var parames = new List<object> { parkingConfig.ApiBase };
 | 
			
		||||
                                        parames.AddRange(tagNameSplit.Take(tagNameSplit.Length - 1));  // tag 前 4段
 | 
			
		||||
                                        parames.Add(tagName);  // 最後一段 完整 tag
 | 
			
		||||
 | 
			
		||||
                                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(apiFormat, parames.ToArray()));
 | 
			
		||||
                                        request.Method = "POST";
 | 
			
		||||
                                        request.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                        request.PreAuthenticate = true;
 | 
			
		||||
                                        string requestUri = string.Format(apiFormat, parames.ToArray());
 | 
			
		||||
 | 
			
		||||
                                        // 構建要發送的實體資料
 | 
			
		||||
                                        var real = $@"<real val='{equipment.Alive.ToString().ToLower()}' />";
 | 
			
		||||
                                        byte[] realByteArray = Encoding.UTF8.GetBytes(real);
 | 
			
		||||
                                        using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
                                        {
 | 
			
		||||
                                            reqStream.Write(realByteArray, 0, realByteArray.Length);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        batchRequests.Add($"<uri is='obix:Invoke' val='{requestUri}'>" +
 | 
			
		||||
                                                          $"<real name='in' val='{equipment.Alive.ToString().ToLower()}' />" +
 | 
			
		||||
                                                          $"</uri>");
 | 
			
		||||
 | 
			
		||||
                                        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
                                        var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
 | 
			
		||||
 | 
			
		||||
                                        XmlDocument xmlDocument = new XmlDocument();
 | 
			
		||||
                                        xmlDocument.LoadXml(responseContent);
 | 
			
		||||
                                        string json = JsonConvert.SerializeXmlNode(xmlDocument);
 | 
			
		||||
                                        JObject jsonResult = (JObject)JsonConvert.DeserializeObject(json);
 | 
			
		||||
 | 
			
		||||
                                        if (jsonResult.ContainsKey("err")) //抓取錯誤
 | 
			
		||||
                                        {
 | 
			
		||||
                                            logger.LogError("【ParkingJob】【設備資訊】");
 | 
			
		||||
                                            logger.LogError("【ParkingJob】【設備資訊】[錯誤內容]:{0}", json);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else
 | 
			
		||||
                                        {
 | 
			
		||||
                                            if (jsonResult.ContainsKey("bool")) //表示可以讀取到內容
 | 
			
		||||
                                            {
 | 
			
		||||
                                                List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
 | 
			
		||||
                                                var realList = jsonResult["bool"];
 | 
			
		||||
                                                var val = realList["@val"];
 | 
			
		||||
                                                if (val != null)
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    var tempStrSplit = val.ToString();
 | 
			
		||||
                                                    if (tempStrSplit != equipment.Alive.ToString().ToLower())
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        logger.LogError("【ParkingJob】【設備資訊】[修改失敗]:{0}", val.ToString());
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                    else
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        logger.LogInformation("【ParkingJob】【設備資訊】[修改成功]:{0}", val.ToString());
 | 
			
		||||
                                                        logger.LogInformation("【ParkingJob】【設備資訊】[設備資訊]:{0}", item);
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        // 進行日誌記錄
 | 
			
		||||
                                        logger.LogInformation("【ParkingJob】【設備資訊】準備更新設備:{0},設備狀態:{1}", name, equipment.Alive);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        logger.LogWarning("【ParkingJob】【設備資訊】[查無該名稱對應表]:{0}", equipment.Id);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (batchRequests.Any())
 | 
			
		||||
                                {
 | 
			
		||||
                                    // 建立批次請求 XML
 | 
			
		||||
                                    var batchRequestXml = $@"<list is='obix:BatchIn'>
 | 
			
		||||
                                    {string.Join("", batchRequests)}
 | 
			
		||||
                                  </list>";
 | 
			
		||||
 | 
			
		||||
                                    // 發送批次請求
 | 
			
		||||
                                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(parkingConfig.ApiBase + "obix/batch");
 | 
			
		||||
                                    request.Method = "POST";
 | 
			
		||||
                                    request.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                    request.PreAuthenticate = true;
 | 
			
		||||
 | 
			
		||||
                                    byte[] requestData = Encoding.UTF8.GetBytes(batchRequestXml);
 | 
			
		||||
                                    using (Stream reqStream = request.GetRequestStream())
 | 
			
		||||
                                    {
 | 
			
		||||
                                        reqStream.Write(requestData, 0, requestData.Length);
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
                                    var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
 | 
			
		||||
                                    // 檢查回應中是否有錯誤
 | 
			
		||||
                                    if (responseContent.Contains("<err"))
 | 
			
		||||
                                    {
 | 
			
		||||
                                        XmlDocument xmlDocument = new XmlDocument();
 | 
			
		||||
                                        xmlDocument.LoadXml(responseContent);
 | 
			
		||||
 | 
			
		||||
                                        // 找到所有的 err 節點
 | 
			
		||||
                                        XmlNodeList errNodes = xmlDocument.GetElementsByTagName("err");
 | 
			
		||||
 | 
			
		||||
                                        // 如果有錯誤節點,進行處理
 | 
			
		||||
                                        foreach (XmlNode errNode in errNodes)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            logger.LogWarning($"【ParkingJob】【設備資訊】[錯誤內容]:{errNode}");
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        logger.LogInformation("【ParkingJob】【設備資訊】[批次請求成功]");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    logger.LogWarning("【ParkingJob】【設備資訊】[沒有需要發送的請求]");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                logger.LogWarning("【ParkingJob】【設備資訊】 - [查無資料]");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ParkingJob", "Device", "執行成功設備資訊Job");
 | 
			
		||||
                            //logger.LogInformation("【ParkingJob】【執行成功設備資訊Job】");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ using BackendWorkerService.Services.Implement;
 | 
			
		||||
using RainApi;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Xml.Linq;
 | 
			
		||||
 | 
			
		||||
namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
{
 | 
			
		||||
@ -660,44 +661,142 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                        await task_Detail.WorkFail("WeatherAPI", "api_earthquake", ex.Message.ToString());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Niagara批次寫法
 | 
			
		||||
                if (await task_Detail.GetNeedWorkTask("WeatherAPI", "set_weather"))
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        await task_Detail.InsertWorkTime("WeatherAPI", "set_weather");
 | 
			
		||||
 | 
			
		||||
                        var sql = @$"SELECT	
 | 
			
		||||
                                         id,
 | 
			
		||||
                                         weather_type,
 | 
			
		||||
                                         get_value
 | 
			
		||||
                                     FROM api_weateher
 | 
			
		||||
                            where id in (select MAX(id) from api_weateher where start_time < NOW() group by weather_type)
 | 
			
		||||
                            order by start_time desc";
 | 
			
		||||
                                     WHERE id IN (
 | 
			
		||||
                                         SELECT MAX(id) 
 | 
			
		||||
                                         FROM api_weateher 
 | 
			
		||||
                                         WHERE start_time < NOW() 
 | 
			
		||||
                                         GROUP BY weather_type
 | 
			
		||||
                                     )
 | 
			
		||||
                                     ORDER BY start_time DESC";
 | 
			
		||||
                        var types = await backendRepository.GetAllAsync<ShowWeather>(sql);
 | 
			
		||||
                        var T = types.Where(a => a.weather_type == "T").FirstOrDefault();
 | 
			
		||||
                        var RbT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", RbT, T.id);
 | 
			
		||||
                        var urlMapping = new Dictionary<string, string>
 | 
			
		||||
                        {
 | 
			
		||||
                            { "T", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set" },
 | 
			
		||||
                            { "RH", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set" },
 | 
			
		||||
                            { "PoP12h", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set" },
 | 
			
		||||
                            { "Wx", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set" }
 | 
			
		||||
                        };
 | 
			
		||||
 | 
			
		||||
                        var RH = types.Where(a => a.weather_type == "RH").FirstOrDefault();
 | 
			
		||||
                        var RHT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", RHT, RH.id);
 | 
			
		||||
                        // 建立批次請求
 | 
			
		||||
                        var batchRequests = types
 | 
			
		||||
                            .Where(t => urlMapping.ContainsKey(t.weather_type))
 | 
			
		||||
                            .Select(t => (
 | 
			
		||||
                                url: obixApiConfig.ApiBase + urlMapping[t.weather_type],
 | 
			
		||||
                                value: t.get_value
 | 
			
		||||
                            ))
 | 
			
		||||
                            .ToList();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        // 呼叫批次請求
 | 
			
		||||
                        var batchResponse = await ProcessBatchRequestAsync(obixApiConfig, batchRequests);
 | 
			
		||||
 | 
			
		||||
                        // 解析回應 XML
 | 
			
		||||
                        var batchResponseXml = XDocument.Parse(batchResponse);
 | 
			
		||||
 | 
			
		||||
                        var listElement = batchResponseXml.Descendants().FirstOrDefault(e => e.Name.LocalName == "list");
 | 
			
		||||
 | 
			
		||||
                        if (listElement == null)
 | 
			
		||||
                        {
 | 
			
		||||
                            throw new Exception("Batch response XML does not contain a 'list' element.");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        var childElements = listElement.Elements().ToList();
 | 
			
		||||
 | 
			
		||||
                        // 使用 urlMapping 的值反向找對應的 weather_type
 | 
			
		||||
                        for (int i = 0; i < childElements.Count; i++)
 | 
			
		||||
                        {
 | 
			
		||||
                            var tag = childElements[i].Name.LocalName;
 | 
			
		||||
                            var responseStr = childElements[i].ToString();
 | 
			
		||||
                            var currentRequest = batchRequests[i];
 | 
			
		||||
 | 
			
		||||
                            // 找到當前 URL 在 urlMapping 中的 key (weather_type)
 | 
			
		||||
                            var weatherTypeKey = urlMapping.FirstOrDefault(x => currentRequest.url.Contains(x.Value)).Key;
 | 
			
		||||
 | 
			
		||||
                            if (weatherTypeKey != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                var weatherType = types.FirstOrDefault(t => t.weather_type == weatherTypeKey);
 | 
			
		||||
                                if (weatherType != null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (tag == "err")
 | 
			
		||||
                                    {
 | 
			
		||||
                                        UpdatedNiagara("api_weateher", responseStr, weatherType.id);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        UpdatedNiagara("api_weateher", "success", weatherType.id);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    logger.LogWarning($"No matching weather type found for key: {weatherTypeKey}");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                logger.LogWarning($"No matching URL found for request: {currentRequest.url}");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        var PoP12h = types.Where(a => a.weather_type == "PoP12h").FirstOrDefault();
 | 
			
		||||
                        var PoP12hT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", PoP12hT, PoP12h.id);
 | 
			
		||||
 | 
			
		||||
                        var Wx = types.Where(a => a.weather_type == "Wx").FirstOrDefault();
 | 
			
		||||
                        var WxT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", WxT, Wx.id);
 | 
			
		||||
                        await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather");
 | 
			
		||||
                        logger.LogInformation($"set niagara weather value success");
 | 
			
		||||
                        logger.LogInformation($"Set Niagara weather value success");
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
                        logger.LogInformation($"set niagara weather value fail");
 | 
			
		||||
                        await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message.ToString());
 | 
			
		||||
                        logger.LogError($"Set Niagara weather value fail: {ex.Message}");
 | 
			
		||||
                        await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                // Niagara單次寫法
 | 
			
		||||
                //if (await task_Detail.GetNeedWorkTask("WeatherAPI", "set_weather"))
 | 
			
		||||
                //{
 | 
			
		||||
                //    try
 | 
			
		||||
                //    {
 | 
			
		||||
                //        await task_Detail.InsertWorkTime("WeatherAPI", "set_weather");
 | 
			
		||||
                //        var sql = @$"SELECT	
 | 
			
		||||
                //                         id,
 | 
			
		||||
                //                         weather_type,
 | 
			
		||||
                //                         get_value
 | 
			
		||||
                //                     FROM api_weateher
 | 
			
		||||
                //            where id in (select MAX(id) from api_weateher where start_time < NOW() group by weather_type)
 | 
			
		||||
                //            order by start_time desc";
 | 
			
		||||
                //        var types = await backendRepository.GetAllAsync<ShowWeather>(sql);
 | 
			
		||||
                //        var T = types.Where(a => a.weather_type == "T").FirstOrDefault();
 | 
			
		||||
                //        var RbT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value);
 | 
			
		||||
                //        UpdatedNiagara("api_weateher", RbT, T.id);
 | 
			
		||||
 | 
			
		||||
                //        var RH = types.Where(a => a.weather_type == "RH").FirstOrDefault();
 | 
			
		||||
                //        var RHT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value);
 | 
			
		||||
                //        UpdatedNiagara("api_weateher", RHT, RH.id);
 | 
			
		||||
 | 
			
		||||
                //        var PoP12h = types.Where(a => a.weather_type == "PoP12h").FirstOrDefault();
 | 
			
		||||
                //        var PoP12hT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value);
 | 
			
		||||
                //        UpdatedNiagara("api_weateher", PoP12hT, PoP12h.id);
 | 
			
		||||
 | 
			
		||||
                //        var Wx = types.Where(a => a.weather_type == "Wx").FirstOrDefault();
 | 
			
		||||
                //        var WxT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value);
 | 
			
		||||
                //        UpdatedNiagara("api_weateher", WxT, Wx.id);
 | 
			
		||||
                //        await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather");
 | 
			
		||||
                //        logger.LogInformation($"set niagara weather value success");
 | 
			
		||||
                //    }
 | 
			
		||||
                //    catch (Exception ex)
 | 
			
		||||
                //    {
 | 
			
		||||
                //        logger.LogInformation($"set niagara weather value fail");
 | 
			
		||||
                //        await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message.ToString());
 | 
			
		||||
                //    }
 | 
			
		||||
                //}
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
@ -737,6 +836,51 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
            return rint;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<string> ProcessBatchRequestAsync(ObixApiConfig obixApiConfig, List<(string url, string value)> batchRequests)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                var batchRequestData = new StringBuilder();
 | 
			
		||||
                string authInfo = Convert.ToBase64String(Encoding.Default.GetBytes($"{obixApiConfig.UserName}:{obixApiConfig.Password}"));
 | 
			
		||||
 | 
			
		||||
                // 組合批次請求的資料
 | 
			
		||||
                foreach (var request in batchRequests)
 | 
			
		||||
                {
 | 
			
		||||
                    var jsonData = $"<real name='in' val=\"{request.value}\" />";
 | 
			
		||||
                    batchRequestData.AppendLine($"<uri is='obix:Invoke' val='{request.url}'>" + jsonData + "</uri>");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 最終的批次請求資料
 | 
			
		||||
                var batchRequestXml = $@"<list is='obix:BatchIn'>{batchRequestData}</list>";
 | 
			
		||||
 | 
			
		||||
                // 建立 HTTP 請求
 | 
			
		||||
                var requestBacth = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/batch");
 | 
			
		||||
                requestBacth.Method = "POST";
 | 
			
		||||
                requestBacth.Headers.Add("Authorization", "Basic " + authInfo);
 | 
			
		||||
 | 
			
		||||
                // 寫入請求資料
 | 
			
		||||
                using (var streamWriter = new StreamWriter(requestBacth.GetRequestStream()))
 | 
			
		||||
                {
 | 
			
		||||
                    streamWriter.Write(batchRequestXml);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 獲取回應
 | 
			
		||||
                using (var response = (HttpWebResponse)await requestBacth.GetResponseAsync())
 | 
			
		||||
                using (var streamReader = new StreamReader(response.GetResponseStream()))
 | 
			
		||||
                {
 | 
			
		||||
                    return await streamReader.ReadToEndAsync();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                return "BatchRequestg失敗";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public async void UpdatedNiagara(string DBTableName, string ResponseStr, int CheckNumId)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user