Skip to content

Commit

Permalink
feat: atem micro panel support (requires companion 3.4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Feb 2, 2025
1 parent fdfacba commit cd5a034
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 10 deletions.
4 changes: 3 additions & 1 deletion openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,9 @@ components:
type: string
description: Plugin name of the surface
pluginComment:
type: string
type: array
items:
type: string
description: Comment about the plugin
required:
- pluginId
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"dev": "yarn workspace satellite dev",
"dev:electron": "yarn workspace satellite dev:electron",
"dev:webui": "yarn workspace webui dev",
"build:openapi": "openapi-typescript ./openapi.yaml -o ./satellite/src/generated/openapi.ts",
"build:openapi": "openapi-typescript ./openapi.yaml -o ./satellite/src/generated/openapi.ts",
"build": "yarn workspaces foreach --all run build",
"lint:raw": "eslint",
"lint": "eslint .",
Expand All @@ -45,6 +45,7 @@
"eslint-plugin-react-refresh": "^0.4.18",
"husky": "^9.1.7",
"lint-staged": "^15.4.3",
"openapi-typescript": "^7.6.1",
"prettier": "^3.4.2",
"tsx": "^4.19.2",
"typescript": "~5.7.3",
Expand All @@ -54,8 +55,5 @@
"engines": {
"node": "^20.14"
},
"packageManager": "[email protected]",
"dependencies": {
"openapi-typescript": "^7.6.1"
}
"packageManager": "[email protected]"
}
1 change: 1 addition & 0 deletions satellite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"node": "^20.14"
},
"dependencies": {
"@blackmagic-controller/node": "^0.1.1",
"@elgato-stream-deck/node": "^7.1.2",
"@julusian/bonjour-service": "^1.3.0-2",
"@julusian/image-rs": "^1.1.1",
Expand Down
47 changes: 46 additions & 1 deletion satellite/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export type CompanionSatelliteClientEvents = {
brightness: [{ deviceId: string; percent: number }]
newDevice: [{ deviceId: string }]
clearDeck: [{ deviceId: string }]
variableValue: [{ deviceId: string; name: string; value: string }]
deviceErrored: [{ deviceId: string; message: string }]
}

Expand Down Expand Up @@ -304,6 +305,9 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
case 'KEYS-CLEAR':
this.handleClear(params)
break
case 'VARIABLE-VALUE':
this.handleVariableValue(params)
break
case 'BRIGHTNESS':
this.handleBrightness(params)
break
Expand All @@ -319,6 +323,7 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
break
case 'KEY-PRESS':
case 'KEY-ROTATE':
case 'SET-VARIABLE-VALUE':
// Ignore
break
default:
Expand Down Expand Up @@ -379,6 +384,26 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli

this.emit('clearDeck', { deviceId: params.DEVICEID })
}
private handleVariableValue(params: Record<string, string | boolean>) {
if (typeof params.DEVICEID !== 'string') {
console.log('Mising DEVICEID in VARIABLE-VALUE response')
return
}
if (typeof params.VARIABLE !== 'string') {
console.log('Missing VARIABLE in VARIABLE-VALUE response')
return
}
if (typeof params.VALUE !== 'string') {
console.log('Missing VALUE in VARIABLE-VALUE response')
return
}

this.emit('variableValue', {
deviceId: params.DEVICEID,
name: params.VARIABLE,
value: Buffer.from(params.VALUE, 'base64').toString(),
})
}

