Skip to content

Cues

ActionCue

Bases: Cue

A cue that represents an action to be performed on a target object.

This cue is used to trigger actions on other objects in the system, such as playing, pausing, or stopping media cues.

Source code in src/cuemsutils/cues/ActionCue.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class ActionCue(Cue):
    """A cue that represents an action to be performed on a target object.

    This cue is used to trigger actions on other objects in the system, such as
    playing, pausing, or stopping media cues.
    """

    def __init__(self, init_dict: dict = None):
        """Initialize an ActionCue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If not provided, default values from REQ_ITEMS will be used.

        Raises:
            ValueError: If init_dict explicitly sets action_target to None.
        """
        self._initialized = False
        if init_dict:
            if 'action_target' in init_dict and init_dict['action_target'] is None:
                raise ValueError('action_target is required')
            init_dict = ensure_items(init_dict, REQ_ITEMS)
        else:
            init_dict = REQ_ITEMS
        super().__init__(init_dict)
        self._initialized = True
        self._action_target_object = None

    def get_action_target(self):
        """Get the target object for the action.

        Returns:
            The target object identifier.
        """
        return super().__getitem__('action_target')

    def set_action_target(self, action_target: str) -> None:
        """Set the target object for the action.

        Args:
            action_target: The target object identifier.

        Raises:
            ValueError: If action_target is None after initialisation is complete.
        """
        if getattr(self, '_initialized', False) and action_target is None:
            raise ValueError('action_target is required')
        super().__setitem__('action_target', action_target)

    action_target = property(get_action_target, set_action_target)

    def get_action_type(self) -> str:
        """Get the type of action to perform.

        Returns:
            str: The action type (e.g., 'play', 'pause', 'stop').
        """
        return super().__getitem__('action_type')

    def set_action_type(self, action_type: str) -> None:
        """Set the type of action to perform.

        Args:
            action_type (str): The action type (e.g., 'play', 'pause', 'stop').
        """
        super().__setitem__('action_type', action_type)

    action_type = property(get_action_type, set_action_type)

    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items, with required items sorted first.
        """
        x = dict(super().items())
        for k in sorted(REQ_ITEMS.keys()):
            x[k] = self[k]
        return x.items()

__init__(init_dict=None)

Initialize an ActionCue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If not provided, default values from REQ_ITEMS will be used.

None

Raises:

Type Description
ValueError

If init_dict explicitly sets action_target to None.

Source code in src/cuemsutils/cues/ActionCue.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def __init__(self, init_dict: dict = None):
    """Initialize an ActionCue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If not provided, default values from REQ_ITEMS will be used.

    Raises:
        ValueError: If init_dict explicitly sets action_target to None.
    """
    self._initialized = False
    if init_dict:
        if 'action_target' in init_dict and init_dict['action_target'] is None:
            raise ValueError('action_target is required')
        init_dict = ensure_items(init_dict, REQ_ITEMS)
    else:
        init_dict = REQ_ITEMS
    super().__init__(init_dict)
    self._initialized = True
    self._action_target_object = None

get_action_target()

Get the target object for the action.

Returns:

Type Description

The target object identifier.

Source code in src/cuemsutils/cues/ActionCue.py
37
38
39
40
41
42
43
def get_action_target(self):
    """Get the target object for the action.

    Returns:
        The target object identifier.
    """
    return super().__getitem__('action_target')

get_action_type()

Get the type of action to perform.

Returns:

Name Type Description
str str

The action type (e.g., 'play', 'pause', 'stop').

Source code in src/cuemsutils/cues/ActionCue.py
60
61
62
63
64
65
66
def get_action_type(self) -> str:
    """Get the type of action to perform.

    Returns:
        str: The action type (e.g., 'play', 'pause', 'stop').
    """
    return super().__getitem__('action_type')

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items, with required items sorted first.

Source code in src/cuemsutils/cues/ActionCue.py
78
79
80
81
82
83
84
85
86
87
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items, with required items sorted first.
    """
    x = dict(super().items())
    for k in sorted(REQ_ITEMS.keys()):
        x[k] = self[k]
    return x.items()

set_action_target(action_target)

Set the target object for the action.

Parameters:

Name Type Description Default
action_target str

The target object identifier.

required

Raises:

Type Description
ValueError

If action_target is None after initialisation is complete.

Source code in src/cuemsutils/cues/ActionCue.py
45
46
47
48
49
50
51
52
53
54
55
56
def set_action_target(self, action_target: str) -> None:
    """Set the target object for the action.

    Args:
        action_target: The target object identifier.

    Raises:
        ValueError: If action_target is None after initialisation is complete.
    """
    if getattr(self, '_initialized', False) and action_target is None:
        raise ValueError('action_target is required')
    super().__setitem__('action_target', action_target)

set_action_type(action_type)

Set the type of action to perform.

Parameters:

Name Type Description Default
action_type str

The action type (e.g., 'play', 'pause', 'stop').

required
Source code in src/cuemsutils/cues/ActionCue.py
68
69
70
71
72
73
74
def set_action_type(self, action_type: str) -> None:
    """Set the type of action to perform.

    Args:
        action_type (str): The action type (e.g., 'play', 'pause', 'stop').
    """
    super().__setitem__('action_type', action_type)

AudioCue

Bases: MediaCue

A cue for handling audio playback and control.

This class extends MediaCue to provide specific functionality for audio playback, including volume control and OSC communication for audio routing.

Source code in src/cuemsutils/cues/AudioCue.py
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
class AudioCue(MediaCue):
    """A cue for handling audio playback and control.

    This class extends MediaCue to provide specific functionality for audio playback,
    including volume control and OSC communication for audio routing.
    """

    def __init__(self, init_dict = None):
        """Initialize an AudioCue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if not init_dict:
            init_dict = REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
        super().__init__(init_dict)

        self._player = None
        self._osc_route = None

    def get_master_vol(self):
        """Get the master volume level.

        Returns:
            float: The master volume level.
        """
        return super().__getitem__('master_vol')

    def set_master_vol(self, master_vol):
        """Set the master volume level.

        Args:
            master_vol (float): The new master volume level.
        """
        super().__setitem__('master_vol', master_vol)

    master_vol = property(get_master_vol, set_master_vol)

    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items, with required items sorted first.
        """
        x = dict(super().items())
        for k in sorted(REQ_ITEMS.keys()):
            x[k] = self[k]
        return x.items()

    def player(self, player):
        """Set the audio player instance.

        Args:
            player: The audio player instance to use.
        """
        self._player = player

    def osc_route(self, osc_route):
        """Set the OSC route for audio control.

        Args:
            osc_route (str): The OSC route to use for audio control.
        """
        self._osc_route = osc_route

    @deprecated(
        reason="Use loop_cue from CueHandler instead",
        version="0.0.9rc5"
    )
    @logged
    def audio_media_loop(self, ossia, mtc):
        """Handle the audio media playback loop.

        This method manages the playback loop for audio media, including handling
        looping behavior and OSC communication for timing control.

        Args:
            ossia: The OSC communication interface.
            mtc: The MIDI Time Code interface.
        """
        try:
            loop_counter = 0
            duration = self.media.regions[0].out_time - self.media.regions[0].in_time

            while not self.media.regions[0].loop or loop_counter < self.media.regions[0].loop:
                while self._player.is_alive() and (mtc.main_tc.milliseconds_rounded < self._end_mtc.milliseconds_rounded):
                    sleep(0.005)

                if self._local:
                    # Recalculate offset and apply
                    self._end_mtc = self._start_mtc + (duration)
                    offset_to_go = -self._start_mtc.milliseconds_exact + self.media.regions[0].in_time.milliseconds_exact
                    try:
                        key = f'{self._osc_route}/offset'
                        ossia.send_message(key, offset_to_go)
                    except KeyError:
                        Logger.debug(
                            f'Key error 3 in go_callback {key}',
                            extra = {"caller": self.__class__.__name__}
                        )

                loop_counter += 1

            if self._local:                
                try:
                    key = f'{self._osc_route}/mtcfollow'
                    ossia.send_message(key, 0)
                except KeyError:
                    Logger.debug(
                        f'Key error 4 in go_callback {key}',
                        extra = {"caller": self.__class__.__name__}
                    )

        except AttributeError:
            pass

    def stop(self):
        """Stop the audio playback.

        This method stops the audio player and sets the stop request flag.
        """
        self._stop_requested = True
        if self._player and self._player.is_alive():
            self._player.kill()

    def check_mappings(self, settings):
        """Check if the audio output mappings are valid.

        Args:
            settings: The settings containing project node mappings.

        Returns:
            bool: True if the mappings are valid, False otherwise.
        """
        return super().check_mappings()

        if not settings.project_node_mappings:
            return True

        found = True
        map_list = ['default']

        Logger.debug(f'AudioCue check_mappings: {settings.project_node_mappings}')
        if settings.project_node_mappings['audio'][0]['outputs']:
            for elem in settings.project_node_mappings['audio'][0]['outputs']:
                Logger.debug(f'AudioCue elem: {elem}')
                elem = elem['output']
                for map in elem['mappings']:
                    Logger.debug(f'AudioCue map: {map}')
                    map_list.append(map['mapped_to'])

        for output in self.outputs:
            if output['output_name'][:36] == settings.node_conf['uuid']:
                    self._local = True
                    if output['output_name'][37:] not in map_list:
                        found = False
                        break
            else:
                self._local = False
                found = True

        return found

__init__(init_dict=None)

Initialize an AudioCue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/AudioCue.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def __init__(self, init_dict = None):
    """Initialize an AudioCue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if not init_dict:
        init_dict = REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
    super().__init__(init_dict)

    self._player = None
    self._osc_route = None

audio_media_loop(ossia, mtc)

Handle the audio media playback loop.

This method manages the playback loop for audio media, including handling looping behavior and OSC communication for timing control.

Parameters:

Name Type Description Default
ossia

The OSC communication interface.

required
mtc

The MIDI Time Code interface.

required
Source code in src/cuemsutils/cues/AudioCue.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@deprecated(
    reason="Use loop_cue from CueHandler instead",
    version="0.0.9rc5"
)
@logged
def audio_media_loop(self, ossia, mtc):
    """Handle the audio media playback loop.

    This method manages the playback loop for audio media, including handling
    looping behavior and OSC communication for timing control.

    Args:
        ossia: The OSC communication interface.
        mtc: The MIDI Time Code interface.
    """
    try:
        loop_counter = 0
        duration = self.media.regions[0].out_time - self.media.regions[0].in_time

        while not self.media.regions[0].loop or loop_counter < self.media.regions[0].loop:
            while self._player.is_alive() and (mtc.main_tc.milliseconds_rounded < self._end_mtc.milliseconds_rounded):
                sleep(0.005)

            if self._local:
                # Recalculate offset and apply
                self._end_mtc = self._start_mtc + (duration)
                offset_to_go = -self._start_mtc.milliseconds_exact + self.media.regions[0].in_time.milliseconds_exact
                try:
                    key = f'{self._osc_route}/offset'
                    ossia.send_message(key, offset_to_go)
                except KeyError:
                    Logger.debug(
                        f'Key error 3 in go_callback {key}',
                        extra = {"caller": self.__class__.__name__}
                    )

            loop_counter += 1

        if self._local:                
            try:
                key = f'{self._osc_route}/mtcfollow'
                ossia.send_message(key, 0)
            except KeyError:
                Logger.debug(
                    f'Key error 4 in go_callback {key}',
                    extra = {"caller": self.__class__.__name__}
                )

    except AttributeError:
        pass

check_mappings(settings)

Check if the audio output mappings are valid.

Parameters:

Name Type Description Default
settings

The settings containing project node mappings.

required

Returns:

Name Type Description
bool

True if the mappings are valid, False otherwise.

Source code in src/cuemsutils/cues/AudioCue.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
def check_mappings(self, settings):
    """Check if the audio output mappings are valid.

    Args:
        settings: The settings containing project node mappings.

    Returns:
        bool: True if the mappings are valid, False otherwise.
    """
    return super().check_mappings()

    if not settings.project_node_mappings:
        return True

    found = True
    map_list = ['default']

    Logger.debug(f'AudioCue check_mappings: {settings.project_node_mappings}')
    if settings.project_node_mappings['audio'][0]['outputs']:
        for elem in settings.project_node_mappings['audio'][0]['outputs']:
            Logger.debug(f'AudioCue elem: {elem}')
            elem = elem['output']
            for map in elem['mappings']:
                Logger.debug(f'AudioCue map: {map}')
                map_list.append(map['mapped_to'])

    for output in self.outputs:
        if output['output_name'][:36] == settings.node_conf['uuid']:
                self._local = True
                if output['output_name'][37:] not in map_list:
                    found = False
                    break
        else:
            self._local = False
            found = True

    return found

get_master_vol()

Get the master volume level.

Returns:

Name Type Description
float

The master volume level.

Source code in src/cuemsutils/cues/AudioCue.py
35
36
37
38
39
40
41
def get_master_vol(self):
    """Get the master volume level.

    Returns:
        float: The master volume level.
    """
    return super().__getitem__('master_vol')

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items, with required items sorted first.

Source code in src/cuemsutils/cues/AudioCue.py
53
54
55
56
57
58
59
60
61
62
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items, with required items sorted first.
    """
    x = dict(super().items())
    for k in sorted(REQ_ITEMS.keys()):
        x[k] = self[k]
    return x.items()

osc_route(osc_route)

Set the OSC route for audio control.

Parameters:

Name Type Description Default
osc_route str

The OSC route to use for audio control.

required
Source code in src/cuemsutils/cues/AudioCue.py
72
73
74
75
76
77
78
def osc_route(self, osc_route):
    """Set the OSC route for audio control.

    Args:
        osc_route (str): The OSC route to use for audio control.
    """
    self._osc_route = osc_route

player(player)

Set the audio player instance.

Parameters:

Name Type Description Default
player

The audio player instance to use.

required
Source code in src/cuemsutils/cues/AudioCue.py
64
65
66
67
68
69
70
def player(self, player):
    """Set the audio player instance.

    Args:
        player: The audio player instance to use.
    """
    self._player = player

set_master_vol(master_vol)

Set the master volume level.

Parameters:

Name Type Description Default
master_vol float

The new master volume level.

required
Source code in src/cuemsutils/cues/AudioCue.py
43
44
45
46
47
48
49
def set_master_vol(self, master_vol):
    """Set the master volume level.

    Args:
        master_vol (float): The new master volume level.
    """
    super().__setitem__('master_vol', master_vol)

stop()

Stop the audio playback.

This method stops the audio player and sets the stop request flag.

Source code in src/cuemsutils/cues/AudioCue.py
131
132
133
134
135
136
137
138
def stop(self):
    """Stop the audio playback.

    This method stops the audio player and sets the stop request flag.
    """
    self._stop_requested = True
    if self._player and self._player.is_alive():
        self._player.kill()

Cue

Bases: CuemsDict

Base class for all cue types in the system.

A cue represents a single action or event that can be triggered in the system. It contains properties like timing, target, and behavior settings.

