文件
phonerail/rack/frontend/src/components/OtaState.vue
T
zhou yang和Claude Opus 5.5 271c649f66 rack:「固件」页 —— 上传 .bin、选板推送 OTA、实时看进度 / 待验证 / 回滚
- firmware.py:固件库。上传时核 ESP 镜像头(0xE9 + app 描述 + project_name == phonerail + ≤3 MB),
  存成 /root/phonerail/fw/<sha 前 16 位>.bin(nginx 7765 放出去),库里记版本 / 编译时间 / 上传人
- api:GET/POST/DELETE /api/firmware(请求体即 .bin,不引 multipart)、POST /api/boards/{id}/ota(进审计);
  通用 /cmd 不放行 ota —— URL 与哈希只能由固件库生成;OTA 事件按 arg 显示中文、失败 / 回滚标红
- 前端:Firmware.vue + OtaState.vue;推送对话框默认不重启,勾「立刻重启」时列出每块板会断电的路并二次确认;
  单板页显示 OTA 状态
- simboard 模拟 ota(下载进度 / 就绪 / 重启 / 自证);test_firmware.py 13 例,后端共 39 例(本机 + 服务器 3.8)
- service 加 --fw-dir;已部署。板 B 实测:上传 → 推送 → 就绪 → 同镜像带重启 → 不重下直接重启 → 自证健康

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 14:14:06 +08:00

29 行
1.4 KiB
Vue
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
<template>
<span class="ota">
<template v-if="o.st === 'dl'">
<el-progress :percentage="pct" :stroke-width="10" style="width: 140px" />
<span class="muted">下载中</span>
</template>
<el-tag v-else-if="o.st === 'ready'" type="warning" size="small" title="已校验、已切启动分区,下次复位生效">已就绪 · 待重启</el-tag>
<el-tag v-if="o.pend" type="warning" size="small" title="新固件还没连上 broker;120 s 内连不上会自动回滚">待验证</el-tag>
<el-tag v-if="o.err && o.st !== 'dl'" type="danger" size="small">上次失败:{{ OTA_ERR_ZH[o.err] || o.err }}</el-tag>
<el-tag v-if="o.bad" type="danger" size="small" effect="plain" title="这份固件在板子上没通过自证健康,被回滚掉了">回滚过:{{ o.bad }}</el-tag>
<span v-if="!busy && !o.pend && !o.err && !o.bad && o.st !== 'ready'" class="muted">—</span>
</span>
</template>
<script setup>
// 一块板的 OTA 状态,直接读遥测里的 `ota`(firmware/main/cmd_report.c 的 ota_obj)。
import { computed } from 'vue'
import { OTA_ERR_ZH } from '../api'
const props = defineProps({ status: Object })
const o = computed(() => props.status?.ota || {})
const busy = computed(() => o.value.st === 'dl')
const pct = computed(() => (o.value.size ? Math.floor((o.value.got / o.value.size) * 100) : 0))
</script>
<style scoped>
.ota { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
</style>