Sepasoft MES Module Suite
BatchQueueEntry Object
Overview
A Batch Queue Entry represents one batch scheduled for or undergoing execution on a Process Cell. Each entry binds a unique Batch ID to a runtime Batch Control Recipe, optional Batch Formula, unit assignments, scale/quantity overrides, and scheduling metadata. Queue entries live in the gateway batch execution manager — they are not persisted as standalone MES objects and cannot be saved with system.mes.saveMESObject().
Create entries with system.mes.batch.queue.addEntry(), update idle entries with addOrUpdateEntry(), and drive execution with batch-level commands (executeEntryCommand()) and step-level APIs that accept either a batch ID or a BatchQueueEntry reference. When a batch completes and is reset or removed, the entry leaves the active queue; historical batch IDs remain reserved and cannot be reused.
Obtaining a BatchQueueEntry
Python |
# Create a new queue entry from a master recipe or formula link recipeLink = system.mes.batch.recipe.getRecipeLink('Standard Mix', None) entry = system.mes.batch.queue.addEntry( masterRecipeOrFormulaLink=recipeLink, batchName='Mix Run 42', batchID='BATCH-042', priority=1, scale=1.0, quantity=500.0, unitAssignments={'Mix': 'Enterprise\\Site\\Area\\Process Cell\\Mixer 1'}, batchParameters={'Target pH': 7.2}, processCellPath='Enterprise\\Site\\Area\\Process Cell' ) # Load an existing entry by batch ID entry = system.mes.batch.queue.getEntry('BATCH-042') # List entries (use paging when the queue is large) entries = system.mes.batch.queue.getEntries(0, 100, 'BATCH-*') |
Object Identity
|
Field |
Value |
|
Type name |
BatchQueueEntry |
|
Kind |
Runtime response object (not an AbstractMESObject) |
|
Required module |
Batch (Production) |
|
Persistence |
In-memory queue on the gateway that owns the process cell; control recipe data is stored as MES objects |
|
Primary key |
Batch ID (getBatchID()) — globally unique across current and previously executed batches |
Related Objects
|
Relationship |
Type |
Notes |
|
Control recipe |
BatchControlRecipe |
Created when the batch is queued; accessed via getRecipeControlLink(), getRecipeLink(), or getControlRecipeLink() |
|
Master recipe |
BatchMasterRecipe |
Source template; UUID available from getMasterRecipeUUID() after queuing |
|
Formula |
BatchFormula |
Optional; link from getBatchFormulaLink() when the batch was created from or linked to a formula |
|
Process cell |
MESProcessCell |
Execution location; link from getProcessCellLink(), path from getProcessCellEquipmentPath() |
|
Assigned units |
MESObjectLink or equipment path |
Per unit procedure name in getAssignedUnitMap() |
There is no parent/child MES object hierarchy. Unit procedure names in the assigned-unit map must match friendly names in the control recipe.
Properties
All properties are accessed through getter methods on the BatchQueueEntry instance returned by addEntry(), getEntry(), getEntries(), or changeEntryPriority(). Most fields are read-only after the control recipe is created; see Exceptions and Constraints for what can change.
Identification and recipe references
|
Property |
Access |
Type |
Description |
|
Batch Name |
getBatchName() |
String |
Display name for the batch. Multiple queue entries may share the same batch name. Defaults to the master recipe name when omitted at addEntry(). |
|
Batch ID |
getBatchID() |
String |
Unique identifier. Required at creation; cannot be blank or reused. |
|
Recipe Name |
getRecipeName() |
String |
Friendly name of the control recipe instance. |
|
Parent Recipe Name |
getParentRecipeName() |
String |
Name of the Batch Master Recipe Class folder containing the source master recipe, when available. |
|
Master Recipe UUID |
getMasterRecipeUUID() |
String |
UUID of the source Batch Master Recipe. |
|
Recipe Control Link |
getRecipeControlLink() |
MESObjectLink |
Link to the runtime Batch Control Recipe. Synonyms: getControlRecipeLink(), getRecipeLink(). |
|
Recipe User Version |
getRecipeUserVersion() |
Integer |
User version copied from the master recipe at queue time. |
|
Batch Formula Link |
getBatchFormulaLink() |
MESObjectLink |
Link to the Batch Formula when one is associated. Use hasBatchFormulaLink() to test. |
Sizing and priority
|
Property |
Access |
Type |
Description |
|
Scale |
getScale() / setScale(scale) |
Double |
Scale factor applied to the control recipe. Used in recipe calculations and by the allocation manager. |
|
Quantity |
getQuantity() / setQuantity(quantity) |
Double |
Batch size. Use hasQuantity() to test for a positive quantity. |
|
Units |
getUnits() |
String |
Unit of measure for quantity, when specified at creation. |
|
Priority |
getPriority() |
Integer |
Scheduling priority where 1 is highest. Clamped to a minimum of 1 at construction. Change while idle via changeEntryPriority() or addOrUpdateEntry(). |
Process cell and queue behavior
|
Property |
Access |
Type |
Description |
|
Process Cell Link |
getProcessCellLink() / setProcessCellLink(link) |
MESObjectLink |
Process cell that owns execution. Required at creation. Updating the link also refreshes the equipment path. |
|
Process Cell Equipment Path |
getProcessCellEquipmentPath() |
String |
Equipment path of the process cell (for example, Enterprise\\Site\\Area\\Process Cell). |
|
Execution Interval |
getExecutionInterval() |
Long |
Polling interval inherited from the process cell configuration. |
|
Remove Held From Queue |
isRemoveHeldFromQueue() |
Boolean |
When True, held batches are automatically removed from the queue per process cell settings. |
|
Remove Complete From Queue |
isRemoveCompleteFromQueue() |
Boolean |
When True, completed batches are automatically removed from the queue per process cell settings. |
|
Remote Queue Entry |
isRemoteQueueEntry() |
Boolean |
True when the entry is owned by a remote gateway in an enterprise deployment. |
Execution state and scheduling
|
Property |
Access |
Type |
Description |
|
Batch State |
getBatchState() / setBatchState(state) |
String |
Cached batch-level execution state (for example, Idle, Running, Held, Complete). Prefer system.mes.batch.queue.getStatus(entry) for the authoritative live state during execution. |
|
Blocked Reason |
getBlockedReason() / setBlockedReason(reason) |
String |
Reason the batch is blocked from starting or continuing, when set by the execution engine. |
|
Last Activity Date Time |
getLastActivityDateTime() |
LocalDateTime |
Timestamp of the last queue activity. |
|
Scheduled Begin / End |
getScheduledBeginDateTime() / getScheduledEndDateTime() |
LocalDateTime |
Planned schedule window, when populated by scheduling integrations. |
|
Actual Begin / End |
getActualBeginDateTime() / getActualEndDateTime() |
LocalDateTime |
Actual execution window, when recorded. |
|
Original Begin / End |
getOriginalBeginDateTime() / getOriginalEndDateTime() |
LocalDateTime |
Original schedule before rescheduling, when recorded. |
Unit assignments
|
Property |
Access |
Type |
Description |
|
Assigned Unit Map |
getAssignedUnitMap() |
Map |
Read-only map of unit procedure name → equipment path or MESObjectLink. |
|
Unit (by name) |
getUnit(unitProcedureName) / setUnit(name, linkOrPath) |
Serializable |
Get or set one unit assignment. Values may be an equipment path String or MESObjectLink. |
BatchQueueEntry Methods
|
Method |
Return type |
Description |
|
getRecipe() |
BatchControlRecipe |
Loads the control recipe object. Synonym: getControlRecipe(). |
|
withNewPriority(priority) |
BatchQueueEntry |
Returns a copy with a new priority and the same unit assignments. Used internally by changeEntryPriority(). |
|
toString() |
String |
Debug summary: batch name, batch ID, priority, scale, quantity, units, batch state. |
Deprecated parameter helpers
These methods write directly to Batch Control Logic and remain for backward compatibility. Prefer system.mes.batch.queue.setParameterValue() and getParameterValueAsString() with full item paths.
|
Method |
Return type |
Description |
|
setBatchParameter(paramName, value) |
None |
Deprecated. Sets a procedure-level parameter on the control recipe logic and saves. |
|
getBatchParameter(paramName) |
Serializable |
Deprecated. Returns a procedure-level parameter value as a string. |
|
getBatchParameterMap() |
Map |
Deprecated. Returns visible recipe parameters as a name/value map. |
Scope / Availability
|
Context |
How to access |
|
Gateway scripts |
system.mes.batch.queue.* returns and accepts BatchQueueEntry instances |
|
Client / Designer / Perspective scripts |
Same module via RPC (BatchClientQueueScript → gateway) |
|
Perspective UI |
Batch List, Batch Controller, and Batch Recipe Monitor components operate on queue entries selected by Batch ID |
Commands that require electronic signature authorization cannot be driven purely from a BatchQueueEntry handle in script — use the Batch List or Batch Controller components for those commands.
Exceptions and Constraints
|
Situation |
Behavior |
|
Blank batch ID at addEntry() |
Exception: "The batch id cannot be blank." |
|
Duplicate batch ID in queue |
Exception: "The batch id (...) is already in the queue." |
|
Reused batch ID from a prior run |
Exception: "The batch id (...) has already been used." |
|
No process cell at creation |
IllegalStateException: "Process cell was not specified and one could not be determined..." |
|
removeEntry() while not idle |
Exception: "Unable to remove batch queue entry because the batch is not in idle." |
|
changeEntryPriority() while active |
Exception: "Unable to change priority because batch queue entry is active." |
|
addOrUpdateEntry() while not idle (remote) |
Exception: "Unable to edit batch queue entry because it is not idle." |
|
addOrUpdateEntry() on existing entry |
Only priority and unit assignments can change. When the batch is active, only unit assignments can change. |
|
executeEntryCommand(COMMAND_START) on running batch |
Exception: "Unable to begin batch queue entry because it is already running." |
|
Start from invalid state |
Exception: "Unable to begin batch queue entry because it is not in the correct state." |
|
Batch ID not in queue |
BatchQueueEntryNotFoundException from getEntry() and related APIs |
|
Signature-protected commands from script |
IllegalAccessException — use operator UI instead |
|
Remote process cell on wrong gateway |
IllegalAccessException — command must run on the owning gateway |
Use system.mes.batch.queue.getStatus(entry) for live execution state names (Idle, Running, Held, Paused, Complete, and transient -ing states). See ISA-88 state transition matrix for allowed command transitions.
Example Usage
Minimal example — create, inspect, and remove
Python |
recipeLink = system.mes.batch.recipe.getRecipeLink('Standard Mix', None) entry = system.mes.batch.queue.addEntry( masterRecipeOrFormulaLink=recipeLink, batchID='BATCH-DEMO-001', batchName='Demo Mix', priority=1, scale=1.0, quantity=100.0 ) print('Batch ID:', entry.getBatchID()) print('Process cell:', entry.getProcessCellEquipmentPath()) print('Status:', system.mes.batch.queue.getStatus(entry)) # Remove only while idle if system.mes.batch.queue.getStatus(entry) == 'Idle': system.mes.batch.queue.removeEntry(entry) |
Complex example 1 — ERP release with unit assignment, parameters, and monitored start
Schedule a batch from an external order line: queue the entry with overrides, verify assignments, start the batch, and wait until execution reaches Running before writing a tag or ERP status.
Python |
import time # --- Inputs from ERP / tag read --- orderBatchID = 'ORD-2026-0042' recipeName = 'Standard Mix' processCellPath = 'Enterprise\\North Site\\Production\\Reactor Cell' mixerPath = 'Enterprise\\North Site\\Production\\Reactor Cell\\Reactor 1' targetQuantity = 750.0 targetScale = 1.0 recipeLink = system.mes.batch.recipe.getRecipeLink(recipeName, None) if recipeLink is None: raise Exception('Master recipe not found: %s' % recipeName) # Queue with unit and parameter overrides entry = system.mes.batch.queue.addEntry( masterRecipeOrFormulaLink=recipeLink, batchName='Order %s' % orderBatchID, batchID=orderBatchID, priority=2, scale=targetScale, quantity=targetQuantity, processCellPath=processCellPath, unitAssignments={'Reactor': mixerPath}, batchParameters={ 'Order Number': orderBatchID, 'Target Weight': targetQuantity } ) # Confirm queue metadata before start logger = system.util.getLogger('erp.batchRelease') logger.info( 'Queued %s on %s (priority=%s, scale=%s, qty=%s)' % ( entry.getBatchID(), entry.getProcessCellEquipmentPath(), entry.getPriority(), entry.getScale(), entry.getQuantity() ) ) assigned = entry.getAssignedUnitMap() if assigned.get('Reactor') != mixerPath: # Fallback: assign at runtime if the map stores links instead of paths system.mes.batch.queue.assignUnit( entry, '/{}/Reactor', mixerPath ) # Start and wait for Running (up to 60 seconds) system.mes.batch.queue.executeEntryCommand( entry, system.mes.batch.queue.COMMAND_START, changedBy='erpRelease.script' ) deadline = time.time() + 60 while time.time() < deadline: status = system.mes.batch.queue.getStatus(entry) if status == 'Running': break if status in ('Aborted', 'Stopped', 'Internal Fault'): raise Exception('Batch failed to start: %s (%s)' % (entry.getBatchID(), status)) time.sleep(0.5) else: raise Exception('Batch did not reach Running: %s' % entry.getBatchID()) # Publish release confirmation system.tag.writeBlocking( ['[default]ERP/BatchReleaseStatus', '[default]ERP/ActiveBatchID'], ['Running', entry.getBatchID()] ) |
Complex example 2 — manual-mode orchestration with valid next steps
Drive a semi-automatic workflow: start the batch, switch an operation to Manual mode, inspect valid active-step targets, change the active step, and execute the step when the operator (or script) is ready.
Python |
import time batchID = 'BATCH-MANUAL-007' entry = system.mes.batch.queue.getEntry(batchID) if entry is None: raise Exception('Batch not found: %s' % batchID) changedBy = 'manualOrchestrator.script' operationPath = '/{}/Crystallize/Grow Crystals' # Start if still idle if system.mes.batch.queue.getStatus(entry) == 'Idle': system.mes.batch.queue.executeEntryCommand( entry, system.mes.batch.queue.COMMAND_START, changedBy=changedBy ) # Wait until running deadline = time.time() + 45 while time.time() < deadline: if system.mes.batch.queue.getStatus(entry) == 'Running': break time.sleep(0.25) else: raise Exception('Batch not running: %s' % batchID) # Put the operation in Manual so active steps can be selected system.mes.batch.queue.setMode( entry, system.mes.batch.queue.MODE_MANUAL, operationPath, changedBy=changedBy ) # Poll until valid next steps appear (recipe-dependent) validSteps = [] deadline = time.time() + 30 while time.time() < deadline: validSteps = system.mes.batch.queue.getValidNextSteps(entry, operationPath) if validSteps: break time.sleep(0.5) if not validSteps: raise Exception('No valid next steps under %s' % operationPath) targetStep = validSteps[0] logger = system.util.getLogger('batch.manual') logger.info('Changing active step to %s' % targetStep) system.mes.batch.queue.changeActiveStep( entry, targetStep, changedBy=changedBy ) # Execute the now-active step in manual mode system.mes.batch.queue.executeStep( entry, targetStep, changedBy=changedBy ) activeSteps = system.mes.batch.queue.getActiveSteps(entry, operationPath) logger.info('Active steps after execute: %s' % activeSteps) |
Complex example 3 — transition monitoring, skip, and batch messages
Monitor pending transitions under a unit procedure, skip a blocking transition when an external readiness signal is true, and acknowledge operator messages for the same batch.
Python |
import time batchID = 'BATCH-XFER-015' entry = system.mes.batch.queue.getEntry(batchID) logicPath = '/{}/Transfer/Receive' changedBy = 'transferSupervisor.script' readinessTag = '[default]Transfer/ReadyToAdvance' if system.mes.batch.queue.getStatus(entry) != 'Running': system.mes.batch.queue.executeEntryCommand( entry, system.mes.batch.queue.COMMAND_START, changedBy=changedBy ) logger = system.util.getLogger('batch.transfer') deadline = time.time() + 120 while time.time() < deadline and system.mes.batch.queue.getStatus(entry) == 'Running': pending = system.mes.batch.queue.getPendingTransitions(entry, logicPath) for transition in pending: path = transition.getItemPath() overall = transition.getOverallStatus() logger.info('Pending transition %s (overall=%s)' % (path, overall)) # External interlock says we may bypass the transition expression ready = system.tag.readBlocking([readinessTag])[0].value if ready and overall is not True: logger.warn('Skipping transition %s per external ready signal' % path) system.mes.batch.queue.skipTransition( entry, path, changedBy=changedBy ) # Handle operator messages for this batch messages = system.mes.batch.queue.getMessages(entry) for msg in messages: if msg.getRequiresAcknowledgement() and not msg.isAcknowledged(): logger.info('Acknowledging message: %s' % msg.getMessage()) system.mes.batch.queue.acknowledgeMessage(msg) if msg.requiresValueEntry() and msg.getValue() is None: # Example: auto-fill a value prompt from a tag suggested = system.tag.readBlocking(['[default]Transfer/OperatorValue'])[0].value msg.setValue(suggested) system.mes.batch.queue.assignMessageValue(msg) if not pending: # No pending transitions — check whether the unit procedure finished status = system.mes.batch.queue.getTransitionStatus( entry, '/{}/Transfer/Receive:Complete Transition' ) if status is not None and status.getOverallStatus() is True: logger.info('Transfer logic complete for %s' % batchID) break time.sleep(1.0) |
Related Functions
Module: system.mes.batch.queue
|
Function |
Description |
|
addEntry(...) |
Create a queue entry from a master recipe or formula link. Returns a BatchQueueEntry. |
|
addOrUpdateEntry(entry) |
Add a new entry or update priority/unit assignments on an existing entry. |
|
getEntry(batchID) |
Return one BatchQueueEntry by batch ID. |
|
getEntries(pageNumber, pageSize, searchPattern) |
Return a filtered, paged list of queue entries. |
|
getEntryLinks(...) |
Return Batch Control Recipe links for queue entries. |
|
getEntryCount(searchPattern) |
Count entries matching a batch ID pattern. |
|
removeEntry(entry) / removeEntry(batchID) |
Remove an idle entry from the queue. |
|
changeEntryPriority(entry, newPriority) |
Change priority on an inactive entry. |
|
assignUnit(entry, unitProcedurePath, unitEquipmentPath) |
Assign a unit to a unit procedure. |
|
getStatus(entry) / getStatus(batchID) |
Authoritative batch execution state string. |
|
executeEntryCommand(...) |
Batch-level commands (Start, Hold, Reset, …). See executeEntryCommand-script.md. |
|
setMode(...) |
Set Auto / Semi-Auto / Manual on procedure logic. See setMode-script.md. |
|
getValidNextSteps(...) |
Valid manual active-step targets. See getValidNextSteps-script.md. |
|
changeActiveStep(...) |
Change the active step in manual logic. See changeActiveStep-script.md. |
|
executeStep(...) |
Execute the active step when parent logic is in Manual mode. |
|
getPendingTransitions(...) / getTransitionStatus(...) |
Inspect transition expressions. See TransitionExpressionStatus-object.md. |
|
skipTransition(...) |
Force a false transition to fire. |
|
setParameterValue(...) / getParameterValue(...) |
Read and write batch parameter values by item path. |
|
getMessages(entry) |
Batch messages for all units in the entry. |
|
getBatchEBR(...) / getBatchBOM(...) |
Export electronic batch record or bill of materials. |
|
getExecutedBatchIDs(...) |
Query historical batch IDs no longer in the queue. |
For the full API table, see batch-procedure-script-reference.md.
Related Objects and Components
-
BatchControlRecipe — Runtime recipe executed for this queue entry; loaded via entry.getRecipe().
-
BatchMasterRecipe — Engineering template used when the batch was queued
-
BatchFormula — Optional formula linked at queue time
-
TransitionExpressionStatus — Transition evaluation snapshots for this entry during execution.
-
Batch List — Operator queue UI (mes.batch.batchList); see batchList-component.md.
-
Batch Controller — Step-level control bound to a batch ID and item path.
- Batch Recipe Monitor — Live SFC diagram for the entry's control recipe.
Sepasoft MES Module Suite