Source code in src/cuemsutils/cues/Cue.py
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
class Cue(CuemsDict):
    """Base class for all cue types in the system.

    A cue represents a single action or event that can be triggered in the system.
    It contains properties like timing, target, and behavior settings.
    """

    def __init__(self, init_dict = None):
        """Initialize a new Cue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if init_dict:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
            self.setter(init_dict)

        self._target_object = None
        self._conf = None
        self._armed_list = None
        self._start_mtc = CTimecode()
        self._end_mtc = CTimecode()
        self._end_reached = False
        self._go_thread = None
        self._stop_requested = False
        self._local = False

    def get_id(self):
        """Get the unique identifier of the cue.

        Returns:
            Uuid: The cue's unique identifier.
        """
        return super().__getitem__('id')

    def set_id(self, id):
        """Set the unique identifier of the cue.

        Args:
            id: The new unique identifier.
        """
        id = Uuid(id)
        super().__setitem__('id', id)

    id = property(get_id, set_id)

    def get_name(self):
        """Get the name of the cue.

        Returns:
            str: The cue's name.
        """
        return super().__getitem__('name')

    def set_name(self, name):
        """Set the name of the cue.

        Args:
            name (str): The new name for the cue.
        """
        super().__setitem__('name', name)

    name = property(get_name, set_name)

    def get_description(self):
        """Get the description of the cue.

        Returns:
            str: The cue's description.
        """
        return super().__getitem__('description')

    def set_description(self, description):
        """Set the description of the cue.

        Args:
            description (str): The new description for the cue.
        """
        super().__setitem__('description', description)

    description = property(get_description, set_description)

    def get_enabled(self):
        """Get whether the cue is enabled.

        Returns:
            bool: True if the cue is enabled, False otherwise.
        """
        return super().__getitem__('enabled')

    def set_enabled(self, enabled):
        """Set whether the cue is enabled.

        Args:
            enabled (bool): True to enable the cue, False to disable it.
        """
        super().__setitem__('enabled', enabled)

    enabled = property(get_enabled, set_enabled)

    def get_autoload(self):
        """Get whether the cue should be autoloaded.

        Returns:
            bool: True if the cue should be autoloaded, False otherwise.
        """
        return super().__getitem__('autoload')

    def set_autoload(self, autoload: bool):
        """Set whether the cue should be autoloaded.

        Args:
            autoload (bool): True to enable autoloading, False to disable it.
        """
        super().__setitem__('autoload', autoload)

    autoload = property(get_autoload, set_autoload)

    def get_timecode(self):
        """Get the timecode setting of the cue.

        Returns:
            bool: The timecode setting.
        """
        return super().__getitem__('timecode')

    def set_timecode(self, timecode):
        """Set the timecode setting of the cue.

        Args:
            timecode (bool): The new timecode setting.
        """
        super().__setitem__('timecode', timecode)

    timecode = property(get_timecode, set_timecode)

    def get_offset(self):
        """Get the timecode offset of the cue.

        Returns:
            CTimecode: The cue's timecode offset.
        """
        return super().__getitem__('offset')

    def set_offset(self, offset):
        """Set the timecode offset of the cue.

        Args:
            offset: The new timecode offset.
        """
        offset = format_timecode(offset)
        self.__setitem__('offset', offset)

    offset = property(get_offset, set_offset)

    def get_loop(self):
        """Get the loop count of the cue.

        Returns:
            int: The number of times the cue should loop.
        """
        return super().__getitem__('loop')

    def set_loop(self, loop):
        """Set the loop count of the cue.

        Args:
            loop (int): The number of times the cue should loop.
        """
        super().__setitem__('loop', loop)

    loop = property(get_loop, set_loop)

    def get_prewait(self):
        """Get the pre-wait time of the cue.

        Returns:
            CTimecode: The time to wait before executing the cue.
        """
        return super().__getitem__('prewait')

    def set_prewait(self, prewait):
        """Set the pre-wait time of the cue.

        Args:
            prewait: The new pre-wait time.
        """
        prewait = format_timecode(prewait)
        super().__setitem__('prewait', prewait)

    prewait = property(get_prewait, set_prewait)

    def get_postwait(self):
        """Get the post-wait time of the cue.

        Returns:
            CTimecode: The time to wait after executing the cue.
        """
        return super().__getitem__('postwait')

    def set_postwait(self, postwait):
        """Set the post-wait time of the cue.

        Args:
            postwait: The new post-wait time.
        """
        postwait = format_timecode(postwait)
        super().__setitem__('postwait', postwait)

    postwait = property(get_postwait, set_postwait)

    def get_post_go(self):
        """Get the post-go behavior of the cue.

        Returns:
            str: The post-go behavior (e.g., 'pause').
        """
        return super().__getitem__('post_go')

    def set_post_go(self, post_go):
        """Set the post-go behavior of the cue.

        Args:
            post_go (str): The new post-go behavior.
        """
        super().__setitem__('post_go', post_go)

    post_go = property(get_post_go, set_post_go)

    def get_target(self):
        """Get the target of the cue.

        Returns:
            Uuid: The target's unique identifier.
        """
        return super().__getitem__('target')

    def set_target(self, target):
        """Set the target of the cue.

        Args:
            target: The new target identifier.
        """
        if target is not None:
            target = Uuid(target)
        super().__setitem__('target', target)

    target = property(get_target, set_target)

    def get_ui_properties(self):
        """Get the UI properties of the cue.

        Returns:
            dict: The cue's UI properties.
        """
        return super().__getitem__('ui_properties')

    def set_ui_properties(self, ui_properties):
        """Set the UI properties of the cue.

        Args:
            ui_properties (dict): The new UI properties.
        """
        ui_properties = as_cuemsdict(ui_properties)
        super().__setitem__('ui_properties', ui_properties)

    ui_properties = property(get_ui_properties, set_ui_properties)

    def __eq__(self, other):
        """Compare two cues by their id.

        Args:
            other: The other cue to compare with.

        Returns:
            bool: True if the cues have the same id, False otherwise.
        """
        if isinstance(other, Cue):
            return self.id == other.id
        return False

    def __hash__(self):
        """Hash the cue by its id.

        Returns:
            int: The hash value of the cue's id.
        """
        return hash(self.id)

    def __json__(self):
        """Convert the cue to a JSON-compatible dictionary.

        Returns:
            dict: A dictionary representation of the cue.
        """
        return {type(self).__name__: dict(self.items())}

    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items.
        """
        return extract_items(super().items(), REQ_ITEMS.keys())

    def target_object(self, target_object):
        """Set the target object for the cue.

        Args:
            target_object: The target object to set.
        """
        self._target_object = target_object

    def type(self):
        """Get the type of the cue.

        Returns:
            type: The class type of the cue.
        """
        return type(self)

    def _next_enabled(self):
        """Return the first enabled cue in the target chain, or None."""
        cue = self._target_object if self.target else None
        depth = 0
        while cue and not cue.enabled:
            cue = cue._target_object if cue.target else None
            depth += 1
            if depth > 50:
                return None
        return cue

    def get_next_cue(self):
        """Get the next enabled cue in the sequence, skipping disabled cues.

        Returns:
            Cue or None: The next enabled cue to execute, or None if there is no next cue.
        """
        next_cue = self._next_enabled()
        if not next_cue:
            return None
        if self.post_go == 'pause':
            return next_cue
        return next_cue.get_next_cue()

    @deprecated(reason="This method is deprecated in favor of new mapping logic. Use localize_cue instead.", version="0.1.0rc4")
    def check_mappings(self, settings):
        """Check if the given settings are valid for this cue.

        Args:
            settings: The settings to check.

        Returns:
            bool: True if the settings are valid, False otherwise.
        """
        return True

    def localize_cue(self, node_id: str | None = None) -> None:
        """Fallback method to set the _local attribute to True.

        This method is a fallback for cues that do not implement their own localization logic.

        Args:
            node_id: The ID of the node to localize the cue to.
        """
        self._local = True

    def stop(self):
        """Stop the execution of the cue."""
        pass

__eq__(other)

Compare two cues by their id.

Parameters:

Name Type Description Default
other

The other cue to compare with.

required

Returns:

Name Type Description
bool

True if the cues have the same id, False otherwise.

Source code in src/cuemsutils/cues/Cue.py
292
293
294
295
296
297
298
299
300
301
302
303
def __eq__(self, other):
    """Compare two cues by their id.

    Args:
        other: The other cue to compare with.

    Returns:
        bool: True if the cues have the same id, False otherwise.
    """
    if isinstance(other, Cue):
        return self.id == other.id
    return False

__hash__()

Hash the cue by its id.

Returns:

Name Type Description
int

The hash value of the cue's id.

Source code in src/cuemsutils/cues/Cue.py
305
306
307
308
309
310
311
def __hash__(self):
    """Hash the cue by its id.

    Returns:
        int: The hash value of the cue's id.
    """
    return hash(self.id)

__init__(init_dict=None)

Initialize a new Cue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/Cue.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def __init__(self, init_dict = None):
    """Initialize a new Cue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if init_dict:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
        self.setter(init_dict)

    self._target_object = None
    self._conf = None
    self._armed_list = None
    self._start_mtc = CTimecode()
    self._end_mtc = CTimecode()
    self._end_reached = False
    self._go_thread = None
    self._stop_requested = False
    self._local = False

__json__()

Convert the cue to a JSON-compatible dictionary.

Returns:

Name Type Description
dict

A dictionary representation of the cue.

Source code in src/cuemsutils/cues/Cue.py
313
314
315
316
317
318
319
def __json__(self):
    """Convert the cue to a JSON-compatible dictionary.

    Returns:
        dict: A dictionary representation of the cue.
    """
    return {type(self).__name__: dict(self.items())}

check_mappings(settings)

Check if the given settings are valid for this cue.

Parameters:

Name Type Description Default
settings

The settings to check.

required

Returns:

Name Type Description
bool

True if the settings are valid, False otherwise.

Source code in src/cuemsutils/cues/Cue.py
369
370
371
372
373
374
375
376
377
378
379
@deprecated(reason="This method is deprecated in favor of new mapping logic. Use localize_cue instead.", version="0.1.0rc4")
def check_mappings(self, settings):
    """Check if the given settings are valid for this cue.

    Args:
        settings: The settings to check.

    Returns:
        bool: True if the settings are valid, False otherwise.
    """
    return True

get_autoload()

Get whether the cue should be autoloaded.

Returns:

Name Type Description
bool

True if the cue should be autoloaded, False otherwise.

Source code in src/cuemsutils/cues/Cue.py
124
125
126
127
128
129
130
def get_autoload(self):
    """Get whether the cue should be autoloaded.

    Returns:
        bool: True if the cue should be autoloaded, False otherwise.
    """
    return super().__getitem__('autoload')

get_description()

Get the description of the cue.

Returns:

Name Type Description
str

The cue's description.

Source code in src/cuemsutils/cues/Cue.py
88
89
90
91
92
93
94
def get_description(self):
    """Get the description of the cue.

    Returns:
        str: The cue's description.
    """
    return super().__getitem__('description')

get_enabled()

Get whether the cue is enabled.

Returns:

Name Type Description
bool

True if the cue is enabled, False otherwise.

Source code in src/cuemsutils/cues/Cue.py
106
107
108
109
110
111
112
def get_enabled(self):
    """Get whether the cue is enabled.

    Returns:
        bool: True if the cue is enabled, False otherwise.
    """
    return super().__getitem__('enabled')

get_id()

Get the unique identifier of the cue.

Returns:

Name Type Description
Uuid

The cue's unique identifier.

Source code in src/cuemsutils/cues/Cue.py
51
52
53
54
55
56
57
def get_id(self):
    """Get the unique identifier of the cue.

    Returns:
        Uuid: The cue's unique identifier.
    """
    return super().__getitem__('id')

get_loop()

Get the loop count of the cue.

Returns:

Name Type Description
int

The number of times the cue should loop.

Source code in src/cuemsutils/cues/Cue.py
179
180
181
182
183
184
185
def get_loop(self):
    """Get the loop count of the cue.

    Returns:
        int: The number of times the cue should loop.
    """
    return super().__getitem__('loop')

get_name()

Get the name of the cue.

Returns:

Name Type Description
str

The cue's name.

Source code in src/cuemsutils/cues/Cue.py
70
71
72
73
74
75
76
def get_name(self):
    """Get the name of the cue.

    Returns:
        str: The cue's name.
    """
    return super().__getitem__('name')

get_next_cue()

Get the next enabled cue in the sequence, skipping disabled cues.

Returns:

Type Description

Cue or None: The next enabled cue to execute, or None if there is no next cue.

Source code in src/cuemsutils/cues/Cue.py
356
357
358
359
360
361
362
363
364
365
366
367
def get_next_cue(self):
    """Get the next enabled cue in the sequence, skipping disabled cues.

    Returns:
        Cue or None: The next enabled cue to execute, or None if there is no next cue.
    """
    next_cue = self._next_enabled()
    if not next_cue:
        return None
    if self.post_go == 'pause':
        return next_cue
    return next_cue.get_next_cue()

get_offset()

Get the timecode offset of the cue.

Returns:

Name Type Description
CTimecode

The cue's timecode offset.

Source code in src/cuemsutils/cues/Cue.py
160
161
162
163
164
165
166
def get_offset(self):
    """Get the timecode offset of the cue.

    Returns:
        CTimecode: The cue's timecode offset.
    """
    return super().__getitem__('offset')

get_post_go()

Get the post-go behavior of the cue.

Returns:

Name Type Description
str

The post-go behavior (e.g., 'pause').

Source code in src/cuemsutils/cues/Cue.py
235
236
237
238
239
240
241
def get_post_go(self):
    """Get the post-go behavior of the cue.

    Returns:
        str: The post-go behavior (e.g., 'pause').
    """
    return super().__getitem__('post_go')

get_postwait()

Get the post-wait time of the cue.

Returns:

Name Type Description
CTimecode

The time to wait after executing the cue.

Source code in src/cuemsutils/cues/Cue.py
216
217
218
219
220
221
222
def get_postwait(self):
    """Get the post-wait time of the cue.

    Returns:
        CTimecode: The time to wait after executing the cue.
    """
    return super().__getitem__('postwait')

get_prewait()

Get the pre-wait time of the cue.

Returns:

Name Type Description
CTimecode

The time to wait before executing the cue.

Source code in src/cuemsutils/cues/Cue.py
197
198
199
200
201
202
203
def get_prewait(self):
    """Get the pre-wait time of the cue.

    Returns:
        CTimecode: The time to wait before executing the cue.
    """
    return super().__getitem__('prewait')

get_target()

Get the target of the cue.

Returns:

Name Type Description
Uuid

The target's unique identifier.

Source code in src/cuemsutils/cues/Cue.py
253
254
255
256
257
258
259
def get_target(self):
    """Get the target of the cue.

    Returns:
        Uuid: The target's unique identifier.
    """
    return super().__getitem__('target')

get_timecode()

Get the timecode setting of the cue.

Returns:

Name Type Description
bool

The timecode setting.

Source code in src/cuemsutils/cues/Cue.py
142
143
144
145
146
147
148
def get_timecode(self):
    """Get the timecode setting of the cue.

    Returns:
        bool: The timecode setting.
    """
    return super().__getitem__('timecode')

get_ui_properties()

Get the UI properties of the cue.

Returns:

Name Type Description
dict

The cue's UI properties.

Source code in src/cuemsutils/cues/Cue.py
273
274
275
276
277
278
279
def get_ui_properties(self):
    """Get the UI properties of the cue.

    Returns:
        dict: The cue's UI properties.
    """
    return super().__getitem__('ui_properties')

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items.

Source code in src/cuemsutils/cues/Cue.py
321
322
323
324
325
326
327
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items.
    """
    return extract_items(super().items(), REQ_ITEMS.keys())

localize_cue(node_id=None)

Fallback method to set the _local attribute to True.

This method is a fallback for cues that do not implement their own localization logic.

Parameters:

Name Type Description Default
node_id str | None

The ID of the node to localize the cue to.

None
Source code in src/cuemsutils/cues/Cue.py
381
382
383
384
385
386
387
388
389
def localize_cue(self, node_id: str | None = None) -> None:
    """Fallback method to set the _local attribute to True.

    This method is a fallback for cues that do not implement their own localization logic.

    Args:
        node_id: The ID of the node to localize the cue to.
    """
    self._local = True

set_autoload(autoload)

Set whether the cue should be autoloaded.

Parameters:

Name Type Description Default
autoload bool

True to enable autoloading, False to disable it.

required
Source code in src/cuemsutils/cues/Cue.py
132
133
134
135
136
137
138
def set_autoload(self, autoload: bool):
    """Set whether the cue should be autoloaded.

    Args:
        autoload (bool): True to enable autoloading, False to disable it.
    """
    super().__setitem__('autoload', autoload)

set_description(description)

Set the description of the cue.

Parameters:

Name Type Description Default
description str

The new description for the cue.

required
Source code in src/cuemsutils/cues/Cue.py
 96
 97
 98
 99
100
101
102
def set_description(self, description):
    """Set the description of the cue.

    Args:
        description (str): The new description for the cue.
    """
    super().__setitem__('description', description)

set_enabled(enabled)

Set whether the cue is enabled.

Parameters:

Name Type Description Default
enabled bool

True to enable the cue, False to disable it.

required
Source code in src/cuemsutils/cues/Cue.py
114
115
116
117
118
119
120
def set_enabled(self, enabled):
    """Set whether the cue is enabled.

    Args:
        enabled (bool): True to enable the cue, False to disable it.
    """
    super().__setitem__('enabled', enabled)

set_id(id)

Set the unique identifier of the cue.

Parameters:

Name Type Description Default
id

The new unique identifier.

required
Source code in src/cuemsutils/cues/Cue.py
59
60
61
62
63
64
65
66
def set_id(self, id):
    """Set the unique identifier of the cue.

    Args:
        id: The new unique identifier.
    """
    id = Uuid(id)
    super().__setitem__('id', id)

set_loop(loop)

Set the loop count of the cue.

Parameters:

Name Type Description Default
loop int

The number of times the cue should loop.

required
Source code in src/cuemsutils/cues/Cue.py
187
188
189
190
191
192
193
def set_loop(self, loop):
    """Set the loop count of the cue.

    Args:
        loop (int): The number of times the cue should loop.
    """
    super().__setitem__('loop', loop)

set_name(name)

Set the name of the cue.

Parameters:

Name Type Description Default
name str

The new name for the cue.

required
Source code in src/cuemsutils/cues/Cue.py
78
79
80
81
82
83
84
def set_name(self, name):
    """Set the name of the cue.

    Args:
        name (str): The new name for the cue.
    """
    super().__setitem__('name', name)

set_offset(offset)

Set the timecode offset of the cue.

Parameters:

Name Type Description Default
offset

The new timecode offset.

required
Source code in src/cuemsutils/cues/Cue.py
168
169
170
171
172
173
174
175
def set_offset(self, offset):
    """Set the timecode offset of the cue.

    Args:
        offset: The new timecode offset.
    """
    offset = format_timecode(offset)
    self.__setitem__('offset', offset)

set_post_go(post_go)

Set the post-go behavior of the cue.

Parameters:

Name Type Description Default
post_go str

The new post-go behavior.

required
Source code in src/cuemsutils/cues/Cue.py
243
244
245
246
247
248
249
def set_post_go(self, post_go):
    """Set the post-go behavior of the cue.

    Args:
        post_go (str): The new post-go behavior.
    """
    super().__setitem__('post_go', post_go)

set_postwait(postwait)

Set the post-wait time of the cue.

Parameters:

Name Type Description Default
postwait

The new post-wait time.

required
Source code in src/cuemsutils/cues/Cue.py
224
225
226
227
228
229
230
231
def set_postwait(self, postwait):
    """Set the post-wait time of the cue.

    Args:
        postwait: The new post-wait time.
    """
    postwait = format_timecode(postwait)
    super().__setitem__('postwait', postwait)

set_prewait(prewait)

Set the pre-wait time of the cue.

Parameters:

Name Type Description Default
prewait

The new pre-wait time.

required
Source code in src/cuemsutils/cues/Cue.py
205
206
207
208
209
210
211
212
def set_prewait(self, prewait):
    """Set the pre-wait time of the cue.

    Args:
        prewait: The new pre-wait time.
    """
    prewait = format_timecode(prewait)
    super().__setitem__('prewait', prewait)

set_target(target)

Set the target of the cue.

Parameters:

Name Type Description Default
target

The new target identifier.

required
Source code in src/cuemsutils/cues/Cue.py
261
262
263
264
265
266
267
268
269
def set_target(self, target):
    """Set the target of the cue.

    Args:
        target: The new target identifier.
    """
    if target is not None:
        target = Uuid(target)
    super().__setitem__('target', target)

set_timecode(timecode)

Set the timecode setting of the cue.

Parameters:

Name Type Description Default
timecode bool

The new timecode setting.

required
Source code in src/cuemsutils/cues/Cue.py
150
151
152
153
154
155
156
def set_timecode(self, timecode):
    """Set the timecode setting of the cue.

    Args:
        timecode (bool): The new timecode setting.
    """
    super().__setitem__('timecode', timecode)

set_ui_properties(ui_properties)

Set the UI properties of the cue.

Parameters:

Name Type Description Default
ui_properties dict

The new UI properties.

required
Source code in src/cuemsutils/cues/Cue.py
281
282
283
284
285
286
287
288
def set_ui_properties(self, ui_properties):
    """Set the UI properties of the cue.

    Args:
        ui_properties (dict): The new UI properties.
    """
    ui_properties = as_cuemsdict(ui_properties)
    super().__setitem__('ui_properties', ui_properties)

stop()

Stop the execution of the cue.

Source code in src/cuemsutils/cues/Cue.py
391
392
393
def stop(self):
    """Stop the execution of the cue."""
    pass

target_object(target_object)

Set the target object for the cue.

