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: WebSocket Client #369

Draft
wants to merge 34 commits into
base: release52
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
be244ed
feat: WebsocketTcpClient
olzzon Feb 20, 2025
dfb7036
feat: websockettcpclient move options to schema
olzzon Feb 21, 2025
c2afeeb
feat: websockettcpclient move actions to schema
olzzon Feb 21, 2025
6c64c86
feat: websockettcpclient add basic functionality to connection
olzzon Feb 21, 2025
e75b543
feat: inital test sketch for websocketTcpClient
olzzon Feb 24, 2025
8e65e45
feat: update of documentation and implementation of state and device …
olzzon Feb 24, 2025
0ec46a7
fix: typo in type Buffer
olzzon Feb 24, 2025
523ab60
fix: linting
olzzon Feb 24, 2025
75c6903
feat: update tsr types mock to include the websocketTcpClient
olzzon Feb 24, 2025
e51695c
feat: use sendCommand for better checks
olzzon Feb 25, 2025
251bb35
feat: websocketTcpClient test working basics
olzzon Feb 25, 2025
3633b3d
fix: use stringify instead of isEqual
olzzon Feb 25, 2025
a9a91da
fix: test of connection
olzzon Feb 25, 2025
565d9c7
fix: tcpmessage was not renamed from tcp command in schemas
olzzon Feb 25, 2025
d045fa3
fix: type name in timeline for tcp was still command
olzzon Feb 25, 2025
9f954d1
fix: generated websocketTcpClient types updated
olzzon Feb 25, 2025
b6e62e9
feat: update comment in test
olzzon Feb 25, 2025
46f333f
feat: connection status for websocketTcpClient
olzzon Feb 25, 2025
391623d
feat: websockettcpclient test connection status
olzzon Feb 25, 2025
973fa25
fix: add websocketTcpClient to services in tsr
olzzon Feb 26, 2025
ca4671a
fix: add websocketTcpClient to connection manager
olzzon Feb 26, 2025
6601ff3
fix: websocketTcpClient tests to use refactored init()
olzzon Feb 26, 2025
990c868
fix: remove encoding option as this is included in command
olzzon Feb 26, 2025
0b61576
feat: remove optional tcp in websocket connection
olzzon Feb 28, 2025
71c8bcd
fix: missing linting
olzzon Feb 28, 2025
e0d035a
fix: use undefined in initialization instead of !
olzzon Feb 28, 2025
02711c8
fix: websocketclient action type
olzzon Feb 28, 2025
bce3d1a
fix: websocketClient diffstates oldState could be undefined
olzzon Feb 28, 2025
a6d66a6
fix: websocketClient test should spy on function
olzzon Feb 28, 2025
b5fee17
fix: update comment with missing details
olzzon Feb 28, 2025
fc514a3
feat: websocketclient move buffer encoding to options
olzzon Feb 28, 2025
f877542
fix: websocketclient bufferEnc option should be optional
olzzon Feb 28, 2025
e420459
fix: websocketClient test - remove unused afterEach()
olzzon Feb 28, 2025
40dfc34
fix: websocketclient tests - reorder terminate spy
olzzon Feb 28, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ exports[`index imports 1`] = `
"TimelineContentTypeTriCaster",
"TimelineContentTypeVMix",
"TimelineContentTypeVizMSE",
"TimelineContentTypeWebSocketTcpClient",
"Transition",
"TranslationsBundleType",
"TransportStatus",
Expand All @@ -81,5 +82,6 @@ exports[`index imports 1`] = `
"ViscaOverIPActions",
"VizMSEActions",
"VmixActions",
"WebsocketTcpClientActions",
]
`;
6 changes: 6 additions & 0 deletions packages/timeline-state-resolver-types/src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
TriCasterOptions,
MultiOSCOptions,
ViscaOverIPOptions,
WebSocketTCPClientOptions,
} from '.'
import { DeviceCommonOptions } from './generated/common-options'

Expand Down Expand Up @@ -78,6 +79,7 @@ export type DeviceOptionsAny =
| DeviceOptionsTriCaster
| DeviceOptionsMultiOSC
| DeviceOptionsViscaOverIP
| DeviceOptionsWebSocketTcpClient

export interface DeviceOptionsAbstract extends DeviceOptionsBase<AbstractOptions> {
type: DeviceType.ABSTRACT
Expand Down Expand Up @@ -148,3 +150,7 @@ export interface DeviceOptionsMultiOSC extends DeviceOptionsBase<MultiOSCOptions
export interface DeviceOptionsViscaOverIP extends DeviceOptionsBase<ViscaOverIPOptions> {
type: DeviceType.VISCA_OVER_IP
}

export interface DeviceOptionsWebSocketTcpClient extends DeviceOptionsBase<WebSocketTCPClientOptions> {
type: DeviceType.WEBSOCKET_TCP_CLIENT
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ import { SomeMappingVizMSE } from './vizMSE'
export * from './vmix'
import { SomeMappingVmix } from './vmix'

export * from './websocketTcpClient'
import { SomeMappingWebsocketTcpClient } from './websocketTcpClient'

export type TSRMappingOptions =
| SomeMappingAbstract
| SomeMappingAtem
Expand All @@ -100,3 +103,4 @@ export type TSRMappingOptions =
| SomeMappingViscaOverIP
| SomeMappingVizMSE
| SomeMappingVmix
| SomeMappingWebsocketTcpClient
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* 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 WebSocketTCPClientOptions {
webSocket: {
/**
* URI to connect to, e.g. 'ws://localhost:8080'
*/
uri: string
/**
* Interval between reconnection attempts in milliseconds
*/
reconnectInterval?: number
[k: string]: unknown
}
tcp: {
/**
* Optional TCP server host to connect to, e.g. '127.0.0.1' - some devices may have a TCP connection too
*/
host: string
/**
* TCP server port to connect to
*/
port: number
[k: string]: unknown
}
}

export type SomeMappingWebsocketTcpClient = Record<string, never>

export interface SendWebSocketMessagePayload {
/**
* Message to send over WebSocket
*/
message: string
/**
* Optional queue ID for ordered message handling
*/
queueId?: string
}

export interface SendTcpMessagePayload {
/**
* Message to send over TCP
*/
message: string
/**
* Optional queue ID for ordered message handling
*/
queueId?: string
}

export enum WebsocketTcpClientActions {
Reconnect = 'reconnect',
ResetState = 'resetState',
SendWebSocketMessage = 'sendWebSocketMessage',
SendTcpMessage = 'sendTcpMessage'
}
export interface WebsocketTcpClientActionExecutionResults {
reconnect: () => void,
resetState: () => void,
sendWebSocketMessage: (payload: SendWebSocketMessagePayload) => void,
sendTcpMessage: (payload: SendTcpMessagePayload) => void
}
export type WebsocketTcpClientActionExecutionPayload<A extends keyof WebsocketTcpClientActionExecutionResults> = Parameters<
WebsocketTcpClientActionExecutionResults[A]
>[0]

export type WebsocketTcpClientActionExecutionResult<A extends keyof WebsocketTcpClientActionExecutionResults> =
ActionExecutionResult<ReturnType<WebsocketTcpClientActionExecutionResults[A]>>
4 changes: 4 additions & 0 deletions packages/timeline-state-resolver-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { TimelineContentSingularLiveAny } from './integrations/singularLive'
import { TimelineContentVMixAny } from './integrations/vmix'
import { TimelineContentOBSAny } from './integrations/obs'
import { TimelineContentTriCasterAny } from './integrations/tricaster'
import { TimelineContentWebSocketTcpClientAny } from './integrations/websocketTcpClient'

export * from './integrations/abstract'
export * from './integrations/atem'
Expand All @@ -46,6 +47,7 @@ export * from './integrations/tricaster'
export * from './integrations/telemetrics'
export * from './integrations/multiOsc'
export * from './integrations/viscaOverIP'
export * from './integrations/websocketTcpClient'

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

export interface TSRTimelineKeyframe<TContent> extends Omit<Timeline.TimelineKeyframe, 'content'> {
Expand Down Expand Up @@ -149,6 +152,7 @@ export type TSRTimelineContent =
| TimelineContentVIZMSEAny
| TimelineContentTelemetricsAny
| TimelineContentTriCasterAny
| TimelineContentWebSocketTcpClientAny

/**
* A simple key value store that can be referred to from the timeline objects
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { DeviceType } from '..'

export enum TimelineContentTypeWebSocketTcpClient {
WEBSOCKET_MESSAGE = 'websocketMessage',
TCP_MESSAGE = 'tcpMessage',
}

export interface TimelineContentWebSocketTcpClientBase {
deviceType: DeviceType.WEBSOCKET_TCP_CLIENT
type: TimelineContentTypeWebSocketTcpClient
}

export interface TimelineContentWebSocketMessage extends TimelineContentWebSocketTcpClientBase {
type: TimelineContentTypeWebSocketTcpClient.WEBSOCKET_MESSAGE
/** Stringified data to send over TCP */
message: string
/** If message contains stringified Base64 binary data or UTF-8 encoded string */
isBase64Encoded?: boolean
}

export interface TimelineContentTcpMessage extends TimelineContentWebSocketTcpClientBase {
type: TimelineContentTypeWebSocketTcpClient.TCP_MESSAGE
/** Stringified data to send over TCP */
message: string
/** If message contains stringified Base64 binary data or UTF-8 encoded string */
isBase64Encoded?: boolean
}

export type TimelineContentWebSocketTcpClientAny = TimelineContentWebSocketMessage | TimelineContentTcpMessage
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ exports[`index imports 1`] = `
"TimelineContentTypeTriCaster",
"TimelineContentTypeVMix",
"TimelineContentTypeVizMSE",
"TimelineContentTypeWebSocketTcpClient",
"Transition",
"TranslationsBundleType",
"TransportStatus",
Expand All @@ -95,6 +96,7 @@ exports[`index imports 1`] = `
"VizMSEActions",
"VizMSEDevice",
"VmixActions",
"WebsocketTcpClientActions",
"manifest",
]
`;
2 changes: 2 additions & 0 deletions packages/timeline-state-resolver/src/conductor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
DeviceOptionsViscaOverIP,
DeviceOptionsTriCaster,
DeviceOptionsSingularLive,
DeviceOptionsWebSocketTcpClient,
} from 'timeline-state-resolver-types'

