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.

345 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, 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()