运行日志数据接入
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
'views/machine_info_present.xml',
|
||||
'views/delivery_record.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/maintenance_views.xml',
|
||||
|
||||
],
|
||||
'assets': {
|
||||
|
||||
@@ -1,11 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import ast
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
def convert_to_seconds(time_str):
|
||||
# 修改正则表达式,使 H、M、S 部分可选
|
||||
|
||||
pattern = r"(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?"
|
||||
match = re.match(pattern, time_str)
|
||||
|
||||
if match:
|
||||
# 提取各时间单位,如果某个单位缺失则默认设为0
|
||||
hours = int(match.group(1)) if match.group(1) else 0
|
||||
minutes = int(match.group(2)) if match.group(2) else 0
|
||||
seconds = int(match.group(3)) if match.group(3) else 0
|
||||
|
||||
# 计算总秒数
|
||||
total_seconds = hours * 3600 + minutes * 60 + seconds
|
||||
if total_seconds == 0:
|
||||
# return None
|
||||
pattern = r"(?:(\d+)小时)?(?:(\d+)分钟)?(?:(\d+)秒)?"
|
||||
match = re.match(pattern, time_str)
|
||||
if match:
|
||||
# 提取各时间单位,如果某个单位缺失则默认设为0
|
||||
hours = int(match.group(1)) if match.group(1) else 0
|
||||
minutes = int(match.group(2)) if match.group(2) else 0
|
||||
seconds = int(match.group(3)) if match.group(3) else 0
|
||||
|
||||
# 计算总秒数
|
||||
total_seconds = hours * 3600 + minutes * 60 + seconds
|
||||
return total_seconds
|
||||
else:
|
||||
return None
|
||||
return total_seconds
|
||||
|
||||
|
||||
class Sf_Dashboard_Connect(http.Controller):
|
||||
|
||||
@http.route('/api/get_machine_datas/list', type='http', auth='public', methods=['GET', 'POST'], csrf=False,
|
||||
@@ -18,6 +52,11 @@ class Sf_Dashboard_Connect(http.Controller):
|
||||
"""
|
||||
res = {'status': 1, 'message': '成功', 'data': []}
|
||||
logging.info('前端请求机床数据的参数为:%s' % kw)
|
||||
|
||||
# 获取当前时间的时间戳
|
||||
current_timestamp = datetime.now().timestamp()
|
||||
print(current_timestamp)
|
||||
|
||||
# tem_list = [
|
||||
# "XT-GNJC-WZZX-X800-Y550-Z550-T24-A5-1", "XT-GNJC-LSZX-X800-Y550-Z550-T24-A3-3",
|
||||
# "XT-GNJC-LSZX-X800-Y550-Z550-T24-A3-4", "XT-GNJC-LSZX-X800-Y550-Z550-T24-A3-5",
|
||||
@@ -33,8 +72,21 @@ class Sf_Dashboard_Connect(http.Controller):
|
||||
machine_list = ast.literal_eval(kw['machine_list'])
|
||||
for item in machine_list:
|
||||
machine_data = equipment_obj.search([('code', '=', item)])
|
||||
|
||||
# 机床上线时间段
|
||||
first_online_duration = current_timestamp - int(machine_data.first_online_time.timestamp())
|
||||
|
||||
power_off_time = None
|
||||
power_off_rate = None
|
||||
if machine_data.machine_power_on_time:
|
||||
power_off_time = first_online_duration - convert_to_seconds(machine_data.machine_power_on_time)
|
||||
power_off_rate = round((power_off_time / first_online_duration), 3)
|
||||
else:
|
||||
power_off_time = False
|
||||
power_off_rate = False
|
||||
if machine_data:
|
||||
res['data'].append({
|
||||
'active': machine_data.status,
|
||||
'id': machine_data.id,
|
||||
'name': machine_data.name,
|
||||
'brand': machine_data.type_id.name,
|
||||
@@ -92,6 +144,13 @@ class Sf_Dashboard_Connect(http.Controller):
|
||||
# 计算出来的数据
|
||||
# 开动率:运行时间/通电时间
|
||||
'run_rate': machine_data.run_rate,
|
||||
# 关机时长:初次上线时间 - 通电时间
|
||||
'power_off_time': power_off_time,
|
||||
# 关机率:关机时长/初次上线时间
|
||||
'power_off_rate': power_off_rate,
|
||||
'first_online_duration': first_online_duration,
|
||||
# 停机时间:关机时间 - 运行时间
|
||||
# 停机时长:关机时间 - 初次上线时间
|
||||
})
|
||||
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -101,6 +160,95 @@ class Sf_Dashboard_Connect(http.Controller):
|
||||
res['message'] = '前端请求机床数据失败,原因:%s' % e
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
# @http.route('/api/logs/list', type='http', auth='public', methods=['GET', 'POST'], csrf=False,
|
||||
# cors="*")
|
||||
# def logs_list(self, **kw):
|
||||
# """
|
||||
# 拿到日志数据返回给大屏展示
|
||||
# :param kw:
|
||||
# :return:
|
||||
# """
|
||||
# res = {'status': 1, 'message': '成功', 'data': []}
|
||||
# logging.info('前端请求日志数据的参数为:%s' % kw)
|
||||
#
|
||||
# try:
|
||||
# # 获取请求的日志数据
|
||||
# logs_obj = request.env['maintenance.equipment.oee.log.detail'].sudo()
|
||||
# # 获取请求的机床数据
|
||||
# machine_list = ast.literal_eval(kw['machine_list'])
|
||||
# begin_time_str = kw['begin_time'].strip('"')
|
||||
# end_time_str = kw['end_time'].strip('"')
|
||||
#
|
||||
# begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
|
||||
# end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
|
||||
#
|
||||
# print('begin_time: %s' % begin_time)
|
||||
# for item in machine_list:
|
||||
# log_datas = logs_obj.search(
|
||||
# [('equipment_code', '=', item), ('time', '>=', begin_time), ('time', '<=', end_time)])
|
||||
# print('log_datas: %s' % log_datas)
|
||||
# for log_data in log_datas:
|
||||
# res['data'].append({
|
||||
# 'equipment_code': log_data.equipment_code,
|
||||
# 'time': log_data.time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
# 'state': log_data.state
|
||||
#
|
||||
# })
|
||||
#
|
||||
# return json.JSONEncoder().encode(res)
|
||||
#
|
||||
# except Exception as e:
|
||||
# logging.info('前端请求日志数据失败,原因:%s' % e)
|
||||
# res['status'] = -1
|
||||
# res['message'] = '前端请求日志数据失败,原因:%s' % e
|
||||
# return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/api/logs/list', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
||||
def logs_list(self, **kw):
|
||||
"""
|
||||
拿到日志数据返回给大屏展示
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
res = {'status': 1, 'message': '成功', 'data': {}}
|
||||
logging.info('前端请求日志数据的参数为:%s' % kw)
|
||||
|
||||
try:
|
||||
# 获取请求的日志数据
|
||||
logs_obj = request.env['maintenance.equipment.oee.log.detail'].sudo()
|
||||
# 获取请求的机床数据
|
||||
machine_list = ast.literal_eval(kw['machine_list'])
|
||||
begin_time_str = kw['begin_time'].strip('"')
|
||||
end_time_str = kw['end_time'].strip('"')
|
||||
|
||||
begin_time = datetime.strptime(begin_time_str, '%Y-%m-%d %H:%M:%S')
|
||||
end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
|
||||
|
||||
print('begin_time: %s' % begin_time)
|
||||
|
||||
for item in machine_list:
|
||||
log_datas = logs_obj.search(
|
||||
[('equipment_code', '=', item), ('time', '>=', begin_time), ('time', '<=', end_time)])
|
||||
print('log_datas: %s' % log_datas)
|
||||
|
||||
# 将数据按照 equipment_code 进行分组
|
||||
if item not in res['data']:
|
||||
res['data'][item] = []
|
||||
|
||||
for log_data in log_datas:
|
||||
res['data'][item].append({
|
||||
'time': log_data.time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'state': log_data.state
|
||||
})
|
||||
|
||||
return json.dumps(res) # 注意使用 json.dumps 而不是直接用 json.JSONEncoder().encode()
|
||||
|
||||
except Exception as e:
|
||||
logging.info('前端请求日志数据失败,原因:%s' % e)
|
||||
res['status'] = -1
|
||||
res['message'] = '前端请求日志数据失败,原因:%s' % e
|
||||
return json.dumps(res)
|
||||
|
||||
# 返回CNC机床列表
|
||||
@http.route('/api/CNCList', type='http', auth='public', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
|
||||
@@ -121,6 +121,13 @@ class Machine_ftp(models.Model):
|
||||
"""
|
||||
_inherit = 'maintenance.equipment'
|
||||
|
||||
# 机床首次上线时间(默认取值2024年08月01日零点)
|
||||
|
||||
def _get_default_online_time(self):
|
||||
return datetime(2024, 1, 1, 0, 0, 0)
|
||||
|
||||
first_online_time = fields.Datetime(string='首次上线时间', default=_get_default_online_time)
|
||||
|
||||
# workorder_ids = fields.One2many('mrp.workorder', 'machine_tool_id', string='工单')
|
||||
|
||||
# # 机床配置项目
|
||||
@@ -278,6 +285,26 @@ class Machine_ftp(models.Model):
|
||||
# # 开动率
|
||||
run_rate = fields.Char('开动率', readonly=True)
|
||||
|
||||
# 同步CNC设备到oee
|
||||
def sync_oee(self):
|
||||
"""
|
||||
同步CNC设备到oee
|
||||
:return:
|
||||
"""
|
||||
for record in self:
|
||||
record.ensure_one()
|
||||
cnc_oee_dict = {
|
||||
'equipment_id': record.id,
|
||||
'type_id': record.type_id.id,
|
||||
'machine_tool_picture': record.machine_tool_picture,
|
||||
'equipment_code': record.code,
|
||||
'function_type': record.function_type,
|
||||
}
|
||||
if self.env['maintenance.equipment.oee.logs'].search([('equipment_id', '=', record.id)]):
|
||||
self.env['maintenance.equipment.oee.logs'].write(cnc_oee_dict)
|
||||
else:
|
||||
self.env['maintenance.equipment.oee.logs'].create(cnc_oee_dict)
|
||||
|
||||
|
||||
class WorkCenterBarcode(models.Model):
|
||||
"""
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<field name="run_status"/>
|
||||
<field name="run_time"/>
|
||||
<field name="system_date"/>
|
||||
<field name="first_online_time"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="cut_status"/>
|
||||
|
||||
17
sf_machine_connect/views/maintenance_views.xml
Normal file
17
sf_machine_connect/views/maintenance_views.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<!-- 修改设备列表视图-->
|
||||
<record id="sf_machine_hr_equipment_view_tree_inherit" model="ir.ui.view">
|
||||
<field name="name">sf.machine.hr.equipment.view.tree.inherit</field>
|
||||
<field name="model">maintenance.equipment</field>
|
||||
<field name="inherit_id" ref="maintenance.hr_equipment_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="inside">
|
||||
<header>
|
||||
<button name="sync_oee" type="object" string="同步设备至OEE"/>
|
||||
</header>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user