From c93553e78ec56a76da3c9bc6448fbbf46c4f45a8 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 14 Apr 2025 16:42:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A8=BC=E5=8A=A8=E7=8E=87?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/controllers/controllers.py | 241 +++++++++++++++--- 1 file changed, 204 insertions(+), 37 deletions(-) diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py index d5c8c7cb..00ba6223 100644 --- a/sf_machine_connect/controllers/controllers.py +++ b/sf_machine_connect/controllers/controllers.py @@ -5,7 +5,7 @@ import json import base64 import logging import psycopg2 -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from odoo import http, fields from odoo.http import request @@ -898,8 +898,6 @@ class Sf_Dashboard_Connect(http.Controller): # 获取请求的机床数据 machine_list = ast.literal_eval(kw['machine_list']) total_alarm_time = 0 - today_alarm_time = 0 - month_alarm_time = 0 alarm_count_num = 0 for item in machine_list: sql = ''' @@ -912,11 +910,6 @@ class Sf_Dashboard_Connect(http.Controller): ) subquery; ''' - # 计算时间范围 - now = datetime.now() - today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) - month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) - sql2 = ''' SELECT DISTINCT ON (alarm_start_time) alarm_time, alarm_start_time FROM device_data @@ -931,15 +924,6 @@ class Sf_Dashboard_Connect(http.Controller): cur.execute(sql2, (item,)) result2 = cur.fetchall() - today_data = [] - month_data = [] - - for record in result2: - alarm_start = datetime.strptime(record[1], "%Y-%m-%d %H:%M:%S") - if alarm_start >= today_start: - today_data.append(record) - if alarm_start >= month_start: - month_data.append(record) for row in result: res['data'][item] = {'idle_count': row[0]} @@ -961,27 +945,7 @@ class Sf_Dashboard_Connect(http.Controller): else: alarm_count_num = len(list(set(alarm_count))) - for today in today_data: - if today[0]: - if float(today[0]) >= 28800: - continue - today_alarm_time += float(today[0]) - else: - today_alarm_time += 0.0 - for month in month_data: - if month[0]: - if float(month[0]) >= 28800: - continue - month_alarm_time += float(month[0]) - else: - month_alarm_time += 0.0 - - TotalAlarmTime = total_alarm_time / 3600 - TodayAlarmTime = today_alarm_time / 3600 - MonthAlarmTime = month_alarm_time / 3600 - logging.info('=====AlarmTime===== %s, %s, %s' % (TotalAlarmTime, TodayAlarmTime, MonthAlarmTime)) res['data'][item]['total_alarm_time'] = total_alarm_time / 3600 - logging.info('=======================') res['data'][item]['alarm_count_num'] = alarm_count_num # 返回统计结果 @@ -1451,3 +1415,206 @@ class Sf_Dashboard_Connect(http.Controller): conn.close() return json.dumps(res) + + @http.route('/api/utilization/rate', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*") + def UtilizationRate(self, **kw): + """ + 获取稼动率 + """ + logging.info("kw=:%s" % kw) + res = {'status': 1, 'message': '成功', 'data': {}} + # 获取请求的机床数据 + machine_list = ast.literal_eval(kw['machine_list']) + line = kw['line'] + orders = request.env['mrp.workorder'].sudo().search([ + ('routing_type', '=', 'CNC加工'), # 将第一个条件合并进来 + ('production_line_id.name', '=', line), + ('state', 'in', ['done']) + ]) + + faulty_plans = request.env['quality.check'].sudo().search([ + ('operation_id.name', '=', 'CNC加工'), + ('quality_state', 'in', ['fail']) + ]) + + # 计算时间范围 + now = datetime.now() + today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) + month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) + + total_power_on_time = 0 + month_power_on_time = 0 + today_power_on_time = 0 + today_power_on_dict = {} + + today_data = [] + month_data = [] + today_check_ng = [] + month_check_ng = [] + + total_alarm_time = 0 + today_alarm_time = 0 + month_alarm_time = 0 + + for order in orders: + time = datetime.strptime(order.date_finished, "%Y-%m-%d %H:%M:%S") + if time >= today_start: + today_data.append(order) + if time >= month_start: + month_data.append(order) + + for faulty_plan in faulty_plans: + time = faulty_plan.write_date + if time >= today_start: + today_check_ng.append(faulty_plan) + if time >= month_start: + month_check_ng.append(faulty_plan) + + # 连接数据库 + conn = psycopg2.connect(**db_config) + for item in machine_list: + with conn.cursor() as cur: + cur.execute(""" + ( + SELECT power_on_time, 'latest' AS record_type + FROM device_data + WHERE device_name = %s + AND power_on_time IS NOT NULL + ORDER BY time DESC + LIMIT 1 + ) + UNION ALL + ( + SELECT power_on_time, 'month_first' AS record_type + FROM device_data + WHERE device_name = %s + AND power_on_time IS NOT NULL + AND time >= date_trunc('month', CURRENT_DATE) -- ✅ 修复日期函数 + AND time < (date_trunc('month', CURRENT_DATE) + INTERVAL '1 month')::date + ORDER BY time ASC + LIMIT 1 + ) + UNION ALL + ( + SELECT power_on_time, 'day_first' AS record_type + FROM device_data + WHERE device_name = %s + AND power_on_time IS NOT NULL + AND time::date = CURRENT_DATE -- ✅ 更高效的写法 + ORDER BY time ASC + LIMIT 1 + ); + """, (item, item, item)) + results = cur.fetchall() + print(results) + if len(results) >= 1: + total_power_on_time = convert_to_seconds(results[0][0]) + else: + total_power_on_time = 0 + if len(results) >= 2: + month_power_on_time = total_power_on_time - convert_to_seconds(results[1][0]) + else: + month_power_on_time = 0 + if len(results) >= 3: + today_power_on_time = total_power_on_time - convert_to_seconds(results[2][0]) + today_power_on_dict[item] = today_power_on_time + else: + today_power_on_time = 0 + print(total_power_on_time, month_power_on_time, today_power_on_time) + + with conn.cursor() as cur: + cur.execute(""" + SELECT DISTINCT ON (alarm_start_time) alarm_time, alarm_start_time + FROM device_data + WHERE device_name = %s AND alarm_start_time IS NOT NULL + ORDER BY alarm_start_time, time; + """, (item,)) + results = cur.fetchall() + today_data = [] + month_data = [] + + for record in results: + if record[0]: + if float(record[0]) >= 28800: + continue + total_alarm_time += float(record[0]) + else: + total_alarm_time += 0.0 + alarm_start = datetime.strptime(record[1], "%Y-%m-%d %H:%M:%S") + if alarm_start >= today_start: + today_data.append(record) + if alarm_start >= month_start: + month_data.append(record) + for today in today_data: + if today[0]: + if float(today[0]) >= 28800: + continue + today_alarm_time += float(today[0]) + else: + today_alarm_time += 0.0 + for month in month_data: + if month[0]: + if float(month[0]) >= 28800: + continue + month_alarm_time += float(month[0]) + else: + month_alarm_time += 0.0 + + conn.close() + + print('报警时间=============', TotalAlarmTime, MonthAlarmTime, TodayAlarmTime) + logging.info("报警时间=%s" % TotalAlarmTime) + logging.info("月报警时间=%s" % MonthAlarmTime) + logging.info("日报警时间=%s" % TodayAlarmTime) + + # 计算时间开动率(累计、月、日) + if total_power_on_time and TotalAlarmTime: + total_power_on_rate = (total_power_on_time - TotalAlarmTime) / total_power_on_time + else: + total_power_on_rate = 0 + if month_power_on_time and MonthAlarmTime: + month_power_on_rate = (month_power_on_time - MonthAlarmTime) / month_power_on_time + else: + month_power_on_rate = 0 + if today_power_on_time and TodayAlarmTime: + today_power_on_rate = (today_power_on_time - TodayAlarmTime) / today_power_on_time + else: + today_power_on_rate = 0 + print("总开动率: %s" % total_power_on_rate) + print("月开动率: %s" % month_power_on_rate) + print("日开动率: %s" % today_power_on_rate) + + # 计算性能开动率(累计、月、日) + total_performance_rate = len(orders) * 30 * 60 / (total_power_on_time - TotalAlarmTime) + month_performance_rate = len(month_data) * 30 * 60 / (month_power_on_time - MonthAlarmTime) + today_performance_rate = len(today_data) * 30 * 60 / (today_power_on_time - TodayAlarmTime) if today_power_on_time != 0 else 0 + print("总性能率: %s" % total_performance_rate) + print("月性能率: %s" % month_performance_rate) + print("日性能率: %s" % today_performance_rate) + + # 计算累计合格率 + total_pass_rate = (len(orders) - len(today_check_ng)) / len(orders) if len(orders) != 0 else 0 + month_pass_rate = (len(month_data) - len(month_check_ng)) / len(month_data) if len(month_data) != 0 else 0 + today_pass_rate = (len(today_data) - len(today_check_ng)) / len(today_data) if len(today_data) != 0 else 0 + print("总合格率: %s" % total_pass_rate) + print("月合格率: %s" % month_pass_rate) + print("日合格率: %s" % today_pass_rate) + + # # 返回数据 + # res['data'][item] = { + # 'total_utilization_rate': total_power_on_rate * total_performance_rate * total_pass_rate, + # 'month_utilization_rate': month_power_on_rate * month_performance_rate * month_pass_rate, + # 'today_utilization_rate': today_power_on_rate * today_performance_rate * today_pass_rate, + # } + res['data'] = { + 'total_utilization_rate': total_power_on_rate * total_performance_rate * total_pass_rate, + 'month_utilization_rate': month_power_on_rate * month_performance_rate * month_pass_rate, + 'today_utilization_rate': today_power_on_rate * today_performance_rate * today_pass_rate, + } + + return json.dumps(res) + + + + +