accel / app.py
Andrew76214's picture
Update app.py
dde6407 verified
import gradio as gr
import matplotlib.pyplot as plt
import pandas as pd
import io
import tempfile
import os
# 直接複製 main.py 的處理邏輯
def parse_accel_hex(tokens):
if len(tokens) < 6:
return None, None, None
acc_x = int(tokens[0], 16) << 8 | int(tokens[1], 16)
acc_y = int(tokens[2], 16) << 8 | int(tokens[3], 16)
acc_z = int(tokens[4], 16) << 8 | int(tokens[5], 16)
def to_int16(val):
return val - 0x10000 if val & 0x8000 else val
return to_int16(acc_x), to_int16(acc_y), to_int16(acc_z)
def process_file(file_obj, acc_sensitivity):
# 支援 gradio 3.x/4.x: file_obj 可能是檔案物件或路徑字串或 NamedString
if hasattr(file_obj, 'read'):
# 檔案物件
file_obj.seek(0)
lines = file_obj.read().decode('utf-8').splitlines()
else:
# 路徑字串或 NamedString
with open(str(file_obj), 'r', encoding='utf-8') as f:
lines = f.read().splitlines()
output = io.StringIO()
output.write('Timestamp,AccelX,AccelY,AccelZ\n')
data = []
for line in lines:
if 'INFO' not in line:
continue
parts = line.split()
if not parts:
continue
timestamp = parts[0]
idx = line.find('value (0x):')
if idx == -1:
continue
hex_str = line[idx + len('value (0x):'):].strip()
tokens = [tok for tok in hex_str.split('-') if tok]
acc_x, acc_y, acc_z = parse_accel_hex(tokens)
if acc_x is None:
continue
f_acc_x = acc_x / acc_sensitivity
f_acc_y = acc_y / acc_sensitivity
f_acc_z = acc_z / acc_sensitivity
output.write(f"{timestamp},{f_acc_x:.4f},{f_acc_y:.4f},{f_acc_z:.4f}\n")
data.append((timestamp, f_acc_x, f_acc_y, f_acc_z))
# 刪除第一筆資料
if data:
data.pop(0)
output.seek(0)
return output, data
def gradio_interface(file, acc_sensitivity):
if file is None:
return None, None, None
csv_io, data = process_file(file, acc_sensitivity)
# 下載用:寫入臨時檔案,回傳路徑
with tempfile.NamedTemporaryFile(delete=False, suffix='.csv', mode='w', encoding='utf-8') as tmp:
tmp.write(csv_io.getvalue())
tmp_path = tmp.name
# 視覺化
if not data:
return tmp_path, None, "No valid data."
df = pd.DataFrame(data, columns=['Timestamp', 'AccelX', 'AccelY', 'AccelZ'])
# 將 Timestamp 轉為 datetime
df['Timestamp'] = pd.to_datetime(df['Timestamp'], errors='coerce')
fig, ax = plt.subplots(figsize=(10,6))
ax.plot(df['Timestamp'], df['AccelX'], label='Ax')
ax.plot(df['Timestamp'], df['AccelY'], label='Ay')
ax.plot(df['Timestamp'], df['AccelZ'], label='Az')
ax.set_xlabel('Time')
ax.set_ylabel('Acceleration (g)')
ax.set_title('Accelerometer Data')
ax.legend()
fig.autofmt_xdate()
plt.tight_layout()
return tmp_path, fig, None
demo = gr.Blocks()
with demo:
gr.Markdown("""
<img src="https://custom-images.strikinglycdn.com/res/hrscywv4p/image/upload/c_limit,fl_lossy,h_300,w_300,f_auto,q_auto/4493206/132971_72411.png" width="100" />
# 加速度資料轉換與視覺化
上傳原始檔案(如 data.txt),調整 ACC_SENSITIVITY,下載轉換後的 csv,並預覽加速度圖表。
""")
with gr.Row():
file_input = gr.File(label="上傳原始檔案(txt)")
acc_input = gr.Number(value=4096.0, label="ACC_SENSITIVITY (例如 4096.0)")
with gr.Row():
csv_output = gr.File(label="下載轉換後的 CSV")
plot_output = gr.Plot(label="加速度圖表")
msg_output = gr.Textbox(label="訊息", interactive=False)
btn = gr.Button("執行轉換與繪圖")
btn.click(fn=gradio_interface, inputs=[file_input, acc_input], outputs=[csv_output, plot_output, msg_output])
demo.launch()