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.
313 lines
12 KiB
313 lines
12 KiB
|
|
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
|
|
import os
|
|
import codecs
|
|
scheduler = AsyncIOScheduler(timezone=timezone('Asia/Shanghai'))
|
|
|
|
|
|
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(is_shelf = True, is_valid = False, is_active = True, orderids__contains=[cmdStd["orderid"]])
|
|
if len(qs) > 0:
|
|
#check if already allocate Vacancy
|
|
print("already allocate Vacancy: ", qs)
|
|
vacancy = qs[0]
|
|
#generate destination with respond to task
|
|
cmdStdl.append({vacancy.number: cmdStd})
|
|
else:
|
|
#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
|
|
orderids = vacancy.orderids
|
|
if not orderids:
|
|
orderids = [ cmdStd["orderid"] ]
|
|
else:
|
|
orderids.append(cmdStd["orderid"])
|
|
|
|
vacancy.is_valid = False
|
|
vacancy.orderids = orderids
|
|
await vacancy.save()
|
|
else:
|
|
raise Exception("Shelf vacancy is not enough!")
|
|
|
|
elif 5 == cmdStd["action"]:
|
|
#5: 现场领用
|
|
|
|
qs = await Vacancy.filter(is_connect = True, is_valid = False, is_active = True, orderids__contains=[cmdStd["orderid"]])
|
|
if len(qs) > 0:
|
|
#check if already allocate Vacancy
|
|
print("already allocate Vacancy: ", qs)
|
|
vacancy = qs[0]
|
|
#generate destination with respond to task
|
|
cmdStdl.append({vacancy.number: cmdStd})
|
|
else:
|
|
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
|
|
orderids = vacancy.orderids
|
|
if not orderids:
|
|
orderids = [ cmdStd["orderid"] ]
|
|
else:
|
|
orderids.append(cmdStd["orderid"])
|
|
|
|
vacancy.is_valid = False
|
|
vacancy.orderids = orderids
|
|
await vacancy.save()
|
|
else:
|
|
raise Exception("Shelf 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:
|
|
|
|
if orderids and len(orderids) > 0:
|
|
orderids.remove
|
|
else:
|
|
orderids = []
|
|
|
|
if len(orderids) > 0:
|
|
vacancy3.is_valid = False
|
|
else:
|
|
vacancy3.is_valid = True
|
|
|
|
vacancy3.orderids = orderids
|
|
await vacancy3.save()
|
|
|
|
# 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("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()
|