Skip to content

Commit 08dc25e

Browse files
committed
SOFIE-47 | add automatic configuration of peripheral devices if there is only 1 studio
1 parent b6af173 commit 08dc25e

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

meteor/server/api/__tests__/peripheralDevice.test.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import { EmptyPieceTimelineObjectsBlob } from '@sofie-automation/corelib/dist/dataModel/Piece'
99
import { literal, getRandomId, getRandomString } from '@sofie-automation/corelib/dist/lib'
1010
import { LogLevel } from '@sofie-automation/meteor-lib/dist/lib'
11-
import { protectString, ProtectedString } from '@sofie-automation/corelib/dist/protectedString'
11+
import { protectString, ProtectedString, unprotectString } from '@sofie-automation/corelib/dist/protectedString'
1212
import { getCurrentTime } from '../../lib/lib'
1313
import { waitUntil } from '../../../__mocks__/helpers/jest'
1414
import { setupDefaultStudioEnvironment, DefaultEnvironment } from '../../../__mocks__/helpers/database'
@@ -45,7 +45,9 @@ import {
4545
RundownPlaylists,
4646
Rundowns,
4747
Segments,
48+
Studios,
4849
} from '../../collections'
50+
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
4951
import { SupressLogMessages } from '../../../__mocks__/suppressLogging'
5052
import { JSONBlobStringify } from '@sofie-automation/shared-lib/dist/lib/JSONBlob'
5153
import { PeripheralDeviceCommand } from '@sofie-automation/corelib/dist/dataModel/PeripheralDeviceCommand'
@@ -165,6 +167,7 @@ describe('test peripheralDevice general API methods', () => {
165167
name: 'Earth',
166168
})
167169
})
170+
168171
beforeEach(async () => {
169172
QueueStudioJobSpy.mockReset()
170173
QueueStudioJobSpy.mockClear()
@@ -745,4 +748,50 @@ describe('test peripheralDevice general API methods', () => {
745748
})
746749
})
747750
})
751+
752+
describe('auto-assign devices', () => {
753+
beforeEach(async () => {
754+
env = await setupDefaultStudioEnvironment()
755+
})
756+
757+
test('initialize auto-assign to single studio', async () => {
758+
if (DEBUG) setLogLevel(LogLevel.DEBUG)
759+
760+
// Prepare a new device id, not present in the DB yet
761+
const newDeviceId = getRandomId()
762+
const token = getRandomString()
763+
const options: PeripheralDeviceInitOptions = {
764+
category: PeripheralDeviceCategory.PLAYOUT,
765+
type: PeripheralDeviceType.PLAYOUT,
766+
subType: 'test',
767+
name: 'autoAssignDevice',
768+
connectionId: 'testconn',
769+
configManifest: {
770+
deviceConfigSchema: JSONBlobStringify({}),
771+
subdeviceManifest: {},
772+
},
773+
documentationUrl: 'http://example.com',
774+
}
775+
776+
// Ensure it's not present yet
777+
expect(await PeripheralDevices.findOneAsync(newDeviceId)).toBeFalsy()
778+
779+
// Initialize the device
780+
await MeteorCall.peripheralDevice.initialize(newDeviceId, token, options)
781+
782+
// Ensure the device exists and is assigned to the only studio in the db
783+
const initDevice = (await PeripheralDevices.findOneAsync(newDeviceId)) as PeripheralDevice
784+
expect(initDevice).toBeTruthy()
785+
expect(initDevice.studioAndConfigId).toBeTruthy()
786+
expect(initDevice.studioAndConfigId!.studioId).toBe(env.studio._id)
787+
788+
// Ensure it is created in the "parent devices" mapping (deviceSettings)
789+
const studio = await Studios.findOneAsync(env.studio._id)
790+
const deviceSettings = applyAndValidateOverrides(studio!.peripheralDeviceSettings.deviceSettings).obj
791+
expect(deviceSettings[unprotectString(newDeviceId)]).toBeTruthy()
792+
793+
const playoutDevices = applyAndValidateOverrides(studio!.peripheralDeviceSettings.playoutDevices).obj
794+
expect(playoutDevices[unprotectString(newDeviceId)]).toBeFalsy()
795+
})
796+
})
748797
})

meteor/server/api/peripheralDevice.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ export namespace ServerPeripheralDeviceAPI {
166166

167167
documentationUrl: options.documentationUrl,
168168
})
169+
170+
// If there is only one Studio, assign the device to that studio.
171+
// Overall plan at the moment is to have only 1 studio per sofie instance in mid-term future
172+
await assignToStudioIfOnlyOnePresent(deviceId, options)
169173
}
170174
if (options.configManifest?.translations) {
171175
await upsertBundles(
@@ -175,6 +179,43 @@ export namespace ServerPeripheralDeviceAPI {
175179
}
176180
return deviceId
177181
}
182+
183+
async function assignToStudioIfOnlyOnePresent(deviceId: PeripheralDeviceId, options: PeripheralDeviceInitOptions) {
184+
if ((await Studios.countDocuments()) !== 1) {
185+
return
186+
}
187+
188+
const studio = await Studios.findOneAsync({})
189+
190+
if (!studio) {
191+
return
192+
}
193+
194+
const configId = unprotectString(deviceId)
195+
196+
await Studios.updateAsync(studio._id, {
197+
$push: {
198+
[`peripheralDeviceSettings.deviceSettings.overrides`]: {
199+
op: 'set',
200+
path: configId,
201+
value: {
202+
name: options.name,
203+
options: {},
204+
},
205+
},
206+
},
207+
})
208+
209+
await PeripheralDevices.updateAsync(deviceId, {
210+
$set: {
211+
studioAndConfigId: {
212+
configId,
213+
studioId: studio._id,
214+
},
215+
},
216+
})
217+
}
218+
178219
export async function unInitialize(
179220
context: MethodContext,
180221
deviceId: PeripheralDeviceId,

0 commit comments

Comments
 (0)