Parameters:

Name Type Description Default
target_object

The target object to set.

required
Source code in src/cuemsutils/cues/Cue.py
329
330
331
332
333
334
335
def target_object(self, target_object):
    """Set the target object for the cue.

    Args:
        target_object: The target object to set.
    """
    self._target_object = target_object

type()

Get the type of the cue.

Returns:

Name Type Description
type

The class type of the cue.

Source code in src/cuemsutils/cues/Cue.py
337
338
339
340
341
342
343
def type(self):
    """Get the type of the cue.

    Returns:
        type: The class type of the cue.
    """
    return type(self)

UI_properties

Bases: CuemsDict

Class for managing UI-specific properties of cues.

Source code in src/cuemsutils/cues/Cue.py
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
class UI_properties(CuemsDict):
    """Class for managing UI-specific properties of cues."""

    def __init__(self, init_dict = None):
        """Initialize UI properties.

        Args:
            init_dict (dict, optional): Dictionary containing initial UI properties.
        """
        if init_dict:
            super().__init__(init_dict)

    def get_timeline_position(self):
        """Get the timeline position of the cue.

        Returns:
            The timeline position value.
        """
        return super().__getitem__('timeline_position')

__init__(init_dict=None)

Initialize UI properties.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initial UI properties.

None
Source code in src/cuemsutils/cues/Cue.py
398
399
400
401
402
403
404
405
def __init__(self, init_dict = None):
    """Initialize UI properties.

    Args:
        init_dict (dict, optional): Dictionary containing initial UI properties.
    """
    if init_dict:
        super().__init__(init_dict)

get_timeline_position()

Get the timeline position of the cue.

Returns:

Type Description

The timeline position value.

Source code in src/cuemsutils/cues/Cue.py
407
408
409
410
411
412
413
def get_timeline_position(self):
    """Get the timeline position of the cue.

    Returns:
        The timeline position value.
    """
    return super().__getitem__('timeline_position')

CueList

Bases: Cue

A cue that contains a list of other cues.

This class extends Cue to provide functionality for managing collections of cues, including nested cue lists and media tracking.

Source code in src/cuemsutils/cues/CueList.py
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class CueList(Cue):
    """A cue that contains a list of other cues.

    This class extends Cue to provide functionality for managing collections of cues,
    including nested cue lists and media tracking.
    """

    def __init__(self, init_dict = None):
        """Initialize a CueList.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If not provided, default values from REQ_ITEMS will be used.
        """
        if not init_dict:
            init_dict = REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
        super().__init__(init_dict)

    def get_contents(self) -> list[Cue]:
        """Get the list of cues in this cue list.

        Returns:
            list: The list of Cue objects.
        """
        return super().__getitem__('contents')

    def set_contents(self, contents: list[Cue]):
        """Set the list of cues in this cue list.

        Args:
            contents (list): The new list of Cue objects.
        """
        super().__setitem__('contents', contents)

    contents: list[Cue] = property(get_contents, set_contents)

    def append(self, item: Cue):
        """Add a cue to the end of the list.

        Args:
            item (Cue): The cue to add.

        Raises:
            TypeError: If the item is not a Cue object.
        """
        if not isinstance(item, Cue):
            raise TypeError(f'Item {item} is not a Cue object')
        self.contents.append(item)

    def check_mappings(self, settings):
        """Check if the cue list mappings are valid.

        Currently, all CueList objects are considered local.

        Args:
            settings: The settings containing project node mappings.

        Returns:
            bool: Always returns True for CueList objects.
        """
        # DEV: By now let's presume all CueList objects are _local
        return super().check_mappings()

    def find(self, uuid: Uuid):
        """Find a cue by its UUID in this cue list or its nested lists.

        Args:
            uuid (Uuid): The UUID to search for.

        Returns:
            Cue or None: The found cue, or None if not found.
        """
        if self.id == uuid:
            return self
        elif not self.has_contents():
            return None
        else:
            for item in self.contents:
                if item.id == uuid:
                    return item
                elif isinstance(item, CueList):
                    recursive = item.find(uuid)
                    if recursive != None:
                        return recursive

        return None

    def get_media(self):
        """Get a dictionary of all media files present inside contents.

        Returns:
            dict: A dictionary mapping cue UUIDs to their media information.
                Each entry contains the media file name and cue type.
        """
        media_dict = dict()

        if not self.has_contents():
            return media_dict

        for cue in self.contents:
            if isinstance(cue, CueList):
                media_dict.update(cue.get_media())
            elif isinstance(cue, MediaCue) and hasattr(cue.media, 'file_name'):
                media_dict[str(cue.id)] = {str(cue.media.id) : cue.media.file_name }

        return media_dict

    def get_next_cue(self):
        """Get the next enabled cue to be executed after this cue list.

        Returns:
            Cue or None: The next enabled cue to execute, or None if there is no next cue.
        """
        cue_to_return = None
        if self.has_contents():
            # Find first enabled cue in the list
            first = None
            for c in self.contents:
                if c.enabled:
                    first = c
                    break
            if first is None:
                return super().get_next_cue()
            if first.post_go == 'pause':
                cue_to_return = first._next_enabled()
            else:
                cue_to_return = first.get_next_cue()
            if cue_to_return:
                return cue_to_return

        return super().get_next_cue()

    def items(self):
        """Get all items in the cue list as a dictionary.

        Returns:
            dict_items: A view of the cue list's items.
        """
        x = dict(super().items())
        x['contents'] = self.contents
        return x.items()

    def times(self):
        """Get a list of all cue offsets in this cue list.

        Returns:
            list: A list of timecode offsets for each cue in the list.
        """
        timelist = list()
        for item in self['contents']:
            timelist.append(item.offset)
        return timelist

    def has_contents(self):
        """Check if the cue list has contents.

        Returns:
            bool: True if the cue list has contents, False otherwise.
        """
        return isinstance(self.contents, list) and len(self.contents) > 0

__init__(init_dict=None)

Initialize a CueList.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If not provided, default values from REQ_ITEMS will be used.

None
Source code in src/cuemsutils/cues/CueList.py
17
18
19
20
21
22
23
24
25
26
27
28
def __init__(self, init_dict = None):
    """Initialize a CueList.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If not provided, default values from REQ_ITEMS will be used.
    """
    if not init_dict:
        init_dict = REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
    super().__init__(init_dict)

append(item)

Add a cue to the end of the list.

Parameters:

Name Type Description Default
item Cue

The cue to add.

required

Raises:

Type Description
TypeError

If the item is not a Cue object.

Source code in src/cuemsutils/cues/CueList.py
48
49
50
51
52
53
54
55
56
57
58
59
def append(self, item: Cue):
    """Add a cue to the end of the list.

    Args:
        item (Cue): The cue to add.

    Raises:
        TypeError: If the item is not a Cue object.
    """
    if not isinstance(item, Cue):
        raise TypeError(f'Item {item} is not a Cue object')
    self.contents.append(item)

check_mappings(settings)

Check if the cue list mappings are valid.

Currently, all CueList objects are considered local.

Parameters:

Name Type Description Default
settings

The settings containing project node mappings.

required

Returns:

Name Type Description
bool

Always returns True for CueList objects.

Source code in src/cuemsutils/cues/CueList.py
61
62
63
64
65
66
67
68
69
70
71
72
73
def check_mappings(self, settings):
    """Check if the cue list mappings are valid.

    Currently, all CueList objects are considered local.

    Args:
        settings: The settings containing project node mappings.

    Returns:
        bool: Always returns True for CueList objects.
    """
    # DEV: By now let's presume all CueList objects are _local
    return super().check_mappings()

find(uuid)

Find a cue by its UUID in this cue list or its nested lists.

Parameters:

Name Type Description Default
uuid Uuid

The UUID to search for.

required

Returns:

Type Description

Cue or None: The found cue, or None if not found.

Source code in src/cuemsutils/cues/CueList.py
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def find(self, uuid: Uuid):
    """Find a cue by its UUID in this cue list or its nested lists.

    Args:
        uuid (Uuid): The UUID to search for.

    Returns:
        Cue or None: The found cue, or None if not found.
    """
    if self.id == uuid:
        return self
    elif not self.has_contents():
        return None
    else:
        for item in self.contents:
            if item.id == uuid:
                return item
            elif isinstance(item, CueList):
                recursive = item.find(uuid)
                if recursive != None:
                    return recursive

    return None

get_contents()

Get the list of cues in this cue list.

Returns:

Name Type Description
list list[Cue]

The list of Cue objects.

Source code in src/cuemsutils/cues/CueList.py
30
31
32
33
34
35
36
def get_contents(self) -> list[Cue]:
    """Get the list of cues in this cue list.

    Returns:
        list: The list of Cue objects.
    """
    return super().__getitem__('contents')

get_media()

Get a dictionary of all media files present inside contents.

Returns:

Name Type Description
dict

A dictionary mapping cue UUIDs to their media information. Each entry contains the media file name and cue type.

Source code in src/cuemsutils/cues/CueList.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def get_media(self):
    """Get a dictionary of all media files present inside contents.

    Returns:
        dict: A dictionary mapping cue UUIDs to their media information.
            Each entry contains the media file name and cue type.
    """
    media_dict = dict()

    if not self.has_contents():
        return media_dict

    for cue in self.contents:
        if isinstance(cue, CueList):
            media_dict.update(cue.get_media())
        elif isinstance(cue, MediaCue) and hasattr(cue.media, 'file_name'):
            media_dict[str(cue.id)] = {str(cue.media.id) : cue.media.file_name }

    return media_dict

get_next_cue()

Get the next enabled cue to be executed after this cue list.

Returns:

Type Description

Cue or None: The next enabled cue to execute, or None if there is no next cue.

Source code in src/cuemsutils/cues/CueList.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def get_next_cue(self):
    """Get the next enabled cue to be executed after this cue list.

    Returns:
        Cue or None: The next enabled cue to execute, or None if there is no next cue.
    """
    cue_to_return = None
    if self.has_contents():
        # Find first enabled cue in the list
        first = None
        for c in self.contents:
            if c.enabled:
                first = c
                break
        if first is None:
            return super().get_next_cue()
        if first.post_go == 'pause':
            cue_to_return = first._next_enabled()
        else:
            cue_to_return = first.get_next_cue()
        if cue_to_return:
            return cue_to_return

    return super().get_next_cue()

has_contents()

Check if the cue list has contents.

Returns:

Name Type Description
bool

True if the cue list has contents, False otherwise.

Source code in src/cuemsutils/cues/CueList.py
165
166
167
168
169
170
171
def has_contents(self):
    """Check if the cue list has contents.

    Returns:
        bool: True if the cue list has contents, False otherwise.
    """
    return isinstance(self.contents, list) and len(self.contents) > 0

items()

Get all items in the cue list as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue list's items.

Source code in src/cuemsutils/cues/CueList.py
144
145
146
147
148
149
150
151
152
def items(self):
    """Get all items in the cue list as a dictionary.

    Returns:
        dict_items: A view of the cue list's items.
    """
    x = dict(super().items())
    x['contents'] = self.contents
    return x.items()

set_contents(contents)

Set the list of cues in this cue list.

Parameters:

Name Type Description Default
contents list

The new list of Cue objects.

required
Source code in src/cuemsutils/cues/CueList.py
38
39
40
41
42
43
44
def set_contents(self, contents: list[Cue]):
    """Set the list of cues in this cue list.

    Args:
        contents (list): The new list of Cue objects.
    """
    super().__setitem__('contents', contents)

times()

Get a list of all cue offsets in this cue list.

Returns:

Name Type Description
list

A list of timecode offsets for each cue in the list.

Source code in src/cuemsutils/cues/CueList.py
154
155
156
157
158
159
160
161
162
163
def times(self):
    """Get a list of all cue offsets in this cue list.

    Returns:
        list: A list of timecode offsets for each cue in the list.
    """
    timelist = list()
    for item in self['contents']:
        timelist.append(item.offset)
    return timelist

CuemsScript

Bases: dict

A class representing a complete CueMS script.

This class manages a collection of cues organized in a cue list, along with metadata about the script such as creation time and UI properties.

Source code in src/cuemsutils/cues/CuemsScript.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
class CuemsScript(dict):
    """A class representing a complete CueMS script.

    This class manages a collection of cues organized in a cue list, along with
    metadata about the script such as creation time and UI properties.
    """

    def __init__(self, init_dict = None):
        """Initialize a CuemsScript.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if init_dict:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
            self.setter(init_dict)

    def get_id(self):
        """Get the unique identifier of the script.

        Returns:
            Uuid: The script's unique identifier.
        """
        return super().__getitem__('id')

    def set_id(self, id):
        """Set the unique identifier of the script.

        Args:
            id: The new unique identifier.
        """
        id = Uuid(id)
        super().__setitem__('id', id)

    id: Uuid = property(get_id, set_id)

    def get_name(self):
        """Get the name of the script.

        Returns:
            str: The script's name.
        """
        return super().__getitem__('name')

    def set_name(self, name):
        """Set the name of the script.

        Args:
            name (str): The new name for the script.
        """
        super().__setitem__('name', name)

    name: str = property(get_name, set_name)

    def get_description(self):
        """Get the description of the script.

        Returns:
            str: The script's description.
        """
        return super().__getitem__('description')

    def set_description(self, description):
        """Set the description of the script.

        Args:
            description (str): The new description for the script.
        """
        super().__setitem__('description', description)

    description: str = property(get_description, set_description)

    def get_created(self):
        """Get the creation timestamp of the script.

        Returns:
            datetime: When the script was created.
        """
        return super().__getitem__('created')

    def set_created(self, created):
        """Set the creation timestamp of the script.

        Args:
            created (datetime): The new creation timestamp.
        """
        super().__setitem__('created', created)

    created = property(get_created, set_created)

    def get_modified(self):
        """Get the last modification timestamp of the script.

        Returns:
            datetime: When the script was last modified.
        """
        return super().__getitem__('modified')

    def set_modified(self, modified):
        """Set the last modification timestamp of the script.

        Args:
            modified (datetime): The new modification timestamp.
        """
        super().__setitem__('modified', modified)

    modified = property(get_modified, set_modified)

    def get_CueList(self) -> CueList:
        """Get the main cue list of the script.

        Returns:
            CueList: The script's main cue list.
        """
        return super().__getitem__('CueList')

    def set_CueList(self, cuelist: CueList | dict):
        """Set the main cue list of the script.

        Args:
            cuelist (CueList or dict): The new cue list or a dictionary to create one.

        Raises:
            ValueError: If the cuelist is not a valid CueList object or dictionary.
        """
        if not isinstance(cuelist, CueList):
            try:
                cuelist = CueList(cuelist)
            except:
                raise ValueError(
                    f'CueList {cuelist} is not a CueList object or a valid dict'
                )
        super().__setitem__('CueList', cuelist)

    cuelist: CueList = property(get_CueList, set_CueList)

    def get_ui_properties(self) -> CuemsDict:
        """Get the UI properties of the script.

        Returns:
            dict: The script's UI properties.
        """
        return super().__getitem__('ui_properties')

    def set_ui_properties(self, ui_properties: dict | CuemsDict):
        """Set the UI properties of the script.

        Args:
            ui_properties (dict): The new UI properties.
        """
        Logger.debug(f"Setting ui_properties to {ui_properties}")
        ui_properties = as_cuemsdict(ui_properties)
        super().__setitem__('ui_properties', ui_properties)

    ui_properties: CuemsDict = property(get_ui_properties, set_ui_properties)

    def find(self, uuid):
        """Find a cue by its UUID in the script.

        Args:
            uuid: The UUID to search for.

        Returns:
            Cue or None: The found cue, or None if not found.
        """
        return self.cuelist.find(uuid)

    @logged
    def get_media(self) -> dict:
        """Get all media files referenced in a CueList.

        Args:
            cuelist (CueList, optional): The cue list to search in.
                If not provided, uses the script's main cue list.

        Returns:
            dict: A dictionary mapping Cue UUIDs to their media information.
        """
        return self.cuelist.get_media()

    @logged
    def get_media_filenames(self) -> list:
        """Get all media filenames referenced in a CueList.

        Returns:
            list: A list of media filenames.
        """
        media_dict = {k: list(v.values())[0] for k, v in self.get_media().items()}
        return unique_values_to_list(media_dict)

    @logged
    def get_own_media(self, config: dict, cuelist: CueList | None = None) -> dict:
        """Get media files that are local to the current node.

        Args:
            cuelist (CueList, optional): The cue list to search in.
                If not provided, uses the script's main cue list.
            config: The configuration containing node information.

        Returns:
            dict: A dictionary mapping media file names to their associated cues
                that are local to the current node.
        """
        media_dict = dict()

        # If no cuelist is specified we are looking inside our own
        # script object, so our cuelist is our self cuelist
        if not cuelist:
            cuelist = self.cuelist

        if not cuelist.has_contents():
            return media_dict

        pos = 0
        for cue in cuelist.contents:  # type: ignore[union-attr]
            Logger.debug(f'CuemsScript get_own_media: {pos} {cue}')
            if type(cue) == CueList:
                media_dict.update(
                    self.get_own_media(config=config, cuelist=cue)
                )
            elif isinstance(cue, MediaCue) and hasattr(cue.media, 'file_name'):
                Logger.debug(f'get_own_media media cue at {pos}')
                cue.localize_cue(config.node_conf['uuid'])
                if cue._local:
                    media_dict[str(cue.id)] = cue.media.file_name
            pos += 1
        return media_dict

    @logged
    def get_own_media_filenames(self, config: dict, cuelist: CueList | None = None) -> list:
        """Get all media filenames that are local to the current node.

        Returns:
            list: A list of media filenames.
        """
        return unique_values_to_list(
            self.get_own_media(config=config, cuelist=cuelist)
        )

    def to_json(self):
        """Convert the script to a JSON string.

        Returns:
            str: A JSON string representation of the script.
        """
        return json.dumps({'CuemsScript': self})

    def setter(self, settings: dict):
        """Set the object properties from a dictionary.

        Args:
            settings (dict): Dictionary containing property values to set.

        Raises:
            AttributeError: If settings is not a dictionary.
        """
        if not isinstance(settings, dict):
            raise AttributeError(f"Invalid type {type(settings)}. Expected dict.")
        for k, v in settings.items():
            try:
                x = getattr(self, f"set_{k}")
                x(v)
            except AttributeError:
                pass

    def __json__(self):
        """Convert the script to a JSON-compatible dictionary.

        Returns:
            dict: A dictionary representation of the script.
        """
        x = dict(super().items())
        for k, v in x.items():
            if hasattr(v, '__json__'):
                x[k] = v.__json__()
            else:
                x[k] = v
            if k.lower() != k:
                x[k] = x[k][k]
        return x

    def items(self):
        """Get all items in the script as a dictionary.

        Returns:
            dict_items: A view of the script's items.
        """
        x = dict(super().items())
        return x.items()

__init__(init_dict=None)

Initialize a CuemsScript.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/CuemsScript.py
27
28
29
30
31
32
33
34
35
36
def __init__(self, init_dict = None):
    """Initialize a CuemsScript.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if init_dict:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
        self.setter(init_dict)