private handleBrightness(params: Record<string, string | boolean>): void {
if (typeof params.DEVICEID !== 'string') {
Expand Down Expand Up @@ -429,6 +454,16 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
this.socket.write(`KEY-PRESS DEVICEID=${deviceId} KEY=${keyIndex} PRESSED=0\n`)
}
}
public keyDownXY(deviceId: string, x: number, y: number): void {
if (this._connected && this.socket) {
this.socket.write(`KEY-PRESS DEVICEID=${deviceId} KEY=${y}/${x} PRESSED=1\n`)
}
}
public keyUpXY(deviceId: string, x: number, y: number): void {
if (this._connected && this.socket) {
this.socket.write(`KEY-PRESS DEVICEID=${deviceId} KEY=${y}/${x} PRESSED=0\n`)
}
}
public rotateLeft(deviceId: string, keyIndex: number): void {
if (this._connected && this.socket) {
this.socket.write(`KEY-ROTATE DEVICEID=${deviceId} KEY=${keyIndex} DIRECTION=0\n`)
Expand All @@ -439,6 +474,14 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
this.socket.write(`KEY-ROTATE DEVICEID=${deviceId} KEY=${keyIndex} DIRECTION=1\n`)
}
}
public sendVariableValue(deviceId: string, variable: string, value: string): void {
if (this._connected && this.socket) {
const encodedValue = Buffer.from(value).toString('base64')
this.socket.write(
`SET-VARIABLE-VALUE DEVICEID=${deviceId} VARIABLE="${variable}" VALUE="${encodedValue}"\n`,
)
}
}

public addDevice(deviceId: string, productName: string, props: DeviceRegisterProps): void {
if (this._registeredDevices.has(deviceId)) {
Expand All @@ -453,12 +496,14 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
if (this._connected && this.socket) {
this._pendingDevices.set(deviceId, Date.now())

const transferVariables = Buffer.from(JSON.stringify(props.transferVariables ?? [])).toString('base64')

this.socket.write(
`ADD-DEVICE DEVICEID=${deviceId} PRODUCT_NAME="${productName}" KEYS_TOTAL=${
props.keysTotal
} KEYS_PER_ROW=${props.keysPerRow} BITMAPS=${
this._supportsBitmapResolution ? (props.bitmapSize ?? 0) : props.bitmapSize ? 1 : 0
} COLORS=${props.colours ? 1 : 0} TEXT=${props.text ? 1 : 0} BRIGHTNESS=${props.brightness ? 1 : 0}\n`,
} COLORS=${props.colours ? 1 : 0} TEXT=${props.text ? 1 : 0} VARIABLES=${transferVariables} BRIGHTNESS=${props.brightness ? 1 : 0}\n`,
)
}
}
Expand Down
23 changes: 22 additions & 1 deletion satellite/src/device-types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ export interface DeviceRegisterProps {
bitmapSize: number | null
colours: boolean
text: boolean
transferVariables?: Array<DeviceRegisterInputVariable | DeviceRegisterOutputVariable>
}

export interface DeviceRegisterInputVariable {
id: string
type: 'input'
name: string
description?: string
}
export interface DeviceRegisterOutputVariable {
id: string
type: 'output'
name: string
description?: string
}

export interface DiscoveredSurfaceInfo<T> {
Expand Down Expand Up @@ -50,7 +64,7 @@ export interface SurfacePluginDetection<TInfo> extends EventEmitter<SurfacePlugi
export interface SurfacePlugin<TInfo> {
readonly pluginId: string
readonly pluginName: string
readonly pluginComment?: string
readonly pluginComment?: string[]

/**
* Some plugins are forced to use a builtin detection mechanism by their surfaces or inner library
Expand Down Expand Up @@ -120,6 +134,8 @@ export interface WrappedSurface extends EventEmitter<WrappedSurfaceEvents> {

draw(data: DeviceDrawProps): Promise<void>

onVariableValue?(name: string, value: string): void

showStatus(hostname: string, status: string): void
}

Expand All @@ -142,6 +158,11 @@ export interface CompanionClient {
keyDown(deviceId: string, keyIndex: number): void
keyUp(deviceId: string, keyIndex: number): void

keyDownXY(deviceId: string, x: number, y: number): void
keyUpXY(deviceId: string, x: number, y: number): void

rotateLeft(deviceId: string, keyIndex: number): void
rotateRight(deviceId: string, keyIndex: number): void

sendVariableValue(deviceId: string, variable: string, value: any): void
}
Loading

0 comments on commit cd5a034

Please sign in to comment.