using Microsoft.AspNetCore.Http;
|
using Microsoft.Extensions.DependencyInjection;
|
using Quartz;
|
using Quartz.Impl.Matchers;
|
using WIDESEA_Comm.LogInfo;
|
using WIDESEA_Core.Extensions;
|
using WIDESEA_Core.Extensions.AutofacManager;
|
using WIDESEA_Core.FreeDB;
|
using WIDESEA_Core.Utilities;
|
using WIDESEA_Entity.DomainModels;
|
using WIDESEA_WCS.IRepositories;
|
using WIDESEA_WCS.IServices;
|
using WIDESEA_WCS.Services.WCS.Partial.Scheduler;
|
using WIDESEA_WCS.WCSClient;
|
|
namespace WIDESEA_WCS.Services
|
{
|
public partial class VV_DispatchService
|
{
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IVV_DispatchRepository _repository;//访问数据库
|
|
FreeDB freeDB = new FreeDB();
|
SchedulerCenter scheduler = new SchedulerCenter();
|
|
[ActivatorUtilitiesConstructor]
|
public VV_DispatchService(
|
IVV_DispatchRepository dbRepository,
|
IHttpContextAccessor httpContextAccessor
|
)
|
: base(dbRepository)
|
{
|
_httpContextAccessor = httpContextAccessor;
|
_repository = dbRepository;
|
//多租户会用到这init代码,其他情况可以不用
|
//base.Init(dbRepository);
|
}
|
|
public VV_DispatchService(IVV_DispatchRepository repository)
|
: base(repository)
|
{
|
Init(repository);
|
}
|
|
public static IVV_DispatchService Instance
|
{
|
get { return AutofacContainerModule.GetService<IVV_DispatchService>(); }
|
}
|
|
|
/// <summary>
|
/// 启动服务
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent StartServe()
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
try
|
{
|
if (!scheduler.IsRun())
|
{
|
var cooRes = CoonPLC();
|
var startRes = SrartScheduler();
|
if (startRes.Status)
|
{
|
if (cooRes.Status)
|
{
|
return webResponse.OK("服务启动成功!");
|
}
|
else
|
{
|
//返回PLC异常
|
return cooRes;
|
}
|
}
|
else
|
{
|
//调度启动失败,关闭全部
|
WriteLog.Write_Log("服务", "服务", "启动服务\n[调度异常]" + startRes.Message);
|
return startRes;
|
}
|
}
|
else
|
{
|
return webResponse.Error("请勿重复启动!");
|
}
|
}
|
catch (Exception ex)
|
{
|
WriteLog.Write_Log("服务", "服务", "启动服务\n[异常]" + ex.Message);
|
return webResponse.Error($"异常,{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 启动调度
|
/// </summary>
|
private WebResponseContent SrartScheduler()
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
var jobs = freeDB.Select<VV_Dispatch>().ToList();
|
try
|
{
|
foreach (var job in jobs)
|
{
|
scheduler.AddJob(job);
|
}
|
scheduler.Start();
|
}
|
catch (Exception ex)
|
{
|
return webResponse.Error(ex.Message);
|
}
|
Console.WriteLine("服务启动成功!");
|
return webResponse.OK();
|
}
|
|
/// <summary>
|
/// 连接PLC
|
/// </summary>
|
/// <returns></returns>
|
private WebResponseContent CoonPLC()
|
{
|
WebResponseContent content = new WebResponseContent();
|
var plcList = freeDB.Select<dt_plcinfohead>().Where("EXISTS (select * from dt_equipmentinfo where equipment_state='Enable' and equipment_name=a.plcinfo_name)").ToList();
|
if (plcList.Count == 0)
|
{
|
throw new Exception("未配置任何PLC连接对象!");
|
}
|
|
var detialList = freeDB.Select<dt_plcinfodetail>().ToList();
|
PLCClient.Clients = new List<PLCClient>();
|
|
List<string> coonMsgList = new List<string>();
|
foreach (var plc in plcList)
|
{
|
try
|
{
|
#region PLC实例化
|
PLCClient client = null;
|
if (plc.plcinfo_type == "Simene")
|
{
|
client = new SiemensPLCClient()
|
{
|
PLCName = plc.plcinfo_name,
|
Ip = plc.plcinfo_ip,
|
Port = plc.plcinfo_port ?? 102,
|
Slot = plc.plcinfo_slot ?? 0
|
};
|
}
|
else if (plc.plcinfo_type == "SimeneS7_200smart")
|
{
|
client = new SiemensPLCClient(HslCommunication.Profinet.Siemens.SiemensPLCS.S200Smart)
|
{
|
PLCName = plc.plcinfo_name,
|
Ip = plc.plcinfo_ip,
|
Port = plc.plcinfo_port ?? 102,
|
Slot = plc.plcinfo_slot ?? 0
|
};
|
}
|
else if (plc.plcinfo_type == "ModelBus")
|
{
|
client = new ModelBusClient()
|
{
|
PLCName = plc.plcinfo_name,
|
Ip = plc.plcinfo_ip,
|
Port = plc.plcinfo_port ?? 102,
|
Slot = plc.plcinfo_slot ?? 0
|
};
|
}
|
#endregion
|
|
if (client != null)
|
{
|
client.itemGroups = GetItemData(detialList, plc.plcinfo_iotyep);
|
string coonMsg = client.Connect();
|
coonMsgList.Add(coonMsg);
|
|
PLCClient.Clients.Add(client);
|
}
|
else
|
{
|
coonMsgList.Add($"{plc.plcinfo_name},PLC类型{plc.plcinfo_type}不存在。");
|
}
|
}
|
catch (Exception ex)
|
{
|
coonMsgList.Add($"{plc.plcinfo_name}异常,{ex.Message}");
|
}
|
}
|
|
string msg = string.Empty;
|
var coonErrorMsgList = coonMsgList.Where(t => !t.EndsWith("连接成功")).ToList();
|
WriteLog.Write_Log("服务", "服务", "启动服务\n" + string.Join("\n", coonErrorMsgList) + "\n异常数:" + coonErrorMsgList.Count);
|
if (coonErrorMsgList.Count == 0)
|
{
|
return content.OK();
|
}
|
else
|
{
|
msg = string.Join("\n", coonErrorMsgList);
|
return content.Error(msg);
|
}
|
}
|
|
/// <summary>
|
/// 获取交互协议
|
/// </summary>
|
/// <param name="detialList"></param>
|
/// <param name="plcinfo_iotyep"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
private List<DBItemGroup> GetItemData(List<dt_plcinfodetail> detialList, string plcinfo_iotyep)
|
{
|
List<DBItemGroup> itmes = new List<DBItemGroup>();
|
var dataList = detialList.Where(t => t.plcdetail_iotype == plcinfo_iotyep).ToList();
|
foreach (var item in dataList)
|
{
|
var order = new DBItemGroup();
|
order.name = item.plcdetail_name;
|
order.dataType = item.plcdetail_valtype;
|
if (string.IsNullOrEmpty(item.plcdetail_value))
|
{
|
order.dbAddress = item.plcdetail_db;
|
}
|
else
|
{
|
order.dbAddress = item.plcdetail_db + "." + item.plcdetail_value;
|
}
|
itmes.Add(order);
|
}
|
return itmes;
|
}
|
|
/// <summary>
|
/// 关闭服务
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent CloseServe()
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
try
|
{
|
foreach (var item in PLCClient.Clients)
|
{
|
try
|
{
|
item.DisConnect();
|
}
|
catch { }
|
}
|
scheduler.Shutdown();
|
Console.WriteLine("服务关闭成功!");
|
WriteLog.Write_Log("服务", "服务", "服务关闭成功!");
|
}
|
catch (Exception ex)
|
{
|
WriteLog.Write_Log("服务", "服务", "关闭服务\n[异常]" + ex.Message);
|
}
|
return webResponse.OK("服务关闭成功!");
|
}
|
|
/// <summary>
|
/// 开启指定任务
|
/// </summary>
|
/// <param name="jobName"></param>
|
/// <returns></returns>
|
public WebResponseContent StartJob(string jobName)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
if (!scheduler.IsRun())
|
{
|
return webResponse.Error("请先启动服务!");
|
}
|
var jobData = freeDB.Select<VV_Dispatch>().Where(t => t.JobName == jobName).First();
|
if (jobData == null)
|
{
|
webResponse.Error($"调度{jobName}不存在!");
|
}
|
else
|
{
|
var job = scheduler.GetJobByJobName(jobName);
|
if (job != null)
|
{
|
webResponse.Error($"调度{jobName}已是执行状态!");
|
}
|
else
|
{
|
scheduler.AddJob(jobData);
|
webResponse.OK("调度添加成功");
|
}
|
}
|
return webResponse;
|
}
|
|
/// <summary>
|
/// 关闭指定任务
|
/// </summary>
|
/// <param name="jobName"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
public WebResponseContent CloseJob(string jobName)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
if (!scheduler.IsRun())
|
{
|
return webResponse.Error("请先启动服务!");
|
}
|
|
var job = scheduler.GetJobByJobName(jobName);
|
if (job == null)
|
{
|
return webResponse.Error($"任务{jobName},不存在!");
|
}
|
var res = scheduler.RemoveJob(job);
|
if (res)
|
{
|
webResponse.OK($"调度{jobName}关闭成功!");
|
}
|
else
|
{
|
webResponse.Error($"调度{jobName}关闭失败!");
|
}
|
return webResponse;
|
}
|
|
/// <summary>
|
/// 检查服务状态
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent CheckServeState()
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
var state = scheduler.IsRun();
|
if (state)
|
{
|
return webResponse.OK("调度已启动!");
|
}
|
else
|
{
|
return webResponse.Error("调度未启动!");
|
}
|
}
|
|
/// <summary>
|
/// 获取调度详情
|
/// </summary>
|
/// <param name="options"></param>
|
/// <returns></returns>
|
public override PageGridData<VV_Dispatch> GetPageData(PageDataOptions options)
|
{
|
var data = base.GetPageData(options);
|
var isRun = scheduler.IsRun();
|
if (isRun)
|
{
|
var jobs = scheduler.center.GetJobKeys(GroupMatcher<JobKey>.AnyGroup()).Result;
|
foreach (var item in data.rows)
|
{
|
item.IsRun = jobs.Where(t => t.Name == item.JobName).Any();
|
}
|
}
|
else
|
{
|
data.rows.ForEach(t => { t.IsRun = false; });
|
}
|
return data;
|
}
|
}
|
}
|