File size: 3,068 Bytes
bdc1ac8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * Node.js Serial Port Wrapper
 * Standardized serialport API interface with write/read operations
 */

import { SerialPort } from "serialport";

/**
 * Node.js Serial Port wrapper - provides write/read interface similar to web version
 */
export class NodeSerialPortWrapper {
  private port: SerialPort;
  private isConnected: boolean = false;
  public readonly path: string; // Expose path for releaseMotors compatibility

  // Expose underlying port for OLD WORKING approach compatibility
  public get underlyingPort(): SerialPort {
    return this.port;
  }

  constructor(path: string, options: any = {}) {
    this.path = path;
    this.port = new SerialPort({
      path,
      baudRate: options.baudRate || 1000000,
      dataBits: options.dataBits || 8,
      parity: options.parity || "none",
      stopBits: options.stopBits || 1,
      autoOpen: false,
    });
  }

  get isOpen(): boolean {
    return this.isConnected && this.port.isOpen;
  }

  async initialize(): Promise<void> {
    return new Promise((resolve, reject) => {
      this.port.open((err) => {
        if (err) {
          reject(new Error(`Failed to open port: ${err.message}`));
        } else {
          this.isConnected = true;
          resolve();
        }
      });
    });
  }

  // Add open method to match SerialPort interface
  async open(): Promise<void> {
    return this.initialize();
  }

  async write(data: Uint8Array): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!this.isConnected) {
        reject(new Error("Port not open for writing"));
        return;
      }

      this.port.write(Buffer.from(data), (err) => {
        if (err) {
          reject(new Error(`Write failed: ${err.message}`));
        } else {
          resolve();
        }
      });
    });
  }

  async read(timeout: number = 1000): Promise<Buffer | null> {
    return new Promise((resolve, reject) => {
      if (!this.isConnected) {
        reject(new Error("Port not open for reading"));
        return;
      }

      const timeoutId = setTimeout(() => {
        reject(new Error("Read timeout"));
      }, timeout);

      const onData = (data: Buffer) => {
        clearTimeout(timeoutId);
        this.port.removeListener("data", onData);
        resolve(data); // Return Buffer directly to match interface
      };

      this.port.once("data", onData);
    });
  }

  async writeAndRead(
    data: Uint8Array,
    timeout: number = 1000
  ): Promise<Uint8Array> {
    await this.write(data);

    // Wait for motor response (motors need time to process command)
    await new Promise((resolve) => setTimeout(resolve, 10));

    const response = await this.read(timeout);
    return response ? new Uint8Array(response) : new Uint8Array();
  }

  async close(): Promise<void> {
    return new Promise((resolve) => {
      if (this.isConnected && this.port.isOpen) {
        this.port.close(() => {
          this.isConnected = false;
          resolve();
        });
      } else {
        this.isConnected = false;
        resolve();
      }
    });
  }
}