821 lines
43 KiB
Python
821 lines
43 KiB
Python
# -*- coding: utf-8 -*-
|
|
import json
|
|
import base64
|
|
import logging
|
|
from datetime import timedelta
|
|
import requests
|
|
from odoo.addons.sf_base.commons.common import Common
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import UserError, ValidationError
|
|
|
|
|
|
class SfMaintenanceEquipmentCategory(models.Model):
|
|
_inherit = 'maintenance.equipment.category'
|
|
_description = '设备类别'
|
|
|
|
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
|
|
('检测设备', '检测设备'), ('其他', '其他')], string='类型', default='机床')
|
|
equipment_type_code = fields.Char('简写')
|
|
|
|
|
|
class SfMaintenanceEquipmentAGVLog(models.Model):
|
|
_name = 'maintenance.equipment.agv.log'
|
|
_description = 'AGV运行日志'
|
|
|
|
run_type = fields.Char('任务类型')
|
|
run_code = fields.Char('任务指令代码')
|
|
run_first = fields.Char('任务起点')
|
|
production_line = fields.Char('目的生产线')
|
|
run_last = fields.Char('任务终点')
|
|
workorder = fields.Char('工件编码/任务单号')
|
|
time = fields.Datetime('日期/事件')
|
|
state = fields.Char('事件/状体')
|
|
equipment_id = fields.Many2one('maintenance.equipment', '设备')
|
|
|
|
|
|
class SfMaintenanceEquipment(models.Model):
|
|
_inherit = 'maintenance.equipment'
|
|
_description = '设备'
|
|
|
|
crea_url = "/api/machine_tool/create"
|
|
|
|
run_status = fields.Char('机床运行状态', readonly=True)
|
|
|
|
# AGV运行日志
|
|
agv_logs = fields.One2many('maintenance.equipment.agv.log', 'equipment_id', string='AGV运行日志')
|
|
# 1212修改后的字段
|
|
number_of_axles = fields.Selection(
|
|
[("三轴", "三轴"), ("四轴", "四轴"), ("五轴", "五轴"), ("六轴", "六轴")],
|
|
default="", string="轴数")
|
|
|
|
# 1212新增字段
|
|
|
|
function_type = fields.Selection(
|
|
[("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")],
|
|
default="", string="功能类型")
|
|
T_trough_num = fields.Integer('槽数')
|
|
T_trough_wide = fields.Float('槽宽(mm)')
|
|
T_trough_distance = fields.Float('槽距(mm)')
|
|
|
|
taper_type_id = fields.Many2one('spindle.taper.type', string='主轴锥孔型号')
|
|
spindle_center_distance = fields.Float('主轴中心至立柱滑轨面距离(mm)')
|
|
spindle_continuous_power = fields.Float('主轴持续功率(kw)')
|
|
spindle_peak_power = fields.Float('主轴峰值功率(kw)')
|
|
spindle_sustained_torque = fields.Float('主轴持续扭矩(n/m)')
|
|
spindle_peak_torque = fields.Float('主轴峰值扭矩(n/m)')
|
|
linear_axis_guides_type = fields.Char('直线轴导轨类型')
|
|
axis_driven_type = fields.Char('坐标轴驱动类型')
|
|
|
|
X_axis_rapid_traverse_speed = fields.Char('X轴快速进给速度(mm/min)')
|
|
Y_axis_rapid_traverse_speed = fields.Char('Y轴快速进给速度(mm/min)')
|
|
Z_axis_rapid_traverse_speed = fields.Char('Z轴快速进给速度(mm/min)')
|
|
a_axis_rapid_traverse_speed = fields.Char('a轴快速进给速度(mm/min)')
|
|
b_axis_rapid_traverse_speed = fields.Char('b轴快速进给速度(mm/min)')
|
|
c_axis_rapid_traverse_speed = fields.Char('c轴快速进给速度(mm/min)')
|
|
straight_cutting_feed_rate = fields.Char('直线切削进给速度(mm/min)')
|
|
rotary_cutting_feed_rate = fields.Char('回转切削进给速度(mm/min)')
|
|
|
|
X_precision = fields.Char('X轴定位精度(mm)')
|
|
X_precision_repeat = fields.Char('X轴重复定位精度(mm)')
|
|
Y_precision = fields.Char('Y轴定位精度(mm)')
|
|
Y_precision_repeat = fields.Char('Y轴重复定位精度(mm)')
|
|
Z_precision = fields.Char('Z轴定位精度(mm)')
|
|
Z_precision_repeat = fields.Char('Z轴重复定位精度(mm)')
|
|
a_precision = fields.Char('a轴定位精度(mm)')
|
|
a_precision_repeat = fields.Char('a轴重复定位精度(mm)')
|
|
b_precision = fields.Char('b轴定位精度(mm)')
|
|
b_precision_repeat = fields.Char('b轴重复定位精度(mm)')
|
|
c_precision = fields.Char('c轴定位精度(mm)')
|
|
c_precision_repeat = fields.Char('c轴重复定位精度(mm)')
|
|
|
|
tool_full_diameter_max = fields.Float('刀具满刀最大直径(mm)')
|
|
tool_perimeter_diameter_max = fields.Float('刀具邻空刀最大直径(mm)')
|
|
T_tool_time = fields.Float('T-T换刀时间(s)', digits=(12, 1))
|
|
C_tool_time = fields.Float('C-C换刀时间(s)', digits=(12, 1))
|
|
|
|
# 待删除字段
|
|
precision_min = fields.Float('X轴定位精度min(mm)', digits=(12, 3))
|
|
precision_max = fields.Float('X轴定位精度max(mm)', digits=(12, 3))
|
|
lead_screw = fields.Char('丝杆')
|
|
guide_rail = fields.Char('导轨')
|
|
feed_speed = fields.Char('进给速度(mm/min)')
|
|
tool_speed = fields.Char('刀具速度(m/min)')
|
|
torque = fields.Char('主轴点击扭矩(n/m)')
|
|
motor_power = fields.Char('主轴电机功率(kw)')
|
|
taper = fields.Char('主轴锥度(°)')
|
|
tool_diameter_max = fields.Char('刀具刀径max(mm)')
|
|
tool_diameter_min = fields.Char('刀具刀径min(mm)')
|
|
|
|
# def get_no(self):
|
|
# partner = self.env['maintenance.equipment'].sudo().search(
|
|
# [('MTcode', '!=', '')],
|
|
# limit=1,
|
|
# order="id desc")
|
|
# if not partner:
|
|
# num = "%04d" % 1
|
|
#
|
|
# else:
|
|
# m = int(partner.MTcode) + 1
|
|
# num = "%04d" % m
|
|
# return num
|
|
|
|
equipment_maintenance_standards_ids = fields.Many2many('equipment.maintenance.standards',
|
|
'sf_maintenance_equipment_ids', string='设备维保标准')
|
|
eq_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备保养标准',
|
|
domain="[('maintenance_type','=','保养')]")
|
|
|
|
initial_action_date = fields.Date(string='初始保养日期')
|
|
next_action_date = fields.Date(string='下次预防保养')
|
|
initial_overhaul_date = fields.Date(string='初始维修日期')
|
|
overhaul_date = fields.Date(string='下次预防检修')
|
|
overhaul_period = fields.Integer(string='预防检修频次')
|
|
overhaul_duration = fields.Float(string='检修时长')
|
|
|
|
overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准',
|
|
domain="[('maintenance_type','=','检修')]")
|
|
|
|
def confirm_maintenance(self):
|
|
"""
|
|
确认保养/检修
|
|
"""
|
|
context = self.env.context
|
|
initial_date = None
|
|
next_date = None
|
|
if context['type'] == '保养':
|
|
if not self.initial_action_date:
|
|
raise ValidationError('初始保养日期不能为空!!')
|
|
elif self.initial_action_date < fields.Date.today():
|
|
raise ValidationError('初始保养日期不能小于当前日期!!')
|
|
else:
|
|
initial_date = self.initial_action_date
|
|
next_date = self.next_action_date
|
|
elif context['type'] == '检修':
|
|
if not self.initial_overhaul_date:
|
|
raise ValidationError('初始检修日期不能为空!!')
|
|
elif self.initial_overhaul_date < fields.Date.today():
|
|
raise ValidationError('初始检修日期不能小于当前日期!!')
|
|
else:
|
|
initial_date = self.initial_overhaul_date
|
|
next_date = self.overhaul_date
|
|
|
|
request_id = self.env['maintenance.request'].search([('stage_id.done', '=', False),
|
|
('equipment_id', '=', self.id),
|
|
('maintenance_type', '=', 'preventive'),
|
|
('request_date', '=', next_date),
|
|
('sf_maintenance_type', '=', context['type'])])
|
|
if not request_id:
|
|
if context['type'] == '保养':
|
|
self._create_new_request(initial_date)
|
|
elif context['type'] == '检修':
|
|
self._create_new_request1(initial_date)
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': f'创建{context["type"]}计划',
|
|
'message': f'{context["type"]}维保计划创建成功',
|
|
'type': 'success'
|
|
}
|
|
}
|
|
else:
|
|
pass
|
|
|
|
@api.onchange('eq_maintenance_id', 'overhaul_id')
|
|
def _compute_equipment_maintenance_standards_ids(self):
|
|
for record in self:
|
|
if record.eq_maintenance_id and record.overhaul_id:
|
|
record.equipment_maintenance_standards_ids = [
|
|
(6, 0, [record.eq_maintenance_id.id, record.overhaul_id.id])]
|
|
break
|
|
if record.eq_maintenance_id:
|
|
record.equipment_maintenance_standards_ids = [(6, 0, [record.eq_maintenance_id.id])]
|
|
break
|
|
if record.overhaul_id:
|
|
record.equipment_maintenance_standards_ids = [(6, 0, [record.overhaul_id.id])]
|
|
break
|
|
else:
|
|
record.equipment_maintenance_standards_ids = False
|
|
|
|
MTcode = fields.Char("机台编码")
|
|
created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user)
|
|
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
|
|
('检测设备', '检测设备'), ('其他', '其他')], compute='_compute_category_id')
|
|
|
|
@api.depends('category_id')
|
|
def _compute_category_id(self):
|
|
for record in self:
|
|
if record:
|
|
record.equipment_type = record.category_id.equipment_type
|
|
|
|
code = fields.Char('行业编码')
|
|
name = fields.Char('机台号', required=False)
|
|
knife_type = fields.Selection(
|
|
[("BT40", "BT40"), ("BT30", "BT30"), ("BT50", "BT50")],
|
|
default="", string="刀把类型")
|
|
number_of_knife_library = fields.Integer('刀库数量(把)')
|
|
rotate_speed = fields.Integer('转速')
|
|
# 加工进程
|
|
a_axis = fields.Char('a轴')
|
|
x_axis = fields.Integer('X轴')
|
|
y_axis = fields.Integer('Y轴')
|
|
z_axis = fields.Integer('Z轴')
|
|
b_axis = fields.Char('B轴')
|
|
c_axis = fields.Char('C轴')
|
|
remark = fields.Char('备注')
|
|
is_binding = fields.Boolean('是否绑定机床', default=False)
|
|
control_system_id = fields.Many2one('sf.machine.control_system',
|
|
string="控制系统")
|
|
# 多个机床型号对应一个机床
|
|
brand_id = fields.Many2one('sf.machine.brand', string='品牌', domain="[('tag_ids.name', 'ilike', equipment_type)]")
|
|
type_id = fields.Many2one('sf.machine_tool.type', '型号')
|
|
|
|
state = fields.Selection(
|
|
[("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"), ("空闲", "空闲"),
|
|
("封存(报废)", "封存(报废)")],
|
|
default='正常', string="机床状态")
|
|
run_time = fields.Char('总运行时长')
|
|
# 0606新增字段
|
|
machine_tool_picture = fields.Binary('图片')
|
|
heightened_way = fields.Selection([
|
|
('sifudianji', '伺服电机驱动'),
|
|
('youyagang', '油压缸驱动'),
|
|
('chilunjia', '齿轮架驱动')
|
|
], string="主轴加高方式", default='sifudianji')
|
|
workpiece_load = fields.Char('工件最大负载(kg)')
|
|
workbench_L = fields.Char('工作台长度(mm)')
|
|
workbench_W = fields.Char('工作台宽度(mm)')
|
|
workbench_H = fields.Char('工作台高度(mm)')
|
|
machine_tool_L = fields.Char('机床长度(mm)')
|
|
machine_tool_W = fields.Char('机床宽度(mm)')
|
|
machine_tool_H = fields.Char('机床高度(mm)')
|
|
distance_min = fields.Char('主轴端面至工作台面距离MIN(mm)')
|
|
distance_max = fields.Char('主轴端面至工作台面距离MAX(mm)')
|
|
tool_quality_max = fields.Char('刀具最大质量(kg)')
|
|
tool_long_max = fields.Char('刀具最大长度(mm)')
|
|
machine_tool_category = fields.Many2one('sf.machine_tool.category', string='机床类型')
|
|
# 一个机床对应一個加工工厂,一个加工工厂对应多个机床
|
|
factory_id = fields.Many2one('res.partner', string='所属工厂',
|
|
domain="[('is_factory', '=', True)]")
|
|
# 一个机床对应一个供应商,一个供应商对应多个机床
|
|
supplier_id = fields.Many2one('res.partner', string='制造商',
|
|
domain="[('is_vendor', '=', True)]")
|
|
registration_date = fields.Date('注册日期')
|
|
state_zc = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册',
|
|
tracking=True)
|
|
active = fields.Boolean('有效', default=True)
|
|
# 多个型号对应一个机床
|
|
machine_tool_id = fields.Many2one('sf.machine_tool', '机床')
|
|
sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_id', '设备故障日志')
|
|
equipment_oee_ids = fields.One2many('maintenance.equipment.oee', 'equipment_id', '设备OEE')
|
|
|
|
# def name_get(self):
|
|
# result = []
|
|
# for parameter in self:
|
|
# if parameter.code:
|
|
# name = parameter.name + '-' + parameter.code
|
|
# else:
|
|
# name = parameter.name
|
|
# result.append((parameter.id, name))
|
|
# return result
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
# 在创建设备之前执行一些自定义逻辑
|
|
|
|
equipment = super(SfMaintenanceEquipment, self).create(vals)
|
|
if equipment.category_id:
|
|
equipment.name = "%s%s" % (equipment.MTcode, equipment.category_id.name)
|
|
if equipment.category_id.equipment_type == '机床':
|
|
equipment_id = self.env['maintenance.equipment.oee'].search([('equipment_id', '=', equipment.id)])
|
|
if not equipment_id:
|
|
self.env['maintenance.equipment.oee'].sudo().create({
|
|
'equipment_id': equipment.id,
|
|
'name': equipment.name,
|
|
|
|
})
|
|
|
|
# 在创建设备之后执行一些自定义逻辑
|
|
# ...
|
|
|
|
return equipment
|
|
|
|
# @api.constrains('rotate_speed')
|
|
# def _check_rotate_speed(self):
|
|
# if self.rotate_speed <= 0:
|
|
# raise UserError("转速不能为0")
|
|
#
|
|
# @api.constrains('precision')
|
|
# def _check_precision(self):
|
|
# if self.equipment_type == '机床' and self.precision <= 0.00:
|
|
# raise UserError("加工精度不能为0")
|
|
#
|
|
# @api.constrains('number_of_knife_library')
|
|
# def _check_number_of_knife_library(self):
|
|
# if self.equipment_type == '机床' and self.number_of_knife_library <= 0:
|
|
# raise UserError("刀库数量不能为0")
|
|
#
|
|
# @api.constrains('x_axis')
|
|
# def _check_x_axis(self):
|
|
# if self.equipment_type == '机床' and self.x_axis <= 0:
|
|
# raise UserError("加工行程里x轴不能为0")
|
|
#
|
|
# @api.constrains('y_axis')
|
|
# def _check_y_axis(self):
|
|
# if self.equipment_type == '机床' and self.y_axis <= 0:
|
|
# raise UserError("加工行程里y轴不能为0")
|
|
#
|
|
# @api.constrains('z_axis')
|
|
# def _check_z_axis(self):
|
|
# if self.equipment_type == '机床' and self.z_axis <= 0:
|
|
# raise UserError("加工行程里z轴不能为0")
|
|
#
|
|
# @api.constrains('b_axis')
|
|
# def _check_b_axis(self):
|
|
# if self.equipment_type == '机床' and self.number_of_axles == '四轴':
|
|
# print(self.number_of_axles)
|
|
# if self.b_axis <= 0:
|
|
# raise UserError("加工行程里b轴不能为0")
|
|
#
|
|
# @api.constrains('c_axis')
|
|
# def _check_c_axis(self):
|
|
# if self.equipment_type == '机床' and self.number_of_axles == '五轴':
|
|
# if self.c_axis <= 0:
|
|
# raise UserError("加工行程里c轴不能为0")
|
|
|
|
@api.onchange('type_id')
|
|
def get_type_info(self):
|
|
for item in self:
|
|
item.knife_type = item.type_id.knife_type
|
|
item.number_of_knife_library = item.type_id.number_of_knife_library
|
|
item.number_of_axles = item.type_id.number_of_axles
|
|
item.rotate_speed = item.type_id.rotate_speed
|
|
item.precision_min = item.type_id.precision_min
|
|
item.precision_max = item.type_id.precision_max
|
|
item.control_system_id = item.type_id.control_system_id
|
|
item.x_axis = item.type_id.x_axis
|
|
item.y_axis = item.type_id.y_axis
|
|
item.z_axis = item.type_id.z_axis
|
|
item.b_axis = item.type_id.b_axis
|
|
item.c_axis = item.type_id.c_axis
|
|
item.machine_tool_picture = item.type_id.machine_tool_picture
|
|
item.heightened_way = item.type_id.heightened_way
|
|
item.workpiece_load = item.type_id.workpiece_load
|
|
item.lead_screw = item.type_id.lead_screw
|
|
item.workbench_L = item.type_id.workbench_L
|
|
item.workbench_W = item.type_id.workbench_W
|
|
item.guide_rail = item.type_id.guide_rail
|
|
item.machine_tool_L = item.type_id.machine_tool_L
|
|
item.machine_tool_W = item.type_id.machine_tool_W
|
|
item.machine_tool_H = item.type_id.machine_tool_H
|
|
item.feed_speed = item.type_id.feed_speed
|
|
item.tool_speed = item.type_id.tool_speed
|
|
item.distance_min = item.type_id.distance_min
|
|
item.distance_max = item.type_id.distance_max
|
|
item.taper = item.type_id.taper
|
|
item.torque = item.type_id.torque
|
|
item.motor_power = item.type_id.motor_power
|
|
item.tool_quality_max = item.type_id.tool_quality_max
|
|
item.tool_long_max = item.type_id.tool_long_max
|
|
item.tool_diameter_max = item.type_id.tool_diameter_max
|
|
item.tool_diameter_min = item.type_id.tool_diameter_min
|
|
item.machine_tool_category = item.type_id.machine_tool_category.id
|
|
item.brand_id = item.type_id.brand_id.id
|
|
# 新增修改字段
|
|
item.taper_type_id = item.type_id.taper_type_id.id
|
|
item.function_type = item.type_id.function_type
|
|
item.a_axis = item.type_id.a_axis
|
|
item.T_trough_num = item.type_id.T_trough_num
|
|
item.T_trough_wide = item.type_id.T_trough_wide
|
|
item.T_trough_distance = item.type_id.T_trough_distance
|
|
item.spindle_center_distance = item.type_id.spindle_center_distance
|
|
item.spindle_continuous_power = item.type_id.spindle_continuous_power
|
|
item.spindle_peak_power = item.type_id.spindle_peak_power
|
|
item.spindle_sustained_torque = item.type_id.spindle_sustained_torque
|
|
item.spindle_peak_torque = item.type_id.spindle_peak_torque
|
|
item.linear_axis_guides_type = item.type_id.linear_axis_guides_type
|
|
item.axis_driven_type = item.type_id.axis_driven_type
|
|
item.X_axis_rapid_traverse_speed = item.type_id.X_axis_rapid_traverse_speed
|
|
item.Y_axis_rapid_traverse_speed = item.type_id.Y_axis_rapid_traverse_speed
|
|
item.Z_axis_rapid_traverse_speed = item.type_id.Z_axis_rapid_traverse_speed
|
|
item.a_axis_rapid_traverse_speed = item.type_id.a_axis_rapid_traverse_speed
|
|
item.b_axis_rapid_traverse_speed = item.type_id.b_axis_rapid_traverse_speed
|
|
item.c_axis_rapid_traverse_speed = item.type_id.c_axis_rapid_traverse_speed
|
|
item.straight_cutting_feed_rate = item.type_id.straight_cutting_feed_rate
|
|
item.rotary_cutting_feed_rate = item.type_id.rotary_cutting_feed_rate
|
|
item.X_precision = item.type_id.X_precision
|
|
item.X_precision_repeat = item.type_id.X_precision_repeat
|
|
item.Y_precision = item.type_id.Y_precision
|
|
item.Y_precision_repeat = item.type_id.Y_precision_repeat
|
|
item.Z_precision = item.type_id.Z_precision
|
|
item.Z_precision_repeat = item.type_id.Z_precision_repeat
|
|
item.a_precision = item.type_id.a_precision
|
|
item.a_precision_repeat = item.type_id.a_precision_repeat
|
|
item.b_precision = item.type_id.b_precision
|
|
item.b_precision_repeat = item.type_id.b_precision_repeat
|
|
item.c_precision = item.type_id.c_precision
|
|
item.c_precision_repeat = item.type_id.c_precision_repeat
|
|
item.tool_full_diameter_max = item.type_id.tool_full_diameter_max
|
|
item.tool_perimeter_diameter_max = item.type_id.tool_perimeter_diameter_max
|
|
item.T_tool_time = item.type_id.T_tool_time
|
|
item.C_tool_time = item.type_id.C_tool_time
|
|
item.C_tool_time = item.type_id.C_tool_time
|
|
item.image_id = item.type_id.jg_image_id.ids
|
|
item.image_lq_id = item.type_id.lq_image_id.ids
|
|
|
|
# AGV小车设备参数
|
|
AGV_L = fields.Char('AGV尺寸(长)')
|
|
AGV_W = fields.Char('AGV尺寸(宽)')
|
|
AGV_H = fields.Char('AGV尺寸(高)')
|
|
AGV_goods_L = fields.Char('载货尺寸(长)')
|
|
AGV_goods_W = fields.Char('载货尺寸(宽)')
|
|
AGV_goods_H = fields.Char('载货尺寸(高)')
|
|
AGV_velocity = fields.Char('标准速度')
|
|
AGV_velocity_min = fields.Char('标准速度(最小)')
|
|
AGV_velocity_max = fields.Char('标准速度(最大)')
|
|
AGV_Lifting_height = fields.Char('升降高度(max)')
|
|
AGV_ground_clearance = fields.Char('最小离地高度')
|
|
AGV_turning_radius = fields.Char('最小转弯半径')
|
|
AGV_gradeability_max = fields.Integer('最大爬坡度')
|
|
AGV_parking_accuracy = fields.Char('停车精度')
|
|
AGV_load_weight_max = fields.Char('AGV最大负载重量')
|
|
AGV_weight = fields.Char('AGV本体总重量')
|
|
AGV_job_duration = fields.Char('连续作业时长')
|
|
AGV_transfer_mode = fields.Char('移载方式')
|
|
AGV_drive_motor_power = fields.Char('驱动电机功率')
|
|
AGV_hoist_motor_power = fields.Char('提升电机功率')
|
|
AGV_drive_motor_speed_ratio = fields.Char('驱动电机速比')
|
|
AGV_veer_motor_power = fields.Char('转向电机功率')
|
|
AGV_veer_motor_speed_ratio = fields.Char('转向电机速比')
|
|
AGV_move_motor_power = fields.Char('前移电机功率')
|
|
AGV_move_motor_speed_ratio = fields.Char('前移电机速比')
|
|
AGV_drive_mode = fields.Char('AGV驱动方式')
|
|
AGV_navigation_mode = fields.Char('导航方式')
|
|
AGV_communication_mode = fields.Char('通讯方式')
|
|
AGV_direction_travel = fields.Char('行走方向')
|
|
AGV_power_requirements = fields.Char('AGV电源要求')
|
|
AGV_charge_mode = fields.Selection([('手动', '手动'), ('自动', '自动')], string='充电方式')
|
|
AGV_security = fields.Char('安全防护')
|
|
AGV_operating_temperature = fields.Char('环境温度')
|
|
AGV_operating_humidity = fields.Char('环境湿度')
|
|
|
|
# 三元检测设备参数
|
|
detect_L = fields.Char('设备尺寸(长)')
|
|
detect_W = fields.Char('设备尺寸(宽)')
|
|
detect_H = fields.Char('设备尺寸(高)')
|
|
detect_x_axis = fields.Char('检测X轴')
|
|
detect_y_axis = fields.Char('检测Y轴')
|
|
detect_z_axis = fields.Char('检测Z轴')
|
|
detect_precision = fields.Char('测量精度')
|
|
detect_measurement_mode = fields.Selection([('光栅尺', '光栅尺'), ('容栅', '容栅'), ('磁栅', '磁栅'),
|
|
('激光干涉仪', '激光干涉仪')], string='测量方式')
|
|
detect_resolution = fields.Char('分辨率')
|
|
detect_load_weight_max = fields.Char('检测设备最大负载重量')
|
|
detect_weight = fields.Char('检测设备本体总重量')
|
|
detect_measurement_length = fields.Char('深孔测量长度(max)')
|
|
detect_control_mode = fields.Char('控制方式')
|
|
detect_balance_mode_for_Z = fields.Char('Z轴平衡方式')
|
|
detect_zoom_objective_magnification = fields.Char('变焦物镜倍率')
|
|
detect_magnification = fields.Char('放大倍率')
|
|
detect_working_distance = fields.Char('工作距离')
|
|
detect_locking_mode = fields.Char('锁紧方式')
|
|
detect_pressurized_air = fields.Char('压缩空气')
|
|
detect_object_field_of_view_max = fields.Char('物方视场(最大)')
|
|
detect_object_field_of_view_min = fields.Char('物方视场(最小)')
|
|
detect_power_requirements = fields.Char('电源要求')
|
|
detect_operating_temperature = fields.Char('检测设备环境温度')
|
|
detect_operating_humidity = fields.Char('检测设备环境湿度')
|
|
|
|
# 机器人设备参数
|
|
robot_gripping_of_workpieces_L = fields.Char('可抓取工件(长)')
|
|
robot_gripping_of_workpieces_W = fields.Char('可抓取工件(宽)')
|
|
robot_gripping_of_workpieces_H = fields.Char('可抓取工件(高)')
|
|
robot_radius_of_the_boom = fields.Char('展臂半径')
|
|
robot_load_weight_max = fields.Char('机械臂最大负载重量')
|
|
robot_weight = fields.Char('机械臂本体总重量')
|
|
robot_repeatable_positioning_accuracy = fields.Char('重复定位精度')
|
|
robot_axis_num = fields.Selection([('2轴', '2轴'), ('3轴', '3轴'), ('4轴', '4轴'), ('5轴', '5轴'), ('6轴', '6轴'),
|
|
('7轴', '7轴'), ('8轴', '8轴')], string='机械臂轴数')
|
|
axis_ids = fields.One2many('sf.robot.axis.num', 'equipment_id', string='动作范围')
|
|
robot_track_dimensions_L = fields.Char('轨道尺寸(长)')
|
|
robot_track_dimensions_W = fields.Char('轨道尺寸(宽)')
|
|
robot_track_dimensions_H = fields.Char('轨道尺寸(高)')
|
|
robot_drive_mode = fields.Char('驱动方式')
|
|
robot_installation_method = fields.Selection([('置地式', '置地式'), ('壁挂式', '壁挂式'), ('倒挂式', '倒挂式')],
|
|
string='安装方式')
|
|
robot_operating_temperature = fields.Char('机器人环境温度')
|
|
robot_operating_humidity = fields.Char('机器人环境湿度')
|
|
|
|
# 其他参数(所有设备)
|
|
date_of_purchase = fields.Date('采购日期')
|
|
date_of_manufacture = fields.Date('出厂日期')
|
|
date_of_warranty = fields.Date('质保截至日期')
|
|
original_value = fields.Char('原值')
|
|
incomplete_value = fields.Char('残值')
|
|
|
|
# 注册同步机床
|
|
def enroll_machine_tool(self):
|
|
sf_sync_config = self.env['res.config.settings'].get_values()
|
|
token = sf_sync_config['token']
|
|
sf_secret_key = sf_sync_config['sf_secret_key']
|
|
headers = Common.get_headers(self, token, sf_secret_key)
|
|
strurl = sf_sync_config['sf_url'] + self.crea_url
|
|
objs_all = self.env['maintenance.equipment'].search([('id', '=', self.id)])
|
|
machine_tool_list = []
|
|
if objs_all:
|
|
for item in objs_all:
|
|
images_ids_names = []
|
|
for a in self.env['maintenance.equipment.image'].search([('id', 'in', item.image_id.ids)]):
|
|
images_ids_names.append(a.name)
|
|
if item.machine_tool_picture:
|
|
image = base64.b64encode(item.machine_tool_picture).decode('utf-8')
|
|
else:
|
|
image = False
|
|
control_system_id = self.env['sf.machine.control_system'].sudo().browse(item.control_system_id.id).code
|
|
|
|
val = {
|
|
'MTcode': item.MTcode,
|
|
'factory_token': token,
|
|
'id': item.id,
|
|
'name': item.name,
|
|
'code': item.code,
|
|
'knife_type': item.knife_type,
|
|
'number_of_knife_library': item.number_of_knife_library,
|
|
'rotate_speed': item.rotate_speed,
|
|
'number_of_axles': item.number_of_axles,
|
|
'control_system_id': control_system_id,
|
|
'type_id': self.env['sf.machine_tool.type'].sudo().browse(item.type_id.id).code,
|
|
'brand_id': self.env['sf.machine.brand'].sudo().browse(item.brand_id.id).code,
|
|
'supplier_id': item.supplier_id.id,
|
|
'x_axis': item.x_axis,
|
|
'y_axis': item.y_axis,
|
|
'z_axis': item.z_axis,
|
|
'b_axis': item.b_axis,
|
|
'c_axis': item.c_axis,
|
|
'state': item.state,
|
|
'active': item.active,
|
|
'machine_tool_picture': image,
|
|
'heightened_way': item.heightened_way,
|
|
'workpiece_load': item.workpiece_load,
|
|
'lead_screw': item.lead_screw,
|
|
'workbench_L': item.workbench_L,
|
|
'workbench_W': item.workbench_W,
|
|
'workbench_H': item.workbench_H,
|
|
'guide_rail': item.guide_rail,
|
|
'machine_tool_L': item.machine_tool_L,
|
|
'machine_tool_W': item.machine_tool_W,
|
|
'machine_tool_H': item.machine_tool_H,
|
|
'feed_speed': item.feed_speed,
|
|
'tool_speed': item.tool_speed,
|
|
'taper': item.taper,
|
|
'torque': item.torque,
|
|
'motor_power': item.motor_power,
|
|
'tool_quality_max': item.tool_quality_max,
|
|
'tool_long_max': item.tool_long_max,
|
|
'tool_diameter_max': item.tool_diameter_max,
|
|
'precision_min': item.precision_min,
|
|
'precision_max': item.precision_max,
|
|
'distance_min': item.distance_min,
|
|
'distance_max': item.distance_max,
|
|
'tool_diameter_min': item.tool_diameter_min,
|
|
'machine_tool_category': item.machine_tool_category.code,
|
|
'image_id': images_ids_names,
|
|
'taper_type_id': item.taper_type_id.name,
|
|
'function_type': item.function_type,
|
|
'a_axis': item.a_axis,
|
|
'T_trough_num': item.T_trough_num,
|
|
'T_trough_wide': item.T_trough_wide,
|
|
'T_trough_distance': item.T_trough_distance,
|
|
'spindle_center_distance': item.spindle_center_distance,
|
|
'spindle_continuous_power': item.spindle_continuous_power,
|
|
'spindle_peak_power': item.spindle_peak_power,
|
|
'spindle_sustained_torque': item.spindle_sustained_torque,
|
|
'spindle_peak_torque': item.spindle_peak_torque,
|
|
'linear_axis_guides_type': item.linear_axis_guides_type,
|
|
'axis_driven_type': item.axis_driven_type,
|
|
'X_axis_rapid_traverse_speed': item.X_axis_rapid_traverse_speed,
|
|
'Y_axis_rapid_traverse_speed': item.Y_axis_rapid_traverse_speed,
|
|
'Z_axis_rapid_traverse_speed': item.Z_axis_rapid_traverse_speed,
|
|
'a_axis_rapid_traverse_speed': item.a_axis_rapid_traverse_speed,
|
|
'b_axis_rapid_traverse_speed': item.b_axis_rapid_traverse_speed,
|
|
'c_axis_rapid_traverse_speed': item.c_axis_rapid_traverse_speed,
|
|
'straight_cutting_feed_rate': item.straight_cutting_feed_rate,
|
|
'rotary_cutting_feed_rate': item.rotary_cutting_feed_rate,
|
|
'X_precision': item.X_precision,
|
|
'X_precision_repeat': item.X_precision_repeat,
|
|
'Y_precision': item.X_precision,
|
|
'Y_precision_repeat': item.X_precision_repeat,
|
|
'Z_precision': item.X_precision,
|
|
'Z_precision_repeat': item.X_precision_repeat,
|
|
'a_precision': item.X_precision,
|
|
'a_precision_repeat': item.X_precision_repeat,
|
|
'b_precision': item.X_precision,
|
|
'b_precision_repeat': item.X_precision_repeat,
|
|
'c_precision': item.X_precision,
|
|
'c_precision_repeat': item.X_precision_repeat,
|
|
'tool_full_diameter_max': item.tool_full_diameter_max,
|
|
'tool_perimeter_diameter_max': item.tool_perimeter_diameter_max,
|
|
'T_tool_time': item.T_tool_time,
|
|
'C_tool_time': item.C_tool_time,
|
|
'jiancheng': item.category_id.equipment_type_code,
|
|
}
|
|
machine_tool_list.append(val)
|
|
# kw = machine_tool_list
|
|
kw = json.dumps(machine_tool_list, ensure_ascii=False)
|
|
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
|
ret = r.json()
|
|
self.code = ret['data']
|
|
self.state_zc = "已注册"
|
|
if r == 200:
|
|
return "机床注册成功"
|
|
else:
|
|
raise UserError("没有注册机床信息")
|
|
|
|
# 修改原生方法,生成维保日期
|
|
@api.depends('effective_date', 'period', 'maintenance_ids.request_date', 'maintenance_ids.close_date',
|
|
'overhaul_period')
|
|
def _compute_next_maintenance(self):
|
|
date_now = fields.Date.context_today(self)
|
|
equipments = self.filtered(lambda x: x.period > 0)
|
|
if equipments:
|
|
for equipment in equipments:
|
|
next_maintenance_todo = self.env['maintenance.request'].search([
|
|
('equipment_id', '=', equipment.id),
|
|
('sf_maintenance_type', '=', '保养'),
|
|
('stage_id.done', '!=', True),
|
|
('close_date', '=', False)], order="request_date asc", limit=1)
|
|
last_maintenance_done = self.env['maintenance.request'].search([
|
|
('equipment_id', '=', equipment.id),
|
|
('sf_maintenance_type', '=', '保养'),
|
|
('stage_id.done', '=', True),
|
|
('close_date', '!=', False)], order="close_date desc", limit=1)
|
|
if next_maintenance_todo and last_maintenance_done:
|
|
next_date = next_maintenance_todo.request_date
|
|
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date
|
|
# If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than
|
|
# 2 times the period and next request is in the future
|
|
# We use 2 times the period to avoid creation too closed request from a manually one created
|
|
if date_gap > timedelta(0) and date_gap > timedelta(
|
|
days=equipment.period) * 2 and next_maintenance_todo.request_date > date_now:
|
|
# If the new date still in the past, we set it for today
|
|
if last_maintenance_done.close_date + timedelta(days=equipment.period) < date_now:
|
|
next_date = date_now
|
|
else:
|
|
next_date = last_maintenance_done.close_date + timedelta(days=equipment.period)
|
|
elif next_maintenance_todo:
|
|
next_date = next_maintenance_todo.request_date
|
|
date_gap = next_maintenance_todo.request_date - date_now
|
|
# If next maintenance to do is in the future, and in more than 2 times the period, we insert
|
|
# an new request
|
|
# We use 2 times the period to avoid creation too closed request from a manually one created
|
|
if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.period) * 2:
|
|
next_date = date_now + timedelta(days=equipment.period)
|
|
elif last_maintenance_done:
|
|
next_date = last_maintenance_done.close_date + timedelta(days=equipment.period)
|
|
# If when we add the period to the last maintenance done and we still in past, we plan it for today
|
|
if next_date < date_now:
|
|
next_date = date_now
|
|
else:
|
|
next_date = equipment.initial_action_date + timedelta(days=equipment.period)
|
|
equipment.next_action_date = next_date
|
|
else:
|
|
self.next_action_date = False
|
|
overhaul_equipments = self.filtered(lambda x: x.overhaul_period > 0)
|
|
if overhaul_equipments:
|
|
for equipment in overhaul_equipments:
|
|
next_maintenance_todo = self.env['maintenance.request'].search([
|
|
('equipment_id', '=', equipment.id),
|
|
('sf_maintenance_type', '=', '检修'),
|
|
('stage_id.done', '!=', True),
|
|
('close_date', '=', False)], order="request_date asc", limit=1)
|
|
last_maintenance_done = self.env['maintenance.request'].search([
|
|
('equipment_id', '=', equipment.id),
|
|
('sf_maintenance_type', '=', '检修'),
|
|
('stage_id.done', '=', True),
|
|
('close_date', '!=', False)], order="close_date desc", limit=1)
|
|
if next_maintenance_todo and last_maintenance_done:
|
|
next_date = next_maintenance_todo.request_date
|
|
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date
|
|
# If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than 2
|
|
# times the period and next request is in the future
|
|
# We use 2 times the period to avoid creation too closed request from a manually one created
|
|
if date_gap > timedelta(0) and date_gap > timedelta(
|
|
days=equipment.overhaul_period) * 2 and next_maintenance_todo.request_date > date_now:
|
|
# If the new date still in the past, we set it for today
|
|
if last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period) < date_now:
|
|
next_date = date_now
|
|
else:
|
|
next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period)
|
|
elif next_maintenance_todo:
|
|
next_date = next_maintenance_todo.request_date
|
|
date_gap = next_maintenance_todo.request_date - date_now
|
|
# If next maintenance to do is in the future, and in more than 2 times the period, we insert
|
|
# an new request
|
|
# We use 2 times the period to avoid creation too closed request from a manually one created
|
|
if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.overhaul_period) * 2:
|
|
next_date = date_now + timedelta(days=equipment.overhaul_period)
|
|
elif last_maintenance_done:
|
|
next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period)
|
|
# If when we add the period to the last maintenance done and we still in past, we plan it for today
|
|
if next_date < date_now:
|
|
next_date = date_now
|
|
else:
|
|
next_date = equipment.initial_overhaul_date + timedelta(days=equipment.overhaul_period)
|
|
equipment.overhaul_date = next_date
|
|
else:
|
|
self.overhaul_date = False
|
|
|
|
# 拼接维保请求字符串
|
|
def _prepare_maintenance_request_vals(self, date):
|
|
self.ensure_one()
|
|
return {
|
|
'name': _('Preventive Maintenance - %s', self.name),
|
|
'request_date': fields.Date.today(),
|
|
'schedule_date': date,
|
|
'category_id': self.category_id.id,
|
|
'equipment_id': self.id,
|
|
'maintenance_type': 'preventive',
|
|
'owner_user_id': self.owner_user_id.id,
|
|
'user_id': self.technician_user_id.id,
|
|
'maintenance_team_id': self.maintenance_team_id.id,
|
|
'duration': self.maintenance_duration,
|
|
'company_id': self.company_id.id or self.env.company.id,
|
|
'equipment_maintenance_id': self.eq_maintenance_id.id,
|
|
'sf_maintenance_type': '保养'
|
|
}
|
|
|
|
# 拼接维保请求字符串
|
|
|
|
def _prepare_maintenance_request_vals1(self, date):
|
|
self.ensure_one()
|
|
return {
|
|
'name': _('Preventive Maintenance - %s', self.name),
|
|
'request_date': fields.Date.today(),
|
|
'schedule_date': date,
|
|
'category_id': self.category_id.id,
|
|
'equipment_id': self.id,
|
|
'maintenance_type': 'preventive',
|
|
'owner_user_id': self.owner_user_id.id,
|
|
'user_id': self.technician_user_id.id,
|
|
'maintenance_team_id': self.maintenance_team_id.id,
|
|
'duration': self.overhaul_duration,
|
|
'company_id': self.company_id.id or self.env.company.id,
|
|
'equipment_maintenance_id': self.overhaul_id.id,
|
|
'sf_maintenance_type': '检修'
|
|
}
|
|
|
|
# 创建维保请求
|
|
def _create_new_request(self, date):
|
|
self.ensure_one()
|
|
vals = self._prepare_maintenance_request_vals(date)
|
|
maintenance_requests = self.env['maintenance.request'].create(vals)
|
|
return maintenance_requests
|
|
|
|
def _create_new_request1(self, date):
|
|
self.ensure_one()
|
|
vals = self._prepare_maintenance_request_vals1(date)
|
|
maintenance_requests = self.env['maintenance.request'].create(vals)
|
|
return maintenance_requests
|
|
|
|
# 生成维保请求定时器
|
|
@api.model
|
|
def _cron_generate_requests(self):
|
|
"""
|
|
Generates maintenance request on the next_action_date or today if none exists
|
|
"""
|
|
for equipment in self.search([('period', '>', 0)]):
|
|
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
|
|
('equipment_id', '=', equipment.id),
|
|
('maintenance_type', '=', 'preventive'),
|
|
('request_date', '=', equipment.next_action_date),
|
|
('sf_maintenance_type', '=', '保养')])
|
|
if not next_requests:
|
|
equipment._create_new_request(equipment.next_action_date)
|
|
for equipment in self.search([('overhaul_period', '>', 0)]):
|
|
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
|
|
('equipment_id', '=', equipment.id),
|
|
('maintenance_type', '=', 'preventive'),
|
|
('request_date', '=', equipment.overhaul_date),
|
|
('sf_maintenance_type', '=', '检修')])
|
|
if not next_requests:
|
|
equipment._create_new_request1(equipment.overhaul_date)
|
|
|
|
image_id = fields.Many2many('maintenance.equipment.image', 'equipment_id',
|
|
domain="[('type', '=', '加工能力')]")
|
|
image_lq_id = fields.Many2many('maintenance.equipment.image', 'equipment_lq_id', string='冷却方式',
|
|
domain="[('type', '=', '冷却方式')]")
|
|
|
|
|
|
class SfRobotAxisNum(models.Model):
|
|
_name = 'sf.robot.axis.num'
|
|
_description = '机器人轴参数'
|
|
|
|
name = fields.Char('*轴')
|
|
angle_min = fields.Char('最小角度-(°)')
|
|
angle_max = fields.Char('最大角度+(°)')
|
|
velocity = fields.Char('最大速度(°/s)')
|
|
weight = fields.Char('最大负载(kg)')
|
|
permissible_load_torque = fields.Char('允许负载扭矩(N-m)')
|
|
permissible_inertial_torque = fields.Char('允许惯性扭矩(kg-m²)')
|
|
equipment_id = fields.Many2one('maintenance.equipment', string='机器人',
|
|
domain="[('equipment_type', '=', '机器人')]")
|