mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 23:19:09 +00:00
feat: add change endpoint to ws (#618)
* feat: add change endpoint to ws
This commit is contained in:
@@ -3,7 +3,7 @@ import { LogOrigin, OSCSettings } from 'ontime-types';
|
|||||||
import { Server } from 'node-osc';
|
import { Server } from 'node-osc';
|
||||||
|
|
||||||
import { IAdapter } from './IAdapter.js';
|
import { IAdapter } from './IAdapter.js';
|
||||||
import { dispatchFromAdapter } from '../controllers/integrationController.js';
|
import { dispatchFromAdapter, type ChangeOptions } from '../controllers/integrationController.js';
|
||||||
import { logger } from '../classes/Logger.js';
|
import { logger } from '../classes/Logger.js';
|
||||||
|
|
||||||
export class OscServer implements IAdapter {
|
export class OscServer implements IAdapter {
|
||||||
@@ -36,12 +36,36 @@ export class OscServer implements IAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let transformedPayload: unknown = args;
|
||||||
|
// we need to transform the params for the change endpoint
|
||||||
|
// OSC: ontime/change/{eventID}/{propertyName} value
|
||||||
|
if (path === 'change') {
|
||||||
|
if (params.length < 2) {
|
||||||
|
logger.error(LogOrigin.Rx, 'OSC IN: No params provided for change');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args === undefined) {
|
||||||
|
logger.error(LogOrigin.Rx, 'OSC IN: No valid payload provided for change');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventId = params[0];
|
||||||
|
const property = params[1];
|
||||||
|
const value: string | number | boolean = args as string | number | boolean;
|
||||||
|
|
||||||
|
transformedPayload = {
|
||||||
|
eventId,
|
||||||
|
property,
|
||||||
|
value,
|
||||||
|
} satisfies ChangeOptions;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const reply = dispatchFromAdapter(
|
const reply = dispatchFromAdapter(
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
payload: args,
|
payload: transformedPayload,
|
||||||
params,
|
|
||||||
},
|
},
|
||||||
'osc',
|
'osc',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
import { LogOrigin } from 'ontime-types';
|
import { LogOrigin } from 'ontime-types';
|
||||||
|
|
||||||
import { WebSocket, WebSocketServer } from 'ws';
|
import { WebSocket, WebSocketServer } from 'ws';
|
||||||
|
import type { Server } from 'http';
|
||||||
|
|
||||||
import getRandomName from '../utils/getRandomName.js';
|
import getRandomName from '../utils/getRandomName.js';
|
||||||
import { IAdapter } from './IAdapter.js';
|
import { IAdapter } from './IAdapter.js';
|
||||||
@@ -43,7 +44,7 @@ export class SocketServer implements IAdapter {
|
|||||||
this.wss = null;
|
this.wss = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(server) {
|
init(server: Server) {
|
||||||
this.wss = new WebSocketServer({ path: '/ws', server });
|
this.wss = new WebSocketServer({ path: '/ws', server });
|
||||||
|
|
||||||
this.wss.on('connection', (ws) => {
|
this.wss.on('connection', (ws) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { LogOrigin, OSCSettings } from 'ontime-types';
|
|||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import expressStaticGzip from 'express-static-gzip';
|
import expressStaticGzip from 'express-static-gzip';
|
||||||
import http from 'http';
|
import http, { type Server } from 'http';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
|
||||||
// import utils
|
// import utils
|
||||||
@@ -107,8 +107,8 @@ enum OntimeStartOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let step = OntimeStartOrder.InitAssets;
|
let step = OntimeStartOrder.InitAssets;
|
||||||
let expressServer = null;
|
let expressServer: Server | null = null;
|
||||||
let oscServer = null;
|
let oscServer: OscServer | null = null;
|
||||||
|
|
||||||
const checkStart = (currentState: OntimeStartOrder) => {
|
const checkStart = (currentState: OntimeStartOrder) => {
|
||||||
if (step !== currentState) {
|
if (step !== currentState) {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { OntimeEvent } from 'ontime-types';
|
|
||||||
|
|
||||||
import { messageService } from '../services/message-service/MessageService.js';
|
import { messageService } from '../services/message-service/MessageService.js';
|
||||||
import { PlaybackService } from '../services/PlaybackService.js';
|
import { PlaybackService } from '../services/PlaybackService.js';
|
||||||
import { eventStore } from '../stores/EventStore.js';
|
import { eventStore } from '../stores/EventStore.js';
|
||||||
@@ -7,19 +5,23 @@ import { parse, updateEvent } from './integrationController.config.js';
|
|||||||
import { isKeyOfType } from 'ontime-types/src/utils/guards.js';
|
import { isKeyOfType } from 'ontime-types/src/utils/guards.js';
|
||||||
import { event } from '../models/eventsDefinition.js';
|
import { event } from '../models/eventsDefinition.js';
|
||||||
|
|
||||||
|
export type ChangeOptions = {
|
||||||
|
eventId: string;
|
||||||
|
property: string;
|
||||||
|
value: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
//TODO: re-throwing the error does not add any extra information or value
|
//TODO: re-throwing the error does not add any extra information or value
|
||||||
export function dispatchFromAdapter(
|
export function dispatchFromAdapter(
|
||||||
type: string,
|
type: string,
|
||||||
args: {
|
args: {
|
||||||
payload: unknown;
|
payload: unknown;
|
||||||
params?: Array<string>;
|
|
||||||
},
|
},
|
||||||
_source?: 'osc' | 'ws',
|
_source?: 'osc' | 'ws',
|
||||||
) {
|
) {
|
||||||
const payload = args.payload;
|
const payload = args.payload;
|
||||||
const typeComponents = type.toLowerCase().split('/');
|
const typeComponents = type.toLowerCase().split('/');
|
||||||
const mainType = typeComponents[0];
|
const mainType = typeComponents[0];
|
||||||
const params = args.params || [];
|
|
||||||
|
|
||||||
switch (mainType) {
|
switch (mainType) {
|
||||||
case 'test-ontime': {
|
case 'test-ontime': {
|
||||||
@@ -267,21 +269,14 @@ export function dispatchFromAdapter(
|
|||||||
return { topic: 'timer', payload: timer };
|
return { topic: 'timer', payload: timer };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ontime/change/{eventID}/{propertyName}
|
// WS: {type: 'change', payload: { eventId, property, value } }
|
||||||
case 'change': {
|
case 'change': {
|
||||||
if (params.length < 2) {
|
const { eventId, property, value } = payload as ChangeOptions;
|
||||||
throw new Error('Too few parameters, 3 expected');
|
if (!isKeyOfType(property, event)) {
|
||||||
|
throw new Error(`Cannot update unknown event property ${property}`);
|
||||||
}
|
}
|
||||||
if (payload === undefined) {
|
const parsedPayload = parse(property, value);
|
||||||
throw new Error('No payload found');
|
return updateEvent(eventId, property, parsedPayload);
|
||||||
}
|
|
||||||
const eventID = params[0];
|
|
||||||
const propertyName = params[1] as keyof OntimeEvent;
|
|
||||||
if (!isKeyOfType(propertyName, event)) {
|
|
||||||
throw new Error(`Cannot update unknown event property ${propertyName}`);
|
|
||||||
}
|
|
||||||
const parsedPayload = parse(propertyName, payload);
|
|
||||||
return updateEvent(eventID, propertyName, parsedPayload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
Reference in New Issue
Block a user