ti-pote/apps/robot-client/scripts/hardware-demo.ts
2026-04-08 18:37:08 +02:00

70 lines
1.9 KiB
TypeScript

/**
* Ti-Pote — Hardware bring-up demo.
*
* Run with:
* HARDWARE_SERIAL_PORT=/dev/ttyUSB0 pnpm --filter @ti-pote/robot-client hw:demo
*
* What it does:
* 1. Opens the serial link to the ESP32 firmware.
* 2. Pings it and prints the round-trip time.
* 3. Cycles through every emotion with a 1.2 s pause so you can
* watch the OLED eyes react.
* 4. Finishes on NEUTRAL and disconnects cleanly.
*
* Use this as a smoke test after flashing new firmware, before
* wiring the full robot-client/cloud pipeline.
*/
import { HardwareService, Emotion } from '../src/hardware/index.js';
const path = process.env.HARDWARE_SERIAL_PORT ?? '/dev/ttyUSB0';
const baudRate = parseInt(process.env.HARDWARE_SERIAL_BAUD ?? '921600', 10);
const EMOTION_SEQUENCE: Emotion[] = [
Emotion.NEUTRAL,
Emotion.HAPPY,
Emotion.SAD,
Emotion.ANGRY,
Emotion.SURPRISED,
Emotion.SLEEPY,
Emotion.WINK,
Emotion.LOVE,
Emotion.DIZZY,
Emotion.DEAD,
Emotion.NEUTRAL,
];
async function sleep(ms: number): Promise<void> {
return new Promise((r) => setTimeout(r, ms));
}
async function main(): Promise<void> {
const hw = new HardwareService({ path, baudRate, heartbeatIntervalMs: 1000 });
hw.on('log', (line) => console.log(`[firmware] ${line}`));
hw.on('error', (err) => console.error(`[firmware error] ${err.message}`));
console.log(`→ opening ${path} @ ${baudRate} baud`);
await hw.connect();
try {
const rtt = await hw.ping(Buffer.from('hello'));
console.log(`← pong (rtt ${rtt.toFixed(1)} ms)`);
} catch (err) {
console.warn(`ping failed: ${(err as Error).message}`);
}
for (const emotion of EMOTION_SEQUENCE) {
console.log(`→ emotion ${Emotion[emotion]}`);
hw.sendEmotion(emotion);
await sleep(1200);
}
await hw.disconnect();
console.log('done.');
}
main().catch((err) => {
console.error(err);
process.exit(1);
});