优化agv需求

This commit is contained in:
jinling.yang
2024-04-28 11:34:17 +08:00
parent b7f7f0cdff
commit 5eb946d936
8 changed files with 66 additions and 60 deletions

View File

@@ -451,13 +451,6 @@ class Manufacturing_Connect(http.Controller):
logging.info( logging.info(
'wd.production_line_state:%s' % wd.production_id.production_line_state) 'wd.production_line_state:%s' % wd.production_id.production_line_state)
wd.production_id.write({'production_line_state': '已上产线'}) wd.production_id.write({'production_line_state': '已上产线'})
next_workpiece = request.env['sf.workpiece.delivery'].sudo().search(
[('workorder_id.rfid_code', '=', rfid_code), ('type', '=', '下产线'),
('production_id', '=', wd.production_id.id)])
if next_workpiece:
logging.info('next_workpiece:%s' % next_workpiece.delivery_num)
next_workpiece.write(
{'status': '待下发', 'task_delivery_time': datetime.now()})
else: else:
res = {'Succeed': False, 'ErrorCode': 204, res = {'Succeed': False, 'ErrorCode': 204,
'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']} 'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']}
@@ -470,7 +463,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('AGVToProduct error:%s' % e) logging.info('AGVToProduct error:%s' % e)
return json.JSONEncoder().encode(res) return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False, @http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*") cors="*")
def AGVDownProduct(self, **kw): def AGVDownProduct(self, **kw):
""" """
@@ -510,15 +503,7 @@ class Manufacturing_Connect(http.Controller):
logging.info( logging.info(
'wd.production_line_state:%s' % wd.production_id.production_line_state) 'wd.production_line_state:%s' % wd.production_id.production_line_state)
wd.production_id.write({'production_line_state': '已下产线'}) wd.production_id.write({'production_line_state': '已下产线'})
delivery_Arr.append({wd.id}) delivery_Arr.append(wd.id)
next_workpiece = request.env['sf.workpiece.delivery'].sudo().search(
[('workorder_id.rfid_code', '=', rfid_code),
('type', '=', '运送空料架'),
('production_id', '=', wd.production_id.id)])
if next_workpiece:
logging.info('next_workpiece:%s' % next_workpiece.delivery_num)
next_workpiece.write(
{'status': '待下发', 'task_delivery_time': datetime.now()})
else: else:
res = {'Succeed': False, 'ErrorCode': 204, res = {'Succeed': False, 'ErrorCode': 204,
'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']} 'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']}
@@ -528,6 +513,8 @@ class Manufacturing_Connect(http.Controller):
[('id', 'in', delivery_Arr)]) [('id', 'in', delivery_Arr)])
if delivery_workpiece: if delivery_workpiece:
logging.info('开始向agv下发下产线任务') logging.info('开始向agv下发下产线任务')
is_free = delivery_workpiece._check_avgsite_state()
if is_free is True:
delivery_workpiece._delivery_avg() delivery_workpiece._delivery_avg()
logging.info('agv下发下产线任务下发完成') logging.info('agv下发下产线任务下发完成')
else: else:

View File

