import httpx from apscheduler.schedulers.asyncio import AsyncIOScheduler from pytz import timezone import time from conf import setting from helper.logger import logger from datetime import datetime import json from models.assignment import Assignment from models.warehouse import Vacancy, Hole import os import codecs scheduler = AsyncIOScheduler(timezone=timezone('Asia/Shanghai')) async def findNewShelfVacancy(cmdStdl = [], cmdStd = []): #find new Vacancy qs1 = await Vacancy.filter(is_shelf = True, is_valid = True, is_active = True) if len(qs1) > 0: print("find new Vacancy: ", qs1) vacancy = qs1[0] #generate destination with respond to task cmdStdl.append({vacancy.number: cmdStd}) #update vacancy vacancy.is_valid = False vacancy.orderids = [ cmdStd["orderid"] ] await vacancy.save() hole = await Hole.create( number = 1, orderid = cmdStd["orderid"], coordinates = cmdStd["coordinates"] ) vacancy.holes.add(hole) else: raise Exception("Shelf vacancy is not enough!") async def findNewConnectionVacancy(cmdStdl = [], cmdStd = []): #find new Vacancy qs1 = await Vacancy.filter(is_connect = True, is_valid = True, is_active = True) if len(qs1) > 0: print("find new Vacancy: ", qs1) vacancy = qs1[0] #generate destination with respond to task cmdStdl.append({vacancy.number: cmdStd}) #update vacancy vacancy.is_valid = False vacancy.orderids = [ cmdStd["orderid"] ] await vacancy.save() hole = await Hole.create( number = 1, orderid = cmdStd["orderid"], coordinates = cmdStd["coordinates"] ) vacancy.holes.add(hole) else: raise Exception("Connection vacancy is not enough!") async def genCMD(assignment, cmdStdList, cmdNonStdList): cmdStdl = [] cmdNonStdl = [] for cmdStd in cmdStdList: if 1 == cmdStd["action"]: #1: 归还 cmdStdl.append({"Return": cmdStd}) elif 3 == cmdStd["action"]: #3: 预约领用 qs = await Vacancy.filter( orderids__contains=[ cmdStd["orderid"] ], is_shelf = True, is_valid = False, is_active = True ) if len(qs) > 0: vacancy = qs[0] #need to add deal with hole in tray logic else: findNewShelfVacancy(cmdStdl, cmdStd) elif 5 == cmdStd["action"]: #5: 现场领用 #need to add deal with hole in tray logic qs = await Vacancy.filter( orderids__contains=[ cmdStd["orderid"] ], is_connect = True, is_valid = False, is_active = True ) if len(qs) > 0: vacancy = qs[0] #need to add deal with hole in tray logic else: findNewConnectionVacancy(cmdStdl, cmdStd) # qs1 = await Vacancy.filter(is_connect = True, is_valid = True, is_active = True) # if len(qs1) > 0: # print("find new Vacancy: ", qs1) # vacancy = qs1[0] # #generate destination with respond to task # cmdStdl.append({vacancy.number: cmdStd}) # #update vacancy # vacancy.is_valid = False # vacancy.orderids = [ cmdStd["orderid"] ] # await vacancy.save() # else: # raise Exception("Connection vacancy is not enough!") for cmdNonStd in cmdNonStdList: if 1 == cmdNonStd["action"]: #1: 归还 # cmdNonStdl.append({"Return": cmdNonStd}) #where to return after usage # to shelf or stay in connection !!! #check if next assignment will use this tray assignmentNext = await Assignment.filter( is_canceled = False, is_processing = False, is_failed = False, is_done = False, is_valid = True, is_active = True ).first() if assignmentNext: subtasksNext = await assignmentNext.subtasks.all() for subtaskNext in subtasksNext: if 9 == subtaskNext.typetask: qs4 = await Vacancy.filter(is_connect = True, is_valid = False, is_active = True, traynum=[subtaskNext.traynum]) if len(qs4) > 0: print("connection area tray num {}, is used in next assignment {}, don't need to move ".format(subtaskNext.traynum, assignmentNext.id)) cmdStdl.insert(0, {"Skip": cmdNonStd}) return #check if the tray in Schelve qs5 = await Vacancy.filter(is_shelf = True, is_valid = False, is_active = True, traynum=[cmdNonStd["traynum"]]) if len(qs5) > 0: vacancy = qs5[0] if vacancy.orderids and len(vacancy) > 0: # update destination to Schelve vacancy cmdNonStd["coordinates"] = vacancy.number # insert into beginning of the list cmdStdl.insert(0, {"Return": cmdNonStd}) return # normal return process cmdStdl.append({"Return": cmdNonStd}) elif 3 == cmdNonStd["action"]: #3: 预约领用 qs1 = await Vacancy.filter(is_shelf = True, is_valid = True, is_active = True) if len(qs1) > 0: vacancy = qs1[0] #check if tray already at Vacancy qs3 = await Vacancy.filter(is_valid = False, is_active = True, traynum=[cmdNonStd["traynum"]]) if len(qs3) > 0: vacancy3 = qs3[0] #if exist then change destination to corresponding vacancy cmdNonStd["coordinates"] = vacancy3.number #update vacancy orderids = vacancy3.orderids if not orderids: orderids = [ cmdNonStd["orderid"] ] else: orderids.append(cmdNonStd["orderid"]) vacancy3.is_valid = False vacancy3.orderids = orderids await vacancy3.save() #generate destination with respond to task # cmdNonStdl.append({vacancy.number: cmdNonStd}) cmdStdl.append({vacancy.number: cmdNonStd}) #update vacancy orderids = vacancy.orderids if not orderids: orderids = [ cmdNonStd["orderid"] ] else: orderids.append(cmdNonStd["orderid"]) vacancy.is_valid = False vacancy.traynum = cmdNonStd["traynum"] vacancy.orderids = orderids await vacancy.save() else: raise Exception("Shelf vacancy is not enough!") elif 5 == cmdNonStd["action"]: #5: 现场领用 qs1 = await Vacancy.filter(is_connect = True, is_valid = True, is_active = True) if len(qs1) > 0: vacancy = qs1[0] #check if tray already at Vacancy qs3 = await Vacancy.filter(is_valid = False, is_active = True, traynum=[cmdNonStd["traynum"]]) if len(qs3) > 0: vacancy3 = qs3[0] #if exist then change destination to corresponding vacancy cmdNonStd["coordinates"] = vacancy3.number #update vacancy orderids = vacancy3.orderids if orderids and len(orderids) > 0: lstSet = set(orderids) lstSet.discard( cmdNonStd["orderid"] ) # Converting set back to list orderids=list(lstSet) else: orderids = [] if len(orderids) > 0: vacancy3.is_valid = False else: vacancy3.is_valid = True vacancy3.orderids = orderids await vacancy3.save() #generate destination with respond to task # cmdNonStdl.append({vacancy.number: cmdNonStd}) # #update vacancy # orderids = vacancy.orderids # if not orderids: # orderids = [ cmdNonStd["orderid"] ] # else: # orderids.append(cmdNonStd["orderid"]) # vacancy.is_valid = False # vacancy.traynum = cmdNonStd["traynum"] # # vacancy.orderids = orderids # await vacancy.save() cmdStdl.append({vacancy.number: cmdNonStd}) else: raise Exception("Connect vacancy is not enough!") assignment.cmd = cmdStdl + cmdNonStdl await assignment.save() async def agv_asign_job(): print("Working ", "{}".format(datetime.now())) # assignments = await Assignment.filter(is_canceled = False, is_valid = True, is_active = True) assignments = await Assignment.filter( is_canceled = False, is_processing = False, is_failed = False, is_done = False, is_valid = True, is_active = True ) path = "agvtask/testdata/test-{}.json".format(datetime.now().strftime("%Y-%m-%d_%H_%M_%S")) assignmentsL = [] for assignment in assignments: owner = await assignment.owner subtasks = await assignment.subtasks.all() assignmentJ = assignment.as_json() subtasksL = [] cmdStdList = [] cmdNonStdList = [] for subtask in subtasks: if 1 == subtask.typetask \ or 1 == subtask.typetask \ or 3 == subtask.typetask \ or 5 == subtask.typetask \ or 7 == subtask.typetask: # for standard cmdStdList.append({ "orderid": subtask.orderid, "name": subtask.name, "typetask": subtask.typetask, "action": subtask.action, "quantity": subtask.quantity, "coordinates": subtask.coordinates, "traynum": subtask.traynum, }) else: # for non standard cmdNonStdList.append({ "orderid": subtask.orderid, "name": subtask.name, "typetask": subtask.typetask, "action": subtask.action, "quantity": subtask.quantity, "coordinates": subtask.coordinates, "traynum": subtask.traynum, }) subtasksL.append(subtask.as_json()) assignment.is_processing = True await assignment.save() await genCMD(assignment, cmdStdList, cmdNonStdList) assignmentJ["owner"] = owner.as_json() assignmentJ["subtasks"] = subtasksL assignmentJ["cmd"] = assignment.cmd assignmentsL.append(assignmentJ) # print("assignment: ", assignmentJ) with open(path, "w", encoding="utf-8") as fp: json.dump(assignmentsL, fp, ensure_ascii=False) async def start_scheduler(): """ """ second = 12000000 logger.info(f"准备启动AGV小车任务派发定时任务, 间隔时间: {second}") scheduler.add_job(agv_asign_job, 'interval', seconds=int(second)) # minute = 1 # logger.info(f"准备启动AGV小车任务派发定时任务, 间隔时间: {minute}") # scheduler.add_job(agv_asign_job, 'interval', minutes=int(minute)) # scheduler.add_job(agv_asign_job, 'cron', hour="8,20") scheduler.start()