test.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. from pywebio.input import *
  2. from pywebio.output import *
  3. from pywebio.session import *
  4. import pywebio.pin as pin
  5. from pywebio import start_server
  6. import pandas as pd
  7. from io import StringIO
  8. from utils import judge_field, image
  9. # field: v:[字段名, 单位, 数据类型, 格式, 默认空值填充规则, 默认无效值填充规则]
  10. fields = {
  11. '设备码': ['sn', ['-'], '-', '-', '不处理', '不处理'],
  12. '时间': ['time', ['-'], '-', ['2023-01-01 00:00:00', '-'],'删除整行', '删除整行'],
  13. '电池包电流': ['pack_crnt', ['A', 'mA'], '-', '-', '向上临近填充', '向上临近填充'],
  14. '电池包电压': ['pack_volt', ['V', 'mV'], '-', '-', '向上临近填充', '向上临近填充'],
  15. '电池包soc': ['soc', ['%', '-'], '-', '-', '向上临近填充', '向上临近填充'],
  16. '电池包soh': ['soh', ['%', '-'], '-', '-', '向上临近填充', '向上临近填充'],
  17. '单体电压列表': ['cell_voltage', ['V', 'mV'], '-', ["*,*,*,...", "[*,*,*,...]"], '向上临近填充', '向上临近填充'],
  18. '单体温度列表': ['cell_temp', ['℃'], '-', ["*,*,*,...", "[*,*,*,...]"], '向上临近填充', '向上临近填充'],
  19. '绝缘电阻': ['ins_resis', ['Ω', 'kΩ'], '-', '-', '向上临近填充', '向上临近填充'],
  20. # '速度': ['speed', ['m/s', 'Km/h'], '-', '-', '向上临近填充', '向上临近填充'],
  21. # '海拔': ['altitude', ['Km', 'm'], '-', '-', '向上临近填充', '向上临近填充'],
  22. # '经度': ['longitude', ['-'], '-', '-', '向上临近填充', '向上临近填充'],
  23. # '纬度': ['latitude', ['-'] ,'-', '-', '向上临近填充', '向上临近填充'],
  24. # '累积行驶里程': ['mileage', ['Km', 'm'], '-', '-', '向上临近填充', '向上临近填充']
  25. }
  26. def dataclean(a):
  27. print("数据清洗")
  28. def main():
  29. set_env(title='神目电池安全卫士', output_animation=False)
  30. # while True:
  31. # 上传文件要求: 需要有表头,单体信息格式为 “**,**,**”
  32. file = file_upload(accept=['.csv', '.xlsx','.xls'], placeholder="请上传文件,支持 .csv, .xlsx, .xls 文件")
  33. # filename = '001PB047000001B230100075_2101TS_20230328171402_20230328193302.csv'
  34. # df = pd.read_csv(filename)
  35. filename = file['filename']
  36. put_markdown(f"## 文件读取成功,展示前5条数据如下")
  37. if filename.endswith(".csv"):
  38. df = pd.read_csv(StringIO(file['content'].decode('utf-8')))
  39. elif filename.endswith(".xlsx"):
  40. df = pd.read_excel(file['content'])
  41. elif filename.endswith(".xls"):
  42. df = pd.read_excel(file['content'])
  43. with use_scope('show_data'):
  44. # 展示文件的数据
  45. columns = list(df.columns)
  46. put_table(tdata=df.to_dict(orient='records')[0:5],header=columns)
  47. columns.append('-')
  48. # 判断列映射
  49. column_map_res = judge_field.judge_by_field_name(columns)
  50. with use_scope('set_field'):
  51. # 对文件的列进行选择
  52. put_markdown(f"## 字段自动化识别结果如下,可人工进行修改")
  53. header = ['列名','字段','单位','格式']
  54. values = []
  55. i = 0
  56. for k,v in fields.items():
  57. values.append({
  58. '列名': k,
  59. '字段': pin.put_select(name=f"field_{i}", options=columns, value=column_map_res.get(k, '-')),
  60. '单位': pin.put_select(name=f"unit_{i}", options=v[1]),
  61. '格式': pin.put_select(name=f"format_{i}", options=v[3]),
  62. })
  63. i = i + 1
  64. put_table(values,header=header)
  65. # 数据清洗
  66. put_markdown(f"## 是否进行数据清洗?")
  67. pin.put_radio(name='dataclean', options=['是', '否', '默认'], value='默认', label='')
  68. do_dataclean = pin.pin_wait_change('dataclean')['value']
  69. if do_dataclean == '是':
  70. with use_scope('data_claen'):
  71. # 对文件的列进行选择
  72. put_markdown(f"## 数据清洗规则")
  73. header = ['列名', '空值处理', '空值指定值', '无效值处理', '无效值判定值', '无效值指定值']
  74. clean_rule = ['不处理', '删除整行', '向上临近填充', '向下临近填充', '中位数填充', '平均值填充', '指定值填充']
  75. values = []
  76. i = 0
  77. for k,v in fields.items():
  78. values.append({
  79. '列名': k,
  80. '空值处理': pin.put_select(name=f"none_{i}", options=clean_rule, value=v[4]),
  81. '空值指定值': pin.put_input(name=f"none_assign_{i}", type='float'),
  82. '无效值处理': pin.put_select(name=f"invalid_{i}", options=clean_rule, value=v[5]),
  83. '无效值判定值': pin.put_input(name=f"invalid_judge_{i}", type='float'),
  84. '无效值指定值': pin.put_input(name=f"invalie_assign_{i}", type='float'),
  85. })
  86. i = i + 1
  87. put_table(values,header=header)
  88. put_button("执行数据清洗", onclick=lambda:dataclean(df))
  89. put_markdown(f"## 导出清洗后的数据")
  90. df.to_csv("after_clean.csv")
  91. with open("./after_clean.csv", 'rb') as f:
  92. content = f.read()
  93. put_file('data.csv', content, '下载清洗后的数据文件')
  94. with use_scope('algo_invoke'):
  95. # 对文件的列进行选择
  96. put_markdown(f"## 算法功能模块")
  97. # put_markdown(f"**1. 基本信息统计模块**")
  98. put_button("执行所有算法模块", onclick=lambda:dataclean(df))
  99. header = ['数据包内电池包数', '数据起始时间', '数据结束时间', '数据时长(天)', '电池包最高活跃度', '电池包平均活跃度',
  100. '总数据量', '日最大数据量']
  101. values = [1, "2023/3/28 17:14:00", "2023/3/28 19:32:00", 1, 100, 100, 835, 835]
  102. put_collapse("1. 基本信息统计模块",content=[
  103. put_button("执行本算法模块", onclick=lambda:dataclean(df)),
  104. put_table([values],header=header)])
  105. # put_markdown(f"**2. 电池信息分析模块**")
  106. header = ['SN', '电池类型', '电池包电芯串联数', '温度采样个数']
  107. values = ["001PB047000001B230100075", "三元电池", 112, 12]
  108. put_collapse("2. 电池信息分析模块", content=[
  109. put_button("执行本算法模块", onclick=lambda:dataclean(df)),
  110. put_table([values],header=header)])
  111. # put_markdown(f"**3. 电池安全诊断模块**")
  112. header = ['诊断指标', '数值', '诊断结果', '推荐数值']
  113. values = ['最高电压', 3.68, '⬆', 3.65]
  114. put_collapse("3. 电池安全诊断模块", content=[
  115. put_button("执行本算法模块", onclick=lambda:dataclean(df)),
  116. put_table([values],header=header),
  117. put_text('''
  118. xxxxxxxx电池于xxxx年xx月xx日发生电芯过压故障 ,故障电芯为xx号电芯,故障发生时最高电芯电压为xxV
  119. xxxxxxxx电池于xxxx年xx月xx日发生绝缘离群故障 ,故障发生时绝缘值为xxxxx
  120. 电池是否存在热失控特征
  121. 电池是否存在析锂特征
  122. 电池是否存在内短路特征''')]
  123. )
  124. # put_markdown(f"**4. 电池性能诊断模块**")
  125. header = ['SOC一致性', '内阻一致性', 'SOH一致性', '温度一致性']
  126. values = ["0.9", 0.9, 0.9, 0.9]
  127. put_collapse("4. 电池性能诊断模块", content=[
  128. put_button("执行本算法模块", onclick=lambda:dataclean(df)),
  129. put_markdown(f"**4.1 SOH衰减信息**"),
  130. put_text('''***'''),
  131. put_markdown(f"**4.2 一致性信息**"),
  132. put_table([values],header=header),
  133. put_markdown(f"**4.3 一致性绘图**"),
  134. put_html(image.plot_example().render_notebook()),
  135. ])
  136. header = ['日均充电次数', '累计充电安时量', '累计充电次数']
  137. values = [1, 50, 3]
  138. header2 = ['日均放电次数', '累计放电安时量', '累计放电次数']
  139. values2 = [3, 30, 10]
  140. header3 = ['存储soc均值', '存储温度均值', '最大存储时长']
  141. values3 = [60, 23, 8]
  142. put_collapse("5. 电池画像模块", content=[
  143. put_button("执行本算法模块", onclick=lambda:dataclean(df)),
  144. put_markdown(f"**5.1 电池充电习惯**"),
  145. put_table([values],header=header),
  146. put_markdown("**充电时间段分布图**"),
  147. put_html(image.plot_example2().render_notebook()),
  148. put_markdown("**充电起始soc分布图**"),
  149. put_markdown("**充电结束soc分布图**"),
  150. put_markdown(f"**5.2 电池放电习惯**"),
  151. put_table([values2],header=header2),
  152. put_markdown("**放电时间段分布图**"),
  153. put_markdown("**放电起始soc分布图**"),
  154. put_markdown("**放电结束soc分布图**"),
  155. put_markdown(f"**5.3 电池存储习惯**"),
  156. put_table([values3],header=header3),
  157. put_markdown("**存储温度分布**")])
  158. # main()
  159. start_server(main, port=8080, remote_access=False, debug=True, host="0.0.0.0")