1.快速订单新增特征识别路径字段
2.修复销售经理和销售总监看不到快速订单菜单 3.优化系统设置页面,新增特征识别路径展示,去掉重复的业务平台参数配置展示 4.快速订单去掉老版本的特征识别的代码及包,新增最新的特征识别方法
This commit is contained in:
472
sf_sale/models/parser_and_calculate_work_time.py
Normal file
472
sf_sale/models/parser_and_calculate_work_time.py
Normal file
@@ -0,0 +1,472 @@
|
||||
import time
|
||||
# import pandas as pd
|
||||
from lxml import etree
|
||||
from collections import Counter
|
||||
from . import preload_datas_functions as preload
|
||||
|
||||
|
||||
# import preload_datas_functions as preload
|
||||
|
||||
|
||||
class FeatureParser:
|
||||
"""
|
||||
解析Feature.xml文件
|
||||
"""
|
||||
|
||||
def __init__(self, xml_file):
|
||||
self.root = etree.parse(xml_file).getroot()
|
||||
self.size = self._get_size()
|
||||
self.holes = self._get_holes()
|
||||
self.slots = self._get_slot()
|
||||
self.open_slots = self._get_open_slot()
|
||||
self.vectors = self._get_vectors()
|
||||
|
||||
def _get_size(self):
|
||||
size = self.root.find('Size')
|
||||
return {
|
||||
'length': float(size.get('Length')),
|
||||
'width': float(size.get('Width')),
|
||||
'height': float(size.get('Height'))
|
||||
}
|
||||
|
||||
def _get_vectors(self):
|
||||
vectors = {}
|
||||
for item in self.root.findall('.//Item'):
|
||||
vector = item.find('Vector')
|
||||
if vector is not None:
|
||||
key = (vector.get('i'), vector.get('j'), vector.get('k'))
|
||||
vectors[key] = vectors.get(key, 0) + 1
|
||||
return vectors
|
||||
|
||||
def get_vector_counts(self):
|
||||
return len(self.vectors)
|
||||
|
||||
def _get_holes(self):
|
||||
holes = []
|
||||
hole_element = self.root.find('Hole')
|
||||
if hole_element is not None:
|
||||
for item in self.root.find('Hole').iter('Item'):
|
||||
hole = {} # 每个hole是一个字典
|
||||
hole['id'] = int(item.get('ID'))
|
||||
hole['name'] = item.get('Name')
|
||||
hole['red'] = int(item.get('Red'))
|
||||
hole['green'] = int(item.get('Green'))
|
||||
hole['blue'] = int(item.get('Blue'))
|
||||
# 处理circles
|
||||
circles = []
|
||||
for circle in item.iter('Circle'):
|
||||
circles.append({
|
||||
'x': float(circle.get('x')),
|
||||
'y': float(circle.get('y')),
|
||||
'z': float(circle.get('z')),
|
||||
'rad': float(circle.get('rad'))
|
||||
})
|
||||
hole['circles'] = circles
|
||||
|
||||
# 处理bottom
|
||||
bottoms = []
|
||||
for bottom in item.iter('Bottom'):
|
||||
bottoms.append({
|
||||
'x': float(bottom.get('x')),
|
||||
'y': float(bottom.get('y')),
|
||||
'z': float(bottom.get('z')),
|
||||
'rad': float(bottom.get('rad'))
|
||||
})
|
||||
hole['bottoms'] = bottoms
|
||||
|
||||
# 处理vector
|
||||
for vector in item.iter('Vector'):
|
||||
hole['vector'] = {
|
||||
'i': float(vector.get('i')),
|
||||
'j': float(vector.get('j')),
|
||||
'k': float(vector.get('k'))
|
||||
}
|
||||
|
||||
# 创建元组并添加到列表中
|
||||
z_rad_tuples = []
|
||||
max_z = None
|
||||
non_zero_rads = set() # 使用set来存储rad值,自动去重
|
||||
for circle in circles:
|
||||
z = float(circle.get('z'))
|
||||
rad = float(circle.get('rad'))
|
||||
if max_z is None or z > max_z:
|
||||
max_z = z
|
||||
if rad != 0:
|
||||
non_zero_rads.add(rad)
|
||||
for rad in non_zero_rads:
|
||||
z_rad_tuple = (max_z, rad)
|
||||
z_rad_tuples.append(z_rad_tuple)
|
||||
hole['z_rad_tuples'] = z_rad_tuples
|
||||
|
||||
holes.append(hole) # 添加到holes列表中
|
||||
|
||||
return holes
|
||||
|
||||
def _get_slot(self):
|
||||
"""
|
||||
获取slot信息
|
||||
"""
|
||||
slots = []
|
||||
slot_a_list = []
|
||||
slot_element = self.root.find('Slot')
|
||||
if slot_element is not None:
|
||||
for item in self.root.find('Slot').iter('Item'):
|
||||
slot = {}
|
||||
slot['id'] = int(item.get('ID'))
|
||||
slot['name'] = item.get('Name')
|
||||
slot['red'] = int(item.get('Red'))
|
||||
slot['green'] = int(item.get('Green'))
|
||||
slot['blue'] = int(item.get('Blue'))
|
||||
# 获取Volume和Area信息
|
||||
volume = item.find('Volume')
|
||||
if volume is not None:
|
||||
slot['volume'] = float(volume.get('value'))
|
||||
|
||||
area = item.find('Area')
|
||||
if area is not None:
|
||||
slot['area'] = float(area.get('value'))
|
||||
slot_a_list.append(slot['area'])
|
||||
# 处理lines
|
||||
lines = []
|
||||
for line in item.iter('Line'):
|
||||
lines.append({
|
||||
'type': line.get('Type'), # 'type' : 'line' or 'arc
|
||||
'x1': float(line.get('x1')),
|
||||
'y1': float(line.get('y1')),
|
||||
'z1': float(line.get('z1')),
|
||||
'x2': float(line.get('x2')),
|
||||
'y2': float(line.get('y2')),
|
||||
'z2': float(line.get('z2'))
|
||||
})
|
||||
slot['lines'] = lines
|
||||
|
||||
# 处理Arc
|
||||
arcs = []
|
||||
for arc in item.iter('Arc'):
|
||||
arcs.append({
|
||||
'type': arc.get('Type'),
|
||||
'x1': float(arc.get('x1')),
|
||||
'y1': float(arc.get('y1')),
|
||||
'z1': float(arc.get('z1')),
|
||||
'x2': float(arc.get('x2')),
|
||||
'y2': float(arc.get('y2')),
|
||||
'z2': float(arc.get('z2')),
|
||||
'x3': float(arc.get('x3')),
|
||||
'y3': float(arc.get('y3')),
|
||||
'z3': float(arc.get('z3'))
|
||||
|
||||
})
|
||||
slot['arcs'] = arcs
|
||||
slot['a'] = slot_a_list
|
||||
slots.append(slot)
|
||||
return slots
|
||||
|
||||
def _get_open_slot(self):
|
||||
"""
|
||||
获取open_slot信息
|
||||
"""
|
||||
open_slots = []
|
||||
open_slot_v_list = []
|
||||
open_slot_element = self.root.find('OpenSlot')
|
||||
if open_slot_element is not None:
|
||||
for item in self.root.find('OpenSlot').iter('Item'):
|
||||
open_slot = {}
|
||||
open_slot['id'] = int(item.get('ID'))
|
||||
open_slot['name'] = item.get('Name')
|
||||
open_slot['red'] = int(item.get('Red'))
|
||||
open_slot['green'] = int(item.get('Green'))
|
||||
open_slot['blue'] = int(item.get('Blue'))
|
||||
# 获取Volume和Area信息
|
||||
volume = item.find('Volume')
|
||||
if volume is not None:
|
||||
open_slot['volume'] = float(volume.get('value'))
|
||||
|
||||
area = item.find('Area')
|
||||
if area is not None:
|
||||
open_slot['area'] = float(area.get('value'))
|
||||
# open_slot_v_list.append(round(open_slot['volume'] / open_slot['area'], 3))
|
||||
open_slot_v_list.append(open_slot['area'])
|
||||
# 处理lines
|
||||
lines = []
|
||||
for line in item.iter('Line'):
|
||||
lines.append({
|
||||
'type': line.get('Type'), # 'type' : 'line' or 'arc
|
||||
'x1': float(line.get('x1')),
|
||||
'y1': float(line.get('y1')),
|
||||
'z1': float(line.get('z1')),
|
||||
'x2': float(line.get('x2')),
|
||||
'y2': float(line.get('y2')),
|
||||
'z2': float(line.get('z2'))
|
||||
})
|
||||
open_slot['lines'] = lines
|
||||
|
||||
# 处理Arc
|
||||
arcs = []
|
||||
for arc in item.iter('Arc'):
|
||||
arcs.append({
|
||||
'type': arc.get('Type'),
|
||||
'x1': float(arc.get('x1')),
|
||||
'y1': float(arc.get('y1')),
|
||||
'z1': float(arc.get('z1')),
|
||||
'x2': float(arc.get('x2')),
|
||||
'y2': float(arc.get('y2')),
|
||||
'z2': float(arc.get('z2')),
|
||||
'x3': float(arc.get('x3')),
|
||||
'y3': float(arc.get('y3')),
|
||||
'z3': float(arc.get('z3'))
|
||||
|
||||
})
|
||||
open_slot['arcs'] = arcs
|
||||
open_slot['v'] = open_slot_v_list
|
||||
open_slots.append(open_slot)
|
||||
return open_slots
|
||||
|
||||
|
||||
def hole_time(parser):
|
||||
"""
|
||||
计算孔的工时
|
||||
:return:
|
||||
"""
|
||||
# 判断是否有孔
|
||||
if parser.holes is not None:
|
||||
# 遍历所有的孔,获取孔径和孔深度,然后调用函数查询工时
|
||||
hole_total_time = 0
|
||||
nums = 1
|
||||
expand_hole = '否'
|
||||
j_time = 0
|
||||
j_hole_nums = 0
|
||||
hole_nums = 0
|
||||
for hole in parser.holes:
|
||||
for z_rad_tuple in hole['z_rad_tuples']:
|
||||
if (2 * z_rad_tuple[1] * z_rad_tuple[0] <= 3750) and (2 * z_rad_tuple[1] <= 25):
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = preload.get_suitable_hole_working_hours(preload.df_hole_duration,
|
||||
2 * z_rad_tuple[1],
|
||||
z_rad_tuple[0])
|
||||
# if per_time_minute is None:
|
||||
# raise Exception('孔径为%s,深度为%s的孔没有找到对应的工时' % (2 * z_rad_tuple[1], z_rad_tuple[0]))
|
||||
# print('per_time_minute', per_time_minute)
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif (2 * z_rad_tuple[1] * z_rad_tuple[0] <= 3750) and (2 * z_rad_tuple[1] > 25):
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.0003 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif 3750 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 50000:
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.0003 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif 50000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 100000:
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.00018 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif 100000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 150000:
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.00016 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif 150000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 200000:
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.00015 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
elif 200000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 250000:
|
||||
hole_nums += 1
|
||||
# print('z_rad_tuple', z_rad_tuple)
|
||||
per_time_minute = 0.0002 * 2 * z_rad_tuple[1] * z_rad_tuple[0]
|
||||
expand_hole_end = 0.6 if expand_hole == '是' else 1
|
||||
per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60
|
||||
hole_total_time += per_time
|
||||
else:
|
||||
raise Exception('孔径为%s,深度为%s的孔没有找到对应的工时' % (2 * z_rad_tuple[1], z_rad_tuple[0]))
|
||||
|
||||
print('孔工时', round(hole_total_time * nums * 2) / 2)
|
||||
print('共有%s个孔,其中%s为台阶孔' % (len(parser.holes), hole_nums - len(parser.holes)))
|
||||
return round(hole_total_time * nums * 2) / 2
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def slot_time(parser):
|
||||
# 判断是否有槽
|
||||
if parser.slots is not None:
|
||||
# 遍历所有的槽,获取槽的长度,然后调用函数查询工时
|
||||
slot_total_time = 0
|
||||
nums = 1
|
||||
finish_time = 0
|
||||
process_time = 0
|
||||
process_total_time = 0
|
||||
slot_a = parser.slots[0]['a']
|
||||
|
||||
slot_a_counter = Counter(slot_a)
|
||||
slot_a_counter_result = dict(slot_a_counter)
|
||||
|
||||
for i in slot_a_counter_result:
|
||||
for slot in parser.slots:
|
||||
if slot['area'] == i:
|
||||
# # 计算长度(第一条线和第三条线的X轴距离)
|
||||
# length = abs(slot['lines'][0]['y1'] - slot['lines'][2]['y1'])
|
||||
# # 计算宽度(第一条线和第二条线的Y轴距离)
|
||||
# width = abs(slot['lines'][1]['x1'] - slot['lines'][3]['x1'])
|
||||
# # 计算面积
|
||||
# area = length * width
|
||||
# 槽深度
|
||||
depth = round(slot['volume'] / slot['area'], 3)
|
||||
|
||||
# 沟通刀具暂定为12
|
||||
finish_tool_diameter = 12
|
||||
if 200 < slot['area'] <= 5000:
|
||||
finish_time = 0
|
||||
|
||||
# 加工穴数待定(取得每一个槽的穴数和装夹次数,那这个数量?目前暂时按1来算,待有统计数据之后再说)
|
||||
rough_part_nums = slot_a_counter_result[slot['area']]
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
# 调用函数计算槽的工时
|
||||
slot_total_time = preload.get_suitable_rough_working_hours(preload.df_rough_duration, depth)
|
||||
# if nums > 20:
|
||||
# process_time = round(
|
||||
# (nums * 0.6 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# elif nums > 10:
|
||||
# process_time = round(
|
||||
# (nums * 0.7 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# elif nums > 6:
|
||||
# process_time = round(
|
||||
# (nums * 0.8 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# elif nums > 4:
|
||||
# process_time = round(
|
||||
# (nums * 0.9 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# elif nums > 1:
|
||||
# process_time = round(
|
||||
# (nums * 0.95 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# else:
|
||||
# process_time = round(
|
||||
# (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
# finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
process_time = round(
|
||||
(nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# print('slot_total_time', slot_total_time)
|
||||
elif slot['area'] <= 200:
|
||||
slot_total_time = 0
|
||||
rough_part_nums = slot_a_counter_result[slot['area']]
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
# 调用函数计算槽的工时
|
||||
finish_time = preload.get_suitable_finish_working_hours(preload.df_finish_duration, depth,
|
||||
finish_tool_diameter)
|
||||
process_time = round(
|
||||
(nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# print('finish_time', finish_time)
|
||||
else:
|
||||
rough_part_nums = slot_a_counter_result[slot['area']]
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
process_time = round(
|
||||
(nums * 1 * ((0.00016 * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
process_total_time += process_time
|
||||
|
||||
print('槽工时', process_total_time)
|
||||
return process_total_time
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def open_slot_time(parser):
|
||||
# 判断是否有开口槽
|
||||
if parser.open_slots is not None:
|
||||
# 遍历所有的开口槽,获取槽宽和槽长,然后调用函数查询工时
|
||||
open_slot_total_time = 0
|
||||
nums = 1
|
||||
finish_time = 0
|
||||
open_slot_process_time = 0
|
||||
|
||||
open_slot_v = parser.open_slots[0]['v']
|
||||
|
||||
counter = Counter(open_slot_v)
|
||||
result = dict(counter)
|
||||
|
||||
transiant_time = 0
|
||||
for i in result:
|
||||
for open_slot in parser.open_slots:
|
||||
if open_slot['area'] == i:
|
||||
depth = round(open_slot['volume'] / open_slot['area'], 3)
|
||||
# 沟通刀具暂定为12
|
||||
finish_tool_diameter = 12
|
||||
if 200 < open_slot['area'] <= 5000:
|
||||
finish_time = 0
|
||||
# 加工穴数待定(取得每一个槽的穴数和装夹次数,那这个数量?目前暂时按1来算,待有统计数据之后再说)
|
||||
rough_part_nums = result[open_slot['area']]
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
# 调用函数计算槽的工时
|
||||
slot_total_time = preload.get_suitable_rough_working_hours(preload.df_rough_duration, depth)
|
||||
open_slot_process_time = round(
|
||||
(nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# print('slot_total_time', slot_total_time)
|
||||
elif open_slot['area'] <= 200:
|
||||
slot_total_time = 0
|
||||
rough_part_nums = 1
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
# 调用函数计算槽的工时
|
||||
finish_time = preload.get_suitable_finish_working_hours(preload.df_finish_duration, depth,
|
||||
finish_tool_diameter)
|
||||
open_slot_process_time = round(
|
||||
(nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
# print('finish_time', finish_time)
|
||||
else:
|
||||
rough_part_nums = 1
|
||||
rough_clamping_times = 1
|
||||
finishi_part_nums = 1
|
||||
finish_clamping_times = 1
|
||||
open_slot_process_time = round(
|
||||
(nums * 1 * ((0.00016 * rough_part_nums + rough_clamping_times * 20) + (
|
||||
finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2
|
||||
|
||||
transiant_time += open_slot_process_time
|
||||
print('开口槽工时', transiant_time)
|
||||
return transiant_time
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
time1 = time.time()
|
||||
parser = FeatureParser(
|
||||
'D:\\ccccccccccccccccccccccccccccccccccccccccccccccc\\aa\\JKM001-260.200.30_FeatureTable.xml')
|
||||
# print('parser', parser.holes)
|
||||
# print('parser.slots', parser.slots)
|
||||
# print('parser.open_slots', parser.open_slots)
|
||||
print('总工时', hole_time(parser) + slot_time(parser) + open_slot_time(parser))
|
||||
time2 = time.time()
|
||||
print('耗时:', time2 - time1)
|
||||
Reference in New Issue
Block a user