ibms-dome/BackendWorkerService/Quartz/Jobs/LightScheduleJob .cs

422 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Backend.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Implement;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using System.Linq;
using NCrontab;
using BackendWorkerService.Services.Implement;
using RainApi;
using System.Globalization;
using FrontendWebApi.Models;
using Repository.FrontendRepository.Interface;
using Microsoft.Extensions.Hosting;
using Repository.FrontendRepository.Implement;
using iTextSharp.text;
using NPOI.SS.Formula.Functions;
using System.Text.RegularExpressions;
using Repository.Models;
namespace BackendWorkerService.Quartz.Jobs
{
[DisallowConcurrentExecution]
class LightScheduleJob : IJob
{
private readonly ILogger<LightScheduleJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackendRepository backendRepository;
private readonly ILogger<Task_Detail> loggers;
public LightScheduleJob(ILogger<LightScheduleJob> logger,
IBackgroundServiceRepository backgroundServiceRepository, IBackendRepository backendRepository, ILogger<Task_Detail> loggers)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.backendRepository = backendRepository;
this.loggers = loggers;
}
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)
{
// 先檢查今日否需執行
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(" ");
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)
{
Dictionary<string, object> log = new Dictionary<string, object>()
{
{ "@light_schedule_guid", light_schedule_guid },
{ "@date", date },
};
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 = "false"; // 關閉
}
if (!string.IsNullOrEmpty(check))
{
bool requestSuccess = await UpdatedNiagara(oneSchedule, check);
}
}
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 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");
// 取得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();
foreach (var deviceNum in deviceNumList)
{
// 處理設備號碼分解到URL中
var d = tagChange.AddStringIfStartsWithDigit(deviceNum, "$3");
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(batchRequestData);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
// 發送請求並處理回應
var response = (HttpWebResponse)request.GetResponse();
string responseContent = string.Empty;
using (var sr = new StreamReader(response.GetResponseStream()))
{
responseContent = sr.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($"【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】批次請求發送失敗" + 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;
// }
//}
}
}