Skip to content

Fix/rewrite data handling #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions companion/HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ Tally and connected messages recieved from the router will create new set crossp
### Version 2.0.5

- Parse variables with context object (for local variables)

### Version 2.0.6

- Reworked data processing
- Fixed issue with not getting labels if "Request supported commands" config option was disabled
- Fixed issue where labels were duplicated and in wrong order if router had labels on multiple levels
- Fixed initial label request (non-extended mode) to use the correct format according to specification
- Fixed issue where not all source labels were received, fixes issue #31
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "generic-swp08",
"version": "2.0.5",
"version": "2.0.6",
"main": "src/index.js",
"type": "module",
"scripts": {
Expand Down
76 changes: 38 additions & 38 deletions src/actions.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,93 @@
import { actionOptions } from './consts.js'

export async function UpdateActions(self) {
let actionDefinitions = []
const actionDefinitions = []

actionDefinitions['select_level'] = {
actionDefinitions.select_level = {
name: 'Select Levels',
options: [{ ...actionOptions.levels, choices: self.levels }],
callback: ({ options }) => {
self.processLevelsSelection(options.level, true)
},
}
actionDefinitions['deselect_level'] = {
actionDefinitions.deselect_level = {
name: 'De-Select Levels',
options: [{ ...actionOptions.levels, choices: self.levels }],
callback: ({ options }) => {
self.processLevelsSelection(options.level, false)
},
}
actionDefinitions['toggle_level'] = {
actionDefinitions.toggle_level = {
name: 'Toggle Levels',
options: [{ ...actionOptions.levels, choices: self.levels }],
callback: ({ options }) => {
self.processLevelsSelection(options.level, 'toggle')
},
}
actionDefinitions['select_dest'] = {
actionDefinitions.select_dest = {
name: 'Select Destination',
options: [actionOptions.destination],
callback: ({ options }) => {
self.selected_dest = parseInt(options.dest)
self.selected_dest = Number.parseInt(options.dest)
self.getCrosspoints(options.dest)
console.log('set destination ' + self.selected_dest)
console.log(`set destination ${self.selected_dest}`)
self.setVariableValues({ Destination: self.selected_dest })
self.checkFeedbacks('selected_dest', 'selected_level_dest', 'source_dest_route')
},
subscribe: (action) => {
self.getCrosspoints(action.options.dest)
},
}
actionDefinitions['select_dest_name'] = {
actionDefinitions.select_dest_name = {
name: 'Select Destination name',
options: [{ ...actionOptions.destinationName, choices: self.dest_names }],
callback: async ({ options }, context) => {
const dest = parseInt(await context.parseVariablesInString(options.dest))
if (isNaN(dest) || dest < 1 || dest > 65536) {
const dest = Number.parseInt(await context.parseVariablesInString(options.dest))
if (Number.isNaN(dest) || dest < 1 || dest > 65536) {
self.log('warn', `select_dest_name has been passed an out of range variable ${dest}`)
return undefined
}
self.selected_dest = dest
self.getCrosspoints(dest)
console.log('set destination ' + self.selected_dest)
console.log(`set destination ${self.selected_dest}`)
self.setVariableValues({ Destination: self.selected_dest })
self.checkFeedbacks('selected_dest', 'selected_level_dest', 'source_dest_route')
},
subscribe: async (action, context) => {
const dest = parseInt(await context.parseVariablesInString(action.options.dest))
if (isNaN(dest) || dest < 1 || dest > 65536) {
const dest = Number.parseInt(await context.parseVariablesInString(action.options.dest))
if (Number.isNaN(dest) || dest < 1 || dest > 65536) {
self.log('warn', `select_dest_name:Subscribe has been passed an out of range variable - dst ${dest}`)
return undefined
}
self.getCrosspoints(dest)
},
}
actionDefinitions['select_source'] = {
actionDefinitions.select_source = {
name: 'Select Source',
options: [actionOptions.source],
callback: ({ options }) => {
self.selected_source = parseInt(options.source)
console.log('set source ' + self.selected_source)
self.selected_source = Number.parseInt(options.source)
console.log(`set source ${self.selected_source}`)
self.setVariableValues({ Source: self.selected_source })
self.checkFeedbacks('selected_source')
},
}
actionDefinitions['select_source_name'] = {
actionDefinitions.select_source_name = {
name: 'Select Source name',
options: [{ ...actionOptions.sourceName, choices: self.source_names }],
options: [{ ...actionOptions.sourceName, choices: Array.from(self.source_names.values()) }],
callback: async ({ options }, context) => {
const source = parseInt(await context.parseVariablesInString(options.source))
if (isNaN(source) || source < 1 || source > 65536) {
const source = Number.parseInt(await context.parseVariablesInString(options.source))
if (Number.isNaN(source) || source < 1 || source > 65536) {
self.log('warn', `select_source_name has been passed an out of range variable ${source}`)
return undefined
}
self.selected_source = source
console.log('set source ' + self.selected_source)
console.log(`set source ${self.selected_source}`)
self.setVariableValues({ Source: self.selected_source })
self.checkFeedbacks('selected_source')
},
}
actionDefinitions['route_source'] = {
actionDefinitions.route_source = {
name: 'Route Source to selected Levels and Destination',
options: [actionOptions.source],
callback: ({ options }) => {
Expand All @@ -100,12 +100,12 @@ export async function UpdateActions(self) {
}
},
}
actionDefinitions['route_source_name'] = {
actionDefinitions.route_source_name = {
name: 'Route Source name to selected Levels and Destination',
options: [{ ...actionOptions.sourceName, choices: self.source_names }],
options: [{ ...actionOptions.sourceName, choices: Array.from(self.source_names.values()) }],
callback: async ({ options }, context) => {
const source = parseInt(await context.parseVariablesInString(options.source))
if (isNaN(source) || source < 1 || source > 65536) {
const source = Number.parseInt(await context.parseVariablesInString(options.source))
if (Number.isNaN(source) || source < 1 || source > 65536) {
self.log('warn', `route_source_name has been passed an out of range variable ${source}`)
return undefined
}
Expand All @@ -118,7 +118,7 @@ export async function UpdateActions(self) {
}
},
}
actionDefinitions['take'] = {
actionDefinitions.take = {
name: 'Take',
options: [],
callback: () => {
Expand All @@ -131,7 +131,7 @@ export async function UpdateActions(self) {
}
},
}
actionDefinitions['clear'] = {
actionDefinitions.clear = {
name: 'Clear',
options: [actionOptions.clear, actionOptions.clearEnableLevels],
callback: ({ options }) => {
Expand Down Expand Up @@ -159,35 +159,35 @@ export async function UpdateActions(self) {
}
},
}
actionDefinitions['set_crosspoint'] = {
actionDefinitions.set_crosspoint = {
name: 'Set crosspoint',
options: [{ ...actionOptions.levels, choices: self.levels }, actionOptions.source, actionOptions.destination],
callback: ({ options }) => {
for (let level_val of options.level) {
for (const level_val of options.level) {
self.SetCrosspoint(options.source, options.dest, level_val)
}
},
}
actionDefinitions['set_crosspoint_name'] = {
actionDefinitions.set_crosspoint_name = {
name: 'Set crosspoint by name',
options: [
{ ...actionOptions.levels, choices: self.levels },
{ ...actionOptions.sourceName, choices: self.source_names },
{ ...actionOptions.destinationName, choices: self.dest_names },
{ ...actionOptions.sourceName, choices: Array.from(self.source_names.values()) },
{ ...actionOptions.destinationName, choices: Array.from(self.dest_names.values()) },
],
callback: async ({ options }, context) => {
const source = parseInt(await context.parseVariablesInString(options.source))
const dest = parseInt(await context.parseVariablesInString(options.dest))
if (isNaN(source) || source < 1 || source > 65536 || isNaN(dest) || dest < 1 || dest > 65536) {
const source = Number.parseInt(await context.parseVariablesInString(options.source))
const dest = Number.parseInt(await context.parseVariablesInString(options.dest))
if (Number.isNaN(source) || source < 1 || source > 65536 || Number.isNaN(dest) || dest < 1 || dest > 65536) {
self.log('warn', `set_crosspoint_name has been passed an out of range variable - src ${source} : dst ${dest}`)
return undefined
}
for (let level_val of options.level) {
for (const level_val of options.level) {
self.SetCrosspoint(source, dest, level_val)
}
},
}
actionDefinitions['get_names'] = {
actionDefinitions.get_names = {
name: 'Refresh Source and Destination names',
options: [],
callback: () => {
Expand Down
70 changes: 27 additions & 43 deletions src/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { combineRgb } from '@companion-module/base'
export const msgDelay = 5
export const keepAliveTimeOut = 30000

export const DLE = '10'
export const STX = '02'
export const ETX = '03'
export const ACK = '06'
export const DLE = 0x10
export const STX = 0x02
export const ETX = 0x03
export const ACK = 0x06
export const NAK = 0x15

export const colours = {
white: combineRgb(255, 255, 255),
black: combineRgb(0, 0, 0),
Expand Down Expand Up @@ -130,43 +132,25 @@ export const presetDefaults = {
destCount: 256,
}

export const cmd = {
interrogate: '01',
connect: '02',
tally: '03',
connected: '04',
tallyDumpRequest: '21',
tallyDumpByteMessage: '22',
tallyDumpWordMessage: '23',
getSourceName: '64',
getDestName: '66',
connectOnGoGroupSalvo: '78',
goGroupSalvo: '79',
connectOnGoGroupSalvoAck: '7A',
goDoneGroupSalvoAck: '7B',
salvoGroupInterrogate: '7C',
groupSalvoTally: '7D',
extendedinterrogate: '81',
extendedConnect: '82',
extendedGetSourceName: 'E4',
extendedGetDestName: 'E6',
}

export const hexBytes = {
DLE: 0x10,
STX: 0x02,
ETX: 0x03,
ACK: 0x06,
NAK: 0x15,
cmd: {
tally: 0x03,
connected: 0x04,
extendedTally: 0x83,
extendedConnected: 0x84,
protocolImplementation: 0x62,
sourceNames: 0x6a,
destNames: 0x6b,
extendedSourceNames: 0xea,
extendedDestNames: 0xeb,
},
export const cmds = {
crosspointInterrogate: 0x01,
crosspointConnect: 0x02,
crosspointTally: 0x03,
crosspointConnected: 0x04,
getSourceNames: 0x64,
getDestNames: 0x66,
extendedInterrogate: 0x81,
extendedCrosspointConnect: 0x82,
extendedCrosspointTally: 0x83,
extendedCrosspointConnected: 0x84,
protocolImplementation: 0x61,
protocolImplementationResponse: 0x62,
allSourceNames: 0x64,
allDestNames: 0x66,
sourceNamesResponse: 0x6a,
destNamesResponse: 0x6b,
extendedGetSourceNames: 0xe4,
extendedGetDestNames: 0xe6,
extendedSourceNamesResponse: 0xea,
extendedDestNamesResponse: 0xeb,
}
Loading