import streamlit as st
|
import plotly.express as px
|
import plotly.graph_objects as go
|
import pandas as pd
|
from datetime import datetime, timedelta
|
from app.services.extruder_service import ExtruderService
|
from app.services.main_process_service import MainProcessService
|
|
def show_metered_weight_dashboard():
|
# 初始化服务
|
extruder_service = ExtruderService()
|
main_process_service = MainProcessService()
|
|
# 页面标题
|
st.title("米重综合分析")
|
|
# 初始化会话状态用于日期同步
|
if 'mw_start_date' not in st.session_state:
|
st.session_state['mw_start_date'] = datetime.now().date() - timedelta(days=7)
|
if 'mw_end_date' not in st.session_state:
|
st.session_state['mw_end_date'] = datetime.now().date()
|
if 'mw_quick_select' not in st.session_state:
|
st.session_state['mw_quick_select'] = "最近7天"
|
|
# 定义回调函数
|
def update_dates(qs):
|
st.session_state['mw_quick_select'] = qs
|
today = datetime.now().date()
|
if qs == "今天":
|
st.session_state['mw_start_date'] = today
|
st.session_state['mw_end_date'] = today
|
elif qs == "最近3天":
|
st.session_state['mw_start_date'] = today - timedelta(days=3)
|
st.session_state['mw_end_date'] = today
|
elif qs == "最近7天":
|
st.session_state['mw_start_date'] = today - timedelta(days=7)
|
st.session_state['mw_end_date'] = today
|
elif qs == "最近30天":
|
st.session_state['mw_start_date'] = today - timedelta(days=30)
|
st.session_state['mw_end_date'] = today
|
|
def on_date_change():
|
st.session_state['mw_quick_select'] = "自定义"
|
|
# 查询条件区域
|
with st.expander("🔍 查询配置", expanded=True):
|
# 添加自定义 CSS 实现响应式换行
|
st.markdown("""
|
<style>
|
/* 强制列容器换行 */
|
[data-testid="stExpander"] [data-testid="column"] {
|
flex: 1 1 120px !important;
|
min-width: 120px !important;
|
}
|
/* 针对日期输入框列稍微加宽一点 */
|
@media (min-width: 768px) {
|
[data-testid="stExpander"] [data-testid="column"]:nth-child(6),
|
[data-testid="stExpander"] [data-testid="column"]:nth-child(7) {
|
flex: 2 1 180px !important;
|
min-width: 180px !important;
|
}
|
}
|
</style>
|
""", unsafe_allow_html=True)
|
|
# 创建布局
|
cols = st.columns([1, 1, 1, 1, 1, 1.5, 1.5, 1])
|
|
options = ["今天", "最近3天", "最近7天", "最近30天", "自定义"]
|
for i, option in enumerate(options):
|
with cols[i]:
|
# 根据当前选择状态决定按钮类型
|
button_type = "primary" if st.session_state['mw_quick_select'] == option else "secondary"
|
if st.button(option, key=f"btn_mw_{option}", width='stretch', type=button_type):
|
update_dates(option)
|
st.rerun()
|
|
with cols[5]:
|
start_date = st.date_input(
|
"开始日期",
|
label_visibility="collapsed",
|
key="mw_start_date",
|
on_change=on_date_change
|
)
|
|
with cols[6]:
|
end_date = st.date_input(
|
"结束日期",
|
label_visibility="collapsed",
|
key="mw_end_date",
|
on_change=on_date_change
|
)
|
|
with cols[7]:
|
query_button = st.button("🚀 开始分析", key="mw_query", width='stretch')
|
|
# 转换为datetime对象
|
start_dt = datetime.combine(start_date, datetime.min.time())
|
end_dt = datetime.combine(end_date, datetime.max.time())
|
|
# 查询处理
|
if query_button:
|
with st.spinner("正在聚合数据..."):
|
# 1. 获取挤出机数据
|
df_extruder = extruder_service.get_extruder_data(start_dt, end_dt)
|
# 处理机头压力,去除超过2的值
|
if df_extruder is not None and not df_extruder.empty:
|
df_extruder = df_extruder[df_extruder['head_pressure'] <= 2]
|
|
# 2. 获取主流程控制数据
|
df_main_speed = main_process_service.get_cutting_setting_data(start_dt, end_dt)
|
df_temp = main_process_service.get_temperature_control_data(start_dt, end_dt)
|
# 获取电机运行监视数据
|
df_motor = main_process_service.get_motor_monitoring_data(start_dt, end_dt)
|
# 处理电机线速数据,除以10
|
if df_motor is not None and not df_motor.empty:
|
df_motor['m1_line_speed'] = df_motor['m1_line_speed'] / 10
|
df_motor['m2_line_speed'] = df_motor['m2_line_speed'] / 10
|
|
# 检查是否有数据
|
has_data = any([
|
df_extruder is not None and not df_extruder.empty,
|
df_main_speed is not None and not df_main_speed.empty,
|
df_temp is not None and not df_temp.empty,
|
df_motor is not None and not df_motor.empty
|
])
|
|
if not has_data:
|
st.warning("所选时间段内未找到任何数据,请尝试调整查询条件。")
|
return
|
|
# --- 图表1: 米重与实际参数分析 ---
|
st.subheader("📈 米重与实际参数分析")
|
fig1 = go.Figure()
|
|
# 添加米重
|
if df_extruder is not None and not df_extruder.empty:
|
fig1.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['metered_weight'],
|
name='米重 (Kg/m)',
|
mode='lines',
|
line=dict(color='blue', width=2),
|
yaxis='y1'
|
))
|
|
# 添加挤出机实际转速
|
fig1.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['screw_speed_actual'],
|
name='挤出机实际转速 (RPM)',
|
mode='lines',
|
line=dict(color='green', width=1.5),
|
yaxis='y2'
|
))
|
|
# 添加挤出机机头压力
|
fig1.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['head_pressure'],
|
name='挤出机机头压力',
|
mode='lines',
|
line=dict(color='orange', width=1.5),
|
yaxis='y3'
|
))
|
|
# 添加流程主速
|
if df_main_speed is not None and not df_main_speed.empty:
|
fig1.add_trace(go.Scatter(
|
x=df_main_speed['time'],
|
y=df_main_speed['process_main_speed'],
|
name='流程主速 (M/Min)',
|
mode='lines',
|
line=dict(color='red', width=1.5),
|
yaxis='y4' # 单独的速度轴
|
))
|
|
# 添加温度显示值
|
if df_temp is not None and not df_temp.empty:
|
temp_display_fields = {
|
'nakata_extruder_screw_display_temp': '螺杆显示 (°C)',
|
'nakata_extruder_rear_barrel_display_temp': '后机筒显示 (°C)',
|
'nakata_extruder_front_barrel_display_temp': '前机筒显示 (°C)',
|
'nakata_extruder_head_display_temp': '机头显示 (°C)',
|
}
|
for field, label in temp_display_fields.items():
|
fig1.add_trace(go.Scatter(
|
x=df_temp['time'],
|
y=df_temp[field],
|
name=label,
|
mode='lines',
|
line=dict(width=1),
|
yaxis='y5'
|
))
|
|
# 添加电机线速数据
|
if df_motor is not None and not df_motor.empty:
|
fig1.add_trace(go.Scatter(
|
x=df_motor['time'],
|
y=df_motor['m1_line_speed'],
|
name='拉出一段线速 (M/Min)',
|
mode='lines',
|
line=dict(color='cyan', width=1.5),
|
yaxis='y4'
|
))
|
fig1.add_trace(go.Scatter(
|
x=df_motor['time'],
|
y=df_motor['m2_line_speed'],
|
name='拉出二段线速 (M/Min)',
|
mode='lines',
|
line=dict(color='teal', width=1.5),
|
yaxis='y4'
|
))
|
|
# 设置图表1布局
|
fig1.update_layout(
|
title='米重与实际参数趋势分析',
|
xaxis=dict(
|
title='时间',
|
rangeslider=dict(visible=True),
|
type='date'
|
),
|
yaxis=dict(
|
title='米重 (Kg/m)',
|
title_font=dict(color='blue'),
|
tickfont=dict(color='blue')
|
),
|
yaxis2=dict(
|
title='挤出机转速 (RPM)',
|
title_font=dict(color='green'),
|
tickfont=dict(color='green'),
|
overlaying='y',
|
side='right'
|
),
|
yaxis3=dict(
|
title='机头压力',
|
title_font=dict(color='orange'),
|
tickfont=dict(color='orange'),
|
overlaying='y',
|
side='right',
|
anchor='free',
|
position=0.85
|
),
|
yaxis4=dict(
|
title='流程主速 (M/Min)',
|
title_font=dict(color='red'),
|
tickfont=dict(color='red'),
|
overlaying='y',
|
side='right',
|
anchor='free',
|
position=0.75
|
),
|
yaxis5=dict(
|
title='温度显示 (°C)',
|
title_font=dict(color='purple'),
|
tickfont=dict(color='purple'),
|
overlaying='y',
|
side='left',
|
anchor='free',
|
position=0.15
|
),
|
yaxis6=dict(
|
title='拉出线速 (M/Min)',
|
title_font=dict(color='cyan'),
|
tickfont=dict(color='cyan'),
|
overlaying='y',
|
side='right',
|
anchor='free',
|
position=0.65
|
),
|
legend=dict(
|
orientation="h",
|
yanchor="bottom",
|
y=1.02,
|
xanchor="right",
|
x=1
|
),
|
height=600,
|
margin=dict(l=100, r=200, t=100, b=100),
|
hovermode='x unified'
|
)
|
|
# 显示图表1
|
st.plotly_chart(fig1, width='stretch', config={'scrollZoom': True})
|
|
# --- 图表2: 米重与设定参数分析 ---
|
st.subheader("📈 米重与设定参数分析")
|
fig2 = go.Figure()
|
|
# 添加米重
|
if df_extruder is not None and not df_extruder.empty:
|
fig2.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['metered_weight'],
|
name='米重 (Kg/m)',
|
mode='lines',
|
line=dict(color='blue', width=2),
|
yaxis='y1'
|
))
|
|
# 添加挤出机设定转速
|
fig2.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['screw_speed_set'],
|
name='挤出机设定转速 (RPM)',
|
mode='lines',
|
line=dict(color='green', width=1.5, dash='dash'),
|
yaxis='y2'
|
))
|
|
# 添加挤出机机头压力
|
fig2.add_trace(go.Scatter(
|
x=df_extruder['time'],
|
y=df_extruder['head_pressure'],
|
name='挤出机机头压力',
|
mode='lines',
|
line=dict(color='orange', width=1.5),
|
yaxis='y3'
|
))
|
|
# 添加流程主速
|
if df_main_speed is not None and not df_main_speed.empty:
|
fig2.add_trace(go.Scatter(
|
x=df_main_speed['time'],
|
y=df_main_speed['process_main_speed'],
|
name='流程主速 (M/Min)',
|
mode='lines',
|
line=dict(color='red', width=1.5),
|
yaxis='y4' # 单独的速度轴
|
))
|
|
# 添加温度设定值
|
if df_temp is not None and not df_temp.empty:
|
temp_set_fields = {
|
'nakata_extruder_screw_set_temp': '螺杆设定 (°C)',
|
'nakata_extruder_rear_barrel_set_temp': '后机筒设定 (°C)',
|
'nakata_extruder_front_barrel_set_temp': '前机筒设定 (°C)',
|
'nakata_extruder_head_set_temp': '机头设定 (°C)',
|
}
|
for field, label in temp_set_fields.items():
|
fig2.add_trace(go.Scatter(
|
x=df_temp['time'],
|
y=df_temp[field],
|
name=label,
|
mode='lines',
|
line=dict(width=1, dash='dash'),
|
yaxis='y5'
|
))
|
|
# 设置图表2布局
|
fig2.update_layout(
|
title='米重与设定参数趋势分析',
|
xaxis=dict(
|
title='时间',
|
rangeslider=dict(visible=True),
|
type='date'
|
),
|
yaxis=dict(
|
title='米重 (Kg/m)',
|
title_font=dict(color='blue'),
|
tickfont=dict(color='blue')
|
),
|
yaxis2=dict(
|
title='挤出机转速 (RPM)',
|
title_font=dict(color='green'),
|
tickfont=dict(color='green'),
|
overlaying='y',
|
side='right'
|
),
|
yaxis3=dict(
|
title='机头压力',
|
title_font=dict(color='orange'),
|
tickfont=dict(color='orange'),
|
overlaying='y',
|
side='right',
|
anchor='free',
|
position=0.85
|
),
|
yaxis4=dict(
|
title='流程主速 (M/Min)',
|
title_font=dict(color='red'),
|
tickfont=dict(color='red'),
|
overlaying='y',
|
side='right',
|
anchor='free',
|
position=0.75
|
),
|
yaxis5=dict(
|
title='温度设定 (°C)',
|
title_font=dict(color='purple'),
|
tickfont=dict(color='purple'),
|
overlaying='y',
|
side='left',
|
anchor='free',
|
position=0.15
|
),
|
legend=dict(
|
orientation="h",
|
yanchor="bottom",
|
y=1.02,
|
xanchor="right",
|
x=1
|
),
|
height=600,
|
margin=dict(l=100, r=150, t=100, b=100),
|
hovermode='x unified'
|
)
|
|
# 显示图表2
|
st.plotly_chart(fig2, width='stretch', config={'scrollZoom': True})
|
|
# 数据摘要
|
# st.subheader("📊 数据摘要")
|
# summary_cols = st.columns(4)
|
|
# with summary_cols[0]:
|
# if df_extruder is not None and not df_extruder.empty:
|
# st.metric("平均米重", f"{df_extruder['metered_weight'].mean():.2f} Kg/m")
|
|
# with summary_cols[1]:
|
# if df_extruder is not None and not df_extruder.empty:
|
# st.metric("平均设定转速", f"{df_extruder['screw_speed_set'].mean():.2f} RPM")
|
|
# with summary_cols[2]:
|
# if df_extruder is not None and not df_extruder.empty:
|
# st.metric("平均实际转速", f"{df_extruder['screw_speed_actual'].mean():.2f} RPM")
|
|
# with summary_cols[3]:
|
# if df_extruder is not None and not df_extruder.empty:
|
# st.metric("平均机头压力", f"{df_extruder['head_pressure'].mean():.2f}")
|