From defa62a13bea8750a90d85a331e282576aaeb720 Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 14:50:29 -0500 Subject: [PATCH 1/7] Apply auto-formatting --- .gitignore | 3 +++ ui/stage/stage-test.tsx | 20 ++++---------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index c386638..5eea39b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ dist !.yarn/releases !.yarn/sdks !.yarn/versions + +# python/pyenv +.python-version diff --git a/ui/stage/stage-test.tsx b/ui/stage/stage-test.tsx index a292002..979645d 100644 --- a/ui/stage/stage-test.tsx +++ b/ui/stage/stage-test.tsx @@ -1,23 +1,14 @@ import { useAtomValue, type Atom } from "jotai"; import { useEffect, useState } from "react"; -import type { - SMXPanelTestData, - SMXSensorTestData, -} from "../../sdk/commands/sensor_test"; +import type { SMXPanelTestData, SMXSensorTestData } from "../../sdk/commands/sensor_test"; import { requestTestData } from "../pad-coms"; import { FsrPanel } from "./fsr-panel"; import { SmxStage } from "../../sdk"; -import { - StageInputs, - type EachPanel, - type PanelName, -} from "../../sdk/commands/inputs"; +import { StageInputs, type EachPanel, type PanelName } from "../../sdk/commands/inputs"; import { HID_REPORT_INPUT_STATE } from "../../sdk/packet"; function useInputState(dev: HIDDevice | undefined) { - const [panelStates, setPanelStates] = useState< - EachPanel | undefined - >(); + const [panelStates, setPanelStates] = useState | undefined>(); useEffect(() => { if (!dev) return; function handleInputReport(e: HIDInputReportEvent) { @@ -67,10 +58,7 @@ export function StageTest({ return null; } - const entries = Object.entries(testData.panels) as [ - PanelName, - SMXPanelTestData - ][]; + const entries = Object.entries(testData.panels) as [PanelName, SMXPanelTestData][]; return (
From 748ecc8b78d5987e8f9f0fcab77f96ba20beba9a Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 16:14:12 -0500 Subject: [PATCH 2/7] Massive clean up of sensor_test.ts - Cleanup of logs, code, documentation - Use enums for Panel and Sensor array positions - Clamp/Scale sensor values based on mode --- sdk/api.ts | 22 ++++ sdk/commands/sensor_test.ts | 206 +++++++++++++++++++----------------- sdk/index.ts | 4 +- ui/stage/fsr-panel.tsx | 9 +- 4 files changed, 138 insertions(+), 103 deletions(-) diff --git a/sdk/api.ts b/sdk/api.ts index 10d318e..dc0c3d8 100644 --- a/sdk/api.ts +++ b/sdk/api.ts @@ -21,3 +21,25 @@ export const API_COMMAND = { export const SMX_USB_VENDOR_ID = 0x2341; export const SMX_USB_PRODUCT_ID = 0x8037; export const SMX_USB_PRODUCT_NAME = "StepManiaX"; + +export const PANEL_COUNT = 9; +export const SENSOR_COUNT = 4; + +export enum Panel { + UpLeft = 0, + Up = 1, + UpRight = 2, + Left = 3, + Center = 4, + Right = 5, + DownLeft = 6, + Down = 7, + DownRight = 8, +} + +export enum Sensor { + Left = 0, + Right = 1, + Up = 2, + Down = 3, +} diff --git a/sdk/commands/sensor_test.ts b/sdk/commands/sensor_test.ts index d1edcb7..4aec091 100644 --- a/sdk/commands/sensor_test.ts +++ b/sdk/commands/sensor_test.ts @@ -1,26 +1,37 @@ -import { StructBuffer, bitFields, bits, bool, int16_t, uint16_t, uint8_t } from "@nmann/struct-buffer"; -import { API_COMMAND, char2byte } from "../api"; +import { StructBuffer, bitFields, bits, int16_t, uint16_t, uint8_t } from "@nmann/struct-buffer"; +import { API_COMMAND, PANEL_COUNT, SENSOR_COUNT } from "../api"; import type { Decoded } from "./config"; -import type { EachPanel, EachSensor } from "./inputs"; /** * Sensor Test Mode values the stages expect */ -export const SENSOR_TEST_MODE = { +export enum SensorTestMode { /** Actual 0 value */ - OFF: 0, - - /** Return the raw uncalibrated value of each sensor */ - UNCALIBRATED_VALUES: char2byte("0"), - - /** Return the calibrated value of each sensor */ - CALIBRATED_VALUES: char2byte("1"), - - /** Return the sensor noise value */ - NOISE: char2byte("2"), - - /** Return the sensor tare value */ - TARE: char2byte("3"), + Off = 0, + + /** + * Return the raw uncalibrated value of each sensor. + * 48 represents the char "0" + **/ + UncalibratedValues = 48, + + /** + * Return the calibrated value of each sensor + * 49 represents the char "1" + **/ + CalibratedValues = 49, + + /** + * Return the sensor noise value + * 50 represents the char "2" + **/ + Noise = 50, + + /** + * Return the sensor tare value + * 51 represents the char "3" + **/ + Tare = 51, }; /** @@ -77,27 +88,12 @@ const detail_data_t = new StructBuffer("detail_data_t", { */ export class SMXPanelTestData { have_data_from_panel: boolean; - sensor_level: EachSensor = { - up: 0, - right: 0, - down: 0, - left: 0, - }; - bad_sensor_input: EachSensor = { - up: false, - right: false, - down: false, - left: false, - }; + sensor_level: Array = Array(SENSOR_COUNT).fill(-1); + bad_sensor_input: Array = Array(SENSOR_COUNT).fill(false); dip_switch_value = -1; - bad_jumper: EachSensor = { - up: false, - right: false, - down: false, - left: false, - }; - - constructor(data: Decoded) { + bad_jumper: Array = Array(SENSOR_COUNT).fill(false); + + constructor(data: Decoded, mode: SensorTestMode) { /** * Check the header. this is always `false true false` or `0 1 0` to identify it as a response, * and not as random steps from the player. @@ -107,6 +103,7 @@ export class SMXPanelTestData { return; } + // Assuming the sig bits are correct, we can confirm here that we have proper data this.have_data_from_panel = true; /** @@ -114,67 +111,105 @@ export class SMXPanelTestData { * A sensors reading could be considered invalid if the sensor has been turned * off in the config tool. */ - this.bad_sensor_input = { - up: data.sig_bad.bad_sensor_0, - right: data.sig_bad.bad_sensor_1, - down: data.sig_bad.bad_sensor_2, - left: data.sig_bad.bad_sensor_3, - }; + this.bad_sensor_input = [ + data.sig_bad.bad_sensor_0, + data.sig_bad.bad_sensor_1, + data.sig_bad.bad_sensor_2, + data.sig_bad.bad_sensor_3, + ]; // This is what the dipswitch is set to for this panel this.dip_switch_value = data.dips.dip; // These are true if the sensor has the incorrect jumper set - this.bad_jumper = { - up: !!data.dips.bad_sensor_dip_0, - right: !!data.dips.bad_sensor_dip_1, - down: !!data.dips.bad_sensor_dip_2, - left: !!data.dips.bad_sensor_dip_3, - }; + this.bad_jumper = [ + !!data.dips.bad_sensor_dip_0, + !!data.dips.bad_sensor_dip_1, + !!data.dips.bad_sensor_dip_2, + !!data.dips.bad_sensor_dip_3, + ]; /** * These are 16-bit signed integers for the sensor values. * These are signed as they can be negative, but I imagine them going * negative is just kind of noise from the hardware. */ - this.sensor_level = { - left: data.sensors[0], - right: data.sensors[1], - up: data.sensors[2], - down: data.sensors[3], - }; + this.sensor_level = data.sensors.map((value) => this.clamp_sensor_value(value, mode)); + } + + private clamp_sensor_value(value: number, mode: SensorTestMode) { + if (mode === SensorTestMode.Noise) { + /** + * In Noise mode, we receive standard deviation values squared. + * Display the square root, since the panels don't do this for us. + * This makes the number different than the configured value + * (square it to convert back), but without this we display a bunch + * of four and five digit numbers that are too hard to read. + * + * TODO: Do we want to round this value or just display decimal values? + */ + return Math.sqrt(value); + } + + // TODO: We need a way to pass in if the stage we are getting this data for + // is using FSRs or not. Defined as `true` for now. + const isFSR = true; + + // TODO: This may be necessary for defining sensor value vertial bars in the UI + // const max_value = isFSR ? 250 : 500; + + let clamped_value = value; + /** + * Very slightly negative values happen due to noise. + * The don't indicate a problem, but they're confusing + * in the UI, so clamp them away. + */ + if (value < 0 && value >= -10) { + clamped_value = 0; + } + + // FSR values are bitshifted right by 2 (effectively a div by 4). + if (isFSR) { + clamped_value >>= 2; + } + + return clamped_value; } } export class SMXSensorTestData { - panels: EachPanel; + panels: Array = []; constructor(data: Array) { /** + * The first 3 bytes are the preamble. + * * "y" is a response to our "y" query. This is binary data with the format: * yAB...... - * where A is our original query mode (currently "0", "1", "2", or "3"), and - * B is the number of bits from each panel in the response. - * Each bit is encoded as a 16-bit int, with each int having the response - * bits from each panel. + * where A (mode) is our original query mode (currently "0", "1", "2", or "3"), and + * B (size) is the number of 16-Bit Integers that contain all of our panel data. + * + * The explanation of how these bits are interlaced and decoded can be found + * in the README. + * + * TODO: Put in readme link here */ + const preamble = 3; console.assert(data[0] === API_COMMAND.GET_SENSOR_TEST_DATA); // Expected to be 'y' - // const mode = data[1]; // If we know what command we sent we could confirm we get the right response + // TODO: We need to somehow know what mode we requested, so we can potentially check + // here that we got the right response. + const mode = SensorTestMode[data[1] as unknown as keyof typeof SensorTestMode]; + console.assert(mode !== undefined); const size = data[2]; /** - * Convert the data from 8-Bit Little Endian bytes to 16-Bit Integers + * Convert the data from 8-Bit Little Endian Bytes to 16-Bit Integers */ - const sensor_data_t = new StructBuffer("sensor_data_t", { - data: uint16_t[size], - }); - const decoded_data = sensor_data_t.decode(data.slice(3), true); - const panel_count = 9; // TODO: This could be a const somewhere? - const panel_data = []; + const sensor_data_t = new StructBuffer("sensor_data_t", {data: uint16_t[size]}); + const decoded_data = sensor_data_t.decode(data.slice(preamble), true); // Cycle through each panel and grab the data - // TODO: Document exactly how we're dealing with the bits here and how things are layed out - for (let panel = 0; panel < panel_count; panel++) { + for (let panel = 0; panel < PANEL_COUNT; panel++) { let idx = 0; const out_bytes: Array = []; @@ -185,41 +220,18 @@ export class SMXSensorTestData { for (const _ of Array.from({ length: size / 8 })) { let result = 0; - // Read each bit in each byte + // Read each bit in each 8-bit byte for (let bit = 0; bit < 8; bit++, idx++) { const new_bit = decoded_data.data[idx] & (1 << panel); result |= new_bit << bit; } - // We need to shift the result by the panel to move it back to fit within - // an 8-bit byte + // We need to shift the result by the panel to move it back to fit within an 8-bit byte out_bytes.push(result >> panel); } - console.log(`Panel ${panel}: ${out_bytes}`); - panel_data.push(detail_data_t.decode(out_bytes, true)); + // Generate an SMXPanelTestData object for each panel + this.panels.push(new SMXPanelTestData(detail_data_t.decode(out_bytes, true), mode)); } - - const panels = []; - for (let panel = 0; panel < 9; panel++) { - panels.push(new SMXPanelTestData(panel_data[panel])); - } - - this.panels = { - up_left: panels[0], - up: panels[1], - up_right: panels[2], - left: panels[3], - center: panels[4], - right: panels[5], - down_left: panels[6], - down: panels[7], - down_right: panels[8], - }; - - console.log(decoded_data); - console.log(panel_data); - - console.log(this); } } diff --git a/sdk/index.ts b/sdk/index.ts index 55f9318..c502da6 100644 --- a/sdk/index.ts +++ b/sdk/index.ts @@ -2,7 +2,7 @@ import * as Bacon from "baconjs"; import type { StateF } from "baconjs/types/withstatemachine"; import { API_COMMAND } from "./api"; import { StageInputs } from "./commands/inputs"; -import { SENSOR_TEST_MODE } from "./commands/sensor_test"; +import { SensorTestMode } from "./commands/sensor_test"; import { HID_REPORT_INPUT, HID_REPORT_INPUT_STATE, @@ -25,7 +25,7 @@ export async function getStageConfig(dev: HIDDevice) { } export async function getSensorTestData(dev: HIDDevice) { - await send_data(dev, [API_COMMAND.GET_SENSOR_TEST_DATA, SENSOR_TEST_MODE.CALIBRATED_VALUES], true); + await send_data(dev, [API_COMMAND.GET_SENSOR_TEST_DATA, SensorTestMode.CalibratedValues], true); return process_packets(dev, true); } diff --git a/ui/stage/fsr-panel.tsx b/ui/stage/fsr-panel.tsx index 39013df..2637eab 100644 --- a/ui/stage/fsr-panel.tsx +++ b/ui/stage/fsr-panel.tsx @@ -1,5 +1,6 @@ import cn from "classnames"; import type { SMXPanelTestData } from "../../sdk/commands/sensor_test"; +import { Sensor } from "../../sdk/api"; interface EnabledProps { data: SMXPanelTestData; @@ -15,10 +16,10 @@ export function FsrPanel(props: EnabledProps) { active: props.active, })} > - - - - + + + +
); } From 702b25b21b60bf076ab947ff390cbd7d3bf58bc8 Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 16:35:01 -0500 Subject: [PATCH 3/7] Remove raw packet logging --- sdk/packet.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sdk/packet.ts b/sdk/packet.ts index 0f0e536..7e029ee 100644 --- a/sdk/packet.ts +++ b/sdk/packet.ts @@ -106,9 +106,6 @@ export async function send_data(dev: HIDDevice, data: Array, debug = fal // Send each packet for (const packet of packets) { - if (debug) { - console.log(packet); - } await dev.sendReport(HID_REPORT_OUTPUT, packet); } } @@ -124,10 +121,6 @@ export async function process_packets(dev: HIDDevice, debug = false): Promise): bool // Note that if PACKET_FLAG_HOST_CMD_FINISHED is set, PACKET_FLAG_END_OF_COMMAND will also be set if ((cmd & PACKET_FLAG_HOST_CMD_FINISHED) === PACKET_FLAG_HOST_CMD_FINISHED) { // This tells us that a command we wrote to the devide has finished executing, and it's safe to start writing another. - console.log("Packet Complete"); + // console.log("Packet Complete"); } if ((cmd & PACKET_FLAG_END_OF_COMMAND) === PACKET_FLAG_END_OF_COMMAND) { From d3d558896b1519ab4ee4b4d0a087e295e098ddcb Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 16:41:18 -0500 Subject: [PATCH 4/7] Fix data assumptions --- sdk/commands/sensor_test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sdk/commands/sensor_test.ts b/sdk/commands/sensor_test.ts index 4aec091..98cfbc4 100644 --- a/sdk/commands/sensor_test.ts +++ b/sdk/commands/sensor_test.ts @@ -195,12 +195,17 @@ export class SMXSensorTestData { * TODO: Put in readme link here */ const preamble = 3; - console.assert(data[0] === API_COMMAND.GET_SENSOR_TEST_DATA); // Expected to be 'y' + + // Expected to be 'y' + console.assert(data[0] === API_COMMAND.GET_SENSOR_TEST_DATA, `Unknown PanelTestData Response: ${data[0]}`); + // TODO: We need to somehow know what mode we requested, so we can potentially check // here that we got the right response. - const mode = SensorTestMode[data[1] as unknown as keyof typeof SensorTestMode]; - console.assert(mode !== undefined); + const mode = data[1]; + console.assert(SensorTestMode[mode] !== undefined, `Unknown SensorTestMode: ${mode}`); + const size = data[2]; + console.assert(size === 80, `Unknown PanelTestData Size: ${size}`); /** * Convert the data from 8-Bit Little Endian Bytes to 16-Bit Integers From 1f1a5a3e05dbfbdef29c1d3c1d3d4377909d5701 Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 16:46:47 -0500 Subject: [PATCH 5/7] Only try to read test data if it's actual test data --- ui/pad-coms.ts | 5 ++++- ui/stage/stage-test.tsx | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/pad-coms.ts b/ui/pad-coms.ts index bf48b31..8b41498 100644 --- a/ui/pad-coms.ts +++ b/ui/pad-coms.ts @@ -1,5 +1,5 @@ import { getDeviceInfo, getSensorTestData, getStageConfig } from "../sdk"; -import { SMX_USB_PRODUCT_ID, SMX_USB_VENDOR_ID } from "../sdk/api"; +import { API_COMMAND, SMX_USB_PRODUCT_ID, SMX_USB_VENDOR_ID } from "../sdk/api"; import { SMXConfig } from "../sdk/commands/config"; import { SMXDeviceInfo } from "../sdk/commands/data_info"; import { SMXSensorTestData } from "../sdk/commands/sensor_test"; @@ -75,6 +75,9 @@ export async function requestConfig(dev: HIDDevice) { export async function requestTestData(dev: HIDDevice) { const response = await getSensorTestData(dev); + if (response[0] !== API_COMMAND.GET_SENSOR_TEST_DATA) { + return null; + } return new SMXSensorTestData(response); } diff --git a/ui/stage/stage-test.tsx b/ui/stage/stage-test.tsx index 979645d..5c58d31 100644 --- a/ui/stage/stage-test.tsx +++ b/ui/stage/stage-test.tsx @@ -33,7 +33,9 @@ function useTestData(device: HIDDevice | undefined) { const d = device; async function update() { const data = await requestTestData(d); - setTestData(data); + if (data) { + setTestData(data); + } handle = requestAnimationFrame(update); } From 8f913451c3568bbdcfa85b91e8e4cec63014432d Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 2 Apr 2024 16:55:20 -0500 Subject: [PATCH 6/7] Applied linter --- sdk/commands/sensor_test.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sdk/commands/sensor_test.ts b/sdk/commands/sensor_test.ts index 98cfbc4..2836856 100644 --- a/sdk/commands/sensor_test.ts +++ b/sdk/commands/sensor_test.ts @@ -17,7 +17,7 @@ export enum SensorTestMode { /** * Return the calibrated value of each sensor - * 49 represents the char "1" + * 49 represents the char "1" **/ CalibratedValues = 49, @@ -32,7 +32,7 @@ export enum SensorTestMode { * 51 represents the char "3" **/ Tare = 51, -}; +} /** * The first byte of the test mode detail data contains @@ -145,8 +145,8 @@ export class SMXPanelTestData { * This makes the number different than the configured value * (square it to convert back), but without this we display a bunch * of four and five digit numbers that are too hard to read. - * - * TODO: Do we want to round this value or just display decimal values? + * + * TODO: Do we want to round this value or just display decimal values? */ return Math.sqrt(value); } @@ -183,15 +183,15 @@ export class SMXSensorTestData { constructor(data: Array) { /** * The first 3 bytes are the preamble. - * + * * "y" is a response to our "y" query. This is binary data with the format: * yAB...... * where A (mode) is our original query mode (currently "0", "1", "2", or "3"), and - * B (size) is the number of 16-Bit Integers that contain all of our panel data. - * + * B (size) is the number of 16-Bit Integers that contain all of our panel data. + * * The explanation of how these bits are interlaced and decoded can be found - * in the README. - * + * in the README. + * * TODO: Put in readme link here */ const preamble = 3; @@ -210,7 +210,7 @@ export class SMXSensorTestData { /** * Convert the data from 8-Bit Little Endian Bytes to 16-Bit Integers */ - const sensor_data_t = new StructBuffer("sensor_data_t", {data: uint16_t[size]}); + const sensor_data_t = new StructBuffer("sensor_data_t", { data: uint16_t[size] }); const decoded_data = sensor_data_t.decode(data.slice(preamble), true); // Cycle through each panel and grab the data From 64616ec3c142e6d259cfae627bd1d43810e7e21e Mon Sep 17 00:00:00 2001 From: Noah Manneschmidt Date: Tue, 2 Apr 2024 16:17:10 -0700 Subject: [PATCH 7/7] process_packets now only processes a given command --- sdk/index.ts | 22 ++++++++++++++++++---- sdk/packet.ts | 16 ++++++++++++++-- ui/pad-coms.ts | 24 ++++-------------------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/sdk/index.ts b/sdk/index.ts index c502da6..9fb09a0 100644 --- a/sdk/index.ts +++ b/sdk/index.ts @@ -2,7 +2,7 @@ import * as Bacon from "baconjs"; import type { StateF } from "baconjs/types/withstatemachine"; import { API_COMMAND } from "./api"; import { StageInputs } from "./commands/inputs"; -import { SensorTestMode } from "./commands/sensor_test"; +import { SMXSensorTestData, SensorTestMode } from "./commands/sensor_test"; import { HID_REPORT_INPUT, HID_REPORT_INPUT_STATE, @@ -13,20 +13,34 @@ import { process_packets, send_data, } from "./packet"; +import { SMXConfig } from "./commands/config"; +import { SMXDeviceInfo } from "./commands/data_info"; export async function getDeviceInfo(dev: HIDDevice) { await send_data(dev, [API_COMMAND.GET_DEVICE_INFO], true); - return process_packets(dev, true); + const packet = await process_packets(dev, API_COMMAND.GET_DEVICE_INFO, true); + return new SMXDeviceInfo(packet); } export async function getStageConfig(dev: HIDDevice) { await send_data(dev, [API_COMMAND.GET_CONFIG_V5], true); - return process_packets(dev, true); + const response = await process_packets(dev, API_COMMAND.GET_CONFIG_V5, true); + + const smxconfig = new SMXConfig(response); + + // Right now I just want to confirm that decoding and re-encoding gives back the same data + const encoded_config = smxconfig.encode(); + if (encoded_config) { + const buf = new Uint8Array(encoded_config.buffer); + console.log("Same Thing:", response.slice(2, -1).toString() === buf.toString()); + } + return smxconfig; } export async function getSensorTestData(dev: HIDDevice) { await send_data(dev, [API_COMMAND.GET_SENSOR_TEST_DATA, SensorTestMode.CalibratedValues], true); - return process_packets(dev, true); + const response = await process_packets(dev, API_COMMAND.GET_SENSOR_TEST_DATA, true); + return new SMXSensorTestData(response); } interface PacketHandlingState { diff --git a/sdk/packet.ts b/sdk/packet.ts index 7e029ee..88ee1f4 100644 --- a/sdk/packet.ts +++ b/sdk/packet.ts @@ -110,8 +110,10 @@ export async function send_data(dev: HIDDevice, data: Array, debug = fal } } -export async function process_packets(dev: HIDDevice, debug = false): Promise> { - const current_packet: Array = []; +export async function process_packets(dev: HIDDevice, responseType: number, debug = false): Promise> { + let current_packet: Array = []; + + let seenFirstPacket = false; while (true) { const data = await nextReportCommand(dev); @@ -124,6 +126,16 @@ export async function process_packets(dev: HIDDevice, debug = false): Promise { return { ...devices, @@ -62,23 +58,11 @@ export async function open_smx_device(dev: HIDDevice) { } export async function requestConfig(dev: HIDDevice) { - const response = await getStageConfig(dev); - const smxconfig = new SMXConfig(response); - - // Right now I just want to confirm that decoding and re-encoding gives back the same data - const encoded_config = smxconfig.encode(); - if (encoded_config) { - const buf = new Uint8Array(encoded_config.buffer); - console.log("Same Thing:", response.slice(2, -1).toString() === buf.toString()); - } + return getStageConfig(dev); } export async function requestTestData(dev: HIDDevice) { - const response = await getSensorTestData(dev); - if (response[0] !== API_COMMAND.GET_SENSOR_TEST_DATA) { - return null; - } - return new SMXSensorTestData(response); + return getSensorTestData(dev); } /** anything here will appear in the debug UI to dispatch at will */