Skip to content

Commit

Permalink
feat: configure peripheral device settings from blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Dec 10, 2024
1 parent 6bb0393 commit f5cfbaf
Show file tree
Hide file tree
Showing 60 changed files with 1,135 additions and 507 deletions.
1 change: 1 addition & 0 deletions meteor/__mocks__/defaultCollectionObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function defaultStudio(_id: StudioId): DBStudio {
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
deviceSettings: wrapDefaultObject({}),
playoutDevices: wrapDefaultObject({}),
ingestDevices: wrapDefaultObject({}),
inputDevices: wrapDefaultObject({}),
Expand Down
3 changes: 1 addition & 2 deletions meteor/__mocks__/helpers/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ export async function setupMockPeripheralDevice(
_id: protectString('mockDevice' + dbI++),
name: 'mockDevice',
organizationId: null,
studioId: studio ? studio._id : undefined,
settings: {},
studioAndConfigId: studio ? { studioId: studio._id, configId: 'test' } : undefined,

category: category,
type: type,
Expand Down
1 change: 0 additions & 1 deletion meteor/server/__tests__/cronjobs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ describe('cronjobs', () => {
statusCode: StatusCode.GOOD,
},
token: '',
settings: {},
...props,
})

Expand Down
45 changes: 23 additions & 22 deletions meteor/server/api/__tests__/peripheralDevice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import { getCurrentTime } from '../../lib/lib'
import { waitUntil } from '../../../__mocks__/helpers/jest'
import { setupDefaultStudioEnvironment, DefaultEnvironment } from '../../../__mocks__/helpers/database'
import { setLogLevel } from '../../logging'
import {
IngestDeviceSettings,
IngestDeviceSecretSettings,
} from '@sofie-automation/corelib/dist/dataModel/PeripheralDeviceSettings/ingestDevice'
import { IngestDeviceSecretSettings } from '@sofie-automation/corelib/dist/dataModel/PeripheralDeviceSettings/ingestDevice'
import { MediaWorkFlow } from '@sofie-automation/shared-lib/dist/core/model/MediaWorkFlows'
import { MediaWorkFlowStep } from '@sofie-automation/shared-lib/dist/core/model/MediaWorkFlowSteps'
import { MediaManagerAPI } from '@sofie-automation/meteor-lib/dist/api/mediaManager'
Expand Down Expand Up @@ -412,7 +409,7 @@ describe('test peripheralDevice general API methods', () => {
expect(QueueStudioJobSpy).toHaveBeenNthCalledWith(
1,
StudioJobs.OnPlayoutPlaybackChanged,
device.studioId,
device.studioAndConfigId!.studioId,
literal<Parameters<StudioJobFunc[StudioJobs.OnPlayoutPlaybackChanged]>[0]>({
playlistId: rundownPlaylistID,
changes: [
Expand Down Expand Up @@ -474,7 +471,7 @@ describe('test peripheralDevice general API methods', () => {
expect(QueueStudioJobSpy).toHaveBeenNthCalledWith(
1,
StudioJobs.OnTimelineTriggerTime,
device.studioId,
device.studioAndConfigId!.studioId,
literal<OnTimelineTriggerTimeProps>({
results: timelineTriggerTimeResult,
})
Expand Down Expand Up @@ -556,7 +553,7 @@ describe('test peripheralDevice general API methods', () => {
expect((deviceWithSecretToken.secretSettings as IngestDeviceSecretSettings).accessToken).toBe(
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
)
expect((deviceWithSecretToken.settings as IngestDeviceSettings).secretAccessToken).toBe(true)
expect(deviceWithSecretToken.secretSettingsStatus?.accessToken).toBe(true)
})

test('uninitialize', async () => {
Expand Down Expand Up @@ -643,8 +640,10 @@ describe('test peripheralDevice general API methods', () => {
organizationId: null,
name: 'Mock Media Manager',
deviceName: 'Media Manager',
studioId: env.studio._id,
settings: {},
studioAndConfigId: {
studioId: env.studio._id,
configId: 'test',
},
category: PeripheralDeviceCategory.MEDIA_MANAGER,
configManifest: {
deviceConfigSchema: JSONBlobStringify({}),
Expand All @@ -670,7 +669,7 @@ describe('test peripheralDevice general API methods', () => {
deviceId: device._id,
priority: 1,
source: 'MockSource',
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
finished: false,
success: false,
})
Expand All @@ -682,7 +681,7 @@ describe('test peripheralDevice general API methods', () => {
deviceId: device._id,
priority: 2,
status: MediaManagerAPI.WorkStepStatus.IDLE,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
workFlowId: workFlowId,
})
await MediaWorkFlowSteps.insertAsync({
Expand All @@ -693,14 +692,14 @@ describe('test peripheralDevice general API methods', () => {
deviceId: device._id,
priority: 1,
status: MediaManagerAPI.WorkStepStatus.IDLE,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
workFlowId: workFlowId,
})
})
test('getMediaWorkFlowRevisions', async () => {
const workFlows = (
await MediaWorkFlows.findFetchAsync({
studioId: device.studioId,
studioId: device.studioAndConfigId!.studioId,
})
).map((wf) => ({
_id: wf._id,
Expand All @@ -714,7 +713,7 @@ describe('test peripheralDevice general API methods', () => {
test('getMediaWorkFlowStepRevisions', async () => {
const workFlowSteps = (
await MediaWorkFlowSteps.findFetchAsync({
studioId: device.studioId,
studioId: device.studioAndConfigId!.studioId,
})
).map((wf) => ({
_id: wf._id,
Expand Down Expand Up @@ -799,8 +798,10 @@ describe('test peripheralDevice general API methods', () => {
organizationId: null,
name: 'Mock Media Manager',
deviceName: 'Media Manager',
studioId: env.studio._id,
settings: {},
studioAndConfigId: {
studioId: env.studio._id,
configId: 'test',
},
category: PeripheralDeviceCategory.MEDIA_MANAGER,
configManifest: {
deviceConfigSchema: JSONBlobStringify({}),
Expand Down Expand Up @@ -834,7 +835,7 @@ describe('test peripheralDevice general API methods', () => {
mediaSize: 10,
mediaTime: 0,
objId: MOCK_OBJID,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
thumbSize: 0,
thumbTime: 0,
tinf: '',
Expand All @@ -843,7 +844,7 @@ describe('test peripheralDevice general API methods', () => {
test('getMediaObjectRevisions', async () => {
const mobjects = (
await MediaObjects.findFetchAsync({
studioId: device.studioId,
studioId: device.studioAndConfigId!.studioId,
})
).map((mo) => ({
_id: mo._id,
Expand All @@ -864,7 +865,7 @@ describe('test peripheralDevice general API methods', () => {
test('update', async () => {
const mo = (await MediaObjects.findOneAsync({
collectionId: MOCK_COLLECTION,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
})) as MediaObject
expect(mo).toBeTruthy()

Expand All @@ -882,14 +883,14 @@ describe('test peripheralDevice general API methods', () => {

const updateMo = await MediaObjects.findOneAsync({
collectionId: MOCK_COLLECTION,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
})
expect(updateMo).toMatchObject(newMo)
})
test('remove', async () => {
const mo = (await MediaObjects.findOneAsync({
collectionId: MOCK_COLLECTION,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
})) as MediaObject
expect(mo).toBeTruthy()

Expand All @@ -903,7 +904,7 @@ describe('test peripheralDevice general API methods', () => {

const updateMo = await MediaObjects.findOneAsync({
collectionId: MOCK_COLLECTION,
studioId: device.studioId!,
studioId: device.studioAndConfigId!.studioId,
})
expect(updateMo).toBeFalsy()
})
Expand Down
2 changes: 0 additions & 2 deletions meteor/server/api/__tests__/userActions/system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ describe('User Actions - Disable Peripheral SubDevice', () => {
env.studio,
{
organizationId,
settings: {},
configManifest: {
deviceConfigSchema: JSONBlobStringify({}), // unused
subdeviceManifest: {
Expand Down Expand Up @@ -165,7 +164,6 @@ describe('User Actions - Disable Peripheral SubDevice', () => {
env.studio,
{
organizationId: null,
settings: {},
configManifest: {
deviceConfigSchema: JSONBlobStringify({}), // unused
subdeviceManifest: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/api/deviceTriggers/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export async function receiveInputDeviceTrigger(
check(deviceId, String)
check(triggerId, String)

const studioId = peripheralDevice.studioId
const studioId = peripheralDevice.studioAndConfigId?.studioId
if (!studioId) throw new Meteor.Error(400, `Peripheral Device "${peripheralDevice._id}" not assigned to a studio`)

logger.debug(
Expand Down
41 changes: 21 additions & 20 deletions meteor/server/api/integration/expectedPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
PackageInfos,
} from '../../collections'
import { logger } from '../../logging'
import _ from 'underscore'

export namespace PackageManagerIntegration {
export async function updateExpectedPackageWorkStatuses(
Expand All @@ -58,7 +59,7 @@ export namespace PackageManagerIntegration {
type FromPackage = Omit<ExpectedPackageStatusAPI.WorkBaseInfoFromPackage, 'id'> & { id: ExpectedPackageId }

const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const bulkChanges: AnyBulkWriteOperation<ExpectedPackageWorkStatus>[] = []
Expand Down Expand Up @@ -150,11 +151,11 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)

await ExpectedPackageWorkStatuses.removeAsync({
$or: [
$or: _.compact([
{ deviceId: peripheralDevice._id },
// Since we only have one PM in a studio, we can remove everything in the studio:
{ studioId: peripheralDevice.studioId },
],
peripheralDevice.studioAndConfigId ? { studioId: peripheralDevice.studioAndConfigId.studioId } : null,
]),
})
}

Expand All @@ -177,10 +178,10 @@ export namespace PackageManagerIntegration {
)[]
): Promise<void> {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const studioId = peripheralDevice.studioId
const studioId = peripheralDevice.studioAndConfigId.studioId

const removedIds: PackageContainerPackageId[] = []
const ps: Promise<unknown>[] = []
Expand All @@ -189,7 +190,7 @@ export namespace PackageManagerIntegration {
check(change.packageId, String)

const id = getPackageContainerPackageId(
peripheralDevice.studioId,
peripheralDevice.studioAndConfigId.studioId,
change.containerId,
protectString(change.packageId)
)
Expand Down Expand Up @@ -245,11 +246,11 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)

await PackageContainerPackageStatuses.removeAsync({
$or: [
$or: _.compact([
{ deviceId: peripheralDevice._id },
// Since we only have one PM in a studio, we can remove everything in the studio:
{ studioId: peripheralDevice.studioId },
],
peripheralDevice.studioAndConfigId ? { studioId: peripheralDevice.studioAndConfigId.studioId } : null,
]),
})
}

Expand All @@ -270,17 +271,17 @@ export namespace PackageManagerIntegration {
)[]
): Promise<void> {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const studioId = peripheralDevice.studioId
const studioId = peripheralDevice.studioAndConfigId.studioId

const removedIds: PackageContainerId[] = []
const ps: Promise<unknown>[] = []
for (const change of changes) {
check(change.containerId, String)

const id = getPackageContainerId(peripheralDevice.studioId, change.containerId)
const id = getPackageContainerId(peripheralDevice.studioAndConfigId.studioId, change.containerId)

if (change.type === 'delete') {
removedIds.push(id)
Expand Down Expand Up @@ -332,11 +333,11 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)

await PackageContainerStatuses.removeAsync({
$or: [
$or: _.compact([
{ deviceId: peripheralDevice._id },
// Since we only have one PM in a studio, we can remove everything in the studio:
{ studioId: peripheralDevice.studioId },
],
peripheralDevice.studioAndConfigId ? { studioId: peripheralDevice.studioAndConfigId.studioId } : null,
]),
})
}

Expand All @@ -352,7 +353,7 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
check(packageIds, [String])
check(type, String)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const ids = packageIds.map((packageId) => getPackageInfoId(packageId, type))
Expand Down Expand Up @@ -386,7 +387,7 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
check(packageId, String)
check(type, String)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const id = getPackageInfoId(packageId, type)
Expand All @@ -398,7 +399,7 @@ export namespace PackageManagerIntegration {
expectedContentVersionHash: expectedContentVersionHash,
actualContentVersionHash: actualContentVersionHash,

studioId: peripheralDevice.studioId,
studioId: peripheralDevice.studioAndConfigId.studioId,

deviceId: peripheralDevice._id,

Expand All @@ -425,7 +426,7 @@ export namespace PackageManagerIntegration {
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, deviceToken, context)
check(packageId, String)
check(type, String)
if (!peripheralDevice.studioId)
if (!peripheralDevice.studioAndConfigId)
throw new Meteor.Error(400, 'Device "' + peripheralDevice._id + '" has no studio')

const id = getPackageInfoId(packageId, type)
Expand Down
Loading

0 comments on commit f5cfbaf

Please sign in to comment.