|
@@ -1,21 +1,268 @@
|
|
|
+using DBHelper;
|
|
|
+using DBHelper.Redis;
|
|
|
+using LogHelper;
|
|
|
+using Newtonsoft.Json;
|
|
|
+using ServiceCenter;
|
|
|
+using ServiceCenter.Virtual_PLC;
|
|
|
+using SqlSugar;
|
|
|
+using System.Text;
|
|
|
+using WCS.Core;
|
|
|
+using WCS.Entity;
|
|
|
+using WCS.Entity.Protocol;
|
|
|
+using WCS.Entity.Protocol.BCR;
|
|
|
+using WCS.Entity.Protocol.Station;
|
|
|
+
|
|
|
namespace WCS.Service
|
|
|
{
|
|
|
+ /// <summary>
|
|
|
+ /// 工作服务
|
|
|
+ /// </summary>
|
|
|
public class Worker : BackgroundService
|
|
|
{
|
|
|
+ /// <summary>
|
|
|
+ /// 记录器
|
|
|
+ /// </summary>
|
|
|
private readonly ILogger<Worker> _logger;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 构造函数
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="logger">记录器</param>
|
|
|
public Worker(ILogger<Worker> logger)
|
|
|
{
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
+ public static readonly string WcsDlog = "WCSDlog";
|
|
|
+ public static readonly string Wcsdb = "WCSDB";
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 执行
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="stoppingToken">停止令牌</param>
|
|
|
+ /// <returns></returns>
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
|
{
|
|
|
- while (!stoppingToken.IsCancellationRequested)
|
|
|
+ if (stoppingToken.IsCancellationRequested)
|
|
|
+ return;
|
|
|
+
|
|
|
+ #region 启用日志
|
|
|
+
|
|
|
+ var logConfigText = RedisHub.Default.Check("LogConfigText") ?? throw new Exception("请在Redis中配置log4net相关内容");
|
|
|
+ var logConfig = JsonConvert.DeserializeObject<LogConfig>(logConfigText);
|
|
|
+ LogHub.SetConfigInfo(logConfig!);
|
|
|
+
|
|
|
+ #endregion 启用日志
|
|
|
+
|
|
|
+ _logger.LogInformation("WCS开始启动");
|
|
|
+ Configs.ProtocolProxyBaseType = typeof(ProtocolProxy);
|
|
|
+ Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
|
|
+ Configs.StringEncoding = Encoding.UTF8;
|
|
|
+
|
|
|
+ #region 初始化数据库连接
|
|
|
+
|
|
|
+ var dbConnectionStrings = RedisHub.Default.Check("DbConnectionStrings") ?? throw new Exception("请在Redis中配置数据库连接相关内容");
|
|
|
+ ServiceHub.DbConnectionStrings = JsonConvert.DeserializeObject<List<DataBaseConnectionString>>(dbConnectionStrings);
|
|
|
+ if (ServiceHub.DbConnectionStrings != null)
|
|
|
{
|
|
|
- _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
|
|
- await Task.Delay(1000, stoppingToken);
|
|
|
+ if (ServiceHub.DbConnectionStrings.All(v => v.Key != Wcsdb)) throw new Exception("请在DbConnectionStrings中配置WCS基础数据库连接字符串");
|
|
|
+ if (ServiceHub.DbConnectionStrings.All(v => v.Key == Wcsdb && !v.IsDefault)) throw new Exception("请在DbConnectionStrings中配置WCS基础数据库为默认数据库");
|
|
|
+ if (ServiceHub.DbConnectionStrings.All(v => v.Key != WcsDlog)) throw new Exception("请在DbConnectionStrings中配置WCS日志数据库连接字符串");
|
|
|
}
|
|
|
+
|
|
|
+ foreach (var connectionString in ServiceHub.DbConnectionStrings!)
|
|
|
+ {
|
|
|
+ Db.CreateContext(new ConnectionConfig()
|
|
|
+ {
|
|
|
+ ConnectionString = connectionString.ConnectionString,
|
|
|
+ DbType = connectionString.DbType
|
|
|
+ }, connectionString.Key);
|
|
|
+ if (connectionString.IsDefault) Db.SetDefaultDbContextType(connectionString.Key);
|
|
|
+
|
|
|
+ switch (connectionString.Key)
|
|
|
+ {
|
|
|
+ case "WCSDB"://WCS基本数据库
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_PLC));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_DEVICEHdr));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_PathHdr));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_PathDtl));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_ROUTE));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_TASK));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_TASK_OLD));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_PlcData));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_AGVTask));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_DEVICEPROTOCOL));
|
|
|
+ db.Default.CodeFirst.InitTables(typeof(WCS_GROUPMEMBER));
|
|
|
+
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_BCR80));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_RGV520));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_RGV521));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_RGV523));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_SRM520));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_SRM521));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_SRM537));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_Station520));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_Station521));
|
|
|
+ //db.Default.CodeFirst.InitTables(typeof(WCS_Station523));
|
|
|
+ });
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "WCSDlog"://WCS日志数据库
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ //TODO:DbMaintenance.CreateDatabase()并没起到作用,如果没有对应的数据库的话任然需要手动新建一个
|
|
|
+ db.Context(WcsDlog).DbMaintenance.CreateDatabase();
|
|
|
+ db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_BCR80));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV520));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV521));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV523));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM520));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM521));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM537));
|
|
|
+ db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station520));
|
|
|
+ db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station521));
|
|
|
+ db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station523));
|
|
|
+ db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station91));
|
|
|
+ //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS.Entity.PlcRawData));
|
|
|
+ });
|
|
|
+ break;
|
|
|
+
|
|
|
+ default: //其他库
|
|
|
+ break;
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ #endregion 初始化数据库连接
|
|
|
+
|
|
|
+ #region 创建虚拟PLC
|
|
|
+
|
|
|
+ var isOpenVirtualPlc = RedisHub.Default.Check("isOpenVirtualPLC") ?? throw new Exception("请在Redsi中配置是否启用虚拟PLC");
|
|
|
+ if (isOpenVirtualPlc == "1")
|
|
|
+ {
|
|
|
+ var plcDataConnectionString = RedisHub.Default.Check("plcDataConnectionString") ?? throw new Exception("请在Redsi中配置虚拟PLC使用的Redis连接字符串");
|
|
|
+
|
|
|
+ //从现有结构解析出需要的结构
|
|
|
+ var list = new List<PLCData>();
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ var dataBlocks = db.Default.Queryable<WCS_DATABLOCK>().Includes(v => v.PLC).ToList();
|
|
|
+ list.AddRange(dataBlocks.Select(dataBlock => new PLCData()
|
|
|
+ {
|
|
|
+ IP = dataBlock.PLC.IP,
|
|
|
+ DB = dataBlock.NO,
|
|
|
+ Length = dataBlock.LENGTH,
|
|
|
+ DataLength = dataBlock.DATALENGTH,
|
|
|
+ }));
|
|
|
+ });
|
|
|
+ PlcData.Init(plcDataConnectionString).InitPlcData(list);
|
|
|
+
|
|
|
+ ServiceHub.AddSystemMode(SystemMode.虚拟plc);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion 创建虚拟PLC
|
|
|
+
|
|
|
+ //日志发布事件s
|
|
|
+ Configs.PublishEvent += () =>
|
|
|
+ {
|
|
|
+ //WMS.UploadDevInfo();
|
|
|
+ //ProtocolProxy.Do();
|
|
|
+ };
|
|
|
+ //异常上抛
|
|
|
+ Configs.UploadException = (d, s) =>
|
|
|
+ {
|
|
|
+ //if (s == "接口调用中") return;
|
|
|
+ //if (ProtocolProxy.AllDatas.ContainsKey(d))
|
|
|
+ //{
|
|
|
+ // ProtocolProxy.AllDatas[d].Info = s;
|
|
|
+ // //ProtocolProxy.AllDatas[d].Frame = LogicHandler.Frame;
|
|
|
+ //}
|
|
|
+ //WMS.TaskException(d, s);
|
|
|
+ };
|
|
|
+ //创建PLC访问器
|
|
|
+ Configs.PLCAccessorCreater = new PLCAccessors.PLCAccessorsCreater();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Db.Do(db =>
|
|
|
+ {
|
|
|
+ //获取所有DB块读写协议
|
|
|
+ var dbProtocols = db.Default.Queryable<WCS_DEVICEPROTOCOL>().Includes(v => v.DB, p => p.PLC).ToList();
|
|
|
+ foreach (var dbProtocol in dbProtocols)
|
|
|
+ {
|
|
|
+ if (dbProtocol.DEVICECODE.Contains("SRM"))
|
|
|
+ {
|
|
|
+ }
|
|
|
+ else if (dbProtocol.DEVICECODE.Contains("RGV"))
|
|
|
+ {
|
|
|
+ }
|
|
|
+ else if (dbProtocol.DEVICECODE.Contains("BCR"))
|
|
|
+ {
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (dbProtocol.DB.CODE.Contains("520"))
|
|
|
+ {
|
|
|
+ Add<IStation520>(dbProtocol.DEVICECODE, dbProtocol.POSITION, (ushort)dbProtocol.DB.NO, dbProtocol.DB.PLC.IP);
|
|
|
+ }
|
|
|
+ else if (dbProtocol.DB.CODE.Contains("521"))
|
|
|
+ {
|
|
|
+ Add<IStation521>(dbProtocol.DEVICECODE, dbProtocol.POSITION, (ushort)dbProtocol.DB.NO, dbProtocol.DB.PLC.IP);
|
|
|
+ }
|
|
|
+ else if (dbProtocol.DB.CODE.Contains("523"))
|
|
|
+ {
|
|
|
+ Add<IStation522>(dbProtocol.DEVICECODE, dbProtocol.POSITION, (ushort)dbProtocol.DB.NO, dbProtocol.DB.PLC.IP);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ #region 唤醒所有的世界
|
|
|
+
|
|
|
+ World.StartAll();
|
|
|
+
|
|
|
+ #endregion 唤醒所有的世界
|
|
|
+
|
|
|
+ _logger.LogInformation("WCS启动成功");
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ _logger.LogError("WCS启动失败{0}", ex.Message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 添加协议
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <param name="code"> </param>
|
|
|
+ /// <param name="position"> </param>
|
|
|
+ /// <param name="db"></param>
|
|
|
+ /// <param name="ip"></param>
|
|
|
+ public static void Add<T>(string code, int position, ushort db, string ip)
|
|
|
+ {
|
|
|
+ var info = new ProtocolInfo
|
|
|
+ {
|
|
|
+ Position = position,
|
|
|
+ DBInfo = new DBInfo
|
|
|
+ {
|
|
|
+ No = db,
|
|
|
+ PLCInfo = new PLCInfo
|
|
|
+ {
|
|
|
+ IP = ip,
|
|
|
+ Port = 102,
|
|
|
+ Rack = 0,
|
|
|
+ Slot = 1,
|
|
|
+ Type = Core.PLCType.Siemens
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Protocols<T>.Add(code, info);
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|