__json__()

Convert the script to a JSON-compatible dictionary.

Returns:

Name Type Description
dict

A dictionary representation of the script.

Source code in src/cuemsutils/cues/CuemsScript.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
def __json__(self):
    """Convert the script to a JSON-compatible dictionary.

    Returns:
        dict: A dictionary representation of the script.
    """
    x = dict(super().items())
    for k, v in x.items():
        if hasattr(v, '__json__'):
            x[k] = v.__json__()
        else:
            x[k] = v
        if k.lower() != k:
            x[k] = x[k][k]
    return x

find(uuid)

Find a cue by its UUID in the script.

Parameters:

Name Type Description Default
uuid

The UUID to search for.

required

Returns:

Type Description

Cue or None: The found cue, or None if not found.

Source code in src/cuemsutils/cues/CuemsScript.py
177
178
179
180
181
182
183
184
185
186
def find(self, uuid):
    """Find a cue by its UUID in the script.

    Args:
        uuid: The UUID to search for.

    Returns:
        Cue or None: The found cue, or None if not found.
    """
    return self.cuelist.find(uuid)

get_CueList()

Get the main cue list of the script.

Returns:

Name Type Description
CueList CueList

The script's main cue list.

Source code in src/cuemsutils/cues/CuemsScript.py
129
130
131
132
133
134
135
def get_CueList(self) -> CueList:
    """Get the main cue list of the script.

    Returns:
        CueList: The script's main cue list.
    """
    return super().__getitem__('CueList')

get_created()

Get the creation timestamp of the script.

Returns:

Name Type Description
datetime

When the script was created.

Source code in src/cuemsutils/cues/CuemsScript.py
93
94
95
96
97
98
99
def get_created(self):
    """Get the creation timestamp of the script.

    Returns:
        datetime: When the script was created.
    """
    return super().__getitem__('created')

get_description()

Get the description of the script.

Returns:

Name Type Description
str

The script's description.

Source code in src/cuemsutils/cues/CuemsScript.py
75
76
77
78
79
80
81
def get_description(self):
    """Get the description of the script.

    Returns:
        str: The script's description.
    """
    return super().__getitem__('description')

get_id()

Get the unique identifier of the script.

Returns:

Name Type Description
Uuid

The script's unique identifier.

Source code in src/cuemsutils/cues/CuemsScript.py
38
39
40
41
42
43
44
def get_id(self):
    """Get the unique identifier of the script.

    Returns:
        Uuid: The script's unique identifier.
    """
    return super().__getitem__('id')

get_media()

Get all media files referenced in a CueList.

Parameters:

Name Type Description Default
cuelist CueList

The cue list to search in. If not provided, uses the script's main cue list.

required

Returns:

Name Type Description
dict dict

A dictionary mapping Cue UUIDs to their media information.

Source code in src/cuemsutils/cues/CuemsScript.py
188
189
190
191
192
193
194
195
196
197
198
199
@logged
def get_media(self) -> dict:
    """Get all media files referenced in a CueList.

    Args:
        cuelist (CueList, optional): The cue list to search in.
            If not provided, uses the script's main cue list.

    Returns:
        dict: A dictionary mapping Cue UUIDs to their media information.
    """
    return self.cuelist.get_media()

get_media_filenames()

Get all media filenames referenced in a CueList.

Returns:

Name Type Description
list list

A list of media filenames.

Source code in src/cuemsutils/cues/CuemsScript.py
201
202
203
204
205
206
207
208
209
@logged
def get_media_filenames(self) -> list:
    """Get all media filenames referenced in a CueList.

    Returns:
        list: A list of media filenames.
    """
    media_dict = {k: list(v.values())[0] for k, v in self.get_media().items()}
    return unique_values_to_list(media_dict)

get_modified()

Get the last modification timestamp of the script.

Returns:

Name Type Description
datetime

When the script was last modified.

Source code in src/cuemsutils/cues/CuemsScript.py
111
112
113
114
115
116
117
def get_modified(self):
    """Get the last modification timestamp of the script.

    Returns:
        datetime: When the script was last modified.
    """
    return super().__getitem__('modified')

get_name()

Get the name of the script.

Returns:

Name Type Description
str

The script's name.

Source code in src/cuemsutils/cues/CuemsScript.py
57
58
59
60
61
62
63
def get_name(self):
    """Get the name of the script.

    Returns:
        str: The script's name.
    """
    return super().__getitem__('name')

get_own_media(config, cuelist=None)

Get media files that are local to the current node.

Parameters:

Name Type Description Default
cuelist CueList

The cue list to search in. If not provided, uses the script's main cue list.

None
config dict

The configuration containing node information.

required

Returns:

Name Type Description
dict dict

A dictionary mapping media file names to their associated cues that are local to the current node.

Source code in src/cuemsutils/cues/CuemsScript.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
@logged
def get_own_media(self, config: dict, cuelist: CueList | None = None) -> dict:
    """Get media files that are local to the current node.

    Args:
        cuelist (CueList, optional): The cue list to search in.
            If not provided, uses the script's main cue list.
        config: The configuration containing node information.

    Returns:
        dict: A dictionary mapping media file names to their associated cues
            that are local to the current node.
    """
    media_dict = dict()

    # If no cuelist is specified we are looking inside our own
    # script object, so our cuelist is our self cuelist
    if not cuelist:
        cuelist = self.cuelist

    if not cuelist.has_contents():
        return media_dict

    pos = 0
    for cue in cuelist.contents:  # type: ignore[union-attr]
        Logger.debug(f'CuemsScript get_own_media: {pos} {cue}')
        if type(cue) == CueList:
            media_dict.update(
                self.get_own_media(config=config, cuelist=cue)
            )
        elif isinstance(cue, MediaCue) and hasattr(cue.media, 'file_name'):
            Logger.debug(f'get_own_media media cue at {pos}')
            cue.localize_cue(config.node_conf['uuid'])
            if cue._local:
                media_dict[str(cue.id)] = cue.media.file_name
        pos += 1
    return media_dict

get_own_media_filenames(config, cuelist=None)

Get all media filenames that are local to the current node.

Returns:

Name Type Description
list list

A list of media filenames.

Source code in src/cuemsutils/cues/CuemsScript.py
249
250
251
252
253
254
255
256
257
258
@logged
def get_own_media_filenames(self, config: dict, cuelist: CueList | None = None) -> list:
    """Get all media filenames that are local to the current node.

    Returns:
        list: A list of media filenames.
    """
    return unique_values_to_list(
        self.get_own_media(config=config, cuelist=cuelist)
    )

get_ui_properties()

Get the UI properties of the script.

Returns:

Name Type Description
dict CuemsDict

The script's UI properties.

Source code in src/cuemsutils/cues/CuemsScript.py
157
158
159
160
161
162
163
def get_ui_properties(self) -> CuemsDict:
    """Get the UI properties of the script.

    Returns:
        dict: The script's UI properties.
    """
    return super().__getitem__('ui_properties')

items()

Get all items in the script as a dictionary.

Returns:

Name Type Description
dict_items

A view of the script's items.

Source code in src/cuemsutils/cues/CuemsScript.py
302
303
304
305
306
307
308
309
def items(self):
    """Get all items in the script as a dictionary.

    Returns:
        dict_items: A view of the script's items.
    """
    x = dict(super().items())
    return x.items()

set_CueList(cuelist)

Set the main cue list of the script.

Parameters:

Name Type Description Default
cuelist CueList or dict

The new cue list or a dictionary to create one.

required

Raises:

Type Description
ValueError

If the cuelist is not a valid CueList object or dictionary.

Source code in src/cuemsutils/cues/CuemsScript.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def set_CueList(self, cuelist: CueList | dict):
    """Set the main cue list of the script.

    Args:
        cuelist (CueList or dict): The new cue list or a dictionary to create one.

    Raises:
        ValueError: If the cuelist is not a valid CueList object or dictionary.
    """
    if not isinstance(cuelist, CueList):
        try:
            cuelist = CueList(cuelist)
        except:
            raise ValueError(
                f'CueList {cuelist} is not a CueList object or a valid dict'
            )
    super().__setitem__('CueList', cuelist)

set_created(created)

Set the creation timestamp of the script.

Parameters:

Name Type Description Default
created datetime

The new creation timestamp.

required
Source code in src/cuemsutils/cues/CuemsScript.py
101
102
103
104
105
106
107
def set_created(self, created):
    """Set the creation timestamp of the script.

    Args:
        created (datetime): The new creation timestamp.
    """
    super().__setitem__('created', created)

set_description(description)

Set the description of the script.

Parameters:

Name Type Description Default
description str

The new description for the script.

required
Source code in src/cuemsutils/cues/CuemsScript.py
83
84
85
86
87
88
89
def set_description(self, description):
    """Set the description of the script.

    Args:
        description (str): The new description for the script.
    """
    super().__setitem__('description', description)

set_id(id)

Set the unique identifier of the script.

Parameters:

Name Type Description Default
id

The new unique identifier.

required
Source code in src/cuemsutils/cues/CuemsScript.py
46
47
48
49
50
51
52
53
def set_id(self, id):
    """Set the unique identifier of the script.

    Args:
        id: The new unique identifier.
    """
    id = Uuid(id)
    super().__setitem__('id', id)

set_modified(modified)

Set the last modification timestamp of the script.

Parameters:

Name Type Description Default
modified datetime

The new modification timestamp.

required
Source code in src/cuemsutils/cues/CuemsScript.py
119
120
121
122
123
124
125
def set_modified(self, modified):
    """Set the last modification timestamp of the script.

    Args:
        modified (datetime): The new modification timestamp.
    """
    super().__setitem__('modified', modified)

set_name(name)

Set the name of the script.

Parameters:

Name Type Description Default
name str

The new name for the script.

required
Source code in src/cuemsutils/cues/CuemsScript.py
65
66
67
68
69
70
71
def set_name(self, name):
    """Set the name of the script.

    Args:
        name (str): The new name for the script.
    """
    super().__setitem__('name', name)

set_ui_properties(ui_properties)

Set the UI properties of the script.

Parameters:

Name Type Description Default
ui_properties dict

The new UI properties.

required
Source code in src/cuemsutils/cues/CuemsScript.py
165
166
167
168
169
170
171
172
173
def set_ui_properties(self, ui_properties: dict | CuemsDict):
    """Set the UI properties of the script.

    Args:
        ui_properties (dict): The new UI properties.
    """
    Logger.debug(f"Setting ui_properties to {ui_properties}")
    ui_properties = as_cuemsdict(ui_properties)
    super().__setitem__('ui_properties', ui_properties)

setter(settings)

Set the object properties from a dictionary.

Parameters:

Name Type Description Default
settings dict

Dictionary containing property values to set.

required

Raises:

Type Description
AttributeError

If settings is not a dictionary.

Source code in src/cuemsutils/cues/CuemsScript.py
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
def setter(self, settings: dict):
    """Set the object properties from a dictionary.

    Args:
        settings (dict): Dictionary containing property values to set.

    Raises:
        AttributeError: If settings is not a dictionary.
    """
    if not isinstance(settings, dict):
        raise AttributeError(f"Invalid type {type(settings)}. Expected dict.")
    for k, v in settings.items():
        try:
            x = getattr(self, f"set_{k}")
            x(v)
        except AttributeError:
            pass

to_json()

Convert the script to a JSON string.

Returns:

Name Type Description
str

A JSON string representation of the script.

Source code in src/cuemsutils/cues/CuemsScript.py
260
261
262
263
264
265
266
def to_json(self):
    """Convert the script to a JSON string.

    Returns:
        str: A JSON string representation of the script.
    """
    return json.dumps({'CuemsScript': self})

Cue output configurations.

See docs/canvas_region.md for the coordinate model, alias-vs-custom discrimination, V1 caps, and deferred items (aspect ratio, z-order, off-canvas, multi-custom, drag/resize).

AudioCueOutput

Bases: CueOutput

Output configuration for audio cues.

Free-form output_name; no canvas/region concerns. Left unvalidated by design — audio channels use domain-specific names (e.g. 'system:playback_1').

Source code in src/cuemsutils/cues/CueOutput.py
111
112
113
114
115
116
117
class AudioCueOutput(CueOutput):
    """Output configuration for audio cues.

    Free-form output_name; no canvas/region concerns. Left unvalidated by design
    — audio channels use domain-specific names (e.g. 'system:playback_1').
    """
    pass

CueOutput

Bases: CuemsDict

Base class for cue output configurations.

This class provides the basic structure for configuring how cues are output to different types of devices or systems.

Source code in src/cuemsutils/cues/CueOutput.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
class CueOutput(CuemsDict):
    """Base class for cue output configurations.

    This class provides the basic structure for configuring how cues are output
    to different types of devices or systems.
    """

    def __init__(self, init_dict=None):
        """Initialize a CueOutput.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if init_dict:
            super().__init__(init_dict)

    def __json__(self):
        """Convert the output configuration to a JSON-compatible dictionary.

        Returns:
            dict: A dictionary representation of the output configuration.
        """
        return {type(self).__name__: dict(self.items())}

__init__(init_dict=None)

Initialize a CueOutput.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/CueOutput.py
 92
 93
 94
 95
 96
 97
 98
 99
100
def __init__(self, init_dict=None):
    """Initialize a CueOutput.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if init_dict:
        super().__init__(init_dict)

__json__()

Convert the output configuration to a JSON-compatible dictionary.

Returns:

Name Type Description
dict

A dictionary representation of the output configuration.

Source code in src/cuemsutils/cues/CueOutput.py
102
103
104
105
106
107
108
def __json__(self):
    """Convert the output configuration to a JSON-compatible dictionary.

    Returns:
        dict: A dictionary representation of the output configuration.
    """
    return {type(self).__name__: dict(self.items())}

DmxCueOutput

Bases: CueOutput

Output configuration for DMX cues.

Free-form output_name; left unvalidated by design.

Source code in src/cuemsutils/cues/CueOutput.py
239
240
241
242
243
244
class DmxCueOutput(CueOutput):
    """Output configuration for DMX cues.

    Free-form output_name; left unvalidated by design.
    """
    pass

VideoCueOutput

Bases: CueOutput

Output configuration for video cues.

Two modes distinguished by output_name shape:

  • Alias (<node_uuid>_<int>): references a monitor-resolved entry from project_mappings. canvas_region must be absent.
  • Custom (<node_uuid>_custom_<int>): per-cue custom region on this node's canvas. canvas_region is required and carries normalized floats in [0, 1].

Note: this is the per-cue canvas_region — the authoritative placement of a cue's output on the node's virtual canvas at playback time. The UI-template canvas_region in project_mappings.xsd VideoPutType is a separate concept (a default rectangle offered by the editor when authoring a custom cue); it is neither a physical display-layout directive nor a substitute for this field.

Source code in src/cuemsutils/cues/CueOutput.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
class VideoCueOutput(CueOutput):
    """Output configuration for video cues.

    Two modes distinguished by ``output_name`` shape:

    * Alias (``<node_uuid>_<int>``): references a monitor-resolved entry from
      project_mappings. ``canvas_region`` must be absent.
    * Custom (``<node_uuid>_custom_<int>``): per-cue custom region on this
      node's canvas. ``canvas_region`` is required and carries normalized
      floats in ``[0, 1]``.

    Note: this is the per-cue canvas_region — the authoritative placement
    of a cue's output on the node's virtual canvas at playback time.
    The UI-template canvas_region in ``project_mappings.xsd``
    ``VideoPutType`` is a separate concept (a default rectangle offered
    by the editor when authoring a custom cue); it is neither a
    physical display-layout directive nor a substitute for this field.
    """

    def __init__(self, init_dict=None):
        """Initialize a VideoCueOutput.

        Raises:
            ValueError: On malformed ``output_name``, wrong ``canvas_region``
                presence for the detected mode, or invalid region shape/values.
        """
        self._initialized = False
        if init_dict is None:
            super().__init__()
            self._initialized = True
            return

        init_dict = dict(init_dict)
        output_name = init_dict.get('output_name')
        kind = _classify_output_name(output_name)

        canvas_region = init_dict.get('canvas_region')
        if kind == 'alias' and canvas_region is not None:
            raise ValueError(
                f"canvas_region must be absent for alias output_name "
                f"{output_name!r}"
            )
        if kind == 'custom' and canvas_region is None:
            raise ValueError(
                f"canvas_region is required for custom output_name "
                f"{output_name!r}"
            )
        if canvas_region is not None:
            init_dict['canvas_region'] = _validate_canvas_region(canvas_region)

        super().__init__(init_dict)
        self._initialized = True

    def get_output_name(self) -> str:
        return super().__getitem__('output_name')

    def set_output_name(self, output_name: str) -> None:
        kind = _classify_output_name(output_name)
        if getattr(self, '_initialized', False):
            has_region = 'canvas_region' in self
            if kind == 'alias' and has_region:
                raise ValueError(
                    f"cannot change output_name to alias {output_name!r} "
                    f"while canvas_region is set"
                )
            if kind == 'custom' and not has_region:
                raise ValueError(
                    f"cannot change output_name to custom {output_name!r} "
                    f"without setting canvas_region first"
                )
        super().__setitem__('output_name', output_name)

    output_name = property(get_output_name, set_output_name)

    def get_canvas_region(self):
        return super().__getitem__('canvas_region') if 'canvas_region' in self else None

    def set_canvas_region(self, canvas_region) -> None:
        if canvas_region is None:
            if getattr(self, '_initialized', False):
                output_name = super().__getitem__('output_name')
                if _classify_output_name(output_name) == 'custom':
                    raise ValueError(
                        f"canvas_region cannot be cleared on custom output "
                        f"{output_name!r}"
                    )
            if 'canvas_region' in self:
                super().__delitem__('canvas_region')
            return

        validated = _validate_canvas_region(canvas_region)
        if getattr(self, '_initialized', False):
            output_name = super().__getitem__('output_name')
            if _classify_output_name(output_name) == 'alias':
                raise ValueError(
                    f"canvas_region cannot be set on alias output "
                    f"{output_name!r}"
                )
        super().__setitem__('canvas_region', validated)

    canvas_region = property(get_canvas_region, set_canvas_region)

    def items(self):
        """Return items in XSD element order: output_name, output_geometry, canvas_region.

        canvas_region is emitted only when present.
        """
        ordered = {}
        for key in ('output_name', 'output_geometry'):
            if key in self:
                ordered[key] = super().__getitem__(key)
        if 'canvas_region' in self:
            ordered['canvas_region'] = super().__getitem__('canvas_region')
        for key, value in super().items():
            if key not in ordered:
                ordered[key] = value
        return ordered.items()

