1. ITECH 充放電機系統
- 已達成項目
[✓] 硬體連線:完成 ITECH、HIOKI 與樹莓派串接,並具備實時連線狀態監控。
[✓] 狀態監看與排程控制:支援電腦遠端查看 HIOKI/ITECH 狀態,並可發送編輯排程至 ITECH 執行。
[✓] 排程中斷與保護:
- 觸發中斷條件:Vsr/Tsr 無訊號或連線中斷、達到電壓/電流/功率保護臨界點。
- 斷線防護:電腦關機或斷開連線不影響排程持續執行。
[✓] 資料儲存與下載:
- CSV 紀錄優先存於樹莓派內部,於每次開機或每日
12:00 自動執行備份。
- 提供 API 下載:
http://[IP]:8000/api/logs。
- 用戶端軟體會將樹莓派狀態持久化於 Local 端,啟動時自動同步下載 CSV。
[✓] 條碼與模式控制:預接模式結合 Barcode 自動載入;如需自訂參數可開啟工程模式。
- 工程模式熱鍵:
Ctrl + Shift + E(密碼:1225)
- 未解決問題
[!] 通訊衝突:ITECH 與 VSR/TSR 連線異常,Loop 機制與 VSR/TSR 發生衝突。
- 待辦步驟 1:VSR/TSR 模組需新增實機狀態查詢機制。
- 待辦步驟 2:修正
VSRTSR.py 內的「開始/結束判斷 logic」,納入 LOOP 狀態判定。
- 未來預計達成
[>] 架構擴充:將 DAQ970 整合進系統架構。將 DAQ970 的資料格式重構為與 HIOKI 一致,避免前端需針對新設備處理例外判斷。
2. 產品報表系統
- 已達成項目
[✓] 網路與架構:設定 VPS1 Nginx 反向代理(Reverse Proxy)打通至 VPS2。
[✓] 服務部署:VPS2 採用 Docker 容器化架構,技術棧為 FastAPI (Python) + MariaDB。
[✓] 帳戶與安全管理:
- 預設密碼:
report24837296。
- 支援忘記密碼重設為預設值,並強制於首次登入(
is_first_login = True)變更密碼。
[✓] 使用量指標與防佔線:
- 追蹤指標:累計登入秒數與報表產出總次數。
- 連線管理:透過 WebSocket 實時監測,若用戶 10 分鐘內無動作,伺服器主動強制斷線、登出並結算 Session 時長。
- 未解決問題
[!] 圖檔儲存空間:機構圖儲存需求增長,需額外擴充獨立的圖片儲存空間(Storage Volume / MinIO)。
- 未來預計達成
[>] 自動化報表:整合電器數據自動生成規格報表。
[>] 機構圖標註:實現機構圖自動生成並自動標記尺寸長度。
3. 點鑽系統
- 已達成項目
[✓] MQTT 功能擴充:基於原 HirackEMS 架構,新增 MQTT 訊息拋接功能。
[✓] 安全認證與 SSH:SSH 連線綁定 Key 憑證驗證,用戶端配置如下:
Host Gus-Rasp6-點鑽1
HostName 100.64.28.44
User rasp
IdentityFile "C:\Users\G11407007\.ssh\2609171447key"
IdentitiesOnly yes
- 未解決問題
[!] 憑證遺失風險:若裝置端遺失 SSH 憑證將導致永久鎖死,目前僅能重新燒錄 OS 系統。
- 未來預計達成
[>] 自動回收機制:新增時間到期自動回收/釋放資源功能。
4. 電動巴士 LuCan
- 已達成項目
[✓] Profile 解析與格式化:支援以 JSON 檔進行 CAN Signal Profile 設定與解析。
[✓] 靈活採樣記錄:CSV 資料記錄可配置為「連線即持續記錄」或「連線後僅記錄一筆」,滿足不同產線情境。
[✓] 實車通訊校驗:完成與中鹿客運連線測試與 CAN 解析,經比對數據與阿傑使用之中鹿官方軟體讀出結果一致。
- 未解決問題
[!] 實機測試:等待中鹿電池組組裝完成後進行完整充放電測試。
- 未來預計達成
[>] 穩定度強化:持續監控數據準確度,並依據產線回饋新增自動化功能。
附錄:系統 Schema 與 Profile 配置細節
A. 報表系統 MariaDB 資料庫 Schema
users (PM / 系統帳號表)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
user_id | String(36) | Primary Key (UUID) |
name | String(100) | 使用者姓名 |
email | String(100) | 登入 Email (Unique) |
password | String(255) | 密碼 Hash(預設 report24837296) |
role | String(20) | 權限角色 (PM, Admin) |
is_first_login | Boolean | 首次登入標記 (預設 True) |
total_online_seconds | Integer | 【數據指標】 累計登入總秒數 (預設 0) |
generated_report_count | Integer | 【數據指標】 累計產出報表總次數 (預設 0) |
last_login_at | DateTime | 最後登入時間 |
customers (客戶與聯絡人資料表)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
customer_id | String(36) | Primary Key (UUID) |
pm_id | String(36) | Foreign Key -> users.user_id (負責 PM) |
company_name | String(150) | 公司名稱 |
customer_name | String(100) | 聯絡人姓名 |
customer_mail | String(100) | 聯絡人 Email |
customer_phone | String(50) | 聯絡人電話 |
reports (報表規格主表)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
report_id | String(36) | Primary Key (UUID) |
report_code | String(50) | 報表編號 (Unique Key) |
pm_id | String(36) | Foreign Key -> users.user_id |
customer_id | String(36) | Foreign Key -> customers.customer_id |
status | String(20) | 狀態 (DRAFT, GENERATED, ARCHIVED) |
spec_series | Integer | 串聯數 S (預設 6) |
spec_parallel | Integer | 並聯數 P |
cell_num | String(50) | 電芯型號 / 料號 |
cell_type | String(50) | 電芯種類 (如 18650, 21700, LFP) |
connection_method | String(50) | 串併方式 |
processing_method | String(50) | 加工方式 |
connector_type | String(50) | 連接器類型 |
wire_length | Numeric(10,2) | 線長 (mm/cm) |
outer_casing | String(50) | 外包覆材質 |
array_arrangement | Enum | 排列方式 (I, U, II) |
has_bms | Boolean | 是否包含 BMS (預設 True) |
bms_spec_limit | String(50) | BMS 規格限制 (如 6S?P) |
weight_g | Numeric(10,2) | 估計重量 (g) |
dimensions_mm | String(50) | 尺寸規格 (格式: L_W_H) |
delivery_days | Integer | 交期天數 |
tiered_pricing | Numeric(12,2) | 報表價格 / 階梯價格 |
report_histories (歷史版本快照)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
history_id | String(36) | Primary Key (UUID) |
report_id | String(36) | Foreign Key -> reports.report_id |
version | Integer | 版本號 (1, 2, 3…) |
snapshot_data | JSON | 整份報表與客戶資訊的 JSON 快照 |
created_by | String(36) | Foreign Key -> users.user_id |
user_sessions (登入與時數細節表)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
session_id | String(36) | Primary Key (UUID) |
user_id | String(36) | Foreign Key -> users.user_id |
login_at | DateTime | 登入時間 |
logout_at | DateTime | 登出時間 |
duration_seconds | Integer | Session 線上總秒數 |
audit_logs (系統操作軌跡表)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
log_id | String(36) | Primary Key (UUID) |
user_id | String(36) | Foreign Key -> users.user_id (可為 Null) |
action | String(50) | 操作類型 (LOGIN, CREATE_REPORT, EXPORT_PDF, UPDATE_SPEC) |
resource | String(50) | 操作標的 (reports, customers) |
details | JSON | 詳細操作參數與欄位變更紀錄 |
ip_address | String(45) | 用戶端 IP 地址 |
user_agent | String(255) | 用戶端裝置資訊 |
static_report_masters (靜態報表範本主檔)
| 欄位名稱 | 型態 | 說明 / 預設值 |
|---|
master_id | String(36) | Primary Key (UUID) |
template_code | String(50) | 範本編號 (Unique Key) |
spec_series | Integer | 預設串聯數 S |
spec_parallel | Integer | 預設並聯數 P |
cell_num | String(50) | 標準電芯型號與料號 |
cell_type | String(50) | 電芯種類 (18650, 21700, LFP, NCM) |
connection_method | String(50) | 標準串併與焊接方式 |
processing_method | String(50) | 標準加工方式 |
connector_type | String(50) | 標準連接器規格 |
wire_length | Numeric(10,2) | 標準線長 (mm/cm) |
outer_casing | String(50) | 外包覆材質 (熱縮套管、PVC、金屬殼) |
array_arrangement | Enum | 預設排列方式 (I, U, II) |
has_bms | Boolean | 預設是否包含 BMS (預設 True) |
bms_spec_limit | String(50) | BMS 規格限制 |
weight_g | Numeric(10,2) | 標準估計總重量 (g) |
dimensions_mm | String(50) | 外觀尺寸 (格式: L_W_H) |
delivery_days | Integer | 標準基準交期天數 |
tiered_pricing | Numeric(12,2) | 基礎建議售價 |
is_active | Boolean | 是否啟用此範本 (預設 True) |
created_at | DateTime | 建立時間 |
updated_at | DateTime | 最後異動時間 |
B. LuCan CAN Profile 設定範例 (JSON)
JSON
{
"ProfileName": "LMU_6803_X04",
"BaudRate": "250K",
"CanUSB": "3",
"IsLittleEndian": false,
"CellSignals": {
"TotalCount": 48,
"CanFrames": [
{
"CanId": "0x01X7",
"Signals": [
{ "SignalId": "C01", "StartByte": 0, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.001, "Offset": 0.0, "Unit": "V", "InvalidRaw": "0xFFFF" },
{ "SignalId": "C02", "StartByte": 2, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.001, "Offset": 0.0, "Unit": "V", "InvalidRaw": "0xFFFF" },
{ "SignalId": "C03", "StartByte": 4, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.001, "Offset": 0.0, "Unit": "V", "InvalidRaw": "0xFFFF" },
{ "SignalId": "C04", "StartByte": 6, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.001, "Offset": 0.0, "Unit": "V", "InvalidRaw": "0xFFFF" }
]
}
]
},
"TempSignals": {
"TotalCount": 15,
"CanFrames": [
{
"CanId": "0x01X5",
"Signals": [
{ "SignalId": "T01", "StartByte": 0, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.1, "Offset": -40.0, "Unit": "°C", "InvalidRaw": "0xFFFF" }
]
}
]
},
"BatterySignals": {
"TotalCount": 18,
"CanFrames": [
{
"CanId": "0x01X0",
"Signals": [
{ "SignalId": "CellCount", "StartByte": 0, "LengthBytes": 1, "Mask": "0x7F", "Scale": 1.0, "Offset": 0.0, "Unit": "pcs", "InvalidRaw": "0xFF" },
{ "SignalId": "TempSensorCount", "StartByte": 1, "LengthBytes": 1, "Mask": "0x7F", "Scale": 1.0, "Offset": 0.0, "Unit": "pcs", "InvalidRaw": "0xFF" },
{ "SignalId": "ModuleTotalVoltage_V", "StartByte": 2, "LengthBytes": 2, "Mask": "0x7FFF", "Scale": 0.001, "Offset": 0.0, "Unit": "V", "InvalidRaw": "0xFFFF" }
]
}
]
}
}