upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/tests/helpers/serial.mjs
blob: 306b552bb024a4fda94984836e316c695590d28c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { SerialPort } from 'serialport';
import { ReadlineParser } from '@serialport/parser-readline';
import { execSync } from 'child_process';

const DEFAULT_BAUD = 115200;
const BOOT_TIMEOUT = 30000;

export async function execSerial(portPath, command, timeoutMs = 5000) {
  return new Promise((resolve, reject) => {
    const port = new SerialPort({ path: portPath, baudRate: DEFAULT_BAUD });
    const parser = port.pipe(new ReadlineParser());
    const lines = [];
    let resolved = false;

    const timer = setTimeout(() => {
      if (!resolved) { resolved = true; port.close(); resolve(lines.join('\n')); }
    }, timeoutMs);

    parser.on('data', (line) => {
      lines.push(line);
      if (line.includes('___END___') && !resolved) {
        resolved = true;
        clearTimeout(timer);
        port.close();
        resolve(lines.join('\n'));
      }
    });

    port.on('open', () => {
      port.write(command + '\n');
    });

    port.on('error', (err) => {
      if (!resolved) { resolved = true; clearTimeout(timer); reject(err); }
    });
  });
}

export async function waitForBoot(portPath, timeoutMs = BOOT_TIMEOUT) {
  return new Promise((resolve, reject) => {
    const port = new SerialPort({ path: portPath, baudRate: DEFAULT_BAUD });
    const parser = port.pipe(new ReadlineParser());
    const timer = setTimeout(() => {
      port.close();
      reject(new Error('Boot timeout'));
    }, timeoutMs);

    parser.on('data', (line) => {
      if (line.includes('TollGate services started') || line.includes('WiFi AP+STA started')) {
        clearTimeout(timer);
        setTimeout(() => { port.close(); resolve(true); }, 500);
      }
    });

    port.on('error', (err) => {
      clearTimeout(timer);
      reject(err);
    });
  });
}

export async function readSerial(portPath, durationMs = 3000) {
  return new Promise((resolve, reject) => {
    const port = new SerialPort({ path: portPath, baudRate: DEFAULT_BAUD });
    const parser = port.pipe(new ReadlineParser());
    const lines = [];

    const timer = setTimeout(() => {
      port.close();
      resolve(lines.join('\n'));
    }, durationMs);

    parser.on('data', (line) => lines.push(line));
    port.on('error', (err) => { clearTimeout(timer); reject(err); });
  });
}

export function resetDevice(portPath) {
  try {
    execSync(`python3 -m esptool --port ${portPath} run 2>/dev/null`, { timeout: 5000 });
  } catch {}
}