2.修复销售经理和销售总监看不到快速订单菜单 3.优化系统设置页面,新增特征识别路径展示,去掉重复的业务平台参数配置展示 4.快速订单去掉老版本的特征识别的代码及包,新增最新的特征识别方法
473 lines
22 KiB
Python
473 lines
22 KiB
Python
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)
|