All files / modules / DMXDeviceMock.ts

100.00% Branches 5/5
100.00% Lines 29/29
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
 
 
 
 
 
 
x1
x1
x1
x1
x1
 
 
 
 
 
x1
 
x1
 
 
 
 
 
 
x1
x3
x3
 
 
 
 
 
 
 
x3
 
 
 
 
 
 
 
 
 
 
 
 
x1
 
x8
x11
x11
x11
x11
 
 
x12
x12
x12
x12
 
x8
x10
x10
x10
 
x10
 
x12
x8
x1






































































/**
 * DMX Device serial device mock
 *
 * @module
 */

import { Buffer } from "node:buffer";
import process from "node:process";
import { SerialPortMock, SerialPortMockOpenOptions } from "serialport";
import { DMX_CHANNEL_COUNT } from "../static/packet/lanes_initialize.js";
import { DMX_CHANNEL_MIN, DMX_CHANNEL_MAX } from "../static/packet/lane_modify.js";


/**
 * DMX Device serial device mock
 */
export class DMXDeviceMock extends SerialPortMock {
  /** As device internal memory of dmx values */
  #dmx_values: Uint8Array;

  /**
   * Initialize mock and internal memory
   *
   * @param options Options of serialport initialization
   */
  constructor(options: SerialPortMockOpenOptions) {
    super(options);
    this.#dmx_values = new Uint8Array(DMX_CHANNEL_COUNT);

    //// Non 0 internal values memory initializing - For values request test
    // this.#dmx_values[0] = 0;
    // this.#dmx_values[1] = 10;
    // this.#dmx_values[2] = 100;
    // this.#dmx_values[3] = 255;
    ////
  }

  /**
   * Emulate data sending
   *
   * SerialPort.write(chunk) actual declaration of `chunk` is `any` but it violates deno lint.
   * On this mock, consider only for using `Array` as data input.
   *
   * Note: It considers only for 3bytes data. `chunk` must be 3 length.
   *
   * @param chunk Data to emulate sending
   * @returns `false` if the stream wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`.
   */
  override write(chunk: Array<number>): boolean {
    // Values request packet processing
    if((chunk[0] & chunk[1] & chunk[2]) === 0xff) {
      process.stdout.write(`DMXDeviceMock - Values request \r`);
      this.port?.emitData(Buffer.from(this.#dmx_values));
      return super.write(chunk);
    }

    // Lane modify packet processing
    const channel = (chunk[1] << 8) | chunk[0];  // Read 2bytes as little endian
    const value = chunk[2];
    const channel_str = channel.toString().padStart(3, " ");
    const value_str = value.toString().padStart(3, " ");

    if(DMX_CHANNEL_MIN <= channel && channel <= DMX_CHANNEL_MAX) {
      process.stdout.write(`DMXDeviceMock - ch:${channel_str} val:${value_str} \r`);
      this.#dmx_values[channel] = value;
    }
    else
      process.stdout.write(`DMXDeviceMock - Invalid channel\r`);

    return super.write(chunk);
  }
}