__init__(init_dict=None)

Initialize a VideoCueOutput.

Raises:

Type Description
ValueError

On malformed output_name, wrong canvas_region presence for the detected mode, or invalid region shape/values.

Source code in src/cuemsutils/cues/CueOutput.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
def __init__(self, init_dict=None):
    """Initialize a VideoCueOutput.

    Raises:
        ValueError: On malformed ``output_name``, wrong ``canvas_region``
            presence for the detected mode, or invalid region shape/values.
    """
    self._initialized = False
    if init_dict is None:
        super().__init__()
        self._initialized = True
        return

    init_dict = dict(init_dict)
    output_name = init_dict.get('output_name')
    kind = _classify_output_name(output_name)

    canvas_region = init_dict.get('canvas_region')
    if kind == 'alias' and canvas_region is not None:
        raise ValueError(
            f"canvas_region must be absent for alias output_name "
            f"{output_name!r}"
        )
    if kind == 'custom' and canvas_region is None:
        raise ValueError(
            f"canvas_region is required for custom output_name "
            f"{output_name!r}"
        )
    if canvas_region is not None:
        init_dict['canvas_region'] = _validate_canvas_region(canvas_region)

    super().__init__(init_dict)
    self._initialized = True

items()

Return items in XSD element order: output_name, output_geometry, canvas_region.

canvas_region is emitted only when present.

Source code in src/cuemsutils/cues/CueOutput.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def items(self):
    """Return items in XSD element order: output_name, output_geometry, canvas_region.

    canvas_region is emitted only when present.
    """
    ordered = {}
    for key in ('output_name', 'output_geometry'):
        if key in self:
            ordered[key] = super().__getitem__(key)
    if 'canvas_region' in self:
        ordered['canvas_region'] = super().__getitem__('canvas_region')
    for key, value in super().items():
        if key not in ordered:
            ordered[key] = value
    return ordered.items()

DmxChannel

Bases: CuemsDict

A class representing a single DMX channel.

Source code in src/cuemsutils/cues/DmxCue.py
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
class DmxChannel(CuemsDict):
    """A class representing a single DMX channel."""

    def __init__(self, init_dict = None):
        """Initialize a DMX channel.

        Args:
            value (int, optional): The initial channel value.
            init_dict (dict, optional): Dictionary containing initialization values.
        """
        if not init_dict:
            init_dict = DMXCHANNEL_REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, DMXCHANNEL_REQ_ITEMS)
        if init_dict:
            self.setter(init_dict)



    def get_channel(self):
        """Get the channel number.

        Returns:
            int: The channel number.
        """
        return super().__getitem__('channel')

    def set_channel(self, channel):
        """Set the channel number.

        Args:
            num (int): The new channel number.
        """
        super().__setitem__('channel', channel)
    channel = property(get_channel, set_channel)

    def get_value(self):
        """Get the channel value.

        Returns:
            int: The channel value.
        """
        return super().__getitem__('value')

    def set_value(self, value):
        """Set the channel value.

        Args:
            value (int): The new channel value.
        """
        super().__setitem__('value', value)
    value = property(get_value, set_value)

    def __json__(self):
        """Convert the region to a JSON-compatible dictionary.

        Returns:
            dict: A dictionary representation of the region.
        """
        return {type(self).__name__: dict(self.items())}

__init__(init_dict=None)

Initialize a DMX channel.

Parameters:

Name Type Description Default
value int

The initial channel value.

required
init_dict dict

Dictionary containing initialization values.

None
Source code in src/cuemsutils/cues/DmxCue.py
424
425
426
427
428
429
430
431
432
433
434
435
436
def __init__(self, init_dict = None):
    """Initialize a DMX channel.

    Args:
        value (int, optional): The initial channel value.
        init_dict (dict, optional): Dictionary containing initialization values.
    """
    if not init_dict:
        init_dict = DMXCHANNEL_REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, DMXCHANNEL_REQ_ITEMS)
    if init_dict:
        self.setter(init_dict)

__json__()

Convert the region to a JSON-compatible dictionary.

Returns:

Name Type Description
dict

A dictionary representation of the region.

Source code in src/cuemsutils/cues/DmxCue.py
474
475
476
477
478
479
480
def __json__(self):
    """Convert the region to a JSON-compatible dictionary.

    Returns:
        dict: A dictionary representation of the region.
    """
    return {type(self).__name__: dict(self.items())}

get_channel()

Get the channel number.

Returns:

Name Type Description
int

The channel number.

Source code in src/cuemsutils/cues/DmxCue.py
440
441
442
443
444
445
446
def get_channel(self):
    """Get the channel number.

    Returns:
        int: The channel number.
    """
    return super().__getitem__('channel')

get_value()

Get the channel value.

Returns:

Name Type Description
int

The channel value.

Source code in src/cuemsutils/cues/DmxCue.py
457
458
459
460
461
462
463
def get_value(self):
    """Get the channel value.

    Returns:
        int: The channel value.
    """
    return super().__getitem__('value')

set_channel(channel)

Set the channel number.

Parameters:

Name Type Description Default
num int

The new channel number.

required
Source code in src/cuemsutils/cues/DmxCue.py
448
449
450
451
452
453
454
def set_channel(self, channel):
    """Set the channel number.

    Args:
        num (int): The new channel number.
    """
    super().__setitem__('channel', channel)

set_value(value)

Set the channel value.

Parameters:

Name Type Description Default
value int

The new channel value.

required
Source code in src/cuemsutils/cues/DmxCue.py
465
466
467
468
469
470
471
def set_value(self, value):
    """Set the channel value.

    Args:
        value (int): The new channel value.
    """
    super().__setitem__('value', value)

DmxCue

Bases: Cue

A cue for handling DMX lighting control.

This class extends Cue to provide specific functionality for DMX lighting control, including scene management, fade timing, and OSC communication for DMX routing.

Source code in src/cuemsutils/cues/DmxCue.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
class DmxCue(Cue):
    """A cue for handling DMX lighting control.

    This class extends Cue to provide specific functionality for DMX lighting control,
    including scene management, fade timing, and OSC communication for DMX routing.
    """

    def __init__(self, init_dict = None):
        """Initialize a DmxCue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if not init_dict:
            init_dict = REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
        super().__init__(init_dict)

        self._player = None
        self._osc_route = None
        self._offset_route = '/offset'

    def get_fadein_time(self):
        """Get the fade-in time for the DMX cue.

        Returns:
            The fade-in time value.
        """
        return super().__getitem__('fadein_time')

    def set_fadein_time(self, fadein_time):
        """Set the fade-in time for the DMX cue.

        Args:
            fadein_time: The new fade-in time value.
        """
        super().__setitem__('fadein_time', fadein_time)

    fadein_time = property(get_fadein_time, set_fadein_time)

    def get_fadeout_time(self):
        """Get the fade-out time for the DMX cue.

        Returns:
            The fade-out time value.
        """
        return super().__getitem__('fadeout_time')


    def set_fadeout_time(self, fadeout_time):
        """Set the fade-out time for the DMX cue.

        Args:
            fadeout_time: The new fade-out time value.
        """
        super().__setitem__('fadeout_time', fadeout_time)

    fadeout_time = property(get_fadeout_time, set_fadeout_time)

    def get_outputs(self):
        """Get the output routing configuration.

        Returns:
            list: The list of output configurations.
        """
        return super().__getitem__('outputs')

    def set_outputs(self, outputs):
        """Set the output routing configuration.

        Args:
            outputs (list): The list of output configurations. Each item can be
                a DmxCueOutput object or a dict that will be converted to DmxCueOutput.
        """
        if outputs is None:
            super().__setitem__('outputs', None)
            return

        if not isinstance(outputs, list):
            outputs = [outputs]

        converted_outputs = []
        for output in outputs:
            if output is None:
                continue
            if not isinstance(output, DmxCueOutput):
                if isinstance(output, dict):
                    if 'DmxCueOutput' in output:
                        inner = output['DmxCueOutput']
                        # XML converter may produce a list of dicts for the inner value
                        if isinstance(inner, list):
                            for item in inner:
                                if isinstance(item, dict):
                                    converted_outputs.append(DmxCueOutput(item))
                        elif isinstance(inner, dict):
                            converted_outputs.append(DmxCueOutput(inner))
                    else:
                        converted_outputs.append(DmxCueOutput(output))
                else:
                    converted_outputs.append(output)
            else:
                converted_outputs.append(output)

        super().__setitem__('outputs', converted_outputs)

    outputs = property(get_outputs, set_outputs)

    def get_DmxScene(self):
        """Get the DMX scene for this cue.

        Returns:
            DmxScene: The current DMX scene.
        """
        return super().__getitem__('DmxScene')


    def set_DmxScene(self, dmxscene):
        """Set the DMX scene for this cue.

        Args:
            dmxscene (DmxScene or dict): The new DMX scene or a dictionary to create one.

        Raises:
            NotImplementedError: If the scene type is not supported.
        """
        if not isinstance(dmxscene, DmxScene):
            dmxscene = DmxScene(dmxscene)
        super().__setitem__('DmxScene', dmxscene)

    DmxScene = property(get_DmxScene, set_DmxScene)

    def osc_route(self, osc_route):
        """Set the OSC route for DMX control.

        Args:
            osc_route (str): The OSC route to use for DMX control.
        """
        self._osc_route = osc_route

    def offset_route(self, offset_route):
        """Set the offset route for DMX timing.

        Args:
            offset_route (str): The new offset route.
        """
        self._offset_route = offset_route

    def player(self, player):
        """Set the DMX player instance.

        Args:
            player: The DMX player instance to use.
        """
        self._player = player

    def review_offset(self, timecode):
        """Calculate the offset for DMX timing review.

        Args:
            timecode: The timecode to calculate the offset from.

        Returns:
            float: The calculated offset in milliseconds.
        """
        return -timecode.milliseconds_exact

    def check_mappings(self, settings):
        """Check if the DMX output mappings are valid.

        For DMX cues, the output_name format is "{node_uuid}" (just the node UUID).
        A DMX cue can have multiple outputs (one per target node). This method
        iterates through all outputs and sets _local=True if ANY output_name
        matches the current node UUID. Other outputs are ignored.

        Args:
            settings: The settings containing project node mappings.

        Returns:
            bool: True if the mappings are valid, False otherwise.
        """
        # Call parent check_mappings first
        if not super().check_mappings(settings):
            return False

        if not settings.project_node_mappings:
            return True

        # Initialize _local to False (will be set to True if any output matches)
        self._local = False

        # Get current node UUID
        current_node_uuid = settings.node_conf.get('uuid')
        if not current_node_uuid:
            Logger.warning(f'DmxCue {self.id}: No node UUID found in settings')
            return True

        # Check each output
        if self.outputs:
            for output in self.outputs:
                # For DMX cues, output_name is just the node UUID (not {node_uuid}_{output_name})
                output_name = output.get('output_name', '')

                # Compare entire output_name with current node UUID
                if output_name == current_node_uuid:
                    self._local = True
                    Logger.debug(
                        f'DmxCue {self.id} output_name {output_name} matches current node, setting _local=True'
                    )
                    break  # Found a match, no need to check other outputs

        return True

    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items, with required items included.
        """
        x = dict(super().items())
        for k in REQ_ITEMS.keys():
            x[k] = self[k]
        return x.items()

__init__(init_dict=None)

Initialize a DmxCue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/DmxCue.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def __init__(self, init_dict = None):
    """Initialize a DmxCue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if not init_dict:
        init_dict = REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
    super().__init__(init_dict)

    self._player = None
    self._osc_route = None
    self._offset_route = '/offset'

check_mappings(settings)

Check if the DMX output mappings are valid.

For DMX cues, the output_name format is "{node_uuid}" (just the node UUID). A DMX cue can have multiple outputs (one per target node). This method iterates through all outputs and sets _local=True if ANY output_name matches the current node UUID. Other outputs are ignored.

Parameters:

Name Type Description Default
settings

The settings containing project node mappings.

required

Returns:

Name Type Description
bool

True if the mappings are valid, False otherwise.

Source code in src/cuemsutils/cues/DmxCue.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
def check_mappings(self, settings):
    """Check if the DMX output mappings are valid.

    For DMX cues, the output_name format is "{node_uuid}" (just the node UUID).
    A DMX cue can have multiple outputs (one per target node). This method
    iterates through all outputs and sets _local=True if ANY output_name
    matches the current node UUID. Other outputs are ignored.

    Args:
        settings: The settings containing project node mappings.

    Returns:
        bool: True if the mappings are valid, False otherwise.
    """
    # Call parent check_mappings first
    if not super().check_mappings(settings):
        return False

    if not settings.project_node_mappings:
        return True

    # Initialize _local to False (will be set to True if any output matches)
    self._local = False

    # Get current node UUID
    current_node_uuid = settings.node_conf.get('uuid')
    if not current_node_uuid:
        Logger.warning(f'DmxCue {self.id}: No node UUID found in settings')
        return True

    # Check each output
    if self.outputs:
        for output in self.outputs:
            # For DMX cues, output_name is just the node UUID (not {node_uuid}_{output_name})
            output_name = output.get('output_name', '')

            # Compare entire output_name with current node UUID
            if output_name == current_node_uuid:
                self._local = True
                Logger.debug(
                    f'DmxCue {self.id} output_name {output_name} matches current node, setting _local=True'
                )
                break  # Found a match, no need to check other outputs

    return True

get_DmxScene()

Get the DMX scene for this cue.

Returns:

Name Type Description
DmxScene

The current DMX scene.

Source code in src/cuemsutils/cues/DmxCue.py
138
139
140
141
142
143
144
def get_DmxScene(self):
    """Get the DMX scene for this cue.

    Returns:
        DmxScene: The current DMX scene.
    """
    return super().__getitem__('DmxScene')

get_fadein_time()

Get the fade-in time for the DMX cue.

Returns:

Type Description

The fade-in time value.

Source code in src/cuemsutils/cues/DmxCue.py
53
54
55
56
57
58
59
def get_fadein_time(self):
    """Get the fade-in time for the DMX cue.

    Returns:
        The fade-in time value.
    """
    return super().__getitem__('fadein_time')

get_fadeout_time()

Get the fade-out time for the DMX cue.

Returns:

Type Description

The fade-out time value.

Source code in src/cuemsutils/cues/DmxCue.py
71
72
73
74
75
76
77
def get_fadeout_time(self):
    """Get the fade-out time for the DMX cue.

    Returns:
        The fade-out time value.
    """
    return super().__getitem__('fadeout_time')

get_outputs()

Get the output routing configuration.

Returns:

Name Type Description
list

The list of output configurations.

Source code in src/cuemsutils/cues/DmxCue.py
90
91
92
93
94
95
96
def get_outputs(self):
    """Get the output routing configuration.

    Returns:
        list: The list of output configurations.
    """
    return super().__getitem__('outputs')

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items, with required items included.

Source code in src/cuemsutils/cues/DmxCue.py
243
244
245
246
247
248
249
250
251
252
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items, with required items included.
    """
    x = dict(super().items())
    for k in REQ_ITEMS.keys():
        x[k] = self[k]
    return x.items()

offset_route(offset_route)

Set the offset route for DMX timing.

Parameters:

Name Type Description Default
offset_route str

The new offset route.

required
Source code in src/cuemsutils/cues/DmxCue.py
170
171
172
173
174
175
176
def offset_route(self, offset_route):
    """Set the offset route for DMX timing.

    Args:
        offset_route (str): The new offset route.
    """
    self._offset_route = offset_route

osc_route(osc_route)

Set the OSC route for DMX control.

Parameters:

Name Type Description Default
osc_route str

The OSC route to use for DMX control.

required
Source code in src/cuemsutils/cues/DmxCue.py
162
163
164
165
166
167
168
def osc_route(self, osc_route):
    """Set the OSC route for DMX control.

    Args:
        osc_route (str): The OSC route to use for DMX control.
    """
    self._osc_route = osc_route

player(player)

Set the DMX player instance.

Parameters:

Name Type Description Default
player

The DMX player instance to use.

required
Source code in src/cuemsutils/cues/DmxCue.py
178
179
180
181
182
183
184
def player(self, player):
    """Set the DMX player instance.

    Args:
        player: The DMX player instance to use.
    """
    self._player = player

review_offset(timecode)

Calculate the offset for DMX timing review.

Parameters:

Name Type Description Default
timecode

The timecode to calculate the offset from.

required

Returns:

Name Type Description
float

The calculated offset in milliseconds.

Source code in src/cuemsutils/cues/DmxCue.py
186
187
188
189
190
191
192
193
194
195
def review_offset(self, timecode):
    """Calculate the offset for DMX timing review.

    Args:
        timecode: The timecode to calculate the offset from.

    Returns:
        float: The calculated offset in milliseconds.
    """
    return -timecode.milliseconds_exact

set_DmxScene(dmxscene)

Set the DMX scene for this cue.

Parameters:

Name Type Description Default
dmxscene DmxScene or dict

The new DMX scene or a dictionary to create one.

required

Raises:

Type Description
NotImplementedError

If the scene type is not supported.

Source code in src/cuemsutils/cues/DmxCue.py
147
148
149
150
151
152
153
154
155
156
157
158
def set_DmxScene(self, dmxscene):
    """Set the DMX scene for this cue.

    Args:
        dmxscene (DmxScene or dict): The new DMX scene or a dictionary to create one.

    Raises:
        NotImplementedError: If the scene type is not supported.
    """
    if not isinstance(dmxscene, DmxScene):
        dmxscene = DmxScene(dmxscene)
    super().__setitem__('DmxScene', dmxscene)

set_fadein_time(fadein_time)

Set the fade-in time for the DMX cue.

