Files
test/sf_sale/models/parser_and_calculate_work_time.py
jinling.yang 5646cc492e 1.快速订单新增特征识别路径字段
2.修复销售经理和销售总监看不到快速订单菜单
3.优化系统设置页面,新增特征识别路径展示,去掉重复的业务平台参数配置展示
4.快速订单去掉老版本的特征识别的代码及包,新增最新的特征识别方法
2024-02-20 17:33:06 +08:00

473 lines
22 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)