高级排程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1171 lines
35 KiB

  1. package service
  2. import (
  3. "LAPP_AS/common"
  4. base_dal "LAPP_AS/dao/base"
  5. me_dal "LAPP_AS/dao/me"
  6. om_dal "LAPP_AS/dao/om"
  7. wm_dal "LAPP_AS/dao/wm"
  8. "LAPP_AS/db"
  9. meta "LAPP_AS/meta/om"
  10. base_model "LAPP_AS/models/base"
  11. me_model "LAPP_AS/models/me"
  12. om_model "LAPP_AS/models/om"
  13. wm_model "LAPP_AS/models/wm"
  14. "fmt"
  15. "github.com/pkg/errors"
  16. "time"
  17. )
  18. /**调度引擎**/
  19. type SchedulerSrv struct{
  20. PlantNr int
  21. StartDate time.Time
  22. EndDate time.Time
  23. WorkPlaceDict map[string]*WorkPlaceSrv // 所有的设备对象
  24. WorkPlaceGrpDict map[string]*WorkPlaceGrpSrv
  25. ToolDict map[string]*ToolSrv // 所有的工具对象
  26. ToolGrpDict map[string]*ToolGrpSrv
  27. ArticleDict map[string]*ArticleSrv // 所有的物料对象
  28. SecResourceDict map[string]*SecondaryResourceSrv // 所有的次要资源对象
  29. PersonDict map[int]*PersonSrv // 所有人员对象
  30. SkillDict map[string]*SkillSrv // 所有技能对象
  31. OrderDict map[string]*OrderSrv // 所有工单对象
  32. OperationDict map[string]*OperationSrv // 所有订单工序对象
  33. TmSrv TimeModelSrv // 时间模型
  34. ProjDict map[string]me_model.Project // 激活的项目字典
  35. SchedRule ScheduleRuleSrv // 调度规则
  36. SchedEventQueue *SchedQueue // 调度事件队列
  37. }
  38. // 调度引擎初始化
  39. func(se *SchedulerSrv)Init(plantnr int, stdate, eddate time.Time){
  40. se.PlantNr = plantnr
  41. se.StartDate = stdate
  42. se.EndDate = eddate
  43. se.WorkPlaceDict = make(map[string]*WorkPlaceSrv)
  44. se.WorkPlaceGrpDict = make(map[string]*WorkPlaceGrpSrv)
  45. se.ToolDict = make(map[string]*ToolSrv)
  46. se.ToolGrpDict = make(map[string]*ToolGrpSrv)
  47. se.ArticleDict = make(map[string]*ArticleSrv)
  48. se.SecResourceDict = make(map[string]*SecondaryResourceSrv)
  49. se.PersonDict = make(map[int]*PersonSrv)
  50. se.SkillDict = make(map[string]*SkillSrv)
  51. se.OrderDict = make(map[string]*OrderSrv)
  52. se.OperationDict = make(map[string]*OperationSrv)
  53. se.TmSrv = TimeModelSrv{PlantNr: plantnr}
  54. se.SchedEventQueue = NewSchedQueue()
  55. }
  56. // 加载时间模型主数据
  57. func(se *SchedulerSrv)LoadTimeModelData(){
  58. // 加载指定日期范畴内的时间模型相关主数据
  59. se.TmSrv.LoadBasicData(se.StartDate, se.EndDate)
  60. // 生成日模型的时间线列表
  61. se.TmSrv.GenDayModelLineArray()
  62. }
  63. // 加载激活的项目
  64. func(se *SchedulerSrv)LoadProjectData()(err error){
  65. var(
  66. i int
  67. projtablst []me_model.Project
  68. )
  69. // 初始化
  70. se.ProjDict = make(map[string]me_model.Project )
  71. // 读取激活的项目数据
  72. engine := db.Eloquent.Master()
  73. session := engine.NewSession()
  74. defer session.Close()
  75. me_dao := me_dal.NewProjectDAO(session, se.PlantNr, "scheduler")
  76. if projtablst, err = me_dao.SelectActiveProjects(); err != nil{
  77. err = errors.New(fmt.Sprintf("获取工厂%d的激活的项目失败%v !", se.PlantNr, err))
  78. return
  79. }
  80. // 加载项目
  81. for i = 0; i < len(projtablst); i++ {
  82. se.ProjDict[projtablst[i].ProjectId] = projtablst[i]
  83. }
  84. return
  85. }
  86. // 加载工位主数据
  87. func(se *SchedulerSrv)LoadWorkPlaceData()(err error){
  88. var(
  89. wp *WorkPlaceSrv
  90. wpg *WorkPlaceGrpSrv
  91. wptab base_model.WorkPlace
  92. wptablst []base_model.WorkPlace
  93. wpgtab base_model.WorkPlaceGrp
  94. wpgtablst []base_model.WorkPlaceGrp
  95. ok bool
  96. )
  97. engine := db.Eloquent.Master()
  98. session := engine.NewSession()
  99. defer session.Close()
  100. WorkPlaceGrp_dao := base_dal.NewWorkPlaceGrpDAO(session, se.PlantNr, "scheduler")
  101. // 加载并创建工位组对象
  102. if wpgtablst, err = WorkPlaceGrp_dao.SelectAll(); err != nil{
  103. err = errors.New(fmt.Sprintf("加载工位组主数据出错:%v",err))
  104. return
  105. }
  106. for _, wpgtab = range wpgtablst {
  107. wpg = &WorkPlaceGrpSrv{}
  108. wpg.Create(wpgtab)
  109. se.WorkPlaceGrpDict[wpg.WorkPlaceGrpId] = wpg
  110. }
  111. // 加载并创建工位对象
  112. WorkPlace_dao := base_dal.NewWorkPlaceDAO(session, se.PlantNr, "scheduler")
  113. if wptablst, err = WorkPlace_dao.SelectAll(); err != nil{
  114. err = errors.New(fmt.Sprintf("加载工位主数据出错:%v",err))
  115. return
  116. }
  117. for _, wptab = range wptablst {
  118. wp = &WorkPlaceSrv{}
  119. wp.Create(wptab)
  120. // 生成工位的时间曲线 todo
  121. err := wp.GetWorkDayList(&se.TmSrv)
  122. if err != nil {
  123. fmt.Println(err)
  124. }
  125. // 基于产线的时间模型和排班获取产线在指定时间区间内的时间线集合
  126. wp.GenerateTimeCurve(&se.TmSrv)
  127. // 获取工位组对象
  128. if wpg, ok = se.WorkPlaceGrpDict[wp.WorkPlaceGrpId]; ok {
  129. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  130. se.WorkPlaceGrpDict[wp.WorkPlaceGrpId].WorkPlaceDict[wp.WorkPlaceId] = wp
  131. }
  132. }
  133. return
  134. }
  135. // 加载工具主数据
  136. func(se *SchedulerSrv)LoadToolData()(err error){
  137. var(
  138. toolsrv *ToolSrv
  139. toolgrpsrv *ToolGrpSrv
  140. tooltab base_model.Tool
  141. tooltablst []base_model.Tool
  142. toolgrptab base_model.ToolGrp
  143. toolgrptablst []base_model.ToolGrp
  144. tavailtab base_model.ToolUnAvailTimeLst
  145. tavailtablst []base_model.ToolUnAvailTimeLst
  146. timelinesrv TimeLineSrv
  147. ok bool
  148. )
  149. engine := db.Eloquent.Master()
  150. session := engine.NewSession()
  151. defer session.Close()
  152. // 加载并创建工具组对象
  153. toolGrp_Dao := base_dal.NewToolGrpDAO(session, se.PlantNr, "scheduler")
  154. if toolgrptablst, err = toolGrp_Dao.SelectAll(); err != nil{
  155. err = errors.New(fmt.Sprintf("加载工具组主数据出错:%v",err))
  156. return
  157. }
  158. for _, toolgrptab = range toolgrptablst {
  159. toolgrpsrv = &ToolGrpSrv{}
  160. toolgrpsrv.Create(toolgrptab)
  161. se.ToolGrpDict[toolgrpsrv.ToolGrpId] = toolgrpsrv
  162. }
  163. // 加载并创建工具对象
  164. tool_Dao := base_dal.NewToolDAO(session, se.PlantNr, "scheduler")
  165. if tooltablst, err = tool_Dao.SelectAll(); err != nil{
  166. err = errors.New(fmt.Sprintf("加载工具组主数据出错:%v",err))
  167. return
  168. }
  169. for _, tooltab = range tooltablst {
  170. toolsrv = &ToolSrv{}
  171. toolsrv.Create(tooltab)
  172. // 更新工具组和工具的关联关系
  173. if toolgrpsrv, ok = se.ToolGrpDict[toolsrv.ToolGrpId]; ok {
  174. toolgrpsrv.ToolDict[toolsrv.ToolId] = toolsrv
  175. }
  176. // 插入工具
  177. se.ToolDict[toolsrv.ToolId] = toolsrv
  178. }
  179. // 基于计划的指定计划时段加载工具的不可用时间数据
  180. toolUnAvailTimeLst_Dao := base_dal.NewToolUnAvailTimeLstDAO(session, se.PlantNr, "scheduler")
  181. if tavailtablst, err = toolUnAvailTimeLst_Dao.GetUnAvailTime(se.StartDate, se.EndDate); err != nil{
  182. err = errors.New(fmt.Sprintf("加载工具不可用时间数据出错:%v",err))
  183. return
  184. }
  185. for _, tavailtab = range tavailtablst {
  186. if toolsrv, ok = se.ToolDict[tavailtab.ToolId]; ok{
  187. timelinesrv = TimeLineSrv{}
  188. timelinesrv.Init(tavailtab.BegTime.Restore(), tavailtab.EndTime.Restore())
  189. toolsrv.UnAvailTimeLineArray = append(toolsrv.UnAvailTimeLineArray, timelinesrv)
  190. }
  191. }
  192. return
  193. }
  194. // 加载物料主数据,包括库存及在途
  195. func(se *SchedulerSrv)LoadArticleData()(err error){
  196. var(
  197. artsrv *ArticleSrv
  198. arttab base_model.Article
  199. arttablst []base_model.Article
  200. artstocktab wm_model.Stock
  201. artstocktablst []wm_model.Stock
  202. arttransittab wm_model.TransitStock
  203. arttransittablst []wm_model.TransitStock
  204. ok bool
  205. )
  206. engine := db.Eloquent.Master()
  207. session := engine.NewSession()
  208. defer session.Close()
  209. // 获取物料主数据
  210. article_Dao := base_dal.NewArticleDAO(session, se.PlantNr, "scheduler")
  211. if arttablst, err = article_Dao.SelectAll(); err != nil{
  212. err = errors.New(fmt.Sprintf("加载物料主数据出错:%v",err))
  213. return
  214. }
  215. // 创建物料对象
  216. for _, arttab = range arttablst {
  217. artsrv = &ArticleSrv{}
  218. artsrv.Create(arttab)
  219. se.ArticleDict[artsrv.ArtId] = artsrv
  220. }
  221. // 加载物料库存数据
  222. stock_Dao := wm_dal.NewStockDAO(session, se.PlantNr, "scheduler")
  223. if artstocktablst, err = stock_Dao.SelectAll(); err != nil{
  224. err = errors.New(fmt.Sprintf("加载物料库存数据出错:%v",err))
  225. return
  226. }
  227. for _, artstocktab = range artstocktablst {
  228. if artsrv, ok = se.ArticleDict[artstocktab.ArtId]; ok {
  229. artsrv.AvailQty = artstocktab.AvailableStock
  230. }
  231. }
  232. // 加载物料在途数据
  233. transitStock_Dao := wm_dal.NewTransitStockDAO(session, se.PlantNr, "scheduler")
  234. if arttransittablst, err = transitStock_Dao.SelectAll(); err != nil{
  235. err = errors.New(fmt.Sprintf("加载物料在途库存数据出错:%v",err))
  236. return
  237. }
  238. for _, arttransittab = range arttransittablst {
  239. if artsrv, ok = se.ArticleDict[artstocktab.ArtId]; ok {
  240. artsrv.TransitStockLst = append(artsrv.TransitStockLst, arttransittab)
  241. }
  242. }
  243. return
  244. }
  245. // 加载人员主数据,包括技能
  246. func(se *SchedulerSrv)LoadPersonData()(err error){
  247. var(
  248. persrv *PersonSrv
  249. skillsrv *SkillSrv
  250. pertab base_model.Person
  251. pertablst []base_model.Person
  252. skilltab base_model.Skill
  253. skilltablst []base_model.Skill
  254. perskilltab base_model.PersonSkilllst
  255. perskilltablst []base_model.PersonSkilllst
  256. ok bool
  257. )
  258. engine := db.Eloquent.Master()
  259. session := engine.NewSession()
  260. defer session.Close()
  261. // 加载人员主数据
  262. person_Dao := base_dal.NewPersonDAO(session, se.PlantNr, "scheduler")
  263. if pertablst, err = person_Dao.SelectAll(); err != nil{
  264. err = errors.New(fmt.Sprintf("加载人员主数据出错:%v",err))
  265. return
  266. }
  267. for _, pertab = range pertablst {
  268. persrv = &PersonSrv{}
  269. persrv.Create(pertab)
  270. se.PersonDict[persrv.PersonNr] = persrv
  271. }
  272. // 加载技能数据
  273. skill_Dao := base_dal.NewSkillDAO(session, se.PlantNr, "scheduler")
  274. if skilltablst, err = skill_Dao.SelectAll(); err != nil{
  275. err = errors.New(fmt.Sprintf("加载技能主数据出错:%v",err))
  276. return
  277. }
  278. for _, skilltab = range skilltablst {
  279. skillsrv = &SkillSrv{}
  280. skillsrv.Create(skilltab)
  281. se.SkillDict[skillsrv.SkillId] = skillsrv
  282. }
  283. // 加载技能的人员数据
  284. personSkill_Dao := base_dal.NewPersonSkilllstDAO(session, se.PlantNr, "scheduler")
  285. if perskilltablst, err = personSkill_Dao.SelectAll(); err != nil{
  286. err = errors.New(fmt.Sprintf("加载人员技能主数据出错:%v",err))
  287. return
  288. }
  289. for _, perskilltab = range perskilltablst {
  290. if skillsrv, ok = se.SkillDict[perskilltab.SkillId]; !ok {
  291. continue
  292. }
  293. if persrv, ok = se.PersonDict[perskilltab.PersonNr]; !ok {
  294. continue
  295. }
  296. skillsrv.PersonDict[persrv.PersonNr] = persrv
  297. }
  298. return
  299. }
  300. // 加载辅助资源主数据
  301. func(se *SchedulerSrv)LoadResourceData()(err error){
  302. var(
  303. resourcetab base_model.SecondaryResource
  304. resourcetablst []base_model.SecondaryResource
  305. secressrv *SecondaryResourceSrv
  306. )
  307. engine := db.Eloquent.Master()
  308. session := engine.NewSession()
  309. defer session.Close()
  310. // 加载次要资源
  311. secondaryResouce_Dao := base_dal.NewSecondaryResourceDAO(session, se.PlantNr, "scheduler")
  312. if resourcetablst, err = secondaryResouce_Dao.SelectAll(); err != nil{
  313. err = errors.New(fmt.Sprintf("加载次要资源数据出错:%v",err))
  314. return
  315. }
  316. for _, resourcetab = range resourcetablst {
  317. secressrv = &SecondaryResourceSrv{}
  318. secressrv.Create(resourcetab)
  319. se.SecResourceDict[secressrv.ResourceId] = secressrv
  320. }
  321. // 初始化次要资源的时间模型
  322. return
  323. }
  324. // 加载订单主数据(未完成订单)
  325. func(se *SchedulerSrv)LoadWorkOrderData()(err error){
  326. var(
  327. ordsrv *OrderSrv
  328. opsrv *OperationSrv
  329. vordtablst []om_model.VWorkorder
  330. i int
  331. )
  332. engine := db.Eloquent.Master()
  333. session := engine.NewSession()
  334. defer session.Close()
  335. // 加载所有未完成的订单
  336. workOrder_dao := om_dal.NewWorkOrderDAO(session, se.PlantNr, "scheduler")
  337. if vordtablst, err = workOrder_dao.SelectAllUnfinishedFullData(); err != nil {
  338. err = errors.New(fmt.Sprintf("加载工单数据出错:%v",err))
  339. return
  340. }else{
  341. WOOperation_dao := om_dal.NewWOOperationDAO(session, se.PlantNr, "scheduler")
  342. // 获取订单工序数据
  343. for i = 0; i < len(vordtablst); i++ {
  344. session_OmWooperation := session.Table(meta.WOOperation.TableName)
  345. if err = session_OmWooperation.Where("PlantNr = ? and WorkOrderId = ?",se.PlantNr,
  346. vordtablst[i].WorkOrder.WorkOrderId).Asc("OperationNr", "SplitNr").Find(&vordtablst[i].WorkOrder.Operationlst); err != nil{
  347. return
  348. }
  349. for j := 0; j < len(vordtablst[i].WorkOrder.Operationlst); j++ {
  350. woOperationData, err := WOOperation_dao.SelectOne(vordtablst[i].WorkOrder.Operationlst[j].WorkOrderId,vordtablst[i].WorkOrder.Operationlst[j].OperationNr,vordtablst[i].WorkOrder.Operationlst[j].SplitNr)
  351. if err != nil{
  352. return err
  353. }
  354. vordtablst[i].WorkOrder.Operationlst[j] = *woOperationData
  355. }
  356. }
  357. }
  358. for i = 0; i < len(vordtablst); i++ {
  359. ordsrv = &OrderSrv{}
  360. ordsrv.Create(vordtablst[i].WorkOrder)
  361. se.OrderDict[ordsrv.OrderId] = ordsrv
  362. // 加载订单所有的工序对象
  363. for _, opsrv = range ordsrv.OperationDict {
  364. se.OperationDict[opsrv.GetOrdOpKey()] = opsrv
  365. }
  366. }
  367. return
  368. }
  369. // 加载订单网络数据
  370. func(se *SchedulerSrv)LoadOrderNetworkData()(err error){
  371. // 加载订单网络
  372. return
  373. }
  374. // 加载排程规则数据
  375. func(se *SchedulerSrv)LoadScheduleRuleData()(err error){
  376. return
  377. }
  378. // 启动调度引擎
  379. func(se *SchedulerSrv)Run()(err error){
  380. var(
  381. set SchedEvent
  382. )
  383. // 从队列循环获取任务执行,直至队列为空
  384. for se.SchedEventQueue.Length() > 0 {
  385. set = se.SchedEventQueue.Pop()
  386. switch set.GetEvent() {
  387. case EVENT_TASK_SETUPBEG:
  388. oppbet := set.(OperationEvent)
  389. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 换型开始:%s",oppbet.OrderId,oppbet.OperationNr,oppbet.TriggerTime.Format("2006-01-02 15:04:05")))
  390. se.SchedTaskSetupBeg(oppbet)
  391. continue
  392. case EVENT_TASK_SETUPEND:
  393. oppbet := set.(OperationEvent)
  394. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 换型结束:%s",oppbet.OrderId,oppbet.OperationNr,oppbet.TriggerTime.Format("2006-01-02 15:04:05")))
  395. se.SchedTaskSetupEnd(oppbet)
  396. continue
  397. case EVENT_TASK_PLANBEG:
  398. oppbet := set.(OperationEvent)
  399. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 计划开始:%s",oppbet.OrderId,oppbet.OperationNr,oppbet.TriggerTime.Format("2006-01-02 15:04:05")))
  400. se.SchedTaskPlanBeg(oppbet)
  401. continue
  402. case EVENT_TASK_PLANEND:
  403. oppeet := set.(OperationEvent)
  404. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 计划结束:%s",oppeet.OrderId,oppeet.OperationNr,oppeet.TriggerTime.Format("2006-01-02 15:04:05")))
  405. se.SchedTaskPlanEnd(oppeet)
  406. continue
  407. case EVENT_TASK_POSTBEG:
  408. oppbet := set.(OperationEvent)
  409. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 后处理开始:%s",oppbet.OrderId,oppbet.OperationNr,oppbet.TriggerTime.Format("2006-01-02 15:04:05")))
  410. se.SchedTaskPostBeg(oppbet)
  411. continue
  412. case EVENT_TASK_POSTEND:
  413. oppbet := set.(OperationEvent)
  414. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 后处理结束:%s",oppbet.OrderId,oppbet.OperationNr,oppbet.TriggerTime.Format("2006-01-02 15:04:05")))
  415. se.SchedTaskPostEnd(oppbet)
  416. continue
  417. case EVENT_WP_STATUS_AVAIL:
  418. wpet := set.(WorkPlaceEvent)
  419. fmt.Println(fmt.Sprintf("|| 工位:%s 可使用时间:%s",wpet.WorkPlaceId, wpet.TriggerTime.Format("2006-01-02 15:04:05")))
  420. se.SchedWPAvail(wpet)
  421. continue
  422. case EVENT_WP_STATUS_UNAVAIL:
  423. wpet := set.(WorkPlaceEvent)
  424. fmt.Println(fmt.Sprintf("XX 工位:%s 不可使用时间:%s",wpet.WorkPlaceId, wpet.TriggerTime.Format("2006-01-02 15:04:05")))
  425. se.SchedWPUnAvail(wpet)
  426. continue
  427. case EVENT_TOOL_STATUS_AVAIL:
  428. tet := set.(ToolEvent)
  429. fmt.Println(fmt.Sprintf("|| 工具:%s 可使用时间:%s",tet.ToolId, tet.TriggerTime.Format("2006-01-02 15:04:05")))
  430. se.SchedToolAvail(tet)
  431. continue
  432. case EVENT_TOOL_STATUS_UNAVAIL:
  433. tet := set.(ToolEvent)
  434. fmt.Println(fmt.Sprintf("XX 工具:%s 不可使用时间:%s",tet.ToolId, tet.TriggerTime.Format("2006-01-02 15:04:05")))
  435. se.SchedToolUnAvail(tet)
  436. continue
  437. case EVENT_PERSON_STATUS_AVAIL:
  438. pet := set.(PersonEvent)
  439. fmt.Println(fmt.Sprintf("|| 人员:%d 可使用时间:%s",pet.PersonNr, pet.TriggerTime.Format("2006-01-02 15:04:05")))
  440. se.SchedPersonAvail(pet)
  441. continue
  442. case EVENT_PERSON_STATUS_UNAVAIL:
  443. pet := set.(PersonEvent)
  444. fmt.Println(fmt.Sprintf("|| 人员:%d 不可使用时间:%s",pet.PersonNr, pet.TriggerTime.Format("2006-01-02 15:04:05")))
  445. se.SchedPersonUnAvail(pet)
  446. continue
  447. case EVENT_ART_CONSUME:
  448. aet := set.(ArticleEvent)
  449. fmt.Println(fmt.Sprintf("|| 物料:%s 耗用时间:%s",aet.ArtId, aet.TriggerTime.Format("2006-01-02 15:04:05")))
  450. se.SchedArticleConsume(aet)
  451. continue
  452. case EVENT_ART_YIELD:
  453. aet := set.(ArticleEvent)
  454. fmt.Println(fmt.Sprintf("|| 物料:%s 产出时间:%s",aet.ArtId, aet.TriggerTime.Format("2006-01-02 15:04:05")))
  455. se.SchedArticleYield(aet)
  456. continue
  457. case EVENT_SECRES_CONSUME:
  458. sret := set.(SecondaryResourceEvent)
  459. fmt.Println(fmt.Sprintf("|| 次要资源:%d 耗用时间:%s",sret.ResourceNr, sret.TriggerTime.Format("2006-01-02 15:04:05")))
  460. se.SchedSecondaryResourceConsume(sret)
  461. continue
  462. case EVENT_SECRES_YIELD:
  463. sret := set.(SecondaryResourceEvent)
  464. fmt.Println(fmt.Sprintf("|| 次要资源:%d 耗用时间:%s",sret.ResourceNr, sret.TriggerTime.Format("2006-01-02 15:04:05")))
  465. se.SchedSecondaryResourceYield(sret)
  466. continue
  467. }
  468. }
  469. return
  470. }
  471. // 对换型开始工序进行调度
  472. func(se *SchedulerSrv)SchedTaskSetupBeg(opevent OperationEvent){
  473. }
  474. // 对换型结束工序进行调度
  475. func(se *SchedulerSrv)SchedTaskSetupEnd(opevent OperationEvent){
  476. }
  477. // 对计划开始工序进行调度
  478. func(se *SchedulerSrv)SchedTaskPlanBeg(opevent OperationEvent){
  479. var(
  480. order *OrderSrv
  481. op *OperationSrv
  482. wp *WorkPlaceSrv
  483. wpg *WorkPlaceGrpSrv
  484. t *ToolSrv
  485. tg *ToolGrpSrv
  486. newevent SchedEvent
  487. optionalwplst []OptionalWorkPlaceSrv
  488. optoollst []OptionalToolSrv
  489. ok bool
  490. )
  491. // 获取工序订单对象
  492. if order, ok = se.OrderDict[opevent.OrderId]; !ok {
  493. fmt.Println(fmt.Sprintf("工序事件的订单: %s 不存在", opevent.OrderId))
  494. return
  495. }
  496. // 获取工序对象
  497. if op, ok = order.OperationDict[opevent.GetOpKey()]; !ok {
  498. fmt.Println(fmt.Sprintf("工序事件的工序: %d 不存在于订单: %s 中", opevent.GetOpKey(), opevent.OrderId))
  499. return
  500. }
  501. // 获取可用工位
  502. optionalwplst = se.GetAvailWorkPlaceList(op.WorkPlaceGrpId)
  503. if len(optionalwplst) <= 0 {
  504. //fmt.Println("工位组:",op.WorkPlaceGrpNr," 无可用工位!")
  505. // 获取工位组对象
  506. if wpg, ok = se.WorkPlaceGrpDict[op.WorkPlaceGrpId]; !ok{
  507. //fmt.Println("工位组:",op.WorkPlaceGrpNr," 不存在!")
  508. return
  509. }
  510. // 无可用工位,则将任务放到工位组等待队列
  511. wpg.WaitTaskArray = append(wpg.WaitTaskArray, *op)
  512. return
  513. }
  514. if se.SchedRule.ToolConstraintToggle && op.ToolGrpId != ""{
  515. // 获取可用工位
  516. optoollst = se.GetAvailToolList(op.ToolGrpId)
  517. if len(optoollst) <= 0 {
  518. //fmt.Println("工具组:",op.ToolGrpId," 无可用工位!")
  519. // 获取工具组对象
  520. if tg, ok = se.ToolGrpDict[op.ToolGrpId]; !ok{
  521. //fmt.Println("工具组:",op.ToolGrpId," 不存在!")
  522. return
  523. }
  524. // 无可用工位,则将任务放到工位组等待队列
  525. tg.WaitTaskArray = append(tg.WaitTaskArray, *op)
  526. return
  527. }
  528. }
  529. // 有可用工位,取第一个工位进行调度
  530. op.PlanStartTime = opevent.TriggerTime
  531. op.PlanEndTime = op.PlanStartTime.Add(op.PlanDuration)
  532. op.PlanWorkPlaceId = optionalwplst[0].WorkPlaceId
  533. if se.SchedRule.ToolConstraintToggle && op.ToolGrpId !="" {
  534. op.PlanToolId = optoollst[0].ToolId
  535. }
  536. // 基于工序开始生成工序结束事件
  537. fmt.Println(" 创建工序结束事件:",op.OrderId,op.OperationNr,op.PlanEndTime.Format("2006-01-02 15:04:05"))
  538. newevent = op.GetPlanEndEvent(op.PlanEndTime)
  539. se.SchedEventQueue.Insert(newevent)
  540. // 基于工序开始生成设备事件,占用工位资源
  541. if wp, ok = se.WorkPlaceDict[op.PlanWorkPlaceId]; ok {
  542. newevent = wp.GetUnAvailEvent(opevent.TriggerTime)
  543. se.SchedEventQueue.Insert(newevent)
  544. wp.Status = common.RES_STATUS_UNAVAIL
  545. wp.SchedTaskArray = append(wp.SchedTaskArray, *op)
  546. }
  547. // 考虑有限工具能力
  548. if se.SchedRule.ToolConstraintToggle && op.ToolGrpId != ""{
  549. if t, ok = se.ToolDict[op.PlanToolId]; ok {
  550. newevent = t.GetUnAvailEvent(opevent.TriggerTime)
  551. se.SchedEventQueue.Insert(newevent)
  552. t.Status = common.RES_STATUS_UNAVAIL
  553. t.SchedTaskArray = append(t.SchedTaskArray, *op)
  554. }
  555. }
  556. }
  557. // 对计划结束工序进行调度
  558. func(se *SchedulerSrv)SchedTaskPlanEnd(opevent OperationEvent){
  559. var(
  560. order,nextorder *OrderSrv
  561. op,nextop *OperationSrv
  562. wp *WorkPlaceSrv
  563. t *ToolSrv
  564. newevent SchedEvent
  565. nextoprel OperationRelSrv
  566. ok bool
  567. )
  568. // 获取工序订单对象
  569. if order, ok = se.OrderDict[opevent.OrderId]; !ok {
  570. fmt.Println(fmt.Sprintf("工序事件的订单: %s 不存在", opevent.OrderId))
  571. return
  572. }
  573. // 获取工序对象
  574. if op, ok = order.OperationDict[opevent.GetOpKey()]; !ok {
  575. fmt.Println(fmt.Sprintf("工序事件的工序: %d 不存在于订单: %s 中", opevent.GetOpKey(), opevent.OrderId))
  576. return
  577. }
  578. // 获取占用工位并释放资源
  579. if wp, ok = se.WorkPlaceDict[op.PlanWorkPlaceId]; ok {
  580. newevent = wp.GetAvailEvent(opevent.TriggerTime)
  581. se.SchedEventQueue.Insert(newevent)
  582. wp.Status = common.RES_STATUS_AVAIL
  583. }else{
  584. fmt.Println(fmt.Sprintf("订单:%s 工序:%d 计划工位:%d 不存在!",op.OrderId,op.OperationNr,op.PlanWorkPlaceId))
  585. return
  586. }
  587. if se.SchedRule.ToolConstraintToggle && op.ToolGrpId != ""{
  588. if t, ok = se.ToolDict[op.PlanToolId]; ok{
  589. newevent = t.GetAvailEvent(opevent.TriggerTime)
  590. se.SchedEventQueue.Insert(newevent)
  591. t.Status = common.RES_STATUS_AVAIL
  592. }
  593. }
  594. // 激活后道工序
  595. for _, nextoprel = range op.NextOpDict{
  596. if nextorder, ok = se.OrderDict[nextoprel.OrderId]; ok{
  597. if nextop, ok = nextorder.OperationDict[nextoprel.GetOpKey()]; ok{
  598. newevent = nextop.GetPlanStartEvent(opevent.TriggerTime)
  599. se.SchedEventQueue.Insert(newevent)
  600. }
  601. }else{
  602. fmt.Println(fmt.Sprintf("订单:%s 不存在",nextoprel.OrderId))
  603. continue
  604. }
  605. }
  606. }
  607. // 对工序后处理开始进行调度
  608. func(se *SchedulerSrv)SchedTaskPostBeg(opevent OperationEvent){
  609. }
  610. // 对工序后处理结束进行调度
  611. func(se *SchedulerSrv)SchedTaskPostEnd(opevent OperationEvent){
  612. }
  613. // 对工位可用进行调度
  614. func(se *SchedulerSrv)SchedWPAvail(wpevent WorkPlaceEvent){
  615. var (
  616. wp *WorkPlaceSrv
  617. wpg *WorkPlaceGrpSrv
  618. op OperationSrv
  619. newevent SchedEvent
  620. ok bool
  621. )
  622. // 获取工位对象
  623. if wp, ok = se.WorkPlaceDict[wpevent.WorkPlaceId]; !ok {
  624. fmt.Println(fmt.Sprintf("SchedWPAvail: 工位:%s 不存在",wpevent.WorkPlaceId))
  625. return
  626. }
  627. // 获取工位组对象
  628. if wpg, ok = se.WorkPlaceGrpDict[wp.WorkPlaceGrpId]; !ok {
  629. fmt.Println(fmt.Sprintf("工位组:%s 不存在",wp.WorkPlaceGrpId))
  630. return
  631. }
  632. // 更新工位状态
  633. wp.Status = common.RES_STATUS_AVAIL
  634. //se.WorkPlaceDict[wp.WorkPlaceNr] = wp
  635. // 将等待队列中的工序任务全部推入调度队列
  636. for _, op = range wpg.WaitTaskArray {
  637. fmt.Println("************ 获取等待队列中的等待任务:",op.OrderId,op.OperationNr)
  638. newevent = op.GetPlanStartEvent(wpevent.TriggerTime)
  639. se.SchedEventQueue.Insert(newevent)
  640. }
  641. wpg.WaitTaskArray = []OperationSrv{}
  642. //se.WorkPlaceGrpDict[wpg.WorkPlaceGrpNr] = wpg
  643. return
  644. }
  645. // 对工位不可用进行调度
  646. func(se *SchedulerSrv)SchedWPUnAvail(wpevent WorkPlaceEvent){
  647. var (
  648. wp *WorkPlaceSrv
  649. ok bool
  650. )
  651. // 获取工位对象
  652. if wp, ok = se.WorkPlaceDict[wpevent.WorkPlaceId]; !ok {
  653. fmt.Println(fmt.Sprintf("SchedWPUnAvail: 工位:%s 不存在",wpevent.WorkPlaceId))
  654. return
  655. }
  656. // 更新工位状态
  657. wp.Status = common.RES_STATUS_UNAVAIL
  658. //se.WorkPlaceDict[wp.WorkPlaceNr] = wp
  659. return
  660. }
  661. // 对工具可用进行调度
  662. func(se *SchedulerSrv)SchedToolAvail(tevent ToolEvent){
  663. var (
  664. t *ToolSrv
  665. tg *ToolGrpSrv
  666. op OperationSrv
  667. newevent SchedEvent
  668. ok bool
  669. )
  670. // 获取工具对象
  671. if t, ok = se.ToolDict[tevent.ToolId]; !ok {
  672. fmt.Println(fmt.Sprintf("SchedToolAvail: 工具:%s 不存在",tevent.ToolId))
  673. return
  674. }
  675. // 获取工具组对象
  676. if tg, ok = se.ToolGrpDict[t.ToolGrpId]; !ok {
  677. fmt.Println(fmt.Sprintf("工具组:%d 不存在",t.ToolGrpId))
  678. return
  679. }
  680. // 更新工具状态
  681. t.Status = common.RES_STATUS_AVAIL
  682. // 将等待队列中的工序任务全部推入调度队列
  683. for _, op = range tg.WaitTaskArray {
  684. fmt.Println("************ 获取等待队列中的等待任务:",op.OrderId,op.OperationNr)
  685. newevent = op.GetPlanStartEvent(tevent.TriggerTime)
  686. se.SchedEventQueue.Insert(newevent)
  687. }
  688. tg.WaitTaskArray = []OperationSrv{}
  689. return
  690. }
  691. // 对工具不可用进行调度
  692. func(se *SchedulerSrv)SchedToolUnAvail(tevent ToolEvent){
  693. var (
  694. t *ToolSrv
  695. ok bool
  696. )
  697. // 获取工位对象
  698. if t, ok = se.ToolDict[tevent.ToolId]; !ok {
  699. fmt.Println(fmt.Sprintf("SchedToolUnAvail: 工具:%s 不存在",tevent.ToolId))
  700. return
  701. }
  702. // 更新工位状态
  703. t.Status = common.RES_STATUS_UNAVAIL
  704. return
  705. }
  706. // 对人员可用进行调度
  707. func(se *SchedulerSrv)SchedPersonAvail(pevent PersonEvent){
  708. }
  709. // 对人员不可用进行调度
  710. func(se *SchedulerSrv)SchedPersonUnAvail(pevent PersonEvent){
  711. }
  712. // 对物料耗用进行调度
  713. func(se *SchedulerSrv)SchedArticleConsume(artevent ArticleEvent){
  714. }
  715. // 对物料产出进行调度
  716. func(se *SchedulerSrv)SchedArticleYield(artevent ArticleEvent){
  717. }
  718. // 对次要资源耗用进行调度
  719. func(se *SchedulerSrv)SchedSecondaryResourceConsume(srevent SecondaryResourceEvent){
  720. }
  721. // 对次要资源产出进行调度
  722. func(se *SchedulerSrv)SchedSecondaryResourceYield(srevent SecondaryResourceEvent){
  723. }
  724. // 获取当前可用工位
  725. func(se *SchedulerSrv)GetAvailWorkPlaceList(wpgid string)(optionalwplst []OptionalWorkPlaceSrv){
  726. var(
  727. wpid string
  728. wp *WorkPlaceSrv
  729. wpg *WorkPlaceGrpSrv
  730. ok bool
  731. )
  732. // 获取工位组对象
  733. if wpg, ok = se.WorkPlaceGrpDict[wpgid]; !ok {
  734. fmt.Println(fmt.Sprintf("GetAvailWorkPlaceList: 工位组:%s 不存在",wpgid))
  735. return
  736. }
  737. optionalwplst = []OptionalWorkPlaceSrv{}
  738. for wpid, _ = range wpg.WorkPlaceDict{
  739. if wp, ok = se.WorkPlaceDict[wpid]; !ok{
  740. fmt.Println(fmt.Sprintf("GetAvailWorkPlaceList: 工位:%s 不存在",wpid))
  741. return
  742. }
  743. if wp.Status == common.RES_STATUS_AVAIL {
  744. optionalwp := OptionalWorkPlaceSrv{WorkPlaceId: wp.WorkPlaceId, Priority: 0}
  745. optionalwplst = append(optionalwplst, optionalwp)
  746. }
  747. }
  748. return
  749. }
  750. // 获取当前可用工具
  751. func(se *SchedulerSrv)GetAvailToolList(tgid string)(opttoollst []OptionalToolSrv){
  752. var(
  753. tid string
  754. t *ToolSrv
  755. tg *ToolGrpSrv
  756. ok bool
  757. )
  758. // 获取工位组对象
  759. if tg, ok = se.ToolGrpDict[tgid]; !ok {
  760. fmt.Println(fmt.Sprintf("GetAvailToolList: 工具组:%s 不存在",tgid))
  761. return
  762. }
  763. fmt.Println("获取工具组的工具.......",tg.ToolGrpId)
  764. opttoollst = []OptionalToolSrv{}
  765. //todo
  766. for tid, _ = range tg.ToolDict{
  767. if t, ok = se.ToolDict[tid]; !ok{
  768. fmt.Println(fmt.Sprintf("GetAvailToolList: 工位:%s 不存在",tid))
  769. return
  770. }
  771. fmt.Println(" 工具:",t.ToolId," 状态:",t.Status)
  772. if t.Status == common.RES_STATUS_AVAIL {
  773. optionalt := OptionalToolSrv{ToolId: t.ToolId, Priority: 0}
  774. opttoollst = append(opttoollst, optionalt)
  775. }
  776. }
  777. return
  778. }
  779. // 初始化测试环境,创建一些测试数据
  780. func LoadTestEnvData(se *SchedulerSrv)(err error){
  781. var(
  782. wp *WorkPlaceSrv
  783. wpg *WorkPlaceGrpSrv
  784. t *ToolSrv
  785. tg *ToolGrpSrv
  786. art *ArticleSrv
  787. order *OrderSrv
  788. prevop *OperationSrv
  789. op *OperationSrv
  790. opr OperationRelSrv
  791. st,et time.Time
  792. tls TimeLineSrv
  793. )
  794. // 初始化工厂号及计划区间
  795. st = time.Now()
  796. et = time.Now().Add(time.Hour*24*10)
  797. se.Init(100, st, et)
  798. // 创建工位组
  799. wpg = &WorkPlaceGrpSrv{}
  800. wpg.Init("10")
  801. // 创建工位
  802. wp = &WorkPlaceSrv{}
  803. wp.Init("1","10")
  804. st = time.Now()
  805. et = time.Now().Add(time.Hour*24*10)
  806. wp.TimeCurve.Init(st,et)
  807. tls = TimeLineSrv{}
  808. st = time.Now()
  809. et = time.Now().Add(time.Hour*24)
  810. tls.Init(st, et)
  811. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  812. tls = TimeLineSrv{}
  813. st = time.Now().Add(time.Hour*28)
  814. et = time.Now().Add(time.Hour*48)
  815. tls.Init(st, et)
  816. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  817. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  818. wpg.WorkPlaceDict[wp.WorkPlaceId] = wp
  819. wp = &WorkPlaceSrv{}
  820. wp.Init("2","10")
  821. st = time.Now()
  822. et = time.Now().Add(time.Hour*24*10)
  823. wp.TimeCurve.Init(st,et)
  824. tls = TimeLineSrv{}
  825. st = time.Now()
  826. et = time.Now().Add(time.Hour*16)
  827. tls.Init(st, et)
  828. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  829. tls = TimeLineSrv{}
  830. st = time.Now().Add(time.Hour*24)
  831. et = time.Now().Add(time.Hour*46)
  832. tls.Init(st, et)
  833. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  834. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  835. wpg.WorkPlaceDict[wp.WorkPlaceId] = wp
  836. se.WorkPlaceGrpDict[wpg.WorkPlaceGrpId] = wpg
  837. wpg = &WorkPlaceGrpSrv{}
  838. wpg.Init("20")
  839. wp = &WorkPlaceSrv{}
  840. wp.Init("3","20")
  841. st = time.Now()
  842. et = time.Now().Add(time.Hour*24*10)
  843. wp.TimeCurve.Init(st,et)
  844. tls = TimeLineSrv{}
  845. st = time.Now()
  846. et = time.Now().Add(time.Hour*20)
  847. tls.Init(st, et)
  848. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  849. tls = TimeLineSrv{}
  850. st = time.Now().Add(time.Hour*22)
  851. et = time.Now().Add(time.Hour*44)
  852. tls.Init(st, et)
  853. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  854. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  855. wpg.WorkPlaceDict[wp.WorkPlaceId] = wp
  856. se.WorkPlaceGrpDict[wpg.WorkPlaceGrpId] = wpg
  857. wpg = &WorkPlaceGrpSrv{}
  858. wpg.Init("30")
  859. wp = &WorkPlaceSrv{}
  860. wp.Init("4","30")
  861. st = time.Now()
  862. et = time.Now().Add(time.Hour*24*15)
  863. wp.TimeCurve.Init(st,et)
  864. tls = TimeLineSrv{}
  865. st = time.Now()
  866. et = time.Now().Add(time.Hour*21)
  867. tls.Init(st, et)
  868. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  869. tls = TimeLineSrv{}
  870. st = time.Now().Add(time.Hour*23)
  871. et = time.Now().Add(time.Hour*50)
  872. tls.Init(st, et)
  873. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  874. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  875. wpg.WorkPlaceDict[wp.WorkPlaceId] = wp
  876. wp = &WorkPlaceSrv{}
  877. wp.Init("5","30")
  878. st = time.Now()
  879. et = time.Now().Add(time.Hour*24*10)
  880. wp.TimeCurve.Init(st,et)
  881. tls = TimeLineSrv{}
  882. st = time.Now()
  883. et = time.Now().Add(time.Hour*17)
  884. tls.Init(st, et)
  885. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  886. tls = TimeLineSrv{}
  887. st = time.Now().Add(time.Hour*25)
  888. et = time.Now().Add(time.Hour*52)
  889. tls.Init(st, et)
  890. wp.TimeCurve.TimeLineArray = append(wp.TimeCurve.TimeLineArray, tls)
  891. se.WorkPlaceDict[wp.WorkPlaceId] = wp
  892. wpg.WorkPlaceDict[wp.WorkPlaceId] = wp
  893. se.WorkPlaceGrpDict[wpg.WorkPlaceGrpId] = wpg
  894. // 创建工具
  895. t = &ToolSrv{}
  896. t.Init("1", "10")
  897. tls = TimeLineSrv{}
  898. st = time.Now().Add(time.Hour*5)
  899. et = time.Now().Add(time.Hour*10)
  900. t.UnAvailTimeLineArray = append(t.UnAvailTimeLineArray, tls)
  901. se.ToolDict[t.ToolId] = t
  902. // 创建工具组
  903. tg = &ToolGrpSrv{}
  904. tg.Init("10")
  905. tg.ToolIdxDict[t.ToolId] = t.ToolId
  906. se.ToolGrpDict[tg.ToolGrpId] = tg
  907. // 创建工具
  908. t = &ToolSrv{}
  909. t.Init("2", "20")
  910. tls = TimeLineSrv{}
  911. st = time.Now().Add(time.Hour*6)
  912. et = time.Now().Add(time.Hour*12)
  913. t.UnAvailTimeLineArray = append(t.UnAvailTimeLineArray, tls)
  914. se.ToolDict[t.ToolId] = t
  915. // 创建工具组
  916. tg = &ToolGrpSrv{}
  917. tg.Init("20")
  918. tg.ToolIdxDict[t.ToolId] = t.ToolId
  919. se.ToolGrpDict[tg.ToolGrpId] = tg
  920. // 创建物料
  921. art = &ArticleSrv{}
  922. art.Init("art001",100)
  923. se.ArticleDict[art.ArtId] = art
  924. // 创建工单及工序
  925. order = &OrderSrv{OrderId: "100001", ProjectId: "G18"}
  926. order.OperationArray = []OperationSrv{}
  927. order.OperationDict = make(map[string]*OperationSrv)
  928. op = &OperationSrv{OrderId: "100001",OperationNr: 10, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "10", ToolGrpId: "10", PlanDuration: time.Hour * 4}
  929. op.PrevOpDict = make(map[string]OperationRelSrv)
  930. op.NextOpDict = make(map[string]OperationRelSrv)
  931. order.OperationArray = append(order.OperationArray, *op)
  932. order.OperationDict[op.GetOpKey()] = op
  933. prevop = op
  934. opr = OperationRelSrv{OrderId: "100001", OperationNr: 20, SplitNr: 0, Relation: OP_LINK_END_START}
  935. prevop.NextOpDict[opr.GetFullKey()] = opr
  936. op = &OperationSrv{OrderId: "100001",OperationNr: 20, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "20", PlanDuration: time.Hour * 6}
  937. op.PrevOpDict = make(map[string]OperationRelSrv)
  938. opr = OperationRelSrv{OrderId: "100001", OperationNr: 10, SplitNr: 0, Relation: OP_LINK_END_START}
  939. op.PrevOpDict[opr.GetFullKey()] = opr
  940. op.NextOpDict = make(map[string]OperationRelSrv)
  941. order.OperationArray = append(order.OperationArray, *op)
  942. order.OperationDict[op.GetOpKey()] = op
  943. prevop = op
  944. opr = OperationRelSrv{OrderId: "100001", OperationNr: 30, SplitNr: 0, Relation: OP_LINK_END_START}
  945. prevop.NextOpDict[opr.GetFullKey()] = opr
  946. op = &OperationSrv{OrderId: "100001",OperationNr: 30, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "30", PlanDuration: time.Hour * 8}
  947. op.PrevOpDict = make(map[string]OperationRelSrv)
  948. opr = OperationRelSrv{OrderId: "100001", OperationNr: 20, SplitNr: 0, Relation: OP_LINK_END_START}
  949. op.PrevOpDict[opr.GetFullKey()] = opr
  950. op.NextOpDict = make(map[string]OperationRelSrv)
  951. order.OperationArray = append(order.OperationArray, *op)
  952. order.OperationDict[op.GetOpKey()] = op
  953. se.OrderDict[order.OrderId] = order
  954. order = &OrderSrv{OrderId: "100002", ProjectId: "G18"}
  955. order.OperationArray = []OperationSrv{}
  956. order.OperationDict = make(map[string]*OperationSrv)
  957. op = &OperationSrv{OrderId: "100002",OperationNr: 10, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "10", ToolGrpId: "10", PlanDuration: time.Hour * 5}
  958. op.PrevOpDict = make(map[string]OperationRelSrv)
  959. op.NextOpDict = make(map[string]OperationRelSrv)
  960. order.OperationArray = append(order.OperationArray, *op)
  961. order.OperationDict[op.GetOpKey()] = op
  962. prevop = op
  963. opr = OperationRelSrv{OrderId: "100002", OperationNr: 20, SplitNr: 0, Relation: OP_LINK_END_START}
  964. prevop.NextOpDict[opr.GetFullKey()] = opr
  965. op = &OperationSrv{OrderId: "100002",OperationNr: 20, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "20", PlanDuration: time.Hour * 7}
  966. op.PrevOpDict = make(map[string]OperationRelSrv)
  967. opr = OperationRelSrv{OrderId: "100002", OperationNr: 10, SplitNr: 0, Relation: OP_LINK_END_START}
  968. op.PrevOpDict[opr.GetFullKey()] = opr
  969. op.NextOpDict = make(map[string]OperationRelSrv)
  970. order.OperationArray = append(order.OperationArray, *op)
  971. order.OperationDict[op.GetOpKey()] = op
  972. prevop = op
  973. opr = OperationRelSrv{OrderId: "100002", OperationNr: 30, SplitNr: 0, Relation: OP_LINK_END_START}
  974. prevop.NextOpDict[opr.GetFullKey()] = opr
  975. op = &OperationSrv{OrderId: "100002",OperationNr: 30, SplitNr: 0,PlanQty: 10, WorkPlaceGrpId: "30", PlanDuration: time.Hour * 9}
  976. op.PrevOpDict = make(map[string]OperationRelSrv)
  977. opr = OperationRelSrv{OrderId: "100002", OperationNr: 20, SplitNr: 0, Relation: OP_LINK_END_START}
  978. op.PrevOpDict[opr.GetFullKey()] = opr
  979. op.NextOpDict = make(map[string]OperationRelSrv)
  980. order.OperationArray = append(order.OperationArray, *op)
  981. order.OperationDict[op.GetOpKey()] = op
  982. se.OrderDict[order.OrderId] = order
  983. // 初始化调度队列
  984. se.SchedEventQueue = NewSchedQueue()
  985. // 遍历设备时间曲线,生成设备状态事件,推入队列
  986. for _, wp_p := range se.WorkPlaceDict{
  987. for _, tls := range wp_p.TimeCurve.TimeLineArray{
  988. evt1 := wp_p.GetAvailEvent(tls.StartTime)
  989. se.SchedEventQueue.Insert(evt1)
  990. evt2 := wp_p.GetUnAvailEvent(tls.EndTime)
  991. se.SchedEventQueue.Insert(evt2)
  992. }
  993. }
  994. // 载入订单首工序事件
  995. for _, ord_p := range se.OrderDict{
  996. for _, op_p := range ord_p.OperationDict {
  997. if len(op_p.PrevOpDict) <= 0 {
  998. evt := op_p.GetPlanStartEvent(time.Now())
  999. opet := evt.(OperationEvent)
  1000. fmt.Println("压入订单工序事件:",opet.OrderId,opet.OperationNr, opet.TriggerTime)
  1001. se.SchedEventQueue.Insert(evt)
  1002. }
  1003. }
  1004. }
  1005. return
  1006. }