API Documentation
Communicator
Bases: CommunicatorService
Source code in src/cuemsutils/tools/CommunicatorServices.py
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 | |
__init__(address, communicator_service=NngRequestResponse, requester_dials=True)
Initialize Communicator instance with address and communicator service.
Parameters: - address (str): The address to connect or listen for connections. - communicator_service (Callable[[str, bool], CommunicatorService]): The communicator service to use. - requester_dials (bool): If True, the instance will dial the address. If False, it will listen for connections.
Source code in src/cuemsutils/tools/CommunicatorServices.py
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 | |
CommunicatorService
Bases: ABC
Source code in src/cuemsutils/tools/CommunicatorServices.py
20 21 22 23 24 25 26 27 28 29 30 31 | |
reply(request_processor)
abstractmethod
Get request, give it to request processor, and return the response from it
Source code in src/cuemsutils/tools/CommunicatorServices.py
29 30 31 | |
send_request(request)
abstractmethod
Send request dic and return response dict
Source code in src/cuemsutils/tools/CommunicatorServices.py
25 26 27 | |
IpcAddress
Bases: Enum
IPC addresses for the different services
Source code in src/cuemsutils/tools/CommunicatorServices.py
14 15 16 17 18 | |
NngRequestResponse
Bases: CommunicatorService
Communicates over NNG (nanomsg) using a Request-Response protocol
Source code in src/cuemsutils/tools/CommunicatorServices.py
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 | |
__init__(address, requester_dials=True)
Initialize NngRequestResponse instance with address and dialing/listening mode.
Parameters: - address (str): The address to connect or listen for connections. - requester_dials (bool, optional): If True, the instance requester will dial the address and replier will listen. If False, it will be the opposite way, requester listens and replier dials. Default is True.
The instance will set up the parameters for request and reply sockets based on the requester_dials value.
Source code in src/cuemsutils/tools/CommunicatorServices.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
reply(request_processor)
async
Asynchronously handle incoming requests and respond using the provided request processor.
This function sets up a Rep0 socket with parameters based on the instance's configuration. It then enters a loop where it listens for incoming requests, processes them using the provided request processor, and sends the response back to the requester. Parameters: - request_processor (Callable[[dict], dict]): A function that takes a request dictionary as input and returns a response dictionary.
Returns: - None: This function is designed to run indefinitely, handling incoming requests and responses.
Source code in src/cuemsutils/tools/CommunicatorServices.py
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 | |
send_request(request)
async
Send a request to the specified address and return the response.
Parameters: - request (dict): The request to be sent. It should be a dictionary.
Returns: - dict: The response received from the address. It will be a dictionary.
Source code in src/cuemsutils/tools/CommunicatorServices.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
ConfigBase
Source code in src/cuemsutils/tools/ConfigBase.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 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 | |
conf_path(file_name)
Returns the path to the configuration file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
The name of the file to be checked. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The path to the configuration file. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the configuration file does not exist. |
Source code in src/cuemsutils/tools/ConfigBase.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
set_dir_hierarchy()
Sets the directory hierarchy for the library path.
Source code in src/cuemsutils/tools/ConfigBase.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
ConfigManager
Bases: ConfigBase
Source code in src/cuemsutils/tools/ConfigManager.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 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 | |
__init__(config_dir=CUEMS_CONF_PATH, load_all=True)
ConfigManager constructor. This class is responsible for loading the configuration files and providing the configuration data to the rest of the application.
It also provides methods to check the project files and to load them on demand.
If load_all is True, the configuration files will be loaded and the configuration will be available for the rest of the application on object initialization. If load_all is False, the configuration will be loaded on demand.
Base configuration directory is set to /etc/cuems/ by default. If the environment variable CUEMS_CONF_PATH is set, it will be used instead. If config_dir parameter is set, it will override the default value.
Specifically, base configuration directory precedence is: - Environment variable CUEMS_CONF_PATH - config_dir parameter - /etc/cuems/ (i.e. CUEMS_CONF_PATH constant value) (default value)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_dir
|
str
|
The directory containing the configuration files. |
CUEMS_CONF_PATH
|
load_all
|
bool
|
Whether to load all the configuration files. |
True
|
Raises:
| Type | Description |
|---|---|
Exception
|
If the configuration files are not found. |
Source code in src/cuemsutils/tools/ConfigManager.py
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 | |
check_project_mappings()
Checks if the project mappings are correct.
Source code in src/cuemsutils/tools/ConfigManager.py
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | |
get_audio_output_id(mapping_name)
Returns the audio output id for the given mapping name.
Source code in src/cuemsutils/tools/ConfigManager.py
256 257 258 259 260 261 262 263 264 265 266 267 268 | |
get_video_output_id(mapping_name)
Returns the video output id for the given mapping name.
Source code in src/cuemsutils/tools/ConfigManager.py
241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
load_config()
Loads the system configuration.
Source code in src/cuemsutils/tools/ConfigManager.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | |
load_net_and_node_mappings()
Loads the network and node mappings.
Source code in src/cuemsutils/tools/ConfigManager.py
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 | |
load_network_map()
Loads the network map from the base configuration file.
Source code in src/cuemsutils/tools/ConfigManager.py
118 119 120 121 122 123 124 125 126 127 128 | |
load_project_config(project_uname)
Loads the project configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_uname
|
str
|
The name of the project. |
required |
Source code in src/cuemsutils/tools/ConfigManager.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | |
load_project_mappings(project_uname)
Loads the project mappings from the project file.
Source code in src/cuemsutils/tools/ConfigManager.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | |
load_project_settings(project_uname)
Loads the project settings from the project file.
Source code in src/cuemsutils/tools/ConfigManager.py
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 | |
project_path(project_uname, file_name)
Returns the path to the project file if it exists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_uname
|
str
|
The name of the project. |
required |
file_name
|
str
|
The name of the file to be checked. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The path to the project file. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the project file does not exist. |
Source code in src/cuemsutils/tools/ConfigManager.py
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
CTimecode — cuems wrapper around upstream timecode 1.5.1.
Type contract — three accessors for "milliseconds of the position":
-
.milliseconds_exact: floatMathematical answer (frame_number * 1000 / _int_framerate). Use for precision-sensitive math (offset calc, scheduler) where sub-ms accuracy matters at fractional framerates (29.97/23.976). -
.milliseconds_rounded: intround(.milliseconds_exact). Use for sleep durations, integer CLI args, polling comparisons, dict/set keys, arithmetic with other ints. -
.milliseconds: int(DEPRECATED — alias of .milliseconds_rounded) EmitsDeprecationWarning. Will be removed at the first stable release. Migrate every call-site to one of the explicit names above.
Semantics: cuems uses playhead semantics — at MTC position T,
.milliseconds_exact == T*1000. Upstream timecode 1.5.1 ships
exposure-window semantics (a frame represents 1/FPS of elapsed exposure;
00:00:00:00 is the END of frame 1). The wrapper canonicalizes by routing
all start_seconds= construction through upstream's tc_to_frames (HMSF
string), which handles drop-frame correction at 29.97/59.94 DF correctly.
CTimecode
Bases: Timecode
SMPTE timecode with playhead semantics over upstream timecode 1.5.1.
See module docstring for the .milliseconds / .milliseconds_rounded / .milliseconds_exact precision split contract.
Source code in src/cuemsutils/tools/CTimecode.py
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 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 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 | |
framerate
property
writable
Canonical framerate: int for SMPTE, float for fractional, int 1000 for ms.
Upstream stores integer SMPTE framerates as strings ('25', '30')
but 'ms'/'1000' as int 1000 — making tc.framerate == 25
silently False. This getter normalizes the return type so callers can
compare against numeric literals reliably.
milliseconds
property
DEPRECATED — alias of .milliseconds_rounded.
The original .milliseconds returned int(...) (truncation).
The new .milliseconds_rounded returns round(...) (nearest
int) — at integer framerates the values are identical; at
fractional framerates they may differ by ±1ms. Migrate every
call-site to the explicit name to clarify rounding intent and
silence this warning.
Will be removed in the first stable release after 0.1.0rc6.
milliseconds_exact
property
Time as exact-precision milliseconds (float).
The mathematical answer: frame_number * 1000 / _int_framerate.
At integer framerates (24, 25, 30, ms) this is always a whole number
as a float (e.g., 25fps frame 31 → 1200.0). At fractional framerates
(29.97, 23.976) the float carries the true sub-ms value (29.97fps
frame 31 → 1001.001001...) — this is the precision the old
int-truncating .milliseconds was throwing away.
Use for:
- precision-sensitive math (BaseEngine.go_offset calc, scheduler drift compensation, MTC bias measurement)
- any place where adding/subtracting milliseconds across many frames at fractional framerates would accumulate truncation drift
- comparison against expected exact values in tests
(
pytest.approx(expected, abs=1e-9))
Do NOT use for:
- sleep durations (
time.sleepaccepts float but_roundedbetter signals integer-ms intent) - CLI args expecting integer ms
- dict/set keys (float equality is fragile)
- arithmetic with other ints (float contamination)
Resolves the # TODO: float math for other framerates from the
pre-869cyndtv code.
Note on framerate divisor: uses float(self.framerate) (the actual
SMPTE rate, e.g., 29.97) rather than _int_framerate (the rounded
label rate, 30 for 29.97). For NTSC fractional rates this is the
difference between getting real-time ms (1001.001 at frame 31) vs
label-rate ms (1000.0). cuems consumers want real-time semantics.
milliseconds_rounded
property
Time as milliseconds, rounded to the nearest int (banker's rounding).
Equivalent to round(self.milliseconds_exact). Rounding (not
int-truncation) halves the per-call max error at fractional
framerates from ~1ms to ~0.5ms, and over long sums averages to
zero drift instead of monotonic loss.
Use for:
- sleep durations passed to
time.sleep() - CLI args expecting integer ms (e.g.,
audiowaveform -e) - polling comparisons (
while mtc.main_tc.milliseconds_rounded < target_ms) - dict/set keys
- arithmetic with other ints (no float contamination)
Migration note: This is the spiritual successor of the old
.milliseconds, but with round() instead of int()
truncation. At integer framerates, behavior is identical to the old
.milliseconds. At fractional framerates, values may differ by
±1 from the old truncation — review every call-site that compared
against an exact expected ms value at 29.97/23.976.
__add__(other)
Return a new CTimecode with other added.
For CTimecode operands, both operands' frames are 1-indexed counts;
naively summing them double-applies the +1 offset. Subtract 1 to get
the playhead-correct sum.
Source code in src/cuemsutils/tools/CTimecode.py
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 | |
__mul__(other)
Return a new CTimecode with frames multiplied by other.
Source code in src/cuemsutils/tools/CTimecode.py
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
__sub__(other)
Return a new CTimecode with other subtracted.
Symmetric to add: subtracting two 1-indexed frame counts yields a 0-indexed delta, so add +1 to land back in the 1-indexed convention. Subtracting a larger duration from a smaller position produces frames<=0, which upstream's frames setter rejects with ValueError — that's the intended contract (no silent wrap).
Source code in src/cuemsutils/tools/CTimecode.py
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | |
__truediv__(other)
Return a new CTimecode with frames divided by other.
Rounds the float result to int (upstream's frames setter requires
positive int). Rejects zero/negative divisors explicitly to avoid
silent max(1, negative) clamp paths.
Source code in src/cuemsutils/tools/CTimecode.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | |
return_in_other_framerate(framerate)
Return a copy of this CTimecode at a different framerate.
Frame-domain conversion via frame_number (0-indexed elapsed-frames
count) avoids the lossy time-domain round-trip the previous
implementation used (which constructed the new instance via
start_seconds=self.milliseconds/1000, losing one frame to
upstream's int(s*fr) → frame_number+1 round-trip).
NOTE — throwaway object cost (deferred 869cyndtv PR #6, 2026-04-27):
The CTimecode(framerate=framerate) construction below is
used only to read _int_framerate from the resulting object.
It runs upstream's framerate setter (correct, what we want) but
ALSO calls tc_to_frames("00:00:00:00") to populate
_frames=1 (pure waste). Cost is ~5μs per call. Call-sites
(run_cue.py:62/252, helpers.py:28/31, loop_cue.py:74/183) are
all construction-time, not hot-loop — total project-load impact
~2ms for 100 cues. Deferred because the cost is unmeasurable in
production.
If profiling ever flags this, the recommended fix is a
class-level memoization cache keyed on the framerate input
(Option D in the 869cyndtv PR #6 plan)::
_INT_FR_CACHE: dict = {}
@classmethod
def _int_framerate_for(cls, fr):
key = (type(fr), fr) if isinstance(fr, (int, float, str)) else repr(fr)
if key not in cls._INT_FR_CACHE:
cls._INT_FR_CACHE[key] = CTimecode(framerate=fr)._int_framerate
return cls._INT_FR_CACHE[key]
Then replace the ``target_int_fr = ...`` line below with
``target_int_fr = self._int_framerate_for(framerate)``.
Why a cache (Option D) over inlining upstream's NTSC-detection
logic (Option F): inlining duplicates upstream's algorithm and
silently diverges if upstream changes tolerance or adds new
NTSC-like rates. The cache delegates to upstream on the first
lookup per unique framerate and pays zero on subsequent calls.
Revisit triggers: (1) profiling shows this method on a hot path,
(2) a feature introduces dynamic framerate changes during
playback, (3) the same cache pattern is needed elsewhere in
CTimecode (unify at that point).
Source code in src/cuemsutils/tools/CTimecode.py
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 | |
CTimecodeError
Bases: Exception
Raised when an error occurred in timecode calculation.
Source code in src/cuemsutils/tools/CTimecode.py
455 456 457 | |
Quarter-frame timer that hooks to a CTimecode object.
Fires a registered callback at every quarter-frame boundary. Optionally accepts an immutable list of parameter tuples at construction time; each tuple's contents are unpacked as callback arguments at the corresponding quarter-frame. When a tuple list is provided the timer stops automatically after the last tuple is consumed; without one it runs until explicitly stopped.
CTimecodeTimer
Timer that fires a callback at every quarter-frame boundary.
Source code in src/cuemsutils/tools/CTimecodeTimer.py
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 | |
start()
Start the timer loop.
IDLE or STOPPED → RUNNING. No-op if already RUNNING. EXHAUSTED → no-op with a warning.
Source code in src/cuemsutils/tools/CTimecodeTimer.py
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 | |
stop()
Stop the timer loop. RUNNING → STOPPED. No-op otherwise.
Source code in src/cuemsutils/tools/CTimecodeTimer.py
101 102 103 104 105 106 107 108 109 110 | |
FadeCalculator
Source code in src/cuemsutils/tools/FadeCalculator.py
6 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 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 | |
calculate(fade_function, **kwargs)
staticmethod
Calculate a timeline of timecodes between start_time and end_time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fade_function
|
Callable | str
|
The fade function to apply to the timeline. |
required |
**kwargs
|
Additional keyword arguments to pass to the timeline calculation and the fade function. |
{}
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
A list of tuples, each containing a timecode and the value of the fade function at that timecode. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If fade_function is a string and not a valid function name of FadeCalculator. |
Source code in src/cuemsutils/tools/FadeCalculator.py
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 | |
calculate_timeline(start_time, end_time, **kwargs)
staticmethod
Calculate a timeline of timecodes between start_time and end_time. It does not allow for a zero duration resulting timeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
CTimecode
|
The start timecode. |
required |
end_time
|
CTimecode
|
The end timecode. |
required |
**kwargs
|
Additional keyword arguments to pass to the CTimecode constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
list[str]
|
A list of timecodes as strings. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If start_time or end_time are not of type CTimecode. |
ValueError
|
If the duration is less than or equal to 0. |
Source code in src/cuemsutils/tools/FadeCalculator.py
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 | |
ConnectionInfo
dataclass
Information about an active bus connection.
Source code in src/cuemsutils/tools/HubServices.py
23 24 25 26 27 28 | |
HubService
Bases: ABC
Source code in src/cuemsutils/tools/HubServices.py
31 32 33 34 35 36 37 38 39 40 41 42 | |
get_message()
abstractmethod
Get message from the queue. Message.data is already JSON-decoded as dict
Source code in src/cuemsutils/tools/HubServices.py
40 41 42 | |
send_message(message)
abstractmethod
Add message (dict or Message) to the queue to be sent to hub
Source code in src/cuemsutils/tools/HubServices.py
36 37 38 | |
NngBusHub
Bases: HubService
Communicates over NNG (nanomsg) using Bus topology for many-to-one, one-to-many messaging
Source code in src/cuemsutils/tools/HubServices.py
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 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 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 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 | |
__init__(hub_address, mode)
Initialize Nng_bus_hub instance with address and operational mode.
Parameters: - hub_address (str): The address to connect or listen for bus connections. - mode (Mode): The operational mode - LISTENER (listens) or DIALER (dials)
The instance will set up incoming and outgoing message queues for asynchronous message handling.
Source code in src/cuemsutils/tools/HubServices.py
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 | |
disable_auto_ping()
Disable automatic ping mechanism.
Source code in src/cuemsutils/tools/HubServices.py
356 357 358 359 | |
disable_auto_pong()
Disable automatic pong responses.
Source code in src/cuemsutils/tools/HubServices.py
366 367 368 369 | |
enable_auto_ping(interval=10.0, inactivity_threshold=5.0)
Enable automatic ping mechanism for the controller.
The controller will automatically send ping messages to all nodes if there's been no activity for the specified threshold period. Nodes will automatically respond with pong messages.
Parameters: - interval: How often to check for inactive connections (default: 10.0 seconds) - inactivity_threshold: Send ping if no activity for this many seconds (default: 5.0)
Note: This is primarily useful for LISTENER mode to verify node connections.
Source code in src/cuemsutils/tools/HubServices.py
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | |
enable_auto_pong()
Enable automatic pong responses (enabled by default).
Source code in src/cuemsutils/tools/HubServices.py
361 362 363 364 | |
get_active_connections()
Get a list of all active connections.
Returns: - List[ConnectionInfo]: List of all active connection information.
Source code in src/cuemsutils/tools/HubServices.py
257 258 259 260 261 262 263 264 | |
get_connection_count()
Get the number of active connections.
Returns: - int: Number of currently active connections.
Source code in src/cuemsutils/tools/HubServices.py
266 267 268 269 270 271 272 273 | |
get_connection_health_info(activity_timeout=30.0)
Get connection health information based on message activity.
This is particularly useful for DIALERs to check if they're still connected to the controller, since nodes don't track the controller connection in active_connections.
Parameters: - activity_timeout: Seconds of inactivity before considering unhealthy (default: 30.0)
- dict: Health information containing:
- is_healthy: bool - True if recent activity detected
- last_received: datetime or None - Last message received time
- last_sent: datetime or None - Last message sent time
- seconds_since_activity: float or None - Seconds since last activity
- messages_received: int - Total messages received
- messages_sent: int - Total messages sent
Source code in src/cuemsutils/tools/HubServices.py
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 | |
get_message()
async
Retrieve a message from the incoming queue.
- Message: The next message received from the bus. The
datafield is already JSON-decoded as a dict. This method blocks until a message is available.
Source code in src/cuemsutils/tools/HubServices.py
247 248 249 250 251 252 253 254 255 | |
is_connection_healthy(activity_timeout=30.0)
Check if the connection is healthy based on recent activity.
Parameters: - activity_timeout: Seconds of inactivity before considering unhealthy (default: 30.0)
Returns: - bool: True if connection appears healthy
Source code in src/cuemsutils/tools/HubServices.py
325 326 327 328 329 330 331 332 333 334 335 | |
send_message(message)
async
Queue a message to be sent to the bus.
Parameters: - message (dict | Message): The message to be sent. Must be a dict or Message object with dict data.
Raises: - TypeError: If message is not a dict or Message object, or if Message.data is not a dict.
The message is JSON-encoded and placed in the outgoing queue to be sent by the sender handler.
Source code in src/cuemsutils/tools/HubServices.py
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 | |
send_ping()
async
Manually send a ping message to all connected nodes.
Returns: - int: Number of pings sent
Source code in src/cuemsutils/tools/HubServices.py
371 372 373 374 375 376 377 378 379 380 381 382 | |
start()
async
Start the bus communication by initializing the connection and launching message handlers.
This method starts the bus connection based on the mode (LISTENER or DIALER), then launches infinite receiver and sender loops. It monitors both tasks and exits when the first exception occurs or connection is broken, properly cleaning up all running tasks.
Raises: - ValueError: If an unknown mode is set. - Exception: Re-raises any exception that occurs during task execution after cleanup.
Source code in src/cuemsutils/tools/HubServices.py
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 | |
start_dialer()
async
Initialize the bus connection in DIALER mode (dialing to controller).
Creates a Bus0 socket that dials to the configured address with a 100ms receive timeout. TCP keepalive is enabled BEFORE dialing to ensure it applies to the connection. Non-blocking dial is used to allow reconnection if controller is not yet available. Callbacks are registered BEFORE dialing to ensure no connection events are missed.
Source code in src/cuemsutils/tools/HubServices.py
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
start_listener()
async
Initialize the bus connection in LISTENER mode (listening for connections).
Creates a Bus0 socket that listens on the configured address with a 100ms receive timeout. TCP keepalive is enabled BEFORE listening to ensure it applies to all connections. Callbacks are registered BEFORE listening to ensure no connection events are missed.
Source code in src/cuemsutils/tools/HubServices.py
183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
SignalEngine
A class that handles system signals and status tracking.
Source code in src/cuemsutils/tools/SignalEngine.py
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 | |
StringSanitizer
Ensure that the string is sanitized and safe for use in the system
Source code in src/cuemsutils/tools/StringSanitizer.py
1 2 3 4 5 6 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 | |
Uuid
A class to interact with unique identifiers.
Comparisions should be made based on memory allocation.
Calling or printing the instance will return the uuid4 string.
Source code in src/cuemsutils/tools/Uuid.py
6 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 | |