diff --git a/sf_dlm/models/product_template.py b/sf_dlm/models/product_template.py
index f80f0437..40fcac15 100644
--- a/sf_dlm/models/product_template.py
+++ b/sf_dlm/models/product_template.py
@@ -3,9 +3,10 @@ from odoo.exceptions import ValidationError
import logging
import base64
import os
-from OCC.Extend.DataExchange import read_step_file, write_stl_file
+# from OCC.Extend.DataExchange import read_step_file, write_stl_file
from odoo.modules import get_resource_path
+
class ResProductTemplate(models.Model):
_inherit = 'product.template'
@@ -16,11 +17,11 @@ class ResProductTemplate(models.Model):
model_height = fields.Float('模型高[mm]', digits=(16, 3))
model_volume = fields.Float('模型体积[m³]')
model_machining_precision = fields.Selection([
- ('±0.10mm', '±0.10mm'),
- ('±0.05mm', '±0.05mm'),
- ('±0.03mm', '±0.03mm'),
- ('±0.02mm', '±0.02mm'),
- ('±0.01mm', '±0.01mm')], string='加工精度')
+ ('0.10', '±0.10mm'),
+ ('0.05', '±0.05mm'),
+ ('0.03', '±0.03mm'),
+ ('0.02', '±0.02mm'),
+ ('0.01', '±0.01mm')], string='加工精度')
model_type_id = fields.Many2one('sf.model.type', string='模型类型')
model_processing_panel = fields.Char('模型加工面板')
model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺')
@@ -34,6 +35,15 @@ class ResProductTemplate(models.Model):
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
single_manufacturing = fields.Boolean(string="单个制造")
upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件')
+ model_code = fields.Char('模型编码')
+
+ def _get_volume_uom_id_from_ir_config_parameter(self):
+ product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
+ if product_length_in_feet_param == '1':
+ return self.env.ref('uom.product_uom_cubic_foot')
+ else:
+ return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
+
# model_file = fields.Binary('模型文件')
# 胚料的库存路线设置
@@ -70,18 +80,19 @@ class ResProductTemplate(models.Model):
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
item['model_width'] + model_type.embryo_tolerance) * (
item['model_height'] + model_type.embryo_tolerance),
- 'model_type_id': 1,
- # 'model_machining_precision': item['model_machining_precision'],
- 'model_processing_panel': 'A',
- 'model_machining_precision': '±0.10mm',
+ 'model_type_id': model_type.id,
+ 'model_processing_panel': 'R',
+ 'model_machining_precision': item['model_machining_precision'],
+ 'model_code': item['barcode'],
'length': item['model_long'],
'width': item['model_width'],
'height': item['model_height'],
'volume': item['model_long'] * item['model_width'] * item['model_height'],
- 'model_file': base64.b64decode(item['model_file']),
+ 'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
'model_name': attachment.name,
'upload_model_file': [(6, 0, [attachment.id])],
# 'single_manufacturing': True,
+ 'tracking': 'serial',
'list_price': item['price'],
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
'materials_id': self.env['sf.production.materials'].search(
@@ -94,26 +105,26 @@ class ResProductTemplate(models.Model):
# [('process_encode', '=', item['process_parameters_code'])]).id,
'model_remark': item['remark'],
'default_code': '%s-%s' % (order_number, i),
- #'barcode': item['barcode'],
+ # 'barcode': item['barcode'],
'active': True,
# 'route_ids': self._get_routes('')
}
copy_product_id.sudo().write(vals)
- print(len(copy_product_id.model_file))
- product_id.product_tmpl_id.active = False
+ # product_id.product_tmpl_id.active = False
return copy_product_id
def attachment_create(self, name, data):
attachment = self.env['ir.attachment'].create({
- 'datas': base64.b64decode(data),
+ 'datas': base64.b64decode(data),
'type': 'binary',
+ 'public': True,
'description': '模型文件',
'name': name
})
return attachment
# 创建胚料
- def no_bom_product_create(self, product_id, item, order_id, route_type):
+ def no_bom_product_create(self, product_id, item, order_id, route_type, i):
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
no_bom_copy_product_id.product_tmpl_id.active = True
materials_id = self.env['sf.production.materials'].search(
@@ -124,9 +135,10 @@ class ResProductTemplate(models.Model):
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
vals = {
- 'name': '%s %s %s %s * %s * %s' % (
- order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'],
- item['model_height']),
+ 'name': '%s-%s %s %s %s * %s * %s' % (
+ order_id.name, i, materials_id.name, materials_type_id.name,
+ item['model_long'] + model_type.embryo_tolerance, item['model_width'] + model_type.embryo_tolerance,
+ item['model_height'] + model_type.embryo_tolerance),
'length': item['model_long'] + model_type.embryo_tolerance,
'width': item['model_width'] + model_type.embryo_tolerance,
'height': item['model_height'] + model_type.embryo_tolerance,
@@ -150,40 +162,38 @@ class ResProductTemplate(models.Model):
no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0, 'is_subcontractor': True})]
- logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
elif route_type == 'purchase':
no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
- logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
no_bom_copy_product_id.write(vals)
logging.info('no_bom_copy_product_id-vals:%s' % vals)
- product_id.product_tmpl_id.active = False
+ # product_id.product_tmpl_id.active = False
return no_bom_copy_product_id
- @api.onchange('upload_model_file')
- def onchange_model_file(self):
- for item in self:
- if len(item.upload_model_file) > 1:
- raise ValidationError('只允许上传一个文件')
- if item.upload_model_file:
- file_attachment_id = item.upload_model_file[0]
- item.model_name = file_attachment_id.name
- # 附件路径
- report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
- shapes = read_step_file(report_path)
- output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
- write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
- # 转化为glb
- output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
- util_path = get_resource_path('sf_dlm', 'static/util')
- cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
- os.system(cmd)
- # 转base64
- with open(output_glb_file, 'rb') as fileObj:
- image_data = fileObj.read()
- base64_data = base64.b64encode(image_data)
- item.model_file = base64_data
+ # @api.onchange('upload_model_file')
+ # def onchange_model_file(self):
+ # for item in self:
+ # if len(item.upload_model_file) > 1:
+ # raise ValidationError('只允许上传一个文件')
+ # if item.upload_model_file:
+ # file_attachment_id = item.upload_model_file[0]
+ # item.model_name = file_attachment_id.name
+ # # 附件路径
+ # report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
+ # shapes = read_step_file(report_path)
+ # output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
+ # write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
+ # # 转化为glb
+ # output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
+ # util_path = get_resource_path('sf_dlm', 'static/util')
+ # cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
+ # os.system(cmd)
+ # # 转base64
+ # with open(output_glb_file, 'rb') as fileObj:
+ # image_data = fileObj.read()
+ # base64_data = base64.b64encode(image_data)
+ # item.model_file = base64_data
class ResMrpBom(models.Model):
@@ -244,8 +254,6 @@ class ResMrpBom(models.Model):
# 匹配bom
def get_bom(self, product):
- logging.info('get_bom-product:%s' % product)
- logging.info('get_bom-product:%s' % product.materials_type_id.id)
embryo_has = self.env['product.product'].search(
[('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id),
('length', '>', product.length), ('width', '>', product.width),
@@ -257,7 +265,7 @@ class ResMrpBom(models.Model):
logging.info('get_bom-vals:%s' % embryo_has)
if embryo_has:
rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100
- if rate_of_waste >= 20:
+ if rate_of_waste <= 20:
return embryo_has
else:
return
diff --git a/sf_machine_connect/__manifest__.py b/sf_machine_connect/__manifest__.py
index b74437dc..52fee05c 100644
--- a/sf_machine_connect/__manifest__.py
+++ b/sf_machine_connect/__manifest__.py
@@ -14,7 +14,6 @@
'data': [
# 定义权限组放在最上面
# 权限组
- "security/ir.model.access.csv",
'views/compensation.xml',
'views/ftp_button.xml',
'views/SfWorkOrderBarcodes.xml',
@@ -23,6 +22,9 @@
'views/machine_monitor.xml',
],
+ 'assets': {
+ },
+
'installable': True,
'application': True,
# 'auto_install': False,
diff --git a/sf_machine_connect/models/data_collection.py b/sf_machine_connect/models/data_collection.py
deleted file mode 100644
index 8f860c37..00000000
--- a/sf_machine_connect/models/data_collection.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from odoo import api, fields, models
-
-# ----------------------------------------------------------
-# Models for Simulation
-# ----------------------------------------------------------
-class Simulation(models.Model):
- _name = 'simulation'
- _description = 'SIMULATION'
-
- name = fields.Char('Name', size=50, readonly=True)
- place_value = fields.Boolean(String="位值")
- place_value_random = fields.Boolean(String="位值随机")
- place_value_ai = fields.Boolean(String="位值自增")
- place_value_list = fields.Boolean(String="位值列表")
-
- unsigned_integer_8_DO = fields.Integer(Sting="无符号8位整数D0")
- unsigned_integer_8_D1 = fields.Integer(Sting="无符号8位整数D1")
- unsigned_integer_8_random = fields.Integer(Sting="无符号8位整数随机")
- unsigned_integer_8_ai = fields.Integer(Sting="无符号8位整数自增")
- unsigned_integer_8_list = fields.Integer(Sting="无符号8位整数列表")
-
- integer_8 = fields.Integer(String="有符号8位整数")
- integer_8_random = fields.Integer(String="有符号8位整数随机")
- integer_8_ai = fields.Integer(String="有符号8位整数自增")
- integer_8_ad = fields.Integer(String="有符号8位整数自减")
- integer_16 = fields.Integer(String="有符号16位整数")
- integer_16_random = fields.Integer(String="有符号16位整数随机")
- integer_16_list = fields.Integer(String="有符号16位整数列表")
-
-
-
-
-# ----------------------------------------------------------
-# Models for Mitsubishi
-# ----------------------------------------------------------
-class MitsuCnc(models.Model):
- _name = 'mitsu.cnc'
- _description = 'Mitsubishi CNC'
-
- name = fields.Char('Name', size=50, readonly=True)
- status = fields.Boolean(string="状态")
diff --git a/sf_machine_connect/models/ftp_client.py b/sf_machine_connect/models/ftp_client.py
index 9f943dca..6744ca1a 100644
--- a/sf_machine_connect/models/ftp_client.py
+++ b/sf_machine_connect/models/ftp_client.py
@@ -1,22 +1,21 @@
# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
-
-import psycopg2
-import os
import logging
-from zeep.exceptions import ValidationError
-from odoo import http
-from ftplib import FTP
-from odoo.http import request
-from odoo import api, fields, models
+import json
+import hashlib
+import time
+import requests
+from datetime import datetime
+
+from odoo import fields, models, api, _
+from odoo.exceptions import ValidationError
+from odoo.exceptions import UserError
from odoo.addons.sf_machine_connect.models import py2opcua, ftp_operate
-# from .ftp_operate import FtpController
-# from .py2opcua import Py2opcua
_logger = logging.getLogger(__name__)
+
# ----------------------------------------------------------
# Models for client
# ----------------------------------------------------------
@@ -24,8 +23,13 @@ _logger = logging.getLogger(__name__)
class FtpButton(models.Model):
_inherit = 'sf.cnc.processing'
+ button_state = fields.Boolean(string='是否已经下发')
+
def pri(self):
- print('11111111111111111')
+ """
+ 一个测试函数,用于检测能否从”获取cnc程序“处获得NC代码文件
+ :return:
+ """
s = self.cnc_id
s1 = self.cnc_id._filestore()
print(s1)
@@ -36,72 +40,115 @@ class FtpButton(models.Model):
ftp_operate.FtpController.prin(self)
def up(self):
- # self.env['mrp.workorder'].check_compensation_before_up()
- ftp = ftp_operate.FtpController()
- # ftp.delAllfile('C://Users//马广威//Desktop//ftp')
- a = self.cnc_id
- print(a.display_name)
- _logger.info(a.display_name)
- datas = base64.standard_b64decode(a.datas)
- # file_path = '{}\{}\{}'.format(a._filestore(), a.store_fname.split('/'[0]), a.display_name)
+ """
+ 此函数用于将NC代码下发到机床
+ :return:
+ """
+ # 点击下发按钮自动补偿三元检测偏差值
- # 此方法不走ftp,直接文件写入,暂不确定能否写入ftp服务器,但可以转成ftp方法,只是要把文件暂存到本地,再上传
- # file_path_local = '{}\{}'.format('C://Users//马广威//Desktop//ftp', a.display_name)
- file_path_local = '{}/{}'.format('/nc2machine', a.display_name)
- file_path_remote = '{}\{}'.format('//(192,168,2,141)//DS', a.display_name)
+ try:
+ try:
+ if self.sequence_number == '1':
+ self.check_compensation_before_up()
+ except Exception:
+ raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
+ ftp = ftp_operate.FtpController()
+ # ftp.delAllfile('C://Users//马广威//Desktop//ftp')
+ a = self.cnc_id
+ _logger.info(a.public)
+ _logger.info(a.display_name)
+ datas = base64.standard_b64decode(a.datas)
- with open(file_path_local, mode='wb+') as file:
- file.write(datas)
+ # file_path = '{}\{}\{}'.format(a._filestore(), a.store_fname.split('/'[0]), a.display_name)
+ file_path_local = '{}/{}'.format('/nc2machine', a.display_name)
+ file_path_remote = '{}\{}'.format('//(192,168,2,141)//DS', a.display_name)
- # file = open(file_path_local, 'wb+')
- # file.write(datas)
- # file.close()
+ with open(file_path_local, mode='wb+') as file:
+ file.write(datas)
+ # 存在本地的文件下发到机床
+ ftp.upload_file(remotepath=file_path_remote, localpath=file_path_local)
+ except Exception as e:
+ _logger.info("=====================================", e)
+ raise UserError('NC下发执行超时, 请检查下发状态')
- # 存在本地的文件下发到机床
- ftp.upload_file(remotepath=file_path_remote, localpath=file_path_local)
+ # 补偿下发都执行完毕后,按钮标志位变为true
+ self.button_state = True
+ # 新增,下发完成返回当前工单位置
+ # return {
+ # 'name': _("工单"),
+ # 'view_mode': 'form',
+ # 'res_model': 'mrp.workorder',
+ # 'res_id': self.workorder_id,
+ # 'type': 'ir.actions.act_window',
+ # 'target': 'new'
+ # }
-class FtpClient(models.Model):
- _name = "ftp.client"
- _description = 'Ftp Client'
-
- name = fields.Char('Name', size=50, readonly=True)
- description = fields.Char(size=50)
- mobile = fields.Char(size=50)
-
- def up(self):
- ftp = ftp_operate.FtpController()
- # FtpController.__init__(self, host="127.0.0.1", port=2121, username="admin", password="123456")
- ftp.upload_file(remotepath='/(192,168,199,2)/DS/02-222.NC', localpath='D:/ftp/up/02-222.NC')
-
- # def delete(self):
- # ftp = FtpController()
- # ftp.del_file()
-
- #
- # def _compute_ip_url(self):
- # for box in self:
- # if not box.ip:
- # box.ip_url = False
- # else:
- # url = 'https://%s' if box.get_base_url()[:5] == 'https' else 'http://%s:8069'
- # box.ip_url = url % box.ip
- #
- # def _compute_device_count(self):
- # for box in self:
- # box.device_count = len(box.device_ids)
+ def check_compensation_before_up(self):
+ """
+ 下发NC代码前自动补偿三元检测偏差值
+ :return:
+ """
+ try:
+ temp_dict = {}
+ temp_dict[
+ 'ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang550'] = self.workorder_id.compensation_value_x
+ temp_dict[
+ 'ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang551'] = self.workorder_id.compensation_value_y
+ temp = py2opcua.Py2opcua()
+ # temp.connect()
+ temp.write(temp_dict)
+ # temp.disconnect()
+ except Exception as e:
+ _logger.info("=====================================", e)
+ raise UserError('补偿值获取失败,或机床未连接,请检查')
class Machine_ftp(models.Model):
- # _name = 'data.collection'
+ """
+ 数据采集类
+ """
_inherit = 'sf.machine_tool'
timestamp = fields.Datetime('时间戳', readonly=True)
signed = fields.Integer('刷新间隔', readonly=True)
status = fields.Boolean('在线状态', readonly=True)
+ time_on = fields.Char('总在线时长', readonly=True)
+ time_on_now = fields.Char('本次在线时长', readonly=True)
tool_num = fields.Integer('当前刀具', readonly=True)
program = fields.Char('当前程序', readonly=True)
+ run_status = fields.Selection([('0', '空闲中'), ('1', '加工中'), ('2', '加工中'), ('3', '等待中')], string='运行状态',
+ readonly=True, default='0')
+ run_time = fields.Char('总运行时长', readonly=True)
+ cut_time = fields.Char('总切削时长', readonly=True)
+ cut_status = fields.Selection([('0', '未切削'), ('1', '切削中'), ('2', '切削中'), ('3', '切削中')], string='切削状态',
+ readonly=True, default='0')
+
+ tool_num_process_time1 = fields.Char('刀位1', readonly=True, default='0')
+ tool_num_process_time2 = fields.Char('刀位2', readonly=True, default='0')
+ tool_num_process_time3 = fields.Char('刀位3', readonly=True, default='0')
+ tool_num_process_time4 = fields.Char('刀位4', readonly=True, default='0')
+ tool_num_process_time5 = fields.Char('刀位5', readonly=True, default='0')
+ tool_num_process_time6 = fields.Char('刀位6', readonly=True, default='0')
+ tool_num_process_time7 = fields.Char('刀位7', readonly=True, default='0')
+ tool_num_process_time8 = fields.Char('刀位8', readonly=True, default='0')
+ tool_num_process_time9 = fields.Char('刀位9', readonly=True, default='0')
+ tool_num_process_time10 = fields.Char('刀位10', readonly=True, default='0')
+ tool_num_process_time11 = fields.Char('刀位11', readonly=True, default='0')
+ tool_num_process_time12 = fields.Char('刀位12', readonly=True, default='0')
+ tool_num_process_time13 = fields.Char('刀位13', readonly=True, default='0')
+ tool_num_process_time14 = fields.Char('刀位14', readonly=True, default='0')
+ tool_num_process_time15 = fields.Char('刀位15', readonly=True, default='0')
+ tool_num_process_time16 = fields.Char('刀位16', readonly=True, default='0')
+ tool_num_process_time17 = fields.Char('刀位17', readonly=True, default='0')
+ tool_num_process_time18 = fields.Char('刀位18', readonly=True, default='0')
+ tool_num_process_time19 = fields.Char('刀位19', readonly=True, default='0')
+ tool_num_process_time20 = fields.Char('刀位20', readonly=True, default='0')
+ tool_num_process_time21 = fields.Char('刀位21', readonly=True, default='0')
+ tool_num_process_time22 = fields.Char('刀位22', readonly=True, default='0')
+ tool_num_process_time23 = fields.Char('刀位23', readonly=True, default='0')
+ tool_num_process_time24 = fields.Char('刀位24', readonly=True, default='0')
class WorkCenterBarcode(models.Model):
@@ -109,45 +156,56 @@ class WorkCenterBarcode(models.Model):
扫码托盘码可查到制造订单,由制造订单查工单
"""
_inherit = "mrp.workorder"
+
compensation_value_x = fields.Float(string='X轴补偿值')
compensation_value_y = fields.Float(string='Y轴补偿值')
+ button_compensation_state = fields.Boolean(string='是否已经补偿')
def compensation(self):
- '''
+ """
将节点与其值放入字典,字典作为参数传入
:return:
- '''
- temp_dict = {}
- temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = self.compensation_value_x
- temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = self.compensation_value_y
- print("测试补偿能够执行")
- temp = py2opcua.Py2opcua()
- _logger.info(temp)
- temp.connect()
- temp.write(temp_dict)
- temp.disconnect()
-
- def check_compensation_before_up(self):
- temp_value = self.env['mrp.workorder'].getcenter()
- _logger.info("====================================================================================")
- _logger.info(temp_value)
- if temp_value[0] == 0 or temp_value[1] != 0:
+ """
+ try:
temp_dict = {}
- # temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = temp_value[0]
- temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang520'] = 111
- temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = 111
- # temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC.hongbianliang521'] = temp_value[1]
- print("测试补偿能够执行")
+ temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang550'] = self.compensation_value_x
+ temp_dict['ns=1;s=Project_Default.Group1.Mitsubishi_NC2.hongbianliang551'] = self.compensation_value_y
temp = py2opcua.Py2opcua()
- _logger.info(temp)
- temp.connect()
+ # temp.connect()
temp.write(temp_dict)
- temp.disconnect()
+ self.button_compensation_state = True
+ # temp.disconnect()
+ except Exception as e:
+ _logger.info("=====================================", e)
+ raise UserError('补偿值获取失败,或机床未连接,请检查')
+ def get__state(self):
+ pay_time = str(datetime.now())
+ json = {
+ 'params': {
+ 'model_name': 'jikimo.process.order',
+ 'field_name': 'name',
+ 'default_code': 'PO-2022-1207-0020',
+ 'state': '待付款',
+ # 'pay_time': pay_time,
+ # 'get_order_sf': 21,
+ },
+ }
+ # res_str = json.dumps(vals)
+ url = 'https://bfm.cs.jikimo.com/api/get/state'
+ requests.post(url, json=json, data=None)
+ def process_control(self):
- def test(self, barcode):
- # 托盘对象
- tray = self.env('sf.tray').search("code", "=", barcode)
- product = tray.product_id
\ No newline at end of file
+ if self.routing_type == '获取CNC加工程序' and self.state == '进行中':
+ json = {
+ 'params': {
+ 'model_name': 'jikimo.process.order',
+ 'field_name': 'name',
+ 'default_code': 'PO-2022-1123-0014',
+ 'state': '加工中',
+ },
+ }
+ url = 'https://bfm.cs.jikimo.com/api/get/state'
+ requests.post(url, json=json, data=None)
diff --git a/sf_machine_connect/models/ftp_operate.py b/sf_machine_connect/models/ftp_operate.py
index 052c6e1c..18838684 100644
--- a/sf_machine_connect/models/ftp_operate.py
+++ b/sf_machine_connect/models/ftp_operate.py
@@ -2,13 +2,18 @@
import os
from ftplib import FTP
+
class FTP_P(FTP):
+ """
+ 重写FTP类,重写dirs方法
+ """
+
def dirs(self, *args):
- '''List a directory in long form.
+ """List a directory in long form.
By default list current directory to stdout.
Optional last argument is callback function; all
non-empty arguments before it are concatenated to the
- LIST command. (This *should* only be used for a pathname.)'''
+ LIST command. (This *should* only be used for a pathname.)"""
cmd = 'LIST'
templist = []
tempdic = {}
@@ -19,7 +24,6 @@ class FTP_P(FTP):
if arg:
cmd = cmd + (' ' + arg)
self.retrlines(cmd, templist.append)
- # print(templist)
# 处理返回结果,只需要目录名称
r_files = [file.split(" ")[-1] for file in templist]
tempdic['name'] = [file for file in r_files if file != "." and file != ".."]
@@ -27,13 +31,14 @@ class FTP_P(FTP):
return tempdic
# return [file for file in r_files if file != "." and file != ".."]
-# FTP接口类
-class FtpController():
- '''
+# FTP接口类
+class FtpController:
+ """
这是ftp接口类,在类初始化的时候就连接了ftp服务器,能否成功连接有反馈。
类中定义了两个接口:上传接口和删除接口
- '''
+ """
+
# 三菱机床连接
def __init__(self, host="192.168.2.158", port=8080, username="MITSUBISHI", password="CNC"):
self.host = host
@@ -42,47 +47,41 @@ class FtpController():
self.password = password
ftp = FTP_P()
# self.ftp.set_debuglevel(2) #打开调试级别2,显示详细信息
- ftp.set_pasv(0) #0主动模式 1 #被动模式
+ ftp.set_pasv(0) # 0主动模式 1 #被动模式
try:
ftp.connect(self.host, self.port)
ftp.login(self.username, self.password)
print("连接成功")
self.ftp = ftp
- except:
- print("连接失败")
+ except Exception as e:
+ print("连接失败" + str(e))
# 试验接口
def prin(self):
print("这是试验接口")
- # 试验ftp服务器连接
- # def connect(self, host="127.0.0.1", port=2121, username="admin", password="123456"):
- # ftp = FTP_P()
- # try:
- # ftp.connect(host, port)
- # ftp.login(username, password)
- # print("连接成功")
- # ftp1 = ftp
- # return ftp1
- # except:
- # print("连接失败")
-
-
# 三菱代码下发
def upload_file(self, remotepath='/(192,168,199,2)/DS/Z4.5.NC', localpath='D:/ftp/up/Z4.5.NC'):
- '''
+ """
第一个是要上传到ftp服务器路径下的文件,第二个是本地要上传的的路径文件
:param remotepath: 上传和下载都需要设置工作目录,注意只能使用文件名,不能有路径中的冒号
:param localpath:
:return:
- '''
+ """
bufsize = 1024
- fp = open(localpath, 'rb')
- self.ftp.storbinary('STOR ' + remotepath, fp, bufsize)
- fp.close()
- # return "上传成功"
+ # fp = open(localpath, 'rb')
+ # self.ftp.storbinary('STOR ' + remotepath, fp, bufsize)
+ # fp.close()
+ with open(localpath, mode='rb') as file:
+ self.ftp.storbinary('STOR ' + remotepath, file, bufsize)
+
def delAllfile(self, ftppath):
+ """
+ 删除ftp服务器端全部文件
+ :param ftppath:
+ :return:
+ """
dir_res = []
try:
print(ftppath)
@@ -106,13 +105,13 @@ class FtpController():
# print("删除FTP目录:" + ftppath + "下存在文件:" + f)
# ftp.delete(f)
except Exception as e:
- raise e
+ print("删除失败" + str(e))
- # 删除远端ftp文件
# 出现550 not found file是路径不对
- # def del_file(self, delpath='./YIN.NC'):
def del_file(self, delpath='/(192,168,199,2)/DS/Z4.5.NC'):
- self.ftp.delete(delpath) # 删除远程文件
-
-
-
+ """
+ 删除ftp服务器端指定文件
+ :param delpath:
+ :return:
+ """
+ self.ftp.delete(delpath)
diff --git a/sf_machine_connect/models/py2opcua.py b/sf_machine_connect/models/py2opcua.py
index 992f3f72..479fa91c 100644
--- a/sf_machine_connect/models/py2opcua.py
+++ b/sf_machine_connect/models/py2opcua.py
@@ -2,22 +2,35 @@ from opcua import ua, Client
class Py2opcua:
+ """
+ 将三元检测补偿值写入opcua服务器
+ """
def __init__(self, url='opc.tcp://192.168.2.99:4840'):
self.client = Client(url)
- def connect(self):
-
- try:
- # 连接客户端
- self.client.connect()
- print("opcua服务器连接成功,可以写入")
- return self.client
- except:
- print("opcua服务器连接失败,请检查")
+ # 连接客户端
+ # def connect(self):
+ # try:
+ # self.client.connect()
+ # print("opcua服务器连接成功,可以写入")
+ # return self.client
+ # except Exception as e:
+ # print("opcua服务器连接失败,请检查" + str(e))
def write(self, temp_dict):
- temp_dict = temp_dict
+ """
+ 补偿值写入方法,参数是一个字典,键是节点名,值是补偿值
+ :param temp_dict:
+ :return:
+ """
+ # try:
+ self.client.connect()
+ # print("opcua服务器连接成功,可以写入")
+ # return self.client
+ # except Exception as e:
+ # print("opcua服务器连接失败,请检查" + str(e))
+ # temp_dict = temp_dict
temp_list = list(temp_dict.items())
for i in range(len(temp_list)):
# 寻找节点上的变量
@@ -25,8 +38,9 @@ class Py2opcua:
# var.set_value(ua.Variant(1.234, ua.VariantType.Float))
# 通过set_value写值
var.set_value(ua.Variant(temp_list[i][1], ua.VariantType.Double))
- print("%s 已写入" % var.get_value())
-
- def disconnect(self):
- # 断开连接
+ # print("%s 已写入" % var.get_value())
self.client.disconnect()
+
+ # 断开连接
+ # def disconnect(self):
+ # self.client.disconnect()
diff --git a/sf_machine_connect/static/src/css/many2one_field.scss b/sf_machine_connect/static/src/css/many2one_field.scss
new file mode 100644
index 00000000..00b8d1ae
--- /dev/null
+++ b/sf_machine_connect/static/src/css/many2one_field.scss
@@ -0,0 +1,13 @@
+.o_form_view:not(.o_field_highlight) {
+ .o_field_many2one_selection {
+ .o_external_button, .o_dropdown_button {
+ visibility: hidden;
+ }
+
+ &:hover, &:focus-within {
+ .o_external_button, .o_dropdown_button {
+ visibility: visible;
+ }
+ }
+ }
+}
diff --git a/sf_machine_connect/static/src/js/test.js b/sf_machine_connect/static/src/js/test.js
new file mode 100644
index 00000000..1f1c1d58
--- /dev/null
+++ b/sf_machine_connect/static/src/js/test.js
@@ -0,0 +1,82 @@
+/** @odoo-module **/
+
+import { browser } from "@web/core/browser/browser";
+import { Dialog } from "@web/core/dialog/dialog";
+import { _lt } from "@web/core/l10n/translation";
+import { useChildRef, useOwnedDialogs, useService } from "@web/core/utils/hooks";
+import { sprintf } from "@web/core/utils/strings";
+import { isMobileOS } from "@web/core/browser/feature_detection";
+import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
+
+const {xml, Component} = owl;
+import { standardFieldProps } from "@web/views/fields/standard_field_props";
+// Import the registry
+import {registry} from "@web/core/registry";
+
+
+export class CodeField extends Component {
+ setup() {
+ super.setup();
+ }
+ async onBarcodeBtnClick() {
+ const barcode = await BarcodeScanner.scanBarcode();
+ if (barcode) {
+ await this.onBarcodeScanned(barcode);
+ if ("vibrate" in browser.navigator) {
+ browser.navigator.vibrate(100);
+ }
+ } else {
+ this.notification.add(this.env._t("Please, scan again !"), {
+ type: "warning",
+ });
+ }
+ }
+ async search(barcode) {
+ const results = await this.orm.call("sf.tray", "name_search", [code], {
+ name: barcode,
+ args: this.getDomain(),
+ operator: "ilike",
+ limit: 2, // If one result we set directly and if more than one we use normal flow so no need to search more
+ context: this.context,
+ });
+ return results.map((result) => {
+ const [id, displayName] = result;
+ return {
+ id,
+ name: displayName,
+ };
+ });
+ }
+ async onBarcodeScanned(barcode) {
+ const results = await this.search(barcode);
+ const records = results.filter((r) => !!r.id);
+ if (records.length === 1) {
+ this.update([{ id: records[0].id, name: records[0].name }]);
+ } else {
+ const searchInput = this.autocompleteContainerRef.el.querySelector("input");
+ searchInput.value = barcode;
+ searchInput.dispatchEvent(new Event("input"));
+ if (this.env.isSmall) {
+ searchInput.click();
+ }
+ }
+ }
+}
+
+CodeField.template = xml`
+
+`;
+// CodeField.template = 'sf_machine_connect.CodeField';
+CodeField.props = standardFieldProps;
+
+// Add the field to the correct category
+registry.category("fields").add("code", CodeField);
\ No newline at end of file
diff --git a/sf_machine_connect/static/src/xml/many2one_field.xml b/sf_machine_connect/static/src/xml/many2one_field.xml
index 8ed9b397..97b27357 100644
--- a/sf_machine_connect/static/src/xml/many2one_field.xml
+++ b/sf_machine_connect/static/src/xml/many2one_field.xml
@@ -1,17 +1,20 @@
- 这是我们的数据采集与程序管理页面! -
-- 这是我们的扫码页面! -
-