@@ -8,7 +8,6 @@ class AgvSetting(models.Model):
_name = 'sf.agv.site' _name = 'sf.agv.site'
_description = 'agv站点' _description = 'agv站点'
number = fields.Integer('序号')
name = fields.Char('位置编号') name = fields.Char('位置编号')
owning_region = fields.Char('所属区域') owning_region = fields.Char('所属区域')
state = fields.Selection([ state = fields.Selection([
@@ -26,6 +25,7 @@ class AgvSetting(models.Model):
center_control_r = requests.get(center_control_url, params={}, headers=headers) center_control_r = requests.get(center_control_url, params={}, headers=headers)
ret = center_control_r.json() ret = center_control_r.json()
logging.info('工件配送-请求中控站点信息:%s' % ret) logging.info('工件配送-请求中控站点信息:%s' % ret)
if ret['Succeed'] is True:
datas = ret['Datas'] datas = ret['Datas']
for item in self: for item in self:
for da in datas: for da in datas:

View File

@@ -486,7 +486,7 @@ class ResMrpWorkOrder(models.Model):
return [ return [
[0, '', {'production_id': production.id, 'type': '上产线', 'delivery_num': '%s-%s' % (production.name, 1)}], [0, '', {'production_id': production.id, 'type': '上产线', 'delivery_num': '%s-%s' % (production.name, 1)}],
[0, '', [0, '',
{'production_id': production.id, 'type': '下产线', 'delivery_num': '%s-%s' % (production.name, 2)}], ] {'production_id': production.id, 'type': '下产线', 'delivery_num': '%s-%s' % (production.name, 2)}]]
# 拼接工单对象属性值(表面工艺) # 拼接工单对象属性值(表面工艺)
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id): def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
@@ -1095,9 +1095,12 @@ class WorkPieceDelivery(models.Model):
[('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型') [('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration') delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration')
status = fields.Selection( status = fields.Selection(
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', ) [('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发')
is_cnc_program_down = fields.Boolean('程序是否下发', default=False) is_cnc_program_down = fields.Boolean('程序是否下发', default=False)
# @api.model
# def create(self, vals):
@api.onchange('route_id') @api.onchange('route_id')
def onchange_route(self): def onchange_route(self):
if self.route_id: if self.route_id:
@@ -1113,7 +1116,7 @@ class WorkPieceDelivery(models.Model):
same_production_line_id = None same_production_line_id = None
same_route_id = None same_route_id = None
down_status = '待下发' down_status = '待下发'
production_type = '上产线' production_type = None
num = 0 num = 0
for item in self: for item in self:
num += 1 num += 1
@@ -1126,8 +1129,10 @@ class WorkPieceDelivery(models.Model):
is_not_route += 1 is_not_route += 1
else: else:
raise UserError('请选择【任务路线】再进行配送') raise UserError('请选择【任务路线】再进行配送')
# if production_type != item.type: if production_type is None:
# raise UserError('请选择类型为【上产线】的制造订单进行配送') production_type = item.type
if production_type != item.type:
raise UserError('请选择类型为%s的制造订单进行配送' % production_type)
if down_status != item.status: if down_status != item.status:
raise UserError('请选择状态为【待下发】的制造订单进行配送') raise UserError('请选择状态为【待下发】的制造订单进行配送')
if same_production_line_id is None: if same_production_line_id is None:
@@ -1144,6 +1149,8 @@ class WorkPieceDelivery(models.Model):
raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认') raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认')
if is_not_route >= 1: if is_not_route >= 1:
raise UserError('您所选择制造订单的【任务路线】不一致,请重新确认') raise UserError('您所选择制造订单的【任务路线】不一致,请重新确认')
is_free = self._check_avgsite_state()
if is_free is True:
if delivery_ids: if delivery_ids:
return { return {
'name': _('确认'), 'name': _('确认'),
@@ -1154,13 +1161,28 @@ class WorkPieceDelivery(models.Model):
'context': { 'context': {
'default_delivery_ids': [(6, 0, delivery_ids)], 'default_delivery_ids': [(6, 0, delivery_ids)],
}} }}
else:
raise UserError("您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
# 配送至avg小车 # 验证agv站点是否可用
def _delivery_avg(self): def _check_avgsite_state(self):
is_free = False
agv_site = self.env['sf.agv.site'].search([]) agv_site = self.env['sf.agv.site'].search([])
if agv_site: if agv_site:
agv_site.update_site_state() agv_site.update_site_state()
# if for item in self:
if item.type in ["上产线", "下产线"]:
logging.info('工件配送-起点状态:%s-%s' % (
item.feeder_station_start_id.name, item.feeder_station_start_id.state))
logging.info('工件配送-终点状态:%s-%s' % (
item.feeder_station_destination_id.name, item.feeder_station_destination_id.state))
if item.feeder_station_start_id.state == '占用' and item.feeder_station_destination_id.state == '空闲':
is_free = True
logging.info('is_free:%s' % is_free)
return is_free
# 配送至avg小车
def _delivery_avg(self):
config = self.env['res.config.settings'].get_values() config = self.env['res.config.settings'].get_values()
positionCode_Arr = [] positionCode_Arr = []
delivery_Arr = [] delivery_Arr = []
@@ -1172,7 +1194,7 @@ class WorkPieceDelivery(models.Model):
if feeder_station_destination is None: if feeder_station_destination is None:
feeder_station_destination = item.feeder_station_destination_id.name feeder_station_destination = item.feeder_station_destination_id.name
delivery_Arr.append(item.delivery_num) delivery_Arr.append(item.delivery_num)
delivery_str = ', '.join(map(str, delivery_Arr)) delivery_str = ','.join(map(str, delivery_Arr))
if feeder_station_start is not None: if feeder_station_start is not None:
positionCode_Arr.append({ positionCode_Arr.append({
'positionCode': feeder_station_start, 'positionCode': feeder_station_start,

View File

@@ -7,8 +7,8 @@ import os
from odoo import models, fields, api, _ from odoo import models, fields, api, _
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.modules import get_resource_path from odoo.modules import get_resource_path
# from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import read_step_file
# from OCC.Extend.DataExchange import write_stl_file from OCC.Extend.DataExchange import write_stl_file
class ResProductMo(models.Model): class ResProductMo(models.Model):

View File

@@ -7,7 +7,6 @@
<field name="model">sf.agv.site</field> <field name="model">sf.agv.site</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree editable="bottom"> <tree editable="bottom">
<field name="number" required="1"/>
<field name="name" required="1"/> <field name="name" required="1"/>
<field name="owning_region" required="1"/> <field name="owning_region" required="1"/>
<field name="state" required="1"/> <field name="state" required="1"/>
@@ -39,7 +38,6 @@
<field name="start_site_id" required="1" options="{'no_create': True}" string="起点接驳站"/> <field name="start_site_id" required="1" options="{'no_create': True}" string="起点接驳站"/>
<field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/> <field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/>
<field name="destination_production_line_id" required="1" options="{'no_create': True}"/> <field name="destination_production_line_id" required="1" options="{'no_create': True}"/>
<field name="priority" widget="priority"/>
</tree> </tree>
</field> </field>
</record> </record>

View File

@@ -608,9 +608,9 @@
<field name="model">sf.workpiece.delivery</field> <field name="model">sf.workpiece.delivery</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="工件配送"> <search string="工件配送">
<!-- <filter string="待下发" name="status" domain="[('status', '=', '待下发')]"/>--> <filter string="待下发" name="on_down" domain="[('status', '=', '待下发'),('type','=',['上产线'])]"/>
<!-- <filter string="待配送" name="status" domain="[('status', '=', '待配送')]"/>--> <filter string="上产线" name="down" domain="[('type', '=', '上产线')]"/>
<!-- <filter string="已配送" name="status" domain="[('status', '=', '已配送')]"/>--> <filter string="下产线" name="up" domain="[('type', '=', '下产线')]"/>
<field name="production_id"/> <field name="production_id"/>
<field name="feeder_station_start_id"/> <field name="feeder_station_start_id"/>
<field name="production_line_id"/> <field name="production_line_id"/>
@@ -621,7 +621,6 @@
<field name="status"/> <field name="status"/>
<searchpanel> <searchpanel>
<field name="production_line_id" icon="fa-building" enable_counters="1"/> <field name="production_line_id" icon="fa-building" enable_counters="1"/>
<field name="type" icon="fa-building" enable_counters="1"/>
<field name="status" icon="fa-building" enable_counters="1"/> <field name="status" icon="fa-building" enable_counters="1"/>
</searchpanel> </searchpanel>
</search> </search>
@@ -631,10 +630,10 @@
<record id="sf_workpiece_delivery_act" model="ir.actions.act_window"> <record id="sf_workpiece_delivery_act" model="ir.actions.act_window">
<field name="name">工件配送</field> <field name="name">工件配送</field>
<field name="res_model">sf.workpiece.delivery</field> <field name="res_model">sf.workpiece.delivery</field>
<!-- <field name="search_view_id" ref="sf_workpiece_delivery_search"/>--> <field name="search_view_id" ref="sf_workpiece_delivery_search"/>
<!-- <field name="context">{'search_default_status':'待下发'}</field>--> <field name="context">{'search_default_on_down':1}</field>
<field name="view_mode">tree,search</field> <field name="view_mode">tree,search</field>
<!-- <field name="domain">[('type','in',['上产线']),('status','in',['待下发'])]</field>--> <field name="domain">[('type','in',['上产线','下产线'])]</field>
</record> </record>
</odoo> </odoo>

View File

@@ -8,8 +8,8 @@ from datetime import datetime
import requests import requests
from odoo import http from odoo import http
from odoo.http import request from odoo.http import request
# from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import read_step_file
# from OCC.Extend.DataExchange import write_stl_file from OCC.Extend.DataExchange import write_stl_file
from odoo import models, fields, api from odoo import models, fields, api
from odoo.modules import get_resource_path from odoo.modules import get_resource_path
from odoo.exceptions import ValidationError, UserError from odoo.exceptions import ValidationError, UserError

View File

@@ -6,8 +6,8 @@ import os
from datetime import datetime from datetime import datetime
from stl import mesh from stl import mesh
# from OCC.Core.GProp import GProp_GProps # from OCC.Core.GProp import GProp_GProps
# from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import read_step_file
# from OCC.Extend.DataExchange import write_stl_file from OCC.Extend.DataExchange import write_stl_file
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
from odoo import models, fields, api from odoo import models, fields, api
from odoo.modules import get_resource_path from odoo.modules import get_resource_path