Modify WebUI & system start flow for Mass production
This commit is contained in:
parent
41c0a781f2
commit
49cdb5bbae
20
tools/device/start.sh
Normal file
20
tools/device/start.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
mkdir -p /tmp/venc/c0/;
|
||||||
|
mkdir -p /tmp/aenc/c0/;
|
||||||
|
mkdir -p /tmp/playback/c0/;
|
||||||
|
mkdir -p /tmp/twoway/c0/;
|
||||||
|
mkdir -p /tmp/sr/c0/;
|
||||||
|
mkdir -p /tmp/sdcard;
|
||||||
|
mkdir -p /tmp/canbus/c0/;
|
||||||
|
mount /dev/mmcblk0p1 /tmp/sdcard 2>/dev/null || true
|
||||||
|
export LD_LIBRARY_PATH=$(pwd)/lib;
|
||||||
|
cd ../plus/kp_firmware/kp_firmware_0/kp_firmware/bin
|
||||||
|
./rtsps -c stream_server_config.ini &
|
||||||
|
./kp_firmware_host_stream &
|
||||||
|
#./rtsps -c stream_server_config.ini > /dev/null 2>&1 &
|
||||||
|
#./kp_firmware_host_stream > /tmp/fw.log 2>&1 &
|
||||||
|
### Notice : Codec type AAC4, sample rate 8000, bit rate 32000, raw format, stereo, mic_in ###
|
||||||
|
#./tinyaenc_mmap -d "hw:0,0" -r 8000 -C 0 -b 32000 -t 0 -S 0 -i 0 &
|
||||||
|
#sleep 2;
|
||||||
|
#./volume_ctrl -i 0 -M 0 -v 96;
|
||||||
|
#./playback_example_mmap -d "hw:0,0" -r 8000 -c 2 -C 0 &
|
||||||
108
web_serve.py
108
web_serve.py
@ -46,6 +46,7 @@ DEPLOY_SRC = SCRIPT_DIR / "tools" / "device" / "deploy.sh"
|
|||||||
DEMO_RTSP_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp.sh"
|
DEMO_RTSP_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp.sh"
|
||||||
DEMO_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_hdmi.sh"
|
DEMO_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_hdmi.sh"
|
||||||
DEMO_RTSP_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp_hdmi.sh"
|
DEMO_RTSP_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp_hdmi.sh"
|
||||||
|
START_SH_SRC = SCRIPT_DIR / "tools" / "device" / "start.sh"
|
||||||
NEF_DIR = SCRIPT_DIR / "nef"
|
NEF_DIR = SCRIPT_DIR / "nef"
|
||||||
KCURL_SRC = Path("/home/user/Documents/GOFACE/奧創雲/kCurl-1.1.1-release/kCurl-linux-armv7")
|
KCURL_SRC = Path("/home/user/Documents/GOFACE/奧創雲/kCurl-1.1.1-release/kCurl-linux-armv7")
|
||||||
CONFIG_FILE = SCRIPT_DIR / ".web_config.json"
|
CONFIG_FILE = SCRIPT_DIR / ".web_config.json"
|
||||||
@ -93,6 +94,7 @@ def prepare_build_dir():
|
|||||||
(DEMO_RTSP_SRC, "demo_rtsp.sh"),
|
(DEMO_RTSP_SRC, "demo_rtsp.sh"),
|
||||||
(DEMO_HDMI_SRC, "demo_hdmi.sh"),
|
(DEMO_HDMI_SRC, "demo_hdmi.sh"),
|
||||||
(DEMO_RTSP_HDMI_SRC, "demo_rtsp_hdmi.sh"),
|
(DEMO_RTSP_HDMI_SRC, "demo_rtsp_hdmi.sh"),
|
||||||
|
(START_SH_SRC, "start.sh"),
|
||||||
]:
|
]:
|
||||||
if Path(src).exists():
|
if Path(src).exists():
|
||||||
shutil.copy2(src, BUILD_DIR / name)
|
shutil.copy2(src, BUILD_DIR / name)
|
||||||
@ -521,6 +523,9 @@ def api_deploy_run():
|
|||||||
("Pushing deploy.sh to device...",
|
("Pushing deploy.sh to device...",
|
||||||
f"wget -q {base}/deploy.sh -O /tmp/deploy.sh && chmod +x /tmp/deploy.sh && echo 'deploy.sh OK'",
|
f"wget -q {base}/deploy.sh -O /tmp/deploy.sh && chmod +x /tmp/deploy.sh && echo 'deploy.sh OK'",
|
||||||
False, 30),
|
False, 30),
|
||||||
|
("Updating start.sh...",
|
||||||
|
f"wget -q {base}/start.sh -O /mnt/flash/vienna/start.sh && chmod +x /mnt/flash/vienna/start.sh && echo 'start.sh OK'",
|
||||||
|
False, 30),
|
||||||
("Downloading kCurl (event upload tool)...",
|
("Downloading kCurl (event upload tool)...",
|
||||||
f"wget -q {base}/kCurl -O {bd}/kCurl && chmod +x {bd}/kCurl && echo 'kCurl OK'",
|
f"wget -q {base}/kCurl -O {bd}/kCurl && chmod +x {bd}/kCurl && echo 'kCurl OK'",
|
||||||
False, 30),
|
False, 30),
|
||||||
@ -562,6 +567,89 @@ def api_deploy_run():
|
|||||||
return Response(generate(), mimetype="text/event-stream",
|
return Response(generate(), mimetype="text/event-stream",
|
||||||
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})
|
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})
|
||||||
|
|
||||||
|
# ── API: deploy binary only (SSE) ────────────────────────────────────────────
|
||||||
|
@app.route("/api/deploy/binary")
|
||||||
|
def api_deploy_binary():
|
||||||
|
cfg = load_config()
|
||||||
|
kl_ip = request.args.get("ip", cfg["kl630_ip"])
|
||||||
|
h_ip = request.args.get("host_ip", cfg["host_ip"])
|
||||||
|
port = int(request.args.get("port", cfg["port"]))
|
||||||
|
base = f"http://{h_ip}:{port}"
|
||||||
|
fw = FW_PATH_DEVICE
|
||||||
|
bd = BIN_DIR_DEVICE
|
||||||
|
out_rtsp = request.args.get("out_rtsp", "1") == "1"
|
||||||
|
out_hdmi = request.args.get("out_hdmi", "0") == "1"
|
||||||
|
|
||||||
|
if out_hdmi and not out_rtsp:
|
||||||
|
start_cmd = f"cd {bd} && nohup sh ./ini/demo_hdmi.sh > /tmp/fw.log 2>&1 &"
|
||||||
|
elif out_rtsp and out_hdmi:
|
||||||
|
start_cmd = f"cd {bd} && nohup sh ./ini/demo_rtsp_hdmi.sh > /tmp/fw.log 2>&1 &"
|
||||||
|
else:
|
||||||
|
start_cmd = f"cd {bd} && nohup sh ./ini/demo_rtsp.sh > /tmp/fw.log 2>&1 &"
|
||||||
|
|
||||||
|
def generate():
|
||||||
|
yield sse(f"Connecting to {kl_ip}:23...")
|
||||||
|
try:
|
||||||
|
tn = _telnet_connect(kl_ip)
|
||||||
|
_drain_shell(tn)
|
||||||
|
yield sse("Connected.", "ok")
|
||||||
|
|
||||||
|
yield sse("Stopping firmware...")
|
||||||
|
for ln in _telnet_run(tn, "killall -9 kp_firmware_host_stream 2>/dev/null; killall -9 rtsps 2>/dev/null; sleep 1; rm -f /dev/shm/*", timeout=15):
|
||||||
|
yield sse(ln)
|
||||||
|
|
||||||
|
yield sse("Downloading binary...")
|
||||||
|
for ln in _telnet_run(tn, f"wget -q {base}/kp_firmware_host_stream -O {fw} && chmod +x {fw} && ls -lh {fw}", timeout=60):
|
||||||
|
yield sse(ln, "ok")
|
||||||
|
|
||||||
|
yield sse("Restarting firmware...")
|
||||||
|
for ln in _telnet_run_bg(tn, start_cmd):
|
||||||
|
if ln.strip(): yield sse(ln.strip())
|
||||||
|
|
||||||
|
ok, lines = _verify_firmware_running(tn)
|
||||||
|
for ln in lines:
|
||||||
|
yield sse(ln, "ok" if ok else "warn")
|
||||||
|
if ok:
|
||||||
|
yield sse("Binary updated and firmware running.", "ok")
|
||||||
|
else:
|
||||||
|
yield sse("Firmware may not have started — check /tmp/fw.log", "warn")
|
||||||
|
tn.close()
|
||||||
|
except Exception as e:
|
||||||
|
yield sse(f"Telnet error: {e}", "error")
|
||||||
|
yield sse_done()
|
||||||
|
|
||||||
|
return Response(generate(), mimetype="text/event-stream",
|
||||||
|
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})
|
||||||
|
|
||||||
|
# ── API: deploy start.sh only (SSE) ──────────────────────────────────────────
|
||||||
|
@app.route("/api/deploy/startsh")
|
||||||
|
def api_deploy_startsh():
|
||||||
|
cfg = load_config()
|
||||||
|
kl_ip = request.args.get("ip", cfg["kl630_ip"])
|
||||||
|
h_ip = request.args.get("host_ip", cfg["host_ip"])
|
||||||
|
port = int(request.args.get("port", cfg["port"]))
|
||||||
|
base = f"http://{h_ip}:{port}"
|
||||||
|
|
||||||
|
def generate():
|
||||||
|
yield sse(f"Connecting to {kl_ip}:23...")
|
||||||
|
try:
|
||||||
|
tn = _telnet_connect(kl_ip)
|
||||||
|
_drain_shell(tn)
|
||||||
|
yield sse("Connected.", "ok")
|
||||||
|
|
||||||
|
yield sse("Updating start.sh...")
|
||||||
|
for ln in _telnet_run(tn, f"wget -q {base}/start.sh -O /mnt/flash/vienna/start.sh && chmod +x /mnt/flash/vienna/start.sh && echo 'start.sh OK'", timeout=30):
|
||||||
|
yield sse(ln, "ok")
|
||||||
|
|
||||||
|
tn.close()
|
||||||
|
yield sse("start.sh updated. Takes effect on next reboot.", "ok")
|
||||||
|
except Exception as e:
|
||||||
|
yield sse(f"Telnet error: {e}", "error")
|
||||||
|
yield sse_done()
|
||||||
|
|
||||||
|
return Response(generate(), mimetype="text/event-stream",
|
||||||
|
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})
|
||||||
|
|
||||||
# ── API: SPI setup via Telnet (SSE) ─────────────────────────────────────────
|
# ── API: SPI setup via Telnet (SSE) ─────────────────────────────────────────
|
||||||
@app.route("/api/spi_setup/run")
|
@app.route("/api/spi_setup/run")
|
||||||
def api_spi_setup_run():
|
def api_spi_setup_run():
|
||||||
@ -1693,6 +1781,14 @@ input:checked+.slider:before{transform:translateX(16px);background:#fff}
|
|||||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="5 12 12 5 19 12"/><line x1="12" y1="5" x2="12" y2="19"/></svg>
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="5 12 12 5 19 12"/><line x1="12" y1="5" x2="12" y2="19"/></svg>
|
||||||
Deploy to KL630
|
Deploy to KL630
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-ghost" id="btn-deploy-binary" onclick="runAction('deploy_binary')">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="4" y="2" width="16" height="20" rx="2"/><line x1="8" y1="10" x2="16" y2="10"/><line x1="8" y1="14" x2="16" y2="14"/></svg>
|
||||||
|
Update Binary
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-ghost" id="btn-deploy-startsh" onclick="runAction('deploy_startsh')">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
|
||||||
|
Update start.sh
|
||||||
|
</button>
|
||||||
<button class="btn btn-warn" id="btn-bt-setup" onclick="runAction('bt_setup')">
|
<button class="btn btn-warn" id="btn-bt-setup" onclick="runAction('bt_setup')">
|
||||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/></svg>
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/></svg>
|
||||||
BT 初始化
|
BT 初始化
|
||||||
@ -1864,8 +1960,16 @@ function runAction(action) {
|
|||||||
'&out_hdmi=' + (document.getElementById('out-hdmi').checked ? 1 : 0),
|
'&out_hdmi=' + (document.getElementById('out-hdmi').checked ? 1 : 0),
|
||||||
autostart_read: '/api/autostart/read?ip=' + encodeURIComponent(cfg.kl630_ip),
|
autostart_read: '/api/autostart/read?ip=' + encodeURIComponent(cfg.kl630_ip),
|
||||||
mount_sd: '/api/mount_sd?ip=' + encodeURIComponent(cfg.kl630_ip),
|
mount_sd: '/api/mount_sd?ip=' + encodeURIComponent(cfg.kl630_ip),
|
||||||
|
deploy_binary: '/api/deploy/binary?ip=' + encodeURIComponent(cfg.kl630_ip) +
|
||||||
|
'&host_ip=' + encodeURIComponent(cfg.host_ip) +
|
||||||
|
'&port=' + encodeURIComponent(cfg.port) +
|
||||||
|
'&out_rtsp=' + (document.getElementById('out-rtsp').checked ? 1 : 0) +
|
||||||
|
'&out_hdmi=' + (document.getElementById('out-hdmi').checked ? 1 : 0),
|
||||||
|
deploy_startsh: '/api/deploy/startsh?ip=' + encodeURIComponent(cfg.kl630_ip) +
|
||||||
|
'&host_ip=' + encodeURIComponent(cfg.host_ip) +
|
||||||
|
'&port=' + encodeURIComponent(cfg.port),
|
||||||
};
|
};
|
||||||
const labels = { compile:'Compile', deploy:'Deploy to KL630', bt_setup:'BT 初始化', spi_setup:'SPI 初始化', autostart:'Write Autostart', autostart_read:'Read Autostart', mount_sd:'Mount SD' };
|
const labels = { compile:'Compile', deploy:'Deploy to KL630', bt_setup:'BT 初始化', spi_setup:'SPI 初始化', autostart:'Write Autostart', autostart_read:'Read Autostart', mount_sd:'Mount SD', deploy_binary:'Update Binary', deploy_startsh:'Update start.sh' };
|
||||||
|
|
||||||
appendLog('\\n── ' + labels[action] + ' ' + '─'.repeat(40), 'prompt');
|
appendLog('\\n── ' + labels[action] + ' ' + '─'.repeat(40), 'prompt');
|
||||||
setLogStatus('Running...');
|
setLogStatus('Running...');
|
||||||
@ -1961,7 +2065,7 @@ function appendLog(text, kind) {
|
|||||||
}
|
}
|
||||||
function clearLog() { document.getElementById('log').textContent = ''; setLogStatus(''); }
|
function clearLog() { document.getElementById('log').textContent = ''; setLogStatus(''); }
|
||||||
function setLogStatus(s) { document.getElementById('log-status').textContent = s; }
|
function setLogStatus(s) { document.getElementById('log-status').textContent = s; }
|
||||||
function setBtns(disabled){ ['btn-compile','btn-deploy','btn-bt-setup','btn-spi-setup','btn-autostart','btn-autostart-read','btn-mount-sd','btn-model-apply'].forEach(id => document.getElementById(id).disabled = disabled); }
|
function setBtns(disabled){ ['btn-compile','btn-deploy','btn-bt-setup','btn-spi-setup','btn-autostart','btn-autostart-read','btn-mount-sd','btn-model-apply','btn-deploy-binary','btn-deploy-startsh'].forEach(id => document.getElementById(id).disabled = disabled); }
|
||||||
|
|
||||||
// ── Terminal ──────────────────────────────────────────────────────────────────
|
// ── Terminal ──────────────────────────────────────────────────────────────────
|
||||||
// by mars
|
// by mars
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user