using Newtonsoft.Json; using ServiceCenter; using ServiceCenter.Redis; using ServiceCenter.SqlSugars; 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; using WCS.Service.Systems; namespace WCS.Service { /// /// 工作服务 /// public class Worker : BackgroundService { /// /// 记录器 /// private readonly ILogger _logger; /// /// 构造函数 /// /// 记录器 public Worker(ILogger logger) { _logger = logger; } public static readonly string WcsDlog = "WCSDlog"; public static readonly string Wcsdb = "WCSDB"; /// /// 执行 /// /// 停止令牌 /// protected override async Task ExecuteAsync(CancellationToken stoppingToken) { if (stoppingToken.IsCancellationRequested) return; #region 启用日志 //var logConfigText = RedisHub.Default.Check("LogConfigText") ?? throw new Exception("请在Redis中配置log4net相关内容"); //var logConfig = JsonConvert.DeserializeObject(logConfigText); //LogHub.SetConfigInfo(logConfig!); #endregion 启用日志 _logger.LogInformation("WCS开始启动"); Configs.ProtocolProxyBaseType = typeof(ProtocolProxy); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Configs.StringEncoding = Encoding.UTF8; var warehouseName = RedisHub.Default.Check("WarehouseName") ?? throw new Exception("请在Redis中配置仓库名称"); if (string.IsNullOrEmpty(warehouseName)) throw new Exception("请在Redis中配置仓库名称"); ServiceHub.SetWarehouseName(warehouseName); #region 初始化数据库连接 var dbConnectionStrings = RedisHub.Default.Check("DbConnectionStrings") ?? throw new Exception("请在Redis中配置数据库连接相关内容"); ServiceHub.DbConnectionStrings = JsonConvert.DeserializeObject>(dbConnectionStrings); if (ServiceHub.DbConnectionStrings != null) { 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日志数据库连接字符串"); } //设置连接信息 List connectionConfigs = new List(); foreach (var connectionString in ServiceHub.DbConnectionStrings!) { connectionConfigs.Add(new ConnectionConfig() { ConfigId = connectionString.Key, ConnectionString = connectionString.ConnectionString,//连接符字串 DbType = connectionString.DbType,//数据库类型 IsAutoCloseConnection = true,//不设成true要手动close }); }; SqlSugarHelper.SetDb(new SqlSugarScope(connectionConfigs)); //SqlSugarHelper.SetDb(new SqlSugarScope(connectionConfigs, db => //{ // db.GetConnectionScope(Wcsdb).Aop.OnLogExecuting = (sql, pars) => // { // Console.WriteLine(db.GetConnectionScope(Wcsdb).Ado.Connection.ConnectionString + "\r\n " + sql); // Console.WriteLine(); // Console.WriteLine(); // }; // db.GetConnectionScope(WcsDlog).Aop.OnLogExecuting = (sql, pars) => // { // Console.WriteLine(db.GetConnectionScope(WcsDlog).Ado.Connection.ConnectionString + "\r\n " + sql); // Console.WriteLine(); // Console.WriteLine(); // }; //})); //初始化数据库 SqlSugarHelper.Do(db => { foreach (var connectionString in ServiceHub.DbConnectionStrings!) { var _db = db.Connect.GetConnectionScope(connectionString.Key); switch (connectionString.Key) { case "WCSDB"://WCS基本数据库 SqlSugarHelper.SetDefault(connectionString.Key); _db.CodeFirst.InitTables(typeof(WCS_PLC)); _db.CodeFirst.InitTables(typeof(WCS_DATABLOCK)); _db.CodeFirst.InitTables(typeof(WCS_DEVICEHdr)); _db.CodeFirst.InitTables(typeof(WCS_PathHdr)); _db.CodeFirst.InitTables(typeof(WCS_PathDtl)); _db.CodeFirst.InitTables(typeof(WCS_ROUTE)); _db.CodeFirst.InitTables(typeof(WCS_TASK)); _db.CodeFirst.InitTables(typeof(WCS_TASK_DTL)); _db.CodeFirst.InitTables(typeof(WCS_TASK_OLD)); _db.CodeFirst.InitTables(typeof(WCS_PlcData)); _db.CodeFirst.InitTables(typeof(WCS_AGVTask)); _db.CodeFirst.InitTables(typeof(WCS_DEVICEPROTOCOL)); _db.CodeFirst.InitTables(typeof(WCS_GROUPMEMBER)); break; case "WCSDlog"://WCS日志数据库 SqlSugarHelper.SetDlog(connectionString.Key); _db.DbMaintenance.CreateDatabase(); _db.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.CodeFirst.InitTables(typeof(WCS_SRM520)); //_db.CodeFirst.InitTables(typeof(WCS_SRM521)); //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM537)); _db.CodeFirst.InitTables(typeof(WCS_Station520)); _db.CodeFirst.InitTables(typeof(WCS_Station521)); _db.CodeFirst.InitTables(typeof(WCS_Station523)); _db.CodeFirst.InitTables(typeof(WCS_Station91)); 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(); SqlSugarHelper.Do(db => { var _db = db.Connect; var dataBlocks = _db.Queryable().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 var a = typeof(IStation520); //日志发布事件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 { SqlSugarHelper.Do(db => { var _db = db.Connect; //获取所有DB块读写协议 var dbProtocols = _db.Queryable().Includes(v => v.DB, p => p.PLC).ToList(); foreach (var dbProtocol in dbProtocols) { #pragma warning disable CS8604 // 引用类型参数可能为 null。 Add(Type.GetType(dbProtocol.DB.PROTOCOL), dbProtocol.DEVICECODE, dbProtocol.POSITION, dbProtocol.DB, dbProtocol.DB.PLC); #pragma warning restore CS8604 // 引用类型参数可能为 null。 } }); #region 唤醒所有的世界 World.StartAll(); #endregion 唤醒所有的世界 _logger.LogInformation("WCS启动成功"); #region 启用数据采集器 while (true) { Ltc.GetSystem().Invoke(true); } #endregion 启用数据采集器 } catch (Exception ex) { _logger.LogError("WCS启动失败{0}", ex.Message); } } /// /// 添加协议 /// /// 协议类型 /// 设备号 /// 地址 /// db /// PLC public static void Add(Type type, string code, int position, WCS_DATABLOCK db, WCS_PLC plc) { var info = new ProtocolInfo { Position = position, DBInfo = new DBInfo { No = (ushort)db.NO, PLCInfo = new PLCInfo { IP = plc.IP, Port = plc.PORT, Rack = plc.RACK, Slot = plc.SLOT, Type = Core.PLCType.Siemens } } }; try { Protocols.Add(type, code, info); } catch (Exception ex) { var a = ex; } } } }