import { DoOnTime } from './devices/doOnTime'
Expand Down Expand Up @@ -1218,6 +1219,7 @@ export type DeviceOptionsAnyInternal =
| DeviceOptionsTelemetrics
| DeviceOptionsTriCaster
| DeviceOptionsViscaOverIP
| DeviceOptionsWebSocketTcpClient

function removeParentFromState(
o: Timeline.TimelineState<TSRTimelineContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"$schema": "../../../$schemas/action-schema.json",
"actions": [
{
"id": "reconnect",
"name": "Reconnect device",
"destructive": true,
"timeout": 5000
},
{
"id": "resetState",
"name": "Reset state",
"destructive": true,
"timeout": 5000
},
{
"id": "sendWebSocketMessage",
"name": "Send WebSocket message",
"destructive": false,
"timeout": 5000,
"payload": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Message to send over WebSocket"
},
"queueId": {
"type": "string",
"description": "Optional queue ID for ordered message handling"
}
},
"required": ["message"],
"additionalProperties": false
}
},
{
"id": "sendTcpMessage",
"name": "Send TCP Message",
"destructive": false,
"timeout": 5000,
"payload": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Message to send over TCP"
},
"queueId": {
"type": "string",
"description": "Optional queue ID for ordered message handling"
}
},
"required": ["message"],
"additionalProperties": false
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "WebSocket & TCP Client Options",
"type": "object",
"properties": {
"webSocket": {
"type": "object",
"properties": {
"uri": {
"type": "string",
"ui:title": "WebSocket URI",
"ui:description": "URI to connect to, e.g. 'ws://localhost:8080'",
"description": "URI to connect to, e.g. 'ws://localhost:8080'"
},
"reconnectInterval": {
"type": "integer",
"ui:title": "Reconnect Interval",
"description": "Interval between reconnection attempts in milliseconds",
"default": 5000
}
},
"required": ["uri"]
},
"tcp": {
"type": "object",
"properties": {
"host": {
"type": "string",
"ui:title": "Optional - TCP Host",
"description": "Optional TCP server host to connect to, e.g. '127.0.0.1' - some devices may have a TCP connection too"
},
"port": {
"type": "integer",
"ui:title": "TCP Port",
"description": "TCP server port to connect to"
}
},
"required": ["host", "port"]
}
},
"required": ["webSocket", "tcp"],
"additionalProperties": false
}
Loading
Loading