Skip to content

Commit

Permalink
Added deviceName and improved documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mkurczewski committed Dec 21, 2024
1 parent 55bf8d5 commit d0d1e22
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 10 deletions.
42 changes: 40 additions & 2 deletions libs/app-serialport/devices/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
# app-serialport-devices

This library was generated with [Nx](https://nx.dev).
This library contains SerialPort classes for devices supported by the Mudita Center application.

## Adding a new device

In order to add a new device, you need to:

1. Create a new class that extends the [`SerialPortDevice`](src/lib/serial-port-device.ts) class.
2. Add static properties `matchingVendorIds` and `matchingProductIds`. These properties should be arrays of strings containing the vendor and product IDs of the device.
3. Add a constructor accepting the object of [`SerialPortDeviceOptions`](src/lib/serial-port-device.ts) type that calls the parent constructor using `super` method:
- where the first argument is the SerialPort configuration object taken from the new class constructor,
- and the second argument is the SerialPort parser; for predefined parsers see the [SerialPort documentation](https://serialport.io/docs/api-parsers-overview).
4. Optionally, set the `requestIdKey` property to instruct the [`SerialPortDevice`](src/lib/serial-port-device.ts) class where to put a generated unique key used for identifying the requests.
The value can be a path as defined in the [\_set](https://lodash.com/docs/4.17.15#set) method from Lodash. If not set, it defaults to `"id"`.
5. Override the `parseRequest` method to properly parse the data being sent to the device.
6. Add the new class to the `devices` array in the [`devices.ts`](src/lib/devices.ts) file.

**Example:**

```typescript
// src/lib/new-device/serial-port-new-device.ts
export class SerialPortNewDevice extends SerialPortDevice {
static matchingVendorIds = ["abcd", "1234"]
static matchingProductIds = ["aabb", "aabc", "1234", "4567"]

constructor({ baudRate = 9600, ...options }: SerialPortDeviceOptions) {
super({ baudRate, ...options }, new ApiDeviceResponseParser({ matcher: /#\d{9}/g }))
this.requestIdKey = "rid"
}

parseRequest(data: ApiDeviceRequest) {
return JSON.stringify(data)
}
}
```

```typescript
// src/lib/devices.ts
export const devices = [SerialPortApiDevice, SerialPortNewDevice]
```

## Running unit tests

Run `nx test app-serialport-devices` to execute the unit tests via [Vitest](https://vitest.dev/).
Run `nx test app-serialport-devices` to execute the unit tests via Jest.
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import {
export class SerialPortApiDevice extends SerialPortDevice {
static matchingVendorIds = ["0e8d", "3725"]
static matchingProductIds = ["200a", "2006", "2012", "8198", "8202", "8210"]
static deviceType = "ApiDevice"

constructor({ baudRate = 9600, ...options }: SerialPortDeviceOptions) {
super(
{ baudRate, ...options },
new ApiDeviceResponseParser({ matcher: /#\d{9}/g })
)
this.idKey = "rid"
this.requestIdKey = "rid"
}

parseRequest(data: ApiDeviceRequest) {
Expand Down
19 changes: 12 additions & 7 deletions libs/app-serialport/devices/src/lib/serial-port-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SerialPort, SerialPortOpenOptions } from "serialport"
import { AutoDetectTypes } from "@serialport/bindings-cpp"
import { Transform } from "stream"
import { APIRequestData, APIResponseData } from "app-serialport/models"
import { uniqueId } from "lodash"
import { get, set, uniqueId } from "lodash"
import EventEmitter from "events"
import PQueue from "p-queue"

Expand All @@ -26,9 +26,10 @@ export type SerialPortDeviceOptions = Omit<
export class SerialPortDevice extends SerialPort {
private responseEmitter = new EventEmitter()
private queue: PQueue
matchingVendorIds: string[] = []
matchingProductIds: string[] = []
idKey = "id"
static deviceType = "unknown"
static matchingVendorIds: string[] = []
static matchingProductIds: string[] = []
requestIdKey = "id"

constructor(
{
Expand All @@ -45,8 +46,11 @@ export class SerialPortDevice extends SerialPort {
})
super.pipe(parser).on("data", (buffer: Buffer) => {
const data = JSON.parse(buffer.toString())
if (this.idKey in data) {
this.responseEmitter.emit(`response-${data[this.idKey]}`, data)
if (get(data, this.requestIdKey)) {
this.responseEmitter.emit(
`response-${get(data, this.requestIdKey)}`,
data
)
}
})
}
Expand Down Expand Up @@ -75,7 +79,8 @@ export class SerialPortDevice extends SerialPort {

return new Promise((resolve) => {
void this.queue.add(async () => {
this.write({ ...data, [this.idKey]: id })
const dataWithId = set({ ...data }, this.requestIdKey, id)
this.write(dataWithId)
const response = await this.listenForResponse(id)
resolve(response)
})
Expand Down
14 changes: 14 additions & 0 deletions libs/app-serialport/main/src/lib/app-serial-port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ export class AppSerialPort {
})

if (this.addedDevices.length > 0 || this.removedDevices.length > 0) {
this.currentDevices = this.currentDevices.map((device) => {
const SerialPortInstance = this.getDeviceSerialPortInstance(
device.path
) as typeof SerialPortDevice
return { ...device, deviceType: SerialPortInstance.deviceType }
})

this.addedDevices = this.addedDevices.map((device) => {
const SerialPortInstance = this.getDeviceSerialPortInstance(
device.path
) as typeof SerialPortDevice
return { ...device, deviceType: SerialPortInstance.deviceType }
})

this.eventEmitter.emit(SerialPortEvents.DevicesChanged, {
removed: this.removedDevices,
added: this.addedDevices,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { PortInfo } from "@serialport/bindings-interface"
export interface SerialPortDeviceInfo extends PortInfo {
productId: string
vendorId: string
deviceType: string
}

export interface SerialPortChangedDevices {
Expand Down

0 comments on commit d0d1e22

Please sign in to comment.