Parameters:

Name Type Description Default
fadein_time

The new fade-in time value.

required
Source code in src/cuemsutils/cues/DmxCue.py
61
62
63
64
65
66
67
def set_fadein_time(self, fadein_time):
    """Set the fade-in time for the DMX cue.

    Args:
        fadein_time: The new fade-in time value.
    """
    super().__setitem__('fadein_time', fadein_time)

set_fadeout_time(fadeout_time)

Set the fade-out time for the DMX cue.

Parameters:

Name Type Description Default
fadeout_time

The new fade-out time value.

required
Source code in src/cuemsutils/cues/DmxCue.py
80
81
82
83
84
85
86
def set_fadeout_time(self, fadeout_time):
    """Set the fade-out time for the DMX cue.

    Args:
        fadeout_time: The new fade-out time value.
    """
    super().__setitem__('fadeout_time', fadeout_time)

set_outputs(outputs)

Set the output routing configuration.

Parameters:

Name Type Description Default
outputs list

The list of output configurations. Each item can be a DmxCueOutput object or a dict that will be converted to DmxCueOutput.

required
Source code in src/cuemsutils/cues/DmxCue.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def set_outputs(self, outputs):
    """Set the output routing configuration.

    Args:
        outputs (list): The list of output configurations. Each item can be
            a DmxCueOutput object or a dict that will be converted to DmxCueOutput.
    """
    if outputs is None:
        super().__setitem__('outputs', None)
        return

    if not isinstance(outputs, list):
        outputs = [outputs]

    converted_outputs = []
    for output in outputs:
        if output is None:
            continue
        if not isinstance(output, DmxCueOutput):
            if isinstance(output, dict):
                if 'DmxCueOutput' in output:
                    inner = output['DmxCueOutput']
                    # XML converter may produce a list of dicts for the inner value
                    if isinstance(inner, list):
                        for item in inner:
                            if isinstance(item, dict):
                                converted_outputs.append(DmxCueOutput(item))
                    elif isinstance(inner, dict):
                        converted_outputs.append(DmxCueOutput(inner))
                else:
                    converted_outputs.append(DmxCueOutput(output))
            else:
                converted_outputs.append(output)
        else:
            converted_outputs.append(output)

    super().__setitem__('outputs', converted_outputs)

DmxScene

Bases: CuemsDict

A class representing a DMX scene containing multiple universes.

Source code in src/cuemsutils/cues/DmxCue.py
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
class DmxScene(CuemsDict):
    """A class representing a DMX scene containing multiple universes."""

    def __init__(self, init_dict=None):
        """Initialize a DMX scene.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to create DMX universes.
        """
        if not init_dict:
            init_dict = SCENE_REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, SCENE_REQ_ITEMS)
        if init_dict:
            self.setter(init_dict)

    def get_id(self):
        """Get the scene ID.

        Returns:
            int: The scene ID.
        """
        return super().__getitem__('id')

    def set_id(self, scene_id):
        """Set the scene ID.

        Args:
            scene_id (int): The new scene ID.
        """
        super().__setitem__('id', scene_id)
    id = property(get_id, set_id)
    def get_DmxUniverse(self):
        """Get a specific DMX universe.

        Args:
            num (int, optional): The universe number to get.
                If None, returns None.

        Returns:
            DmxUniverse or None: The requested universe or None if not found.
        """
        return super().__getitem__('DmxUniverse')



    def set_DmxUniverse(self, universe):
        """Set a DMX universe at a specific number.

        Args:
            universe: The universe to set.
            num (int, optional): The universe number. Defaults to 0.
        """
        if not isinstance(universe, DmxUniverse):
            universe = DmxUniverse(universe)
        super().__setitem__('DmxUniverse', universe)

    DmxUniverse = property(get_DmxUniverse, set_DmxUniverse)

__init__(init_dict=None)

Initialize a DMX scene.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to create DMX universes.

None
Source code in src/cuemsutils/cues/DmxCue.py
257
258
259
260
261
262
263
264
265
266
267
268
269
def __init__(self, init_dict=None):
    """Initialize a DMX scene.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to create DMX universes.
    """
    if not init_dict:
        init_dict = SCENE_REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, SCENE_REQ_ITEMS)
    if init_dict:
        self.setter(init_dict)

get_DmxUniverse()

Get a specific DMX universe.

Parameters:

Name Type Description Default
num int

The universe number to get. If None, returns None.

required

Returns:

Type Description

DmxUniverse or None: The requested universe or None if not found.

Source code in src/cuemsutils/cues/DmxCue.py
287
288
289
290
291
292
293
294
295
296
297
def get_DmxUniverse(self):
    """Get a specific DMX universe.

    Args:
        num (int, optional): The universe number to get.
            If None, returns None.

    Returns:
        DmxUniverse or None: The requested universe or None if not found.
    """
    return super().__getitem__('DmxUniverse')

get_id()

Get the scene ID.

Returns:

Name Type Description
int

The scene ID.

Source code in src/cuemsutils/cues/DmxCue.py
271
272
273
274
275
276
277
def get_id(self):
    """Get the scene ID.

    Returns:
        int: The scene ID.
    """
    return super().__getitem__('id')

set_DmxUniverse(universe)

Set a DMX universe at a specific number.

Parameters:

Name Type Description Default
universe

The universe to set.

required
num int

The universe number. Defaults to 0.

required
Source code in src/cuemsutils/cues/DmxCue.py
301
302
303
304
305
306
307
308
309
310
def set_DmxUniverse(self, universe):
    """Set a DMX universe at a specific number.

    Args:
        universe: The universe to set.
        num (int, optional): The universe number. Defaults to 0.
    """
    if not isinstance(universe, DmxUniverse):
        universe = DmxUniverse(universe)
    super().__setitem__('DmxUniverse', universe)

set_id(scene_id)

Set the scene ID.

Parameters:

Name Type Description Default
scene_id int

The new scene ID.

required
Source code in src/cuemsutils/cues/DmxCue.py
279
280
281
282
283
284
285
def set_id(self, scene_id):
    """Set the scene ID.

    Args:
        scene_id (int): The new scene ID.
    """
    super().__setitem__('id', scene_id)

DmxUniverse

Bases: CuemsDict

A class representing a DMX universe containing multiple channels.

Source code in src/cuemsutils/cues/DmxCue.py
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
class DmxUniverse(CuemsDict):
    """A class representing a DMX universe containing multiple channels."""

    def __init__(self, init_dict=None):
        """Initialize a DMX universe.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to create DMX channels.
        """
        if not init_dict:
            init_dict = UNIVERSE_REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, UNIVERSE_REQ_ITEMS)
        if init_dict:
            self.setter(init_dict)

    def get_universe_num(self):
        """Get the universe number.

        Returns:
            int: The universe number.
        """
        return super().__getitem__('universe_num')

    def set_universe_num(self, universe_num):
        """Set the universe number.

        Args:
            universe_num (int): The new universe number.
        """
        super().__setitem__('universe_num', universe_num)
    universe_num = property(get_universe_num, set_universe_num)

    def get_dmx_channels(self):
        """Get the dmx channel for the scene.

        Returns:
            list: The list of dmx channels.
        """
        return super().__getitem__('dmx_channels')

    def set_dmx_channels(self, channels):
        """Set the output routing configuration.

        Args:
            channels (list): The list of output configurations.
        """
        Logger.info("DmxUniverse set_channels called with channels: {}".format(channels))
        if not isinstance(channels, list):
            channels = [channels]
        channel_list = []
        Logger.debug(f'Channels to process: {channels} Type: {type(channels)}')
        try:
            for r in channels:
                    if r is not None:
                        Logger.debug(f'Processing channel: {r}')
                        if not isinstance(r, DmxChannel):
                            Logger.debug(f"Converting to DmxChannel: {r['DmxChannel']}")
                            new_dmxchannel = DmxChannel(r['DmxChannel'])
                            channel_list.append(new_dmxchannel)
                            super().__setitem__('dmx_channels', channel_list)
                        else:
                            super().__setitem__('dmx_channels', channels)
        except Exception as e:
            Logger.error(f"Error converting channels to DmxChannel: {e}")
            super().__setitem__('dmx_channels', channels)


    dmx_channels = property(get_dmx_channels, set_dmx_channels)

__init__(init_dict=None)

Initialize a DMX universe.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to create DMX channels.

None
Source code in src/cuemsutils/cues/DmxCue.py
326
327
328
329
330
331
332
333
334
335
336
337
338
def __init__(self, init_dict=None):
    """Initialize a DMX universe.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to create DMX channels.
    """
    if not init_dict:
        init_dict = UNIVERSE_REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, UNIVERSE_REQ_ITEMS)
    if init_dict:
        self.setter(init_dict)

get_dmx_channels()

Get the dmx channel for the scene.

Returns:

Name Type Description
list

The list of dmx channels.

Source code in src/cuemsutils/cues/DmxCue.py
357
358
359
360
361
362
363
def get_dmx_channels(self):
    """Get the dmx channel for the scene.

    Returns:
        list: The list of dmx channels.
    """
    return super().__getitem__('dmx_channels')

get_universe_num()

Get the universe number.

Returns:

Name Type Description
int

The universe number.

Source code in src/cuemsutils/cues/DmxCue.py
340
341
342
343
344
345
346
def get_universe_num(self):
    """Get the universe number.

    Returns:
        int: The universe number.
    """
    return super().__getitem__('universe_num')

set_dmx_channels(channels)

Set the output routing configuration.

Parameters:

Name Type Description Default
channels list

The list of output configurations.

required
Source code in src/cuemsutils/cues/DmxCue.py
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
def set_dmx_channels(self, channels):
    """Set the output routing configuration.

    Args:
        channels (list): The list of output configurations.
    """
    Logger.info("DmxUniverse set_channels called with channels: {}".format(channels))
    if not isinstance(channels, list):
        channels = [channels]
    channel_list = []
    Logger.debug(f'Channels to process: {channels} Type: {type(channels)}')
    try:
        for r in channels:
                if r is not None:
                    Logger.debug(f'Processing channel: {r}')
                    if not isinstance(r, DmxChannel):
                        Logger.debug(f"Converting to DmxChannel: {r['DmxChannel']}")
                        new_dmxchannel = DmxChannel(r['DmxChannel'])
                        channel_list.append(new_dmxchannel)
                        super().__setitem__('dmx_channels', channel_list)
                    else:
                        super().__setitem__('dmx_channels', channels)
    except Exception as e:
        Logger.error(f"Error converting channels to DmxChannel: {e}")
        super().__setitem__('dmx_channels', channels)

set_universe_num(universe_num)

Set the universe number.

Parameters:

Name Type Description Default
universe_num int

The new universe number.

required
Source code in src/cuemsutils/cues/DmxCue.py
348
349
350
351
352
353
354
def set_universe_num(self, universe_num):
    """Set the universe number.

    Args:
        universe_num (int): The new universe number.
    """
    super().__setitem__('universe_num', universe_num)

FadeCue

Bases: ActionCue

A cue that fades a target cue's level to a specified value over a duration.

FadeCue stores all parameters needed by the show engine to execute a smooth level transition: the target cue identifier (inherited from ActionCue), the curve shape, the fade duration, and the destination level.

The starting level is recovered from the live runtime state by the engine; FadeCue does not store it.

Source code in src/cuemsutils/cues/FadeCue.py
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
class FadeCue(ActionCue):
    """A cue that fades a target cue's level to a specified value over a duration.

    FadeCue stores all parameters needed by the show engine to execute a smooth
    level transition: the target cue identifier (inherited from ActionCue),
    the curve shape, the fade duration, and the destination level.

    The starting level is recovered from the live runtime state by the engine;
    FadeCue does not store it.
    """

    def __init__(self, init_dict: dict = None):
        """Initialise a FadeCue.

        Args:
            init_dict (dict, optional): Initialisation values. When omitted,
                defaults from REQ_ITEMS are used.

        Raises:
            ValueError: If init_dict explicitly sets action_target to None.
            ValueError: If init_dict sets action_type to a value other than
                'fade_action'.
        """
        if init_dict:
            if init_dict.get('action_type', 'fade_action') != 'fade_action':
                raise ValueError(
                    "action_type must be 'fade_action' for FadeCue"
                )
            init_dict = ensure_items(init_dict, REQ_ITEMS)
            super().__init__(init_dict)
        else:
            # No-args construction: delegate to ActionCue with no dict so all
            # Cue defaults are applied without triggering the action_target guard.
            # Then set FadeCue-specific defaults directly in the underlying dict
            # to avoid calling property setters while _initialized is True.
            super().__init__(None)
            dict.__setitem__(self, 'action_type', 'fade_action')
            dict.__setitem__(self, 'curve_type', FadeCurveType.linear)
            dict.__setitem__(self, 'duration', None)
            dict.__setitem__(self, 'target_value', 0)

    # ------------------------------------------------------------------ #
    # action_type — fixed to 'fade_action'                                #
    # ------------------------------------------------------------------ #

    def get_action_type(self) -> str:
        """Return the action type (always 'fade_action').

        Returns:
            str: 'fade_action'
        """
        return super().get_action_type()

    def set_action_type(self, action_type: str) -> None:
        """Set the action type.

        Args:
            action_type (str): Must be 'fade_action'.

        Raises:
            ValueError: If action_type is not 'fade_action' and the object is
                fully initialised (post-construction assignment).
        """
        if getattr(self, '_initialized', False) and action_type != 'fade_action':
            raise ValueError(
                f"action_type must be 'fade_action' for FadeCue, got '{action_type}'"
            )
        super().set_action_type(action_type)

    action_type = property(get_action_type, set_action_type)

    # ------------------------------------------------------------------ #
    # curve_type                                                           #
    # ------------------------------------------------------------------ #

    def get_curve_type(self) -> FadeCurveType:
        """Return the fade curve type.

        When the underlying dict holds a plain string (e.g. after deserialization
        via GenericParser which bypasses the property setter), it is coerced to the
        correct FadeCurveType member on read so callers always get an enum value.

        Returns:
            FadeCurveType: The current curve type.
        """
        value = super(ActionCue, self).__getitem__('curve_type')
        if isinstance(value, FadeCurveType):
            return value
        return FadeCurveType(value)

    def set_curve_type(self, curve_type) -> None:
        """Set the fade curve type.

        Args:
            curve_type (FadeCurveType | str): A FadeCurveType member or its
                string value ('linear', 'exponential', 'logarithmic', 'sigmoid').

        Raises:
            ValueError: If curve_type is not a recognised value.
        """
        if isinstance(curve_type, FadeCurveType):
            super(ActionCue, self).__setitem__('curve_type', curve_type)
            return
        try:
            super(ActionCue, self).__setitem__('curve_type', FadeCurveType(curve_type))
        except ValueError:
            valid = [e.value for e in FadeCurveType]
            raise ValueError(
                f"curve_type must be one of {valid}, got '{curve_type}'"
            )

    curve_type = property(get_curve_type, set_curve_type)

    # ------------------------------------------------------------------ #
    # duration                                                             #
    # ------------------------------------------------------------------ #

    def get_duration(self):
        """Return the fade duration as a CTimecode.

        Returns:
            CTimecode | None: The fade duration, or None if not yet set.
        """
        return super(ActionCue, self).__getitem__('duration')

    def set_duration(self, duration) -> None:
        """Set the fade duration.

        None is accepted during construction (GenericParser pattern).  Any
        explicit non-None value that resolves to zero or negative is rejected.

        Args:
            duration (str | CTimecode | float | int | None): Timecode-compatible
                value, or None to clear.

        Raises:
            ValueError: If duration is a non-None value that is zero or negative.
        """
        if duration is None:
            super(ActionCue, self).__setitem__('duration', None)
            return
        result = format_timecode(duration)
        if result <= _ZERO_TC:
            raise ValueError('duration must be positive and non-zero')
        super(ActionCue, self).__setitem__('duration', result)

    duration = property(get_duration, set_duration)

    # ------------------------------------------------------------------ #
    # target_value                                                         #
    # ------------------------------------------------------------------ #

    def get_target_value(self) -> int:
        """Return the destination level (0–100 inclusive).

        Returns:
            int: The target level.
        """
        return super(ActionCue, self).__getitem__('target_value')

    def set_target_value(self, target_value: int) -> None:
        """Set the destination level.

        Args:
            target_value (int): Destination level in the range 0–100 inclusive.

        Raises:
            ValueError: If target_value is outside [0, 100].
        """
        value = int(target_value)
        if not (0 <= value <= 100):
            raise ValueError(
                f'target_value must be between 0 and 100, got {value}'
            )
        super(ActionCue, self).__setitem__('target_value', value)

    target_value = property(get_target_value, set_target_value)

    # ------------------------------------------------------------------ #
    # items()                                                              #
    # ------------------------------------------------------------------ #

    def items(self):
        """Return all items with own REQ_ITEMS appended in XSD sequence order.

        The XSD sequence for FadeCueType (extending ActionCueType) is:
        ...CommonProperties..., action_target, action_type,
        curve_type, duration, target_value.

        Returns:
            dict_items: Ordered items suitable for XML serialisation.
        """
        x = dict(super().items())
        for k in ('curve_type', 'duration', 'target_value'):
            x[k] = self[k]
        return x.items()

__init__(init_dict=None)

Initialise a FadeCue.

Parameters:

Name Type Description Default
init_dict dict

Initialisation values. When omitted, defaults from REQ_ITEMS are used.

None

Raises:

Type Description
ValueError

If init_dict explicitly sets action_target to None.

ValueError

If init_dict sets action_type to a value other than 'fade_action'.

Source code in src/cuemsutils/cues/FadeCue.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def __init__(self, init_dict: dict = None):
    """Initialise a FadeCue.

    Args:
        init_dict (dict, optional): Initialisation values. When omitted,
            defaults from REQ_ITEMS are used.

    Raises:
        ValueError: If init_dict explicitly sets action_target to None.
        ValueError: If init_dict sets action_type to a value other than
            'fade_action'.
    """
    if init_dict:
        if init_dict.get('action_type', 'fade_action') != 'fade_action':
            raise ValueError(
                "action_type must be 'fade_action' for FadeCue"
            )
        init_dict = ensure_items(init_dict, REQ_ITEMS)
        super().__init__(init_dict)
    else:
        # No-args construction: delegate to ActionCue with no dict so all
        # Cue defaults are applied without triggering the action_target guard.
        # Then set FadeCue-specific defaults directly in the underlying dict
        # to avoid calling property setters while _initialized is True.
        super().__init__(None)
        dict.__setitem__(self, 'action_type', 'fade_action')
        dict.__setitem__(self, 'curve_type', FadeCurveType.linear)
        dict.__setitem__(self, 'duration', None)
        dict.__setitem__(self, 'target_value', 0)

get_action_type()

Return the action type (always 'fade_action').

Returns:

Name Type Description
str str

'fade_action'

Source code in src/cuemsutils/cues/FadeCue.py
78
79
80
81
82
83
84
def get_action_type(self) -> str:
    """Return the action type (always 'fade_action').

    Returns:
        str: 'fade_action'
    """
    return super().get_action_type()

get_curve_type()

Return the fade curve type.

When the underlying dict holds a plain string (e.g. after deserialization via GenericParser which bypasses the property setter), it is coerced to the correct FadeCurveType member on read so callers always get an enum value.

Returns:

Name Type Description
FadeCurveType FadeCurveType

The current curve type.

Source code in src/cuemsutils/cues/FadeCue.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def get_curve_type(self) -> FadeCurveType:
    """Return the fade curve type.

    When the underlying dict holds a plain string (e.g. after deserialization
    via GenericParser which bypasses the property setter), it is coerced to the
    correct FadeCurveType member on read so callers always get an enum value.

    Returns:
        FadeCurveType: The current curve type.
    """
    value = super(ActionCue, self).__getitem__('curve_type')
    if isinstance(value, FadeCurveType):
        return value
    return FadeCurveType(value)

get_duration()

Return the fade duration as a CTimecode.

Returns:

Type Description

CTimecode | None: The fade duration, or None if not yet set.

Source code in src/cuemsutils/cues/FadeCue.py
150
151
152
153
154
155
156
def get_duration(self):
    """Return the fade duration as a CTimecode.

    Returns:
        CTimecode | None: The fade duration, or None if not yet set.
    """
    return super(ActionCue, self).__getitem__('duration')

get_target_value()

Return the destination level (0–100 inclusive).

Returns:

Name Type Description
int int

The target level.

Source code in src/cuemsutils/cues/FadeCue.py
185
186
187
188
189
190
191
def get_target_value(self) -> int:
    """Return the destination level (0–100 inclusive).

    Returns:
        int: The target level.
    """
    return super(ActionCue, self).__getitem__('target_value')

items()

Return all items with own REQ_ITEMS appended in XSD sequence order.

The XSD sequence for FadeCueType (extending ActionCueType) is: ...CommonProperties..., action_target, action_type, curve_type, duration, target_value.

Returns:

Name Type Description
dict_items

Ordered items suitable for XML serialisation.

Source code in src/cuemsutils/cues/FadeCue.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
def items(self):
    """Return all items with own REQ_ITEMS appended in XSD sequence order.

    The XSD sequence for FadeCueType (extending ActionCueType) is:
    ...CommonProperties..., action_target, action_type,
    curve_type, duration, target_value.

    Returns:
        dict_items: Ordered items suitable for XML serialisation.
    """
    x = dict(super().items())
    for k in ('curve_type', 'duration', 'target_value'):
        x[k] = self[k]
    return x.items()

set_action_type(action_type)

Set the action type.

Parameters:

Name Type Description Default
action_type str

Must be 'fade_action'.

required

Raises:

Type Description
ValueError

If action_type is not 'fade_action' and the object is fully initialised (post-construction assignment).

Source code in src/cuemsutils/cues/FadeCue.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def set_action_type(self, action_type: str) -> None:
    """Set the action type.

    Args:
        action_type (str): Must be 'fade_action'.

    Raises:
        ValueError: If action_type is not 'fade_action' and the object is
            fully initialised (post-construction assignment).
    """
    if getattr(self, '_initialized', False) and action_type != 'fade_action':
        raise ValueError(
            f"action_type must be 'fade_action' for FadeCue, got '{action_type}'"
        )
    super().set_action_type(action_type)

set_curve_type(curve_type)

Set the fade curve type.

Parameters:

Name Type Description Default
curve_type FadeCurveType | str

A FadeCurveType member or its string value ('linear', 'exponential', 'logarithmic', 'sigmoid').

required

Raises:

Type Description
ValueError

If curve_type is not a recognised value.

Source code in src/cuemsutils/cues/FadeCue.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def set_curve_type(self, curve_type) -> None:
    """Set the fade curve type.

    Args:
        curve_type (FadeCurveType | str): A FadeCurveType member or its
            string value ('linear', 'exponential', 'logarithmic', 'sigmoid').

    Raises:
        ValueError: If curve_type is not a recognised value.
    """
    if isinstance(curve_type, FadeCurveType):
        super(ActionCue, self).__setitem__('curve_type', curve_type)
        return
    try:
        super(ActionCue, self).__setitem__('curve_type', FadeCurveType(curve_type))
    except ValueError:
        valid = [e.value for e in FadeCurveType]
        raise ValueError(
            f"curve_type must be one of {valid}, got '{curve_type}'"
        )

set_duration(duration)

Set the fade duration.

None is accepted during construction (GenericParser pattern). Any explicit non-None value that resolves to zero or negative is rejected.

Parameters:

Name Type Description Default
duration str | CTimecode | float | int | None

Timecode-compatible value, or None to clear.

required

Raises:

Type Description
ValueError

If duration is a non-None value that is zero or negative.

Source code in src/cuemsutils/cues/FadeCue.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
def set_duration(self, duration) -> None:
    """Set the fade duration.

    None is accepted during construction (GenericParser pattern).  Any
    explicit non-None value that resolves to zero or negative is rejected.

    Args:
        duration (str | CTimecode | float | int | None): Timecode-compatible
            value, or None to clear.

    Raises:
        ValueError: If duration is a non-None value that is zero or negative.
    """
    if duration is None:
        super(ActionCue, self).__setitem__('duration', None)
        return
    result = format_timecode(duration)
    if result <= _ZERO_TC:
        raise ValueError('duration must be positive and non-zero')
    super(ActionCue, self).__setitem__('duration', result)

set_target_value(target_value)

Set the destination level.

Parameters:

Name Type Description Default
target_value int

Destination level in the range 0–100 inclusive.

required

Raises:

Type Description
ValueError

If target_value is outside [0, 100].

Source code in src/cuemsutils/cues/FadeCue.py
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
def set_target_value(self, target_value: int) -> None:
    """Set the destination level.

    Args:
        target_value (int): Destination level in the range 0–100 inclusive.

    Raises:
        ValueError: If target_value is outside [0, 100].
    """
    value = int(target_value)
    if not (0 <= value <= 100):
        raise ValueError(
            f'target_value must be between 0 and 100, got {value}'
        )
    super(ActionCue, self).__setitem__('target_value', value)

FadeCurveType

Bases: Enum

Enumeration of supported fade curve shapes.

Source code in src/cuemsutils/cues/FadeCue.py
10
11
12
13
14
15
16
17
18
19
20
21
22
class FadeCurveType(Enum):
    """Enumeration of supported fade curve shapes."""

    linear = 'linear'
    exponential = 'exponential'
    logarithmic = 'logarithmic'
    sigmoid = 'sigmoid'

    def __str__(self):
        return self.value

    def __json__(self):
        return self.value

FadeFunctionParameter

Bases: CuemsDict

A named numeric parameter for a parametric fade function.

Source code in src/cuemsutils/cues/FadeProfile.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class FadeFunctionParameter(CuemsDict):
    """A named numeric parameter for a parametric fade function."""

    def __init__(self, init_dict=None):
        if not init_dict:
            init_dict = FADE_PARAM_REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, FADE_PARAM_REQ_ITEMS)
        if init_dict:
            self.setter(init_dict)

    def get_parameter_name(self):
        return super().__getitem__('parameter_name')

    def set_parameter_name(self, value):
        super().__setitem__('parameter_name', str(value))

    parameter_name = property(get_parameter_name, set_parameter_name)

    def get_parameter_value(self):
        return super().__getitem__('parameter_value')

    def set_parameter_value(self, value):
        try:
            v = float(value)
        except (TypeError, ValueError) as e:
            raise ValueError(
                f"parameter_value must be numeric, got {value!r}"
            ) from e
        if math.isnan(v) or math.isinf(v):
            raise ValueError("parameter_value must be a finite number")
        super().__setitem__('parameter_value', v)

    parameter_value = property(get_parameter_value, set_parameter_value)

    def __json__(self):
        return {type(self).__name__: dict(self.items())}

FadeProfile

Bases: CuemsDict

Typed fade profile (in or out) attached to a MediaCue.

Supports two modes: - preset: system-defined function, no user parameters required. - parametric: user-supplied parameters control the fade curve.

Source code in src/cuemsutils/cues/FadeProfile.py
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
class FadeProfile(CuemsDict):
    """Typed fade profile (``in`` or ``out``) attached to a MediaCue.

    Supports two modes:
    - ``preset``: system-defined function, no user parameters required.
    - ``parametric``: user-supplied parameters control the fade curve.
    """

    def __init__(self, init_dict=None):
        if not init_dict:
            init_dict = FADE_PROFILE_REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, FADE_PROFILE_REQ_ITEMS)
        if init_dict:
            self.setter(init_dict)

    # -- type ----------------------------------------------------------

    def get_type(self):
        return super().__getitem__('type')

    def set_type(self, value):
        if value not in VALID_FADE_TYPES:
            raise ValueError(
                f"Invalid fade type '{value}'. Must be one of {VALID_FADE_TYPES}"
            )
        super().__setitem__('type', value)

    type = property(get_type, set_type)

    # -- mode ----------------------------------------------------------

    def get_mode(self):
        return super().__getitem__('mode')

    def set_mode(self, value):
        if value not in VALID_FADE_MODES:
            raise ValueError(
                f"Invalid fade mode '{value}'. Must be one of {VALID_FADE_MODES}"
            )
        super().__setitem__('mode', value)

    mode = property(get_mode, set_mode)

    # -- function_id ---------------------------------------------------

    def get_function_id(self):
        return super().__getitem__('function_id')

    def set_function_id(self, value):
        super().__setitem__('function_id', str(value))

    function_id = property(get_function_id, set_function_id)

    # -- parameters ----------------------------------------------------

    def get_parameters(self):
        return super().__getitem__('parameters')

    def set_parameters(self, value):
        if value is None:
            super().__setitem__('parameters', None)
            return
        if not isinstance(value, list):
            value = [value]
        converted = []
        seen_names: set[str] = set()
        for item in value:
            if not isinstance(item, FadeFunctionParameter):
                item = FadeFunctionParameter(item)
            name = item.parameter_name
            if name in seen_names:
                raise ValueError(
                    f"Duplicate parameter_name {name!r} in fade profile"
                )
            seen_names.add(name)
            converted.append(item)
        super().__setitem__('parameters', converted)

    parameters: list[FadeFunctionParameter] | None = property(
        get_parameters, set_parameters
    )

    def __json__(self):
        return {type(self).__name__: dict(self.items())}

Media

Bases: CuemsDict

A class representing a media file with associated regions.

Source code in src/cuemsutils/cues/MediaCue.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
class Media(CuemsDict):
    """A class representing a media file with associated regions."""

    def __init__(self, init_dict = None):
        """Initialize a Media object.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if init_dict:
            self.setter(init_dict)

    def get_file_name(self):
        """Get the media file name.

        Returns:
            str: The name of the media file.
        """
        return super().__getitem__('file_name')

    def set_file_name(self, file_name):
        """Set the media file name.

        Args:
            file_name (str): The new media file name.
        """
        super().__setitem__('file_name', file_name)

    file_name = property(get_file_name, set_file_name)

    def get_id(self):
        """Get the UUID of the media file.

        Returns:
            str: The UUID of the media file.
        """
        return super().__getitem__('id')

    def set_id(self, id):
        """Set the UUID of the media file.

        Args:
            id (str): The new UUID of the media file.
        """
        id = Uuid(id)
        super().__setitem__('id', id)

    id = property(get_id, set_id)

    def get_duration(self):
        """Get the duration of the media file.

        Returns:
            str: The duration of the media file.
        """
        return super().__getitem__('duration')

    def set_duration(self, duration):
        """Set the duration of the media file.

        Args:
            duration (str): The new duration of the media file.
        """
        super().__setitem__('duration', duration)

    duration = property(get_duration, set_duration)

    def get_regions(self):
        """Get the list of regions in the media file.

        Returns:
            list: The list of Region objects.
        """
        return super().__getitem__('regions')

    def set_regions(self, regions):
        """Set the list of regions in the media file.

        Args:
            regions (list or Region): A list of regions or a single region.
                If not already Region objects, they will be converted.
        """
        if not isinstance(regions, list):
            regions = [regions]
        for r in regions:
            if not isinstance(r, Region):
                r = Region(r)
        super().__setitem__('regions', regions)

    regions: list[Region] = property(get_regions, set_regions)

__init__(init_dict=None)

Initialize a Media object.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/MediaCue.py
122
123
124
125
126
127
128
129
130
def __init__(self, init_dict = None):
    """Initialize a Media object.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if init_dict:
        self.setter(init_dict)

get_duration()

Get the duration of the media file.

Returns:

Name Type Description
str

The duration of the media file.

Source code in src/cuemsutils/cues/MediaCue.py
169
170
171
172
173
174
175
def get_duration(self):
    """Get the duration of the media file.

    Returns:
        str: The duration of the media file.
    """
    return super().__getitem__('duration')

get_file_name()

Get the media file name.

Returns:

Name Type Description
str

The name of the media file.

Source code in src/cuemsutils/cues/MediaCue.py
132
133
134
135
136
137
138
def get_file_name(self):
    """Get the media file name.

    Returns:
        str: The name of the media file.
    """
    return super().__getitem__('file_name')

get_id()

Get the UUID of the media file.

Returns:

Name Type Description
str

The UUID of the media file.

Source code in src/cuemsutils/cues/MediaCue.py
150
151
152
153
154
155
156
def get_id(self):
    """Get the UUID of the media file.

    Returns:
        str: The UUID of the media file.
    """
    return super().__getitem__('id')

get_regions()

Get the list of regions in the media file.

Returns:

Name Type Description
list

The list of Region objects.

Source code in src/cuemsutils/cues/MediaCue.py
187
188
189
190
191
192
193
def get_regions(self):
    """Get the list of regions in the media file.

    Returns:
        list: The list of Region objects.
    """
    return super().__getitem__('regions')

set_duration(duration)

Set the duration of the media file.

Parameters:

Name Type Description Default
duration str

The new duration of the media file.

required
Source code in src/cuemsutils/cues/MediaCue.py
177
178
179
180
181
182
183
def set_duration(self, duration):
    """Set the duration of the media file.

    Args:
        duration (str): The new duration of the media file.
    """
    super().__setitem__('duration', duration)

set_file_name(file_name)

Set the media file name.

Parameters:

Name Type Description Default
file_name str

The new media file name.

required
Source code in src/cuemsutils/cues/MediaCue.py
140
141
142
143
144
145
146
def set_file_name(self, file_name):
    """Set the media file name.

    Args:
        file_name (str): The new media file name.
    """
    super().__setitem__('file_name', file_name)

set_id(id)

Set the UUID of the media file.

Parameters:

Name Type Description Default
id str

The new UUID of the media file.

required
Source code in src/cuemsutils/cues/MediaCue.py
158
159
160
161
162
163
164
165
def set_id(self, id):
    """Set the UUID of the media file.

    Args:
        id (str): The new UUID of the media file.
    """
    id = Uuid(id)
    super().__setitem__('id', id)

set_regions(regions)

Set the list of regions in the media file.

Parameters:

Name Type Description Default
regions list or Region

A list of regions or a single region. If not already Region objects, they will be converted.

required
Source code in src/cuemsutils/cues/MediaCue.py
195
196
197
198
199
200
201
202
203
204
205
206
207
def set_regions(self, regions):
    """Set the list of regions in the media file.

    Args:
        regions (list or Region): A list of regions or a single region.
            If not already Region objects, they will be converted.
    """
    if not isinstance(regions, list):
        regions = [regions]
    for r in regions:
        if not isinstance(r, Region):
            r = Region(r)
    super().__setitem__('regions', regions)

MediaCue

Bases: Cue

Base class for media-related cues (audio and video).

This class extends Cue to provide common functionality for media playback, including media file handling and output routing.

Source code in src/cuemsutils/cues/MediaCue.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
class MediaCue(Cue):
    """Base class for media-related cues (audio and video).

    This class extends Cue to provide common functionality for media playback,
    including media file handling and output routing.
    """

    def __init__(self, init_dict = None):
        """Initialize a MediaCue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If not provided, default values from REQ_ITEMS will be used.
        """
        if not init_dict:
            init_dict = REQ_ITEMS
        else:
            init_dict = ensure_items(init_dict, REQ_ITEMS)
        super().__init__(init_dict)

    def __setitem__(self, key, value):
        if key == 'fade_profile':
            self.set_fade_profiles(value)
            return
        if key == 'fade_profiles':
            if isinstance(value, dict) and 'fade_profile' in value:
                inner = value['fade_profile']
                self.set_fade_profiles(
                    inner if isinstance(inner, list) else [inner]
                )
                return
            self.set_fade_profiles(value)
            return
        super().__setitem__(key, value)

    def get_Media(self):
        """Get the media object associated with this cue.

        Returns:
            Media: The media object containing file and region information.
        """
        return super().__getitem__('Media')

    def set_Media(self, value):
        """Set the media object for this cue.

        Args:
            value (Media or dict): The media object or dictionary to create one.
        """
        if not isinstance(value, Media):
            value = Media(value)
        super().__setitem__('Media', value)

    media: Media = property(get_Media, set_Media)

    def get_outputs(self):
        """Get the output routing configuration.

        Returns:
            list: The list of output configurations.
        """
        return super().__getitem__('outputs')

    def set_outputs(self, outputs):
        """Set the output routing configuration.

        Args:
            outputs (list): The list of output configurations.
        """
        super().__setitem__('outputs', outputs)

    outputs = property(get_outputs, set_outputs)

    def get_fade_profiles(self):
        return super().__getitem__('fade_profiles')

    def set_fade_profiles(self, value):
        if value is None:
            super().__setitem__('fade_profiles', None)
            return
        if isinstance(value, FadeProfile):
            value = [value]
        elif not isinstance(value, list):
            value = [value]
        if len(value) == 0:
            super().__setitem__('fade_profiles', None)
            return
        seen_types: set[str] = set()
        result: list[FadeProfile] = []
        for item in value:
            fp = item if isinstance(item, FadeProfile) else FadeProfile(item)
            t = fp.type
            if t in seen_types:
                raise ValueError(f"Duplicate fade profile type {t!r}")
            seen_types.add(t)
            if not str(fp.function_id or '').strip():
                raise ValueError("function_id must be non-empty")
            if fp.mode == 'parametric':
                params = fp.parameters
                if not params:
                    raise ValueError(
                        "parametric fade profile requires non-empty parameters"
                    )
            result.append(fp)
        super().__setitem__('fade_profiles', result)

    fade_profiles = property(get_fade_profiles, set_fade_profiles)

    def get_fade_profile(self, direction: str):
        """Return the fade profile for ``in``/``out`` (or ``fade_in``/``fade_out``)."""
        norm = {'fade_in': 'in', 'fade_out': 'out'}.get(direction, direction)
        if norm not in ('in', 'out'):
            raise ValueError(
                f"direction must be 'in', 'out', 'fade_in', or 'fade_out', got {direction!r}"
            )
        fps = self.get_fade_profiles()
        if not fps:
            return None
        for fp in fps:
            if fp.type == norm:
                return fp
        return None

    def get_all_output_names(self) -> list[Tuple[str, str]]:
        """Get all output names splitted into node and output ids for the media cue.
        Returns:
            list: The list of output names.
        """
        # DEV: To allow proper mapping, we need to split the output name into node and output ids.
        # Additional logic in case mapping is developed and generalized output names (without node id) are used.
        # e.g: [(None,'generalized_output_id'), ('node_uuid','output_id'), ...]
        return [(output['output_name'][:36], output['output_name'][37:]) for output in self.outputs]

    def localize_cue(self, node_id: str) -> None:
        """Localize the cue outputs to the given node UUID.

        Sets the _local attribute to True if any of the cue outputs are local to the given node UUID, False otherwise.

        Args:
            node_id: The ID of the node to localize the cue to.
        """
        self._local = any(x[0] == node_id for x in self.get_all_output_names())


    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items, with required items included.
        """
        x = dict(super().items())
        for k in REQ_ITEMS.keys():
            x[k] = self[k]
        return x.items()

__init__(init_dict=None)

Initialize a MediaCue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If not provided, default values from REQ_ITEMS will be used.

None
Source code in src/cuemsutils/cues/MediaCue.py
218
219
220
221
222
223
224
225
226
227
228
229
def __init__(self, init_dict = None):
    """Initialize a MediaCue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If not provided, default values from REQ_ITEMS will be used.
    """
    if not init_dict:
        init_dict = REQ_ITEMS
    else:
        init_dict = ensure_items(init_dict, REQ_ITEMS)
    super().__init__(init_dict)

get_Media()

Get the media object associated with this cue.

Returns:

Name Type Description
Media

The media object containing file and region information.

Source code in src/cuemsutils/cues/MediaCue.py
246
247
248
249
250
251
252
def get_Media(self):
    """Get the media object associated with this cue.

    Returns:
        Media: The media object containing file and region information.
    """
    return super().__getitem__('Media')

get_all_output_names()

Get all output names splitted into node and output ids for the media cue. Returns: list: The list of output names.

Source code in src/cuemsutils/cues/MediaCue.py
334
335
336
337
338
339
340
341
342
def get_all_output_names(self) -> list[Tuple[str, str]]:
    """Get all output names splitted into node and output ids for the media cue.
    Returns:
        list: The list of output names.
    """
    # DEV: To allow proper mapping, we need to split the output name into node and output ids.
    # Additional logic in case mapping is developed and generalized output names (without node id) are used.
    # e.g: [(None,'generalized_output_id'), ('node_uuid','output_id'), ...]
    return [(output['output_name'][:36], output['output_name'][37:]) for output in self.outputs]

get_fade_profile(direction)

Return the fade profile for in/out (or fade_in/fade_out).

Source code in src/cuemsutils/cues/MediaCue.py
319
320
321
322
323
324
325
326
327
328
329
330
331
332
def get_fade_profile(self, direction: str):
    """Return the fade profile for ``in``/``out`` (or ``fade_in``/``fade_out``)."""
    norm = {'fade_in': 'in', 'fade_out': 'out'}.get(direction, direction)
    if norm not in ('in', 'out'):
        raise ValueError(
            f"direction must be 'in', 'out', 'fade_in', or 'fade_out', got {direction!r}"
        )
    fps = self.get_fade_profiles()
    if not fps:
        return None
    for fp in fps:
        if fp.type == norm:
            return fp
    return None

get_outputs()

Get the output routing configuration.

Returns:

Name Type Description
list

The list of output configurations.

Source code in src/cuemsutils/cues/MediaCue.py
266
267
268
269
270
271
272
def get_outputs(self):
    """Get the output routing configuration.

    Returns:
        list: The list of output configurations.
    """
    return super().__getitem__('outputs')

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items, with required items included.

Source code in src/cuemsutils/cues/MediaCue.py
355
356
357
358
359
360
361
362
363
364
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items, with required items included.
    """
    x = dict(super().items())
    for k in REQ_ITEMS.keys():
        x[k] = self[k]
    return x.items()

localize_cue(node_id)

Localize the cue outputs to the given node UUID.

Sets the _local attribute to True if any of the cue outputs are local to the given node UUID, False otherwise.

Parameters:

Name Type Description Default
node_id str

The ID of the node to localize the cue to.

required
Source code in src/cuemsutils/cues/MediaCue.py
344
345
346
347
348
349
350
351
352
def localize_cue(self, node_id: str) -> None:
    """Localize the cue outputs to the given node UUID.

    Sets the _local attribute to True if any of the cue outputs are local to the given node UUID, False otherwise.

    Args:
        node_id: The ID of the node to localize the cue to.
    """
    self._local = any(x[0] == node_id for x in self.get_all_output_names())

set_Media(value)

Set the media object for this cue.

Parameters:

Name Type Description Default
value Media or dict

The media object or dictionary to create one.

required
Source code in src/cuemsutils/cues/MediaCue.py
254
255
256
257
258
259
260
261
262
def set_Media(self, value):
    """Set the media object for this cue.

    Args:
        value (Media or dict): The media object or dictionary to create one.
    """
    if not isinstance(value, Media):
        value = Media(value)
    super().__setitem__('Media', value)

set_outputs(outputs)

Set the output routing configuration.

Parameters:

Name Type Description Default
outputs list

The list of output configurations.

required
Source code in src/cuemsutils/cues/MediaCue.py
274
275
276
277
278
279
280
def set_outputs(self, outputs):
    """Set the output routing configuration.

    Args:
        outputs (list): The list of output configurations.
    """
    super().__setitem__('outputs', outputs)

Region

Bases: CuemsDict

A class representing a region within a media file.

Source code in src/cuemsutils/cues/MediaCue.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
class Region(CuemsDict):
    """A class representing a region within a media file."""

    def __init__(self, init_dict = None):
        """Initialize a Region.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If not provided, default values will be used.
        """
        empty_keys= {"id": "0"}
        if (init_dict):
            self.setter(init_dict)
        else:
            self.setter(empty_keys)

    def get_id(self):
        """Get the region ID.

        Returns:
            str: The region's identifier.
        """
        return super().__getitem__('id')

    def set_id(self, id):
        """Set the region ID.

        Args:
            id: The new region identifier.
        """
        super().__setitem__('id', id)

    id = property(get_id, set_id)

    def get_loop(self):
        """Get the loop count for this region.

        Returns:
            int: The number of times the region should loop.
        """
        return super().__getitem__('loop')

    def set_loop(self, loop):
        """Set the loop count for this region.

        Args:
            loop (int): The number of times the region should loop.
        """
        super().__setitem__('loop', loop)

    loop = property(get_loop, set_loop)

    def get_in_time(self):
        """Get the in point of the region.

        Returns:
            CTimecode: The timecode where the region starts.
        """
        return super().__getitem__('in_time')

    def set_in_time(self, in_time):
        """Set the in point of the region.

        Args:
            in_time: The new in point timecode.
        """
        in_time = format_timecode(in_time)
        super().__setitem__('in_time', in_time)

    in_time = property(get_in_time, set_in_time)

    def get_out_time(self):
        """Get the out point of the region.

        Returns:
            CTimecode: The timecode where the region ends.
        """
        return super().__getitem__('out_time')

    def set_out_time(self, out_time):
        """Set the out point of the region.

        Args:
            out_time: The new out point timecode.
        """
        out_time = format_timecode(out_time)
        super().__setitem__('out_time', out_time)

    out_time = property(get_out_time, set_out_time)

    def __json__(self):
        """Convert the region to a JSON-compatible dictionary.

        Returns:
            dict: A dictionary representation of the region.
        """
        return {type(self).__name__: dict(self.items())}

__init__(init_dict=None)

Initialize a Region.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If not provided, default values will be used.

None
Source code in src/cuemsutils/cues/MediaCue.py
24
25
26
27
28
29
30
31
32
33
34
35
def __init__(self, init_dict = None):
    """Initialize a Region.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If not provided, default values will be used.
    """
    empty_keys= {"id": "0"}
    if (init_dict):
        self.setter(init_dict)
    else:
        self.setter(empty_keys)

__json__()

Convert the region to a JSON-compatible dictionary.

Returns:

Name Type Description
dict

A dictionary representation of the region.

Source code in src/cuemsutils/cues/MediaCue.py
111
112
113
114
115
116
117
def __json__(self):
    """Convert the region to a JSON-compatible dictionary.

    Returns:
        dict: A dictionary representation of the region.
    """
    return {type(self).__name__: dict(self.items())}

get_id()

Get the region ID.

Returns:

Name Type Description
str

The region's identifier.

Source code in src/cuemsutils/cues/MediaCue.py
37
38
39
40
41
42
43
def get_id(self):
    """Get the region ID.

    Returns:
        str: The region's identifier.
    """
    return super().__getitem__('id')

get_in_time()

Get the in point of the region.

Returns:

Name Type Description
CTimecode

The timecode where the region starts.

Source code in src/cuemsutils/cues/MediaCue.py
73
74
75
76
77
78
79
def get_in_time(self):
    """Get the in point of the region.

    Returns:
        CTimecode: The timecode where the region starts.
    """
    return super().__getitem__('in_time')

get_loop()

Get the loop count for this region.

Returns:

Name Type Description
int

The number of times the region should loop.

Source code in src/cuemsutils/cues/MediaCue.py
55
56
57
58
59
60
61
def get_loop(self):
    """Get the loop count for this region.

    Returns:
        int: The number of times the region should loop.
    """
    return super().__getitem__('loop')

get_out_time()

Get the out point of the region.

Returns:

Name Type Description
CTimecode

The timecode where the region ends.

Source code in src/cuemsutils/cues/MediaCue.py
92
93
94
95
96
97
98
def get_out_time(self):
    """Get the out point of the region.

    Returns:
        CTimecode: The timecode where the region ends.
    """
    return super().__getitem__('out_time')

set_id(id)

Set the region ID.

Parameters:

Name Type Description Default
id

The new region identifier.

required
Source code in src/cuemsutils/cues/MediaCue.py
45
46
47
48
49
50
51
def set_id(self, id):
    """Set the region ID.

    Args:
        id: The new region identifier.
    """
    super().__setitem__('id', id)

set_in_time(in_time)

Set the in point of the region.

Parameters:

Name Type Description Default
in_time

The new in point timecode.

required
Source code in src/cuemsutils/cues/MediaCue.py
81
82
83
84
85
86
87
88
def set_in_time(self, in_time):
    """Set the in point of the region.

    Args:
        in_time: The new in point timecode.
    """
    in_time = format_timecode(in_time)
    super().__setitem__('in_time', in_time)

set_loop(loop)

Set the loop count for this region.

Parameters:

Name Type Description Default
loop int

The number of times the region should loop.

required
Source code in src/cuemsutils/cues/MediaCue.py
63
64
65
66
67
68
69
def set_loop(self, loop):
    """Set the loop count for this region.

    Args:
        loop (int): The number of times the region should loop.
    """
    super().__setitem__('loop', loop)

set_out_time(out_time)

Set the out point of the region.

Parameters:

Name Type Description Default
out_time

The new out point timecode.

required
Source code in src/cuemsutils/cues/MediaCue.py
100
101
102
103
104
105
106
107
def set_out_time(self, out_time):
    """Set the out point of the region.

    Args:
        out_time: The new out point timecode.
    """
    out_time = format_timecode(out_time)
    super().__setitem__('out_time', out_time)

VideoCue

Bases: MediaCue

A cue for handling video playback and control.

This class extends MediaCue to provide specific functionality for video playback, including frame rate handling and OSC communication for video routing.

Source code in src/cuemsutils/cues/VideoCue.py
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
class VideoCue(MediaCue):
    """A cue for handling video playback and control.

    This class extends MediaCue to provide specific functionality for video playback,
    including frame rate handling and OSC communication for video routing.
    """

    def __init__(self, init_dict = None):
        """Initialize a VideoCue.

        Args:
            init_dict (dict, optional): Dictionary containing initialization values.
                If provided, will be used to set initial properties.
        """
        if not init_dict:
            super().__init__()
        else:
            super().__init__(init_dict)

        self._player = None
        self._osc_route = None
        self._go_thread = None

        # TODO: Adjust framerates for universal use, by now 25 fps for video
        self._start_mtc = CTimecode(framerate=25)
        self._end_mtc = CTimecode(framerate=25)

    def player(self, player):
        """Set the video player instance.

        Args:
            player: The video player instance to use.
        """
        self._player = player

    def osc_route(self, osc_route):
        """Set the OSC route for video control.

        Args:
            osc_route (str): The OSC route to use for video control.
        """
        self._osc_route = osc_route

    def items(self):
        """Get all items in the cue as a dictionary.

        Returns:
            dict_items: A view of the cue's items.
        """
        x = dict(super().items())
        return x.items()

    def stop(self):
        """Stop the video playback.

        This method sets the stop request flag to halt video playback.
        """
        self._stop_requested = True

    def check_mappings(self, settings):
        """Check if the video output mappings are valid.

        Args:
            settings: The settings containing project node mappings.

        Returns:
            bool: True if the mappings are valid, False otherwise.
        """
        return super().check_mappings()

        if not settings.project_node_mappings:
            return True

        found = True
        map_list = ['default']

        # DEV: List first index is an artifact of the way the mappings are parsed
        Logger.debug(f'VideoCue check_mappings: {settings.project_node_mappings}')
        if settings.project_node_mappings['video'][0]['outputs']:
            for elem in settings.project_node_mappings['video'][0]['outputs']:
                elem = elem['output']
                Logger.debug(f'VideoCue elem: {elem}')
                for map in elem['mappings']:
                    Logger.debug(f'VideoCue map: {map}')
                    map_list.append(map['mapped_to'])

        for output in self.outputs:
            if output['output_name'][:36] == settings.node_conf['uuid']:
                self._local = True
                if output['output_name'][37:] not in map_list:
                    found = False
                    break
            else:
                self._local = False
                found = True

        return found

__init__(init_dict=None)

Initialize a VideoCue.

Parameters:

Name Type Description Default
init_dict dict

Dictionary containing initialization values. If provided, will be used to set initial properties.

None
Source code in src/cuemsutils/cues/VideoCue.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def __init__(self, init_dict = None):
    """Initialize a VideoCue.

    Args:
        init_dict (dict, optional): Dictionary containing initialization values.
            If provided, will be used to set initial properties.
    """
    if not init_dict:
        super().__init__()
    else:
        super().__init__(init_dict)

    self._player = None
    self._osc_route = None
    self._go_thread = None

    # TODO: Adjust framerates for universal use, by now 25 fps for video
    self._start_mtc = CTimecode(framerate=25)
    self._end_mtc = CTimecode(framerate=25)

check_mappings(settings)

Check if the video output mappings are valid.

Parameters:

Name Type Description Default
settings

The settings containing project node mappings.

required

Returns:

Name Type Description
bool

True if the mappings are valid, False otherwise.

Source code in src/cuemsutils/cues/VideoCue.py
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def check_mappings(self, settings):
    """Check if the video output mappings are valid.

    Args:
        settings: The settings containing project node mappings.

    Returns:
        bool: True if the mappings are valid, False otherwise.
    """
    return super().check_mappings()

    if not settings.project_node_mappings:
        return True

    found = True
    map_list = ['default']

    # DEV: List first index is an artifact of the way the mappings are parsed
    Logger.debug(f'VideoCue check_mappings: {settings.project_node_mappings}')
    if settings.project_node_mappings['video'][0]['outputs']:
        for elem in settings.project_node_mappings['video'][0]['outputs']:
            elem = elem['output']
            Logger.debug(f'VideoCue elem: {elem}')
            for map in elem['mappings']:
                Logger.debug(f'VideoCue map: {map}')
                map_list.append(map['mapped_to'])

    for output in self.outputs:
        if output['output_name'][:36] == settings.node_conf['uuid']:
            self._local = True
            if output['output_name'][37:] not in map_list:
                found = False
                break
        else:
            self._local = False
            found = True

    return found

items()

Get all items in the cue as a dictionary.

Returns:

Name Type Description
dict_items

A view of the cue's items.

Source code in src/cuemsutils/cues/VideoCue.py
50
51
52
53
54
55
56
57
def items(self):
    """Get all items in the cue as a dictionary.

    Returns:
        dict_items: A view of the cue's items.
    """
    x = dict(super().items())
    return x.items()

osc_route(osc_route)

Set the OSC route for video control.

Parameters:

Name Type Description Default
osc_route str

The OSC route to use for video control.

required
Source code in src/cuemsutils/cues/VideoCue.py
42
43
44
45
46
47
48
def osc_route(self, osc_route):
    """Set the OSC route for video control.

    Args:
        osc_route (str): The OSC route to use for video control.
    """
    self._osc_route = osc_route

player(player)

Set the video player instance.

Parameters:

Name Type Description Default
player

The video player instance to use.

required
Source code in src/cuemsutils/cues/VideoCue.py
34
35
36
37
38
39
40
def player(self, player):
    """Set the video player instance.

    Args:
        player: The video player instance to use.
    """
    self._player = player

stop()

Stop the video playback.

This method sets the stop request flag to halt video playback.

Source code in src/cuemsutils/cues/VideoCue.py
59
60
61
62
63
64
def stop(self):
    """Stop the video playback.

    This method sets the stop request flag to halt video playback.
    """
    self._stop_requested = True