From c4ceaa427a63693b4a5593bbd7b71501dd933814 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 15 Mar 2025 12:11:28 -0500 Subject: [PATCH] add decoder for universe --- src/decoders/index.ts | 2 ++ src/decoders/lighting/spot.ts | 2 +- src/decoders/lighting/universe.ts | 41 +++++++++++++++++++++++++++++++ src/models.ts | 8 ++++++ tests/decode.test.js | 30 ++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/decoders/lighting/universe.ts diff --git a/src/decoders/index.ts b/src/decoders/index.ts index 0b1d7dd..e8fcb4a 100644 --- a/src/decoders/index.ts +++ b/src/decoders/index.ts @@ -1,5 +1,6 @@ import ChannelBlock from './lighting/channel-block'; import Spot from './lighting/spot'; +import Universe from './lighting/universe'; import CentroidAccelVelocity from './motion/centroid-accel-velocity'; import CentroidPosition from './motion/centroid-position'; import OrientationEuler from './motion/orientation-euler'; @@ -26,4 +27,5 @@ export const Decoders = { ZoneObject, Spot, ChannelBlock, + Universe, }; diff --git a/src/decoders/lighting/spot.ts b/src/decoders/lighting/spot.ts index 3d9c0d2..d522c9f 100644 --- a/src/decoders/lighting/spot.ts +++ b/src/decoders/lighting/spot.ts @@ -13,7 +13,7 @@ export default (bytes: Uint8Array, isLittleEndian: boolean = false): Spot => { const size = view.getUint16(dataOffset, isLittleEndian); dataOffset += 2; - if (size !== bytes.byteLength) { + if (size < bytes.byteLength) { throw new Error('Spot module size mismatch'); } const id = view.getUint16(dataOffset, isLittleEndian); diff --git a/src/decoders/lighting/universe.ts b/src/decoders/lighting/universe.ts new file mode 100644 index 0000000..ec9cc7b --- /dev/null +++ b/src/decoders/lighting/universe.ts @@ -0,0 +1,41 @@ +import { Decoders } from '..'; +import { Spot, Universe } from '../../models'; + +export default (bytes: Uint8Array, isLittleEndian: boolean = false): Universe => { + const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); + + let dataOffset = 0; + const type = view.getUint8(dataOffset); + dataOffset += 1; + if (type !== 0x09) { + throw new Error('Universe module must have a type of 0x09'); + } + + const size = view.getUint16(dataOffset, isLittleEndian); + dataOffset += 2; + if (size !== bytes.byteLength) { + throw new Error('Universe module size mismatch'); + } + const id = view.getUint16(dataOffset, isLittleEndian); + dataOffset += 2; + const numberOfSpots = view.getUint16(dataOffset, isLittleEndian); + dataOffset += 2; + + const spots: Spot[] = []; + let spotOffset = dataOffset; + + for (let index = 0; index < numberOfSpots; index++) { + const spotData = bytes.subarray(spotOffset); + console.log(spotData); + const spot = Decoders.Spot(spotData); + spots.push(spot); + spotOffset += spot.size; + } + return { + type, + size, + id, + numberOfSpots, + spots, + }; +}; diff --git a/src/models.ts b/src/models.ts index aaef772..dc55bde 100644 --- a/src/models.ts +++ b/src/models.ts @@ -115,6 +115,14 @@ export type ZoneObject = { name: string; }; +export type Universe = { + type: number; + size: number; + id: number; + numberOfSpots: number; + spots: Spot[]; +}; + export type Spot = { type: number; size: number; diff --git a/tests/decode.test.js b/tests/decode.test.js index 72fed4c..6104c4d 100644 --- a/tests/decode.test.js +++ b/tests/decode.test.js @@ -251,6 +251,36 @@ const goodTests = [ }, decoder: Decoders.RTTrPM, }, + { + description: 'Universe + Spot + Single Channel Block', + bytes: new Uint8Array([ + 0x09, 0x00, 0x15, 0x12, 0x34, 0x00, 0x01, 0x0a, 0x00, 0x0e, 0x12, 0x34, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x06, 0x40, + ]), + expected: { + type: 0x09, + size: 21, + id: 0x1234, + numberOfSpots: 1, + spots: [ + { + type: 0x0a, + size: 14, + id: 0x1234, + offset: 1, + numberOfChannelBlocks: 1, + channelBlocks: [ + { + offset: 0x08, + fade: 0x06, + value: 0x40, + }, + ], + }, + ], + }, + decoder: Decoders.Universe, + }, { description: 'Spot + Single Channel Block', bytes: new Uint8Array([0x0a, 0x00, 0x0e, 0x12, 0x34, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, 0x06, 0x40]),