@@ -87,20 +87,33 @@ class SimulationRunCore(WriteableCogniteResource["SimulationRunWrite"]):
8787 def __init__ (
8888 self ,
8989 run_type : str | None ,
90- routine_external_id : str ,
90+ routine_external_id : str | None ,
9191 run_time : int | None = None ,
92+ routine_revision_external_id : str | None = None ,
93+ model_revision_external_id : str | None = None ,
9294 ) -> None :
9395 self .run_type = run_type
9496 self .run_time = run_time
9597 self .routine_external_id = routine_external_id
98+ self .routine_revision_external_id = routine_revision_external_id
99+ self .model_revision_external_id = model_revision_external_id
96100
97101
98102class SimulationRunWrite (SimulationRunCore ):
99103 """
100104 Request to run a simulator routine asynchronously.
101105
106+ This class supports two modes of running simulations:
107+ 1. By routine external ID only
108+ 2. By routine revision external ID + model revision external ID
109+
102110 Args:
103- routine_external_id (str): External id of the associated simulator routine
111+ routine_external_id (str | None): External id of the associated simulator routine.
112+ Cannot be specified together with routine_revision_external_id and model_revision_external_id.
113+ routine_revision_external_id (str | None): External id of the associated simulator routine revision.
114+ Must be specified together with model_revision_external_id.
115+ model_revision_external_id (str | None): External id of the associated simulator model revision.
116+ Must be specified together with routine_revision_external_id.
104117 run_type (str | None): The type of the simulation run
105118 run_time (int | None): Run time in milliseconds. Reference timestamp used for data pre-processing and data sampling.
106119 queue (bool | None): Queue the simulation run when connector is down.
@@ -110,15 +123,34 @@ class SimulationRunWrite(SimulationRunCore):
110123
111124 def __init__ (
112125 self ,
113- routine_external_id : str ,
126+ routine_external_id : str | None = None ,
127+ routine_revision_external_id : str | None = None ,
128+ model_revision_external_id : str | None = None ,
114129 run_type : str | None = None ,
115130 run_time : int | None = None ,
116131 queue : bool | None = None ,
117132 log_severity : str | None = None ,
118133 inputs : list [SimulationInputOverride ] | None = None ,
119134 ) -> None :
135+ is_routine_mode = routine_external_id and not routine_revision_external_id and not model_revision_external_id
136+ is_revision_mode = (
137+ not routine_external_id
138+ and routine_revision_external_id is not None
139+ and model_revision_external_id is not None
140+ )
141+
142+ # Validate that either routine_external_id OR (routine_revision_external_id + model_revision_external_id) is provided
143+ if not (is_routine_mode or is_revision_mode ):
144+ param_error = ValueError (
145+ "Must specify either 'routine_external_id' alone, or both "
146+ "'routine_revision_external_id' and 'model_revision_external_id' together."
147+ )
148+ raise param_error
149+
120150 super ().__init__ (
121151 routine_external_id = routine_external_id ,
152+ routine_revision_external_id = routine_revision_external_id ,
153+ model_revision_external_id = model_revision_external_id ,
122154 run_type = run_type ,
123155 run_time = run_time ,
124156 )
@@ -128,20 +160,36 @@ def __init__(
128160
129161 @classmethod
130162 def _load (cls , resource : dict [str , Any ], cognite_client : CogniteClient | None = None ) -> SimulationRunWrite :
131- inputs = resource .get ("inputs" , None )
163+ inputs = resource .get ("inputs" )
164+ routine_revision_external_id = resource .get ("routineRevisionExternalId" )
165+ model_revision_external_id = resource .get ("modelRevisionExternalId" )
166+ routine_external_id = resource .get ("routineExternalId" )
167+
132168 return cls (
133169 run_type = resource .get ("runType" ),
134- routine_external_id = resource ["routineExternalId" ],
135170 run_time = resource .get ("runTime" ),
136171 queue = resource .get ("queue" ),
137172 log_severity = resource .get ("logSeverity" ),
138173 inputs = ([SimulationInputOverride ._load (_input ) for _input in inputs ] if inputs else None ),
174+ routine_external_id = routine_external_id ,
175+ routine_revision_external_id = routine_revision_external_id ,
176+ model_revision_external_id = model_revision_external_id ,
139177 )
140178
141179 def dump (self , camel_case : bool = True ) -> dict [str , Any ]:
142180 output = super ().dump (camel_case = camel_case )
143181 if self .inputs is not None :
144182 output ["inputs" ] = [input_ .dump (camel_case = camel_case ) for input_ in self .inputs ]
183+
184+ # Remove fields based on the mode we're in
185+ if self .routine_external_id is not None :
186+ # Routine-only mode: remove revision fields that might be None
187+ output .pop ("routineRevisionExternalId" , None )
188+ output .pop ("modelRevisionExternalId" , None )
189+ else :
190+ # Revision mode: remove routine_external_id
191+ output .pop ("routineExternalId" , None )
192+
145193 return output
146194
147195 def as_write (self ) -> SimulationRunWrite :
0 commit comments