Skip to content
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

feat: implement VISCA over IP and Panasonic PTZ actions #340

Merged
merged 12 commits into from
Nov 28, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exports[`index imports 1`] = `
"EmberParameterType",
"FlyKeyDirection",
"FlyKeyKeyFrame",
"FocusMode",
"HttpMethod",
"HttpSendActions",
"HyperdeckActions",
Expand All @@ -39,6 +40,7 @@ exports[`index imports 1`] = `
"MultiOSCDeviceType",
"OSCDeviceType",
"OSCValueType",
"PanasonicPTZActions",
"QuantelActions",
"QuantelControlMode",
"QuantelTransitionType",
Expand Down Expand Up @@ -76,6 +78,7 @@ exports[`index imports 1`] = `
"VMixInputType",
"VMixTransitionType",
"VideoFormat",
"ViscaOverIPActions",
"VizMSEActions",
"VmixActions",
]
Expand Down
5 changes: 5 additions & 0 deletions packages/timeline-state-resolver-types/src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
TelemetricsOptions,
TriCasterOptions,
MultiOSCOptions,
ViscaOverIPOptions,
} from '.'
import { DeviceCommonOptions } from './generated/common-options'

Expand Down Expand Up @@ -76,6 +77,7 @@ export type DeviceOptionsAny =
| DeviceOptionsTelemetrics
| DeviceOptionsTriCaster
| DeviceOptionsMultiOSC
| DeviceOptionsViscaOverIP

export interface DeviceOptionsAbstract extends DeviceOptionsBase<AbstractOptions> {
type: DeviceType.ABSTRACT
Expand Down Expand Up @@ -143,3 +145,6 @@ export interface DeviceOptionsTriCaster extends DeviceOptionsBase<TriCasterOptio
export interface DeviceOptionsMultiOSC extends DeviceOptionsBase<MultiOSCOptions> {
type: DeviceType.MULTI_OSC
}
export interface DeviceOptionsViscaOverIP extends DeviceOptionsBase<ViscaOverIPOptions> {
type: DeviceType.VISCA_OVER_IP
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run "yarn generate-schema-types" to regenerate this file.
*/


export interface SetPanTiltSpeedPayload {
/**
* Pan Speed; Range: [-1.0, 1.0]; -1.0 = fastest LEFT, 0.0 = STOP, 1.0 = fastest RIGHT (each protocol might internally support a different range, which the value will be mapped into)
*/
panSpeed: number
/**
* Tilt Speed; Range: [-1.0, 1.0]; -1.0 = fastest DOWN, 0.0 = STOP, 1.0 = fastest UP (each protocol might internally support a different range, which the value will be mapped into)
*/
tiltSpeed: number
}

export interface GetPanTiltPositionResult {
/**
* Pan Position; Range: [-1.0, 1.0]; -1.0 = furthest LEFT, 0.0 = CENTER, 1.0 = furthest RIGHT (each protocol might internally support a different range, which the value will be mapped from)
*/
panPosition: number
/**
* Tilt Position; Range: [-1.0, 1.0]; -1.0 = furthest DOWN, 0.0 = CENTER, 1.0 = furthest UP (each protocol might internally support a different range, which the value will be mapped from)
*/
tiltPosition: number
}

export interface SetZoomSpeedPayload {
/**
* Zoom Speed; Range: [-1.0, 1.0]; -1.0 = fastest WIDE, 0.0 = STOP, 1.0 = fastest TELE (each protocol might internally support a different range, which the value will be mapped into)
*/
zoomSpeed: number
}

export interface GetZoomPositionResult {
/**
* Zoom Position; Range: [0.0, 1.0]; 0.0 = furthest WIDE, 1.0 = furthest TELE (each protocol might internally support a different range, which the value will be mapped from)
*/
zoomPosition: number
}

export interface StorePresetPayload {
/**
* Preset number, within the range supported by the camera
*/
presetNumber: number
}

export interface RecallPresetPayload {
/**
* Preset number, within the range supported by the camera
*/
presetNumber: number
}

export interface ResetPresetPayload {
/**
* Preset number, within the range supported by the camera
*/
presetNumber: number
}

export interface SetFocusSpeedPayload {
/**
* Focus Speed; Range: [-1.0, 1.0]; -1.0 = fastest NEAR, 0.0 = STOP, 1.0 = fastest FAR (each protocol might internally support a different range, which the value will be mapped into)
*/
focusSpeed: number
}

export interface SetFocusModePayload {
mode: FocusMode
}

export enum FocusMode {
AUTO = 'auto',
MANUAL = 'manual'
}


export interface GetFocusPositionResult {
/**
* Zoom Position; Range: [0.0, 1.0]; 0.0 = furthest NEAR, 1.0 = furthest FAR (each protocol might internally support a different range, which the value will be mapped from)
*/
zoomPosition: number
}

export type FocusModeResult = FocusMode

export interface GetFocusModeResult {
mode: FocusModeResult
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

export * from './action-schema'
export * from './generic-ptz-actions'
export * from './abstract'
import { SomeMappingAbstract } from './abstract'

Expand Down Expand Up @@ -66,6 +67,9 @@ import { SomeMappingTelemetrics } from './telemetrics'
export * from './tricaster'
import { SomeMappingTricaster } from './tricaster'

export * from './viscaOverIP'
import { SomeMappingViscaOverIP } from './viscaOverIP'

export * from './vizMSE'
import { SomeMappingVizMSE } from './vizMSE'

Expand Down Expand Up @@ -93,5 +97,6 @@ export type TSRMappingOptions =
| SomeMappingTcpSend
| SomeMappingTelemetrics
| SomeMappingTricaster
| SomeMappingViscaOverIP
| SomeMappingVizMSE
| SomeMappingVmix
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run "yarn generate-schema-types" to regenerate this file.
*/
import { ActionExecutionResult } from ".."

export interface PanasonicPTZOptions {
host: string
Expand Down Expand Up @@ -35,3 +36,38 @@ export enum MappingPanasonicPTZType {
}

export type SomeMappingPanasonicPTZ = MappingPanasonicPTZPresetMem | MappingPanasonicPTZPresetSpeed | MappingPanasonicPTZZoomSpeed | MappingPanasonicPTZZoom

export enum PanasonicPTZActions {
SetPanTiltSpeed = 'setPanTiltSpeed',
GetPanTiltPosition = 'getPanTiltPosition',
SetZoomSpeed = 'setZoomSpeed',
GetZoomPosition = 'getZoomPosition',
StorePreset = 'storePreset',
RecallPreset = 'recallPreset',
ResetPreset = 'resetPreset',
SetFocusSpeed = 'setFocusSpeed',
SetFocusMode = 'setFocusMode',
TriggerOnePushFocus = 'triggerOnePushFocus',
GetFocusPosition = 'getFocusPosition',
GetFocusMode = 'getFocusMode'
}
export interface PanasonicPTZActionExecutionResults {
setPanTiltSpeed: () => void,
getPanTiltPosition: () => void,
setZoomSpeed: () => void,
getZoomPosition: () => void,
storePreset: () => void,
recallPreset: () => void,
resetPreset: () => void,
setFocusSpeed: () => void,
setFocusMode: () => void,
triggerOnePushFocus: () => void,
getFocusPosition: () => void,
getFocusMode: () => void
}
export type PanasonicPTZActionExecutionPayload<A extends keyof PanasonicPTZActionExecutionResults> = Parameters<
PanasonicPTZActionExecutionResults[A]
>[0]

export type PanasonicPTZActionExecutionResult<A extends keyof PanasonicPTZActionExecutionResults> =
ActionExecutionResult<ReturnType<PanasonicPTZActionExecutionResults[A]>>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run "yarn generate-schema-types" to regenerate this file.
*/
import { ActionExecutionResult } from ".."

export interface ViscaOverIPOptions {
host: string
port?: number
}

export type SomeMappingViscaOverIP = Record<string, never>

export enum ViscaOverIPActions {
SetPanTiltSpeed = 'setPanTiltSpeed',
GetPanTiltPosition = 'getPanTiltPosition',
SetZoomSpeed = 'setZoomSpeed',
GetZoomPosition = 'getZoomPosition',
StorePreset = 'storePreset',
RecallPreset = 'recallPreset',
ResetPreset = 'resetPreset',
SetFocusSpeed = 'setFocusSpeed',
SetFocusMode = 'setFocusMode',
TriggerOnePushFocus = 'triggerOnePushFocus',
GetFocusPosition = 'getFocusPosition',
GetFocusMode = 'getFocusMode'
}
export interface ViscaOverIPActionExecutionResults {
setPanTiltSpeed: () => void,
getPanTiltPosition: () => void,
setZoomSpeed: () => void,
getZoomPosition: () => void,
storePreset: () => void,
recallPreset: () => void,
resetPreset: () => void,
setFocusSpeed: () => void,
setFocusMode: () => void,
triggerOnePushFocus: () => void,
getFocusPosition: () => void,
getFocusMode: () => void
}
export type ViscaOverIPActionExecutionPayload<A extends keyof ViscaOverIPActionExecutionResults> = Parameters<
ViscaOverIPActionExecutionResults[A]
>[0]

export type ViscaOverIPActionExecutionResult<A extends keyof ViscaOverIPActionExecutionResults> =
ActionExecutionResult<ReturnType<ViscaOverIPActionExecutionResults[A]>>
2 changes: 2 additions & 0 deletions packages/timeline-state-resolver-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export * from './integrations/obs'
export * from './integrations/tricaster'
export * from './integrations/telemetrics'
export * from './integrations/multiOsc'
export * from './integrations/viscaOverIP'

export * from './device'
export * from './mapping'
Expand Down Expand Up @@ -86,6 +87,7 @@ export enum DeviceType {
TELEMETRICS = 'TELEMETRICS',
TRICASTER = 'TRICASTER',
MULTI_OSC = 'MULTI_OSC',
VISCA_OVER_IP = 'VISCA_OVER_IP',
}

export interface TSRTimelineKeyframe<TContent> extends Omit<Timeline.TimelineKeyframe, 'content'> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DeviceType } from '..'

export type TimelineContentViscaOverIpAny = TimelineContentViscaOverIp
export interface TimelineContentViscaOverIpBase {
deviceType: DeviceType.VISCA_OVER_IP
}

export type TimelineContentViscaOverIp = TimelineContentViscaOverIpBase
68 changes: 57 additions & 11 deletions packages/timeline-state-resolver/scripts/schema-types.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ const DEREFERENCED_SCHEMA_DIRECTORY = '$schemas/generated'

let hadError = false

const capitalise = (s) => {
if (!s) return s
const base = s.slice(0, 1).toUpperCase() + s.slice(1)

// replace `_a` with `A`
return base.replace(/_[a-z]/gi, (v) => {
return v.slice(1).toUpperCase()
})
}

const PrettierConf = JSON.parse(
await fs.readFile('../../node_modules/@sofie-automation/code-standard-preset/.prettierrc.json')
)
Expand All @@ -41,6 +51,51 @@ try {
hadError = true
}

// convert generic PTZ actions
try {
const actionsDescr = JSON.parse(await fs.readFile('./src/$schemas/generic-ptz-actions.json'))
const actionDefinitions = []
let output = ''
for (const action of actionsDescr.actions) {
let actionTypes = []
const actionDefinition = {
id: action.id,
payloadId: undefined,
resultId: undefined
}
actionDefinitions.push(actionDefinition)
// Payload:
if (action.payload) {
actionDefinition.payloadId = action.payload.id || capitalise(action.id + 'Payload')
actionTypes.push(await compile(action.payload, actionDefinition.payloadId, {
additionalProperties: false,
style: PrettierConf,
bannerComment: '',
enableConstEnums: false,
}))
}
// Return Data:
if (action.result) {
actionDefinition.resultId = action.result.id || capitalise(action.id + 'Result')
actionTypes.push(await compile(action.result, actionDefinition.resultId, {
additionalProperties: false,
style: PrettierConf,
bannerComment: '',
enableConstEnums: false,
}))
}
output += '\n' + actionTypes.join('\n')
}

await fs.writeFile(
'../timeline-state-resolver-types/src/generated/generic-ptz-actions.ts',
BANNER + '\n' + output
)
} catch (e) {
console.error('Error while generating common-options.json, continuing...')
console.error(e)
}

// convert common-options
try {
const commonOptionsDescr = JSON.parse(await fs.readFile('./src/$schemas/common-options.json'))
Expand Down Expand Up @@ -76,17 +131,7 @@ try {
hadError = true
}

const capitalise = (s) => {
if (!s) return s
const base = s.slice(0, 1).toUpperCase() + s.slice(1)

// replace `_a` with `A`
return base.replace(/_[a-z]/gi, (v) => {
return v.slice(1).toUpperCase()
})
}

let indexFile = BANNER + `\nexport * from './action-schema'`
let indexFile = BANNER + `\nexport * from './action-schema'\nexport * from './generic-ptz-actions'`
let baseMappingsTypes = []

// iterate over integrations
Expand Down Expand Up @@ -195,6 +240,7 @@ for (const dir of dirs) {
resultId: undefined
}
actionDefinitions.push(actionDefinition)
if (action.generic) continue


const actionTypes = []
Expand Down
Loading
Loading