[BGService]新增燈控排程背景程式
[Webapi]搭配燈控排程背景程式進行修改
This commit is contained in:
parent
29ee81b469
commit
5b43c7ab63
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Backend\Backend.csproj" />
|
<ProjectReference Include="..\Backend\Backend.csproj" />
|
||||||
|
<ProjectReference Include="..\FrontendWebApi\FrontendWebApi.csproj" />
|
||||||
<ProjectReference Include="..\Repository\Repository.csproj" />
|
<ProjectReference Include="..\Repository\Repository.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ using Repository.FrontendRepository.Interface;
|
|||||||
using Repository.Helper;
|
using Repository.Helper;
|
||||||
using Repository.Models;
|
using Repository.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -149,11 +149,20 @@ namespace BackendWorkerService
|
|||||||
);
|
);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ©w®ÉÀˬd¿O±±±Æµ{
|
||||||
|
services.AddSingleton< LightScheduleJob>();
|
||||||
|
services.AddSingleton(
|
||||||
|
new JobSchedule(jobType: typeof(LightScheduleJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:LightScheduleJob "))
|
||||||
|
);
|
||||||
|
#endregion
|
||||||
|
|
||||||
}).ConfigureLogging((hostContext, logFactory) => {
|
}).ConfigureLogging((hostContext, logFactory) => {
|
||||||
IConfiguration configuration = hostContext.Configuration;
|
IConfiguration configuration = hostContext.Configuration;
|
||||||
|
|
||||||
//logFactory.AddFile("Logs/log-{Date}.txt");
|
//logFactory.AddFile("Logs/log-{Date}.txt");
|
||||||
logFactory.AddFile(configuration.GetValue<string>("LoggerPath") + "/log-{Date}.txt");
|
string loggerPath = configuration.GetValue<string>("LoggerPath");
|
||||||
|
|
||||||
|
logFactory.AddFile($"{loggerPath}/log-{{Date}}.txt");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ namespace BackendWorkerService.Quartz
|
|||||||
/// <param name="task"></param>
|
/// <param name="task"></param>
|
||||||
/// <param name="task_item"></param>
|
/// <param name="task_item"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<string> GetWorkRule(string task,string task_item)
|
private async Task<string> GetWorkRule(string task, string task_item)
|
||||||
{
|
{
|
||||||
string Times = null;
|
string Times = null;
|
||||||
try
|
try
|
||||||
@ -74,10 +74,10 @@ namespace BackendWorkerService.Quartz
|
|||||||
where a.task = '{task}' and a.task_item = '{task_item}'";
|
where a.task = '{task}' and a.task_item = '{task_item}'";
|
||||||
Times = await backendRepository.GetOneAsync<string>(sql);
|
Times = await backendRepository.GetOneAsync<string>(sql);
|
||||||
}
|
}
|
||||||
catch(Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.LogError("【Task_Detail】【任務時間獲取失敗】");
|
logger.LogError("【Task_Detail】【任務時間獲取失敗】");
|
||||||
logger.LogError("【Task_Detail】【任務時間獲取失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(),task,task_item);
|
logger.LogError("【Task_Detail】【任務時間獲取失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||||||
}
|
}
|
||||||
return Times;
|
return Times;
|
||||||
}
|
}
|
||||||
@ -100,13 +100,13 @@ namespace BackendWorkerService.Quartz
|
|||||||
|
|
||||||
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
|
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
|
||||||
|
|
||||||
var nextTime = CrontabSchedule.Parse(await GetWorkRule(task, task_item), new ParseOptions { IncludingSeconds = true } ).GetNextOccurrence(dateTime);
|
var nextTime = CrontabSchedule.Parse(await GetWorkRule(task, task_item), new ParseOptions { IncludingSeconds = true }).GetNextOccurrence(dateTime);
|
||||||
if (DateTime.Now >= nextTime)
|
if (DateTime.Now >= nextTime)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.LogError("【Task_Detail】【時間解析失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
logger.LogError("【Task_Detail】【時間解析失敗】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ namespace BackendWorkerService.Quartz
|
|||||||
/// <param name="task"></param>
|
/// <param name="task"></param>
|
||||||
/// <param name="task_item"></param>
|
/// <param name="task_item"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task InsertWorkTime(string task, string task_item ,string LoggerWord = null, DateTime? dateTime = null)
|
public async Task InsertWorkTime(string task, string task_item, string LoggerWord = null, DateTime? dateTime = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -130,12 +130,15 @@ namespace BackendWorkerService.Quartz
|
|||||||
};
|
};
|
||||||
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
|
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
|
||||||
|
|
||||||
if(LoggerWord == null)
|
if (LoggerWord == null)
|
||||||
{
|
{
|
||||||
logger.LogInformation($"【Task_Detail】【開始{task},{task_item}任務】");
|
logger.LogInformation($"【Task_Detail】【開始{task},{task_item}任務】");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.LogError("【Task_Detail】【任務輸入開始時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
logger.LogError("【Task_Detail】【任務輸入開始時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||||||
@ -147,7 +150,7 @@ namespace BackendWorkerService.Quartz
|
|||||||
/// <param name="task"></param>
|
/// <param name="task"></param>
|
||||||
/// <param name="task_item"></param>
|
/// <param name="task_item"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task InsertWorkTime_End(string task, string task_item,string LoggerWord = null)
|
public async Task InsertWorkTime_End(string task, string task_item, string LoggerWord = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -162,8 +165,11 @@ namespace BackendWorkerService.Quartz
|
|||||||
{
|
{
|
||||||
logger.LogInformation($"【Task_Detail】【結束{task},{task_item}任務】");
|
logger.LogInformation($"【Task_Detail】【結束{task},{task_item}任務】");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.LogError("【Task_Detail】【任務輸入結束時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
logger.LogError("【Task_Detail】【任務輸入結束時間】[Exception]:{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
|
||||||
@ -175,7 +181,7 @@ namespace BackendWorkerService.Quartz
|
|||||||
/// <param name="task"></param>
|
/// <param name="task"></param>
|
||||||
/// <param name="task_item"></param>
|
/// <param name="task_item"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task WorkFail(string task, string task_item,string reason = "")
|
public async Task WorkFail(string task, string task_item, string reason = "")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
194
BackendWorkerService/Quartz/Jobs/LightScheduleJob .cs
Normal file
194
BackendWorkerService/Quartz/Jobs/LightScheduleJob .cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
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");
|
||||||
|
#region 參考
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var d = deviceNum.Split("_");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
"ParkingJob": "0/5 * * * * ?",
|
"ParkingJob": "0/5 * * * * ?",
|
||||||
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
||||||
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
||||||
|
"LightScheduleJob ": "0/5 * * * * ?",
|
||||||
"WeatherAPIJob": "0/5 * * * * ?"
|
"WeatherAPIJob": "0/5 * * * * ?"
|
||||||
},
|
},
|
||||||
"DBConfig": {
|
"DBConfig": {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
//"ParkingJob": "0 0 2 * * ?",
|
//"ParkingJob": "0 0 2 * * ?",
|
||||||
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
||||||
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
||||||
|
"LightScheduleJob ": "0 0/1 * * * ?",
|
||||||
"WeatherAPIJob": "0 0 2 * * ?"
|
"WeatherAPIJob": "0 0 2 * * ?"
|
||||||
},
|
},
|
||||||
"DBConfig": {
|
"DBConfig": {
|
||||||
|
@ -147,8 +147,12 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
{
|
{
|
||||||
opeInput.action_name = "修改";
|
opeInput.action_name = "修改";
|
||||||
Dictionary<string, object> Schedule = new Dictionary<string, object>();
|
Dictionary<string, object> Schedule = new Dictionary<string, object>();
|
||||||
|
// 配合燈控排程背景程式更新guid(因排程根據guid執行起始結束各一次,若中途修改條件則不會執行,故作此修改)
|
||||||
|
var newguid = Guid.NewGuid();
|
||||||
|
|
||||||
Schedule = new Dictionary<string, object>()
|
Schedule = new Dictionary<string, object>()
|
||||||
{
|
{
|
||||||
|
{ "@light_schedule_guid",newguid},
|
||||||
{ "@status", saveSchedule.status},
|
{ "@status", saveSchedule.status},
|
||||||
{ "@full_name", saveSchedule.full_name},
|
{ "@full_name", saveSchedule.full_name},
|
||||||
{ "@week", saveSchedule.week},
|
{ "@week", saveSchedule.week},
|
||||||
@ -198,7 +202,7 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
Dictionary<string, object> ScheduleDevice = new Dictionary<string, object>();
|
Dictionary<string, object> ScheduleDevice = new Dictionary<string, object>();
|
||||||
ScheduleDevice = new Dictionary<string, object>()
|
ScheduleDevice = new Dictionary<string, object>()
|
||||||
{
|
{
|
||||||
{ "@light_schedule_guid", saveSchedule.light_schedule_guid},
|
{ "@light_schedule_guid", newguid},
|
||||||
{ "@device_guid", a}
|
{ "@device_guid", a}
|
||||||
};
|
};
|
||||||
ScheduleDevices.Add(ScheduleDevice);
|
ScheduleDevices.Add(ScheduleDevice);
|
||||||
|
@ -30,6 +30,14 @@ namespace FrontendWebApi.Models
|
|||||||
public string end_time { get; set; }
|
public string end_time { get; set; }
|
||||||
public byte status { get; set; }
|
public byte status { get; set; }
|
||||||
}
|
}
|
||||||
|
public class ScheduleLog
|
||||||
|
{
|
||||||
|
public int light_schedule_log_id { get; set; }
|
||||||
|
public string light_schedule_guid { get; set; }
|
||||||
|
public string date { get; set; }
|
||||||
|
public string start_time { get; set; }
|
||||||
|
public string end_time { get; set; }
|
||||||
|
}
|
||||||
public class SaveSchedule : Schedule
|
public class SaveSchedule : Schedule
|
||||||
{
|
{
|
||||||
public List<string> devicelist { get; set; }
|
public List<string> devicelist { get; set; }
|
||||||
|
Loading…
Reference in New Issue
Block a user