Resumen
Un Calendario (Schedule) es lo que ancla una simulación a la temporización del mundo real. Sin un calendario, un modelo se ejecuta en tiempo abstracto con llegadas sintéticas — útil para trabajo exploratorio, pero no para comparar contra tu piso de planta real. Con un calendario, la simulación se ancla a fechas reales, patrones de turnos reales y planes de producción reales. El material entra cuando tu plan dice que lo hace, las transiciones de turno disparan a horas de reloj de pared específicas, y los resultados son comparables directamente a lo que produjo tu piso de planta. Cada uso serio de ProDex involucra al menos un calendario. La mayoría de los modelos tienen varios — uno para el plan “normal”, algunos para escenarios alternativos que estás comparando. Los calendarios viven junto a las Instantáneas (Snapshots) como las dos cosas que una fila de comparación de Experimento (Experiment) reúne. Una Instantánea congela el modelo + calendario juntos (el calendario está incrustado en la instantánea, no referenciado); el calendario activo cuando se capturó la instantánea viaja con ella.Elegir un Calendario
El selector de calendario vive en la barra superior del Modelador. El menú desplegable lista cada calendario definido en el modelo, más:Default (no schedule)— cuando se selecciona, el modelo se ejecuta en tiempo abstracto con las llegadas estocásticas que las Fuentes (Sources) definan. No hay un objeto de calendario detrás de esto — es una selección nula.+ New schedule— crea un calendario fresco y vacío y cambia a él.Edit— abre el modal Schedule Editor para el calendario actualmente seleccionado. Vive dentro del menú desplegable (no junto al selector).Delete— elimina el calendario actualmente seleccionado. Abre un diálogo de confirmación: “Delete Schedule — Are you sure you want to delete ‘{name}’? This action cannot be undone.”
El editor de Calendario
El editor de calendario es un modal titulado Edit {schedule name} que toma el área de trabajo mientras creas la temporización y eventos de un calendario. La parte superior del modal tiene cuatro campos que definen el calendario:- Name — corto, descriptivo. Esto es lo que aparece en el selector de la barra superior.
- Description — texto libre opcional explicando qué representa este calendario.
- Start Time — el momento de reloj de pared en que comienza la simulación. Cada marca de tiempo de evento en este calendario debe caer en o después de Start Time.
- End Time — el momento de reloj de pared en que termina la simulación. Si se deja en blanco, la simulación se ejecuta durante la Duration configurada del modelo a partir de Start Time. Si se establece, End Time anula Duration.
material_releases[]— entidades entrando al modelo en tiempos específicosscheduled_actions[]— asignaciones y emisiones disparadas en tiempos específicos, opcionalmente condicionadas
actions[] donde cada acción es o un assign o un emit. Los dos tipos de acción comparten una entrada padre scheduled_actions[] y heredan su release_time y condition opcional.
Un solo botón + en la parte superior derecha del modal abre un selector para qué tipo de evento agregar — material release, assign-variable o emit-event.
Qué contiene un Calendario
Un calendario es una secuencia de liberaciones de material y acciones programadas, cada una marcada con un tiempo de reloj de pared absoluto específico. La simulación se ejecuta desde Start Time hasta End Time (o durante la Duration configurada del modelo si End Time no está establecido), y cada evento dispara cuando el tiempo de simulación de reloj de pared alcanza su marca de tiempo. Cada marca de tiempo de evento es absoluta — no un offset relativo desde Start Time.Liberaciones de material
Una liberación de material le indica a una Source o Búfer (Buffer) que emita una o más entidades en un tiempo de reloj de pared específico. El formulario tiene estos campos de esquema:element_id— el id de una Source o Buffer desde la cual liberar. Admite direccionamiento jerárquico (model_node_1::source_1) para componentes dentro de un Model Node.entity_type_id— el slug del tipo de entidad a liberar.quantity— un entero positivo (exclusiveMinimum: 0, tipado como entero; sin unión DSL).release_time— momento absoluto de reloj de pared en que dispara la liberación (datetime ISO con zona horaria).attributes— valores a establecer en las entidades recién creadas usando las seis estrategias de asignación: Fixed, DSL Expression, Round Robin, Random Choice, Random, Weighted.
priority="rush" y due_priority=5; el 1 de noviembre de 2024 a las 9:00 AM UTC liberar 30 unidades de Producto B; y así sucesivamente.
La lógica de llegada de una Source y las liberaciones de material se ejecutan en paralelo. No son mutuamente exclusivas. Una Source puede seguir produciendo llegadas estocásticas mientras un calendario simultáneamente inyecta lotes específicos en tiempos programados, y acciones
release_entity impulsadas por eventos pueden dispararse sobre ambas. Si quieres una Source solo de calendario, deja su lógica de llegada vacía.Acciones programadas
Una acción programada se dispara en un tiempo de reloj de pared específico sin estar atada al evento del ciclo de vida de ningún componente. Campos de esquema:release_time— momento absoluto de reloj de pared en que dispara la acción (con zona horaria).condition(opcional) — expresión DSL booleana. La acción solo dispara si la condición evalúa verdadero enrelease_time.actions[]— lista de entradasassignoemitque disparan juntas en este tiempo.
assign— escribe en una Variable de estado.emit— publica en un Topic.
- Un
emitprogramado dispara en el límite del turno — por ejemplo, publica el topicshift_start_night. - Un Event Listener en el recurso (Resource) se suscribe a ese topic y establece la capacidad al valor nocturno.
SELF no está disponible en acciones programadas. SELF está restringido a event hooks y event listeners. Desde una acción programada, referencia componentes por su id explícito en funciones de consulta de componentes en su lugar.Direccionamiento jerárquico
element_id acepta el separador :: para componentes dentro de un Model Node. Ejemplos:
source_1— una Source de nivel superiormodel_node_1::source_1— una Source dentro de un Model Nodeouter_node::inner_node::buffer_1— anidado profundamente
:: está reservado — ningún id de componente individual puede contenerlo.
El patrón de programación de turnos
La mayoría de las fábricas tienen capacidad basada en turnos que cambia durante el día y la semana. La forma idiomática de modelar esto en ProDex combina calendarios, topics, variables de estado y event listeners:- Una variable de estado de turno —
CURRENT_SHIFT, tipotext, valor inicial"day". - Acciones
emitprogramadas en los límites de turno — publica el topicshift_dayal inicio de cada turno diurno, publica el topicshift_nightal inicio de cada turno nocturno, cada uno con surelease_timede reloj de pared específico. - Un Event Listener en cada recurso afectado suscribiéndose a los topics de turno — cuando se publica
shift_night, establece la capacidad de la máquina CNC al valor nocturno y actualizaCURRENT_SHIFTa"night". - Las expresiones referencian
CURRENT_SHIFT— las tasas de llegada, la puntuación de prioridad y cualquier otra cosa que varíe por turno lee la variable de estado y se ramifica en consecuencia.
Múltiples Calendarios por modelo
Un modelo puede tener múltiples calendarios definidos simultáneamente. Cada uno es un conjunto completo de liberaciones de material y acciones programadas con su propio Start Time y End Time; eliges cuál usar desde el selector de la barra superior al ejecutar una simulación, y cualquier Instantánea guardada mientras un calendario está activo incrusta ese calendario para ejecuciones aguas abajo. Usos típicos:- Escenarios base vs. estrés — un calendario “normal” y un calendario de “aumento de demanda”, comparados en el mismo experimento.
- Repetición histórica — la demanda real del último mes como un calendario, un pronóstico de demanda planificada como otro.
- Variaciones de turno — un calendario estándar de cinco días y un calendario alternativo de siete días con cobertura de fin de semana.
Start Time y End Time
- Start Time es el momento de reloj de pared en que comienza la simulación. Cada marca de tiempo de liberación de material y acción programada debe caer en o después de Start Time.
- End Time, si se proporciona, es cuando termina la simulación. Útil para ejecutar el mismo calendario contra una ventana más corta o más larga sin editar los eventos del calendario.
- Si End Time se deja en blanco, la simulación se ejecuta durante la Duration configurada del modelo desde Start Time.
- Los eventos con marca de tiempo después de End Time (o después de Start Time + Duration si no hay End Time establecido) nunca disparan.
Consejos
- Cada modelo serio necesita un calendario. Las llegadas sintéticas están bien para la primera pasada; los calendarios reales son requeridos para resultados comparables.
- Usa marcas de tiempo absolutas de reloj de pared consistentemente. Es tentador pensar en offsets relativos (“liberar en +3600s”) pero cada evento necesita un
release_timeabsoluto. Si estás esbozando un calendario en papel, calcula las marcas de tiempo absolutas desde tu Start Time base antes de ingresarlas. - Usa
conditionen acciones programadas para condicionar el comportamiento al estado en tiempo de ejecución — p. ej., solo emitir un topic si una variable de estado está en un modo particular. - Mantén la lógica a nivel de calendario en el calendario, la lógica a nivel de componente en los Event Listeners. El calendario emite la señal; el listener maneja los efectos secundarios.
- Usa múltiples calendarios para experimentos. El punto entero de los experimentos es la comparación — los calendarios son un eje de variación, la configuración del modelo el otro.
- Dos eventos en la misma marca de tiempo disparan en un orden no especificado. Si el orden importa, distáncialos por una pequeña cantidad (un segundo) o encadénalos a través de un topic.

