m2-inno-bedpressure/services/BedHardwareSerial.ts.disabled

149 lines
No EOL
4.1 KiB
Text

import { SerialPort } from 'serialport';
import { ReadlineParser } from '@serialport/parser-readline';
import { EventEmitter } from 'events';
import { IBedHardware, PinState, PinChange } from '../types/bedhardware';
export class BedHardwareSerial extends EventEmitter implements IBedHardware {
private serialPort: SerialPort | null = null;
private parser: ReadlineParser | null = null;
private pinStates: Map<number, PinState> = new Map();
private connectionState: boolean = false;
constructor(private portPath: string, private baudRate: number = 9600) {
super();
}
async connect(): Promise<void> {
try {
this.serialPort = new SerialPort({
path: this.portPath,
baudRate: this.baudRate,
autoOpen: false
});
this.parser = new ReadlineParser({ delimiter: '\n' });
this.serialPort.pipe(this.parser);
// Setup event handlers
this.serialPort.on('open', () => {
this.connectionState = true;
this.emit('connected');
console.log('Serial port opened');
});
this.serialPort.on('error', (error) => {
this.emit('error', error);
console.error('Serial port error:', error);
});
this.serialPort.on('close', () => {
this.connectionState = false;
this.emit('disconnected');
console.log('Serial port closed');
});
this.parser.on('data', (data: string) => {
this.handleSerialData(data.trim());
});
// Open the port
await new Promise<void>((resolve, reject) => {
this.serialPort!.open((error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
} catch (error) {
throw new Error(`Failed to connect to ${this.portPath}: ${error}`);
}
}
async disconnect(): Promise<void> {
if (this.serialPort && this.serialPort.isOpen) {
await new Promise<void>((resolve) => {
this.serialPort!.close(() => {
resolve();
});
});
}
this.serialPort = null;
this.parser = null;
this.connectionState = false;
}
private handleSerialData(data: string): void {
const parts = data.split(':');
if (parts[0] === 'INIT') {
if (parts[1] === 'START') {
this.emit('initialized');
console.log('Arduino initialization started');
} else if (parts.length >= 3) {
// INIT:PIN:STATE format
const pin = parseInt(parts[1]);
const state = parseInt(parts[2]);
if (!isNaN(pin) && !isNaN(state)) {
const pinState: PinState = {
pin,
state,
name: `PIN${pin}`,
timestamp: new Date()
};
this.pinStates.set(pin, pinState);
this.emit('pinInitialized', pinState);
}
}
} else if (parts[0] === 'CHANGE' && parts.length >= 4) {
// CHANGE:PIN:PREVIOUS_STATE:CURRENT_STATE format
const pin = parseInt(parts[1]);
const previousState = parseInt(parts[2]);
const currentState = parseInt(parts[3]);
if (!isNaN(pin) && !isNaN(previousState) && !isNaN(currentState)) {
const pinChange: PinChange = {
pin,
previousState,
currentState,
timestamp: new Date()
};
// Update stored pin state
const pinState: PinState = {
pin,
state: currentState,
name: `PIN${pin}`,
timestamp: new Date()
};
this.pinStates.set(pin, pinState);
this.emit('pinChanged', pinChange);
this.emit(`pin${pin}Changed`, pinChange);
}
}
}
getPinState(pin: number): PinState | undefined {
return this.pinStates.get(pin);
}
getAllPinStates(): PinState[] {
return Array.from(this.pinStates.values());
}
isConnected(): boolean {
return this.connectionState && this.serialPort?.isOpen === true;
}
// Static method to list available serial ports
static async listPorts(): Promise<string[]> {
const ports = await SerialPort.list();
return ports.map(port => port.path);
}
}