Worker.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using Newtonsoft.Json;
  2. using ServiceCenter;
  3. using ServiceCenter.Redis;
  4. using ServiceCenter.SqlSugars;
  5. using ServiceCenter.Virtual_PLC;
  6. using SqlSugar;
  7. using System.Text;
  8. using WCS.Core;
  9. using WCS.Entity;
  10. using WCS.Entity.Protocol;
  11. using WCS.Entity.Protocol.BCR;
  12. using WCS.Entity.Protocol.Station;
  13. using WCS.Service.Systems;
  14. namespace WCS.Service
  15. {
  16. /// <summary>
  17. /// 工作服务
  18. /// </summary>
  19. public class Worker : BackgroundService
  20. {
  21. /// <summary>
  22. /// 记录器
  23. /// </summary>
  24. private readonly ILogger<Worker> _logger;
  25. /// <summary>
  26. /// 构造函数
  27. /// </summary>
  28. /// <param name="logger">记录器</param>
  29. public Worker(ILogger<Worker> logger)
  30. {
  31. _logger = logger;
  32. }
  33. public static readonly string WcsDlog = "WCSDlog";
  34. public static readonly string Wcsdb = "WCSDB";
  35. /// <summary>
  36. /// 执行
  37. /// </summary>
  38. /// <param name="stoppingToken">停止令牌</param>
  39. /// <returns></returns>
  40. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  41. {
  42. if (stoppingToken.IsCancellationRequested)
  43. return;
  44. #region 启用日志
  45. //var logConfigText = RedisHub.Default.Check("LogConfigText") ?? throw new Exception("请在Redis中配置log4net相关内容");
  46. //var logConfig = JsonConvert.DeserializeObject<LogConfig>(logConfigText);
  47. //LogHub.SetConfigInfo(logConfig!);
  48. #endregion 启用日志
  49. _logger.LogInformation("WCS开始启动");
  50. Configs.ProtocolProxyBaseType = typeof(ProtocolProxy);
  51. Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
  52. Configs.StringEncoding = Encoding.UTF8;
  53. var warehouseName = RedisHub.Default.Check("WarehouseName") ?? throw new Exception("请在Redis中配置仓库名称");
  54. if (string.IsNullOrEmpty(warehouseName)) throw new Exception("请在Redis中配置仓库名称");
  55. ServiceHub.SetWarehouseName(warehouseName);
  56. #region 初始化数据库连接
  57. var dbConnectionStrings = RedisHub.Default.Check("DbConnectionStrings") ?? throw new Exception("请在Redis中配置数据库连接相关内容");
  58. ServiceHub.DbConnectionStrings = JsonConvert.DeserializeObject<List<DataBaseConnectionString>>(dbConnectionStrings);
  59. if (ServiceHub.DbConnectionStrings != null)
  60. {
  61. if (ServiceHub.DbConnectionStrings.All(v => v.Key != Wcsdb)) throw new Exception("请在DbConnectionStrings中配置WCS基础数据库连接字符串");
  62. if (ServiceHub.DbConnectionStrings.All(v => v.Key == Wcsdb && !v.IsDefault)) throw new Exception("请在DbConnectionStrings中配置WCS基础数据库为默认数据库");
  63. if (ServiceHub.DbConnectionStrings.All(v => v.Key != WcsDlog)) throw new Exception("请在DbConnectionStrings中配置WCS日志数据库连接字符串");
  64. }
  65. //设置连接信息
  66. List<ConnectionConfig> connectionConfigs = new List<ConnectionConfig>();
  67. foreach (var connectionString in ServiceHub.DbConnectionStrings!)
  68. {
  69. connectionConfigs.Add(new ConnectionConfig()
  70. {
  71. ConfigId = connectionString.Key,
  72. ConnectionString = connectionString.ConnectionString,//连接符字串
  73. DbType = connectionString.DbType,//数据库类型
  74. IsAutoCloseConnection = true,//不设成true要手动close
  75. });
  76. };
  77. SqlSugarHelper.SetDb(new SqlSugarScope(connectionConfigs));
  78. //SqlSugarHelper.SetDb(new SqlSugarScope(connectionConfigs, db =>
  79. //{
  80. // db.GetConnectionScope(Wcsdb).Aop.OnLogExecuting = (sql, pars) =>
  81. // {
  82. // Console.WriteLine(db.GetConnectionScope(Wcsdb).Ado.Connection.ConnectionString + "\r\n " + sql);
  83. // Console.WriteLine();
  84. // Console.WriteLine();
  85. // };
  86. // db.GetConnectionScope(WcsDlog).Aop.OnLogExecuting = (sql, pars) =>
  87. // {
  88. // Console.WriteLine(db.GetConnectionScope(WcsDlog).Ado.Connection.ConnectionString + "\r\n " + sql);
  89. // Console.WriteLine();
  90. // Console.WriteLine();
  91. // };
  92. //}));
  93. //初始化数据库
  94. SqlSugarHelper.Do(db =>
  95. {
  96. foreach (var connectionString in ServiceHub.DbConnectionStrings!)
  97. {
  98. var _db = db.Connect.GetConnectionScope(connectionString.Key);
  99. switch (connectionString.Key)
  100. {
  101. case "WCSDB"://WCS基本数据库
  102. SqlSugarHelper.SetDefault(connectionString.Key);
  103. _db.CodeFirst.InitTables(typeof(WCS_PLC));
  104. _db.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
  105. _db.CodeFirst.InitTables(typeof(WCS_DEVICEHdr));
  106. _db.CodeFirst.InitTables(typeof(WCS_PathHdr));
  107. _db.CodeFirst.InitTables(typeof(WCS_PathDtl));
  108. _db.CodeFirst.InitTables(typeof(WCS_ROUTE));
  109. _db.CodeFirst.InitTables(typeof(WCS_TASK));
  110. _db.CodeFirst.InitTables(typeof(WCS_TASK_DTL));
  111. _db.CodeFirst.InitTables(typeof(WCS_TASK_OLD));
  112. _db.CodeFirst.InitTables(typeof(WCS_PlcData));
  113. _db.CodeFirst.InitTables(typeof(WCS_AGVTask));
  114. _db.CodeFirst.InitTables(typeof(WCS_DEVICEPROTOCOL));
  115. _db.CodeFirst.InitTables(typeof(WCS_GROUPMEMBER));
  116. break;
  117. case "WCSDlog"://WCS日志数据库
  118. SqlSugarHelper.SetDlog(connectionString.Key);
  119. _db.DbMaintenance.CreateDatabase();
  120. _db.CodeFirst.InitTables(typeof(WCS_BCR80));
  121. //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV520));
  122. //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV521));
  123. //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV523));
  124. //_db.CodeFirst.InitTables(typeof(WCS_SRM520));
  125. //_db.CodeFirst.InitTables(typeof(WCS_SRM521));
  126. //db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM537));
  127. _db.CodeFirst.InitTables(typeof(WCS_Station520));
  128. _db.CodeFirst.InitTables(typeof(WCS_Station521));
  129. _db.CodeFirst.InitTables(typeof(WCS_Station523));
  130. _db.CodeFirst.InitTables(typeof(WCS_Station91));
  131. break;
  132. default: //其他库
  133. break;
  134. };
  135. };
  136. });
  137. #endregion 初始化数据库连接
  138. #region 创建虚拟PLC
  139. var isOpenVirtualPlc = RedisHub.Default.Check("isOpenVirtualPLC") ?? throw new Exception("请在Redsi中配置是否启用虚拟PLC");
  140. if (isOpenVirtualPlc == "1")
  141. {
  142. var plcDataConnectionString = RedisHub.Default.Check("plcDataConnectionString") ?? throw new Exception("请在Redsi中配置虚拟PLC使用的Redis连接字符串");
  143. //从现有结构解析出需要的结构
  144. var list = new List<PLCData>();
  145. SqlSugarHelper.Do(db =>
  146. {
  147. var _db = db.Connect;
  148. var dataBlocks = _db.Queryable<WCS_DATABLOCK>().Includes(v => v.PLC).ToList();
  149. list.AddRange(dataBlocks.Select(dataBlock => new PLCData()
  150. {
  151. IP = dataBlock.PLC.IP,
  152. DB = dataBlock.NO,
  153. Length = dataBlock.LENGTH,
  154. DataLength = dataBlock.DATALENGTH,
  155. }));
  156. });
  157. PlcData.Init(plcDataConnectionString).InitPlcData(list);
  158. ServiceHub.AddSystemMode(SystemMode.虚拟plc);
  159. }
  160. #endregion 创建虚拟PLC
  161. var a = typeof(IStation520);
  162. //日志发布事件s
  163. Configs.PublishEvent += () =>
  164. {
  165. //WMS.UploadDevInfo();
  166. //ProtocolProxy.Do();
  167. };
  168. //异常上抛
  169. Configs.UploadException = (d, s) =>
  170. {
  171. //if (s == "接口调用中") return;
  172. //if (ProtocolProxy.AllDatas.ContainsKey(d))
  173. //{
  174. // ProtocolProxy.AllDatas[d].Info = s;
  175. // //ProtocolProxy.AllDatas[d].Frame = LogicHandler.Frame;
  176. //}
  177. //WMS.TaskException(d, s);
  178. };
  179. //创建PLC访问器
  180. Configs.PLCAccessorCreater = new PLCAccessors.PLCAccessorsCreater();
  181. try
  182. {
  183. SqlSugarHelper.Do(db =>
  184. {
  185. var _db = db.Connect;
  186. //获取所有DB块读写协议
  187. var dbProtocols = _db.Queryable<WCS_DEVICEPROTOCOL>().Includes(v => v.DB, p => p.PLC).ToList();
  188. foreach (var dbProtocol in dbProtocols)
  189. {
  190. #pragma warning disable CS8604 // 引用类型参数可能为 null。
  191. Add(Type.GetType(dbProtocol.DB.PROTOCOL), dbProtocol.DEVICECODE, dbProtocol.POSITION, dbProtocol.DB, dbProtocol.DB.PLC);
  192. #pragma warning restore CS8604 // 引用类型参数可能为 null。
  193. }
  194. });
  195. #region 唤醒所有的世界
  196. World.StartAll();
  197. #endregion 唤醒所有的世界
  198. _logger.LogInformation("WCS启动成功");
  199. #region 启用数据采集器
  200. while (true)
  201. {
  202. Ltc.GetSystem<DataCollectionSysyem>().Invoke(true);
  203. }
  204. #endregion 启用数据采集器
  205. }
  206. catch (Exception ex)
  207. {
  208. _logger.LogError("WCS启动失败{0}", ex.Message);
  209. }
  210. }
  211. /// <summary>
  212. /// 添加协议
  213. /// </summary>
  214. /// <param name="type">协议类型</param>
  215. /// <param name="code">设备号</param>
  216. /// <param name="position">地址</param>
  217. /// <param name="db">db</param>
  218. /// <param name="plc">PLC</param>
  219. public static void Add(Type type, string code, int position, WCS_DATABLOCK db, WCS_PLC plc)
  220. {
  221. var info = new ProtocolInfo
  222. {
  223. Position = position,
  224. DBInfo = new DBInfo
  225. {
  226. No = (ushort)db.NO,
  227. PLCInfo = new PLCInfo
  228. {
  229. IP = plc.IP,
  230. Port = plc.PORT,
  231. Rack = plc.RACK,
  232. Slot = plc.SLOT,
  233. Type = Core.PLCType.Siemens
  234. }
  235. }
  236. };
  237. try
  238. {
  239. Protocols.Add(type, code, info);
  240. }
  241. catch (Exception ex)
  242. {
  243. var a = ex;
  244. }
  245. }
  246. }
  247. }