4 @copyright 2021 ESO - European Southern Observatory
6 @brief Implements simulation of recdaqif
14 from ModRecif.Recif
import (
24 from ModRecif.Recif.RecCmds
import RecCmdsSyncService
25 from ModDaqsimif.Daqsimif
import Error
as SimCtlError
29 """Holds simulated status for recording"""
43 self.
status = RecStatusNames.Undefined
47 """Simulator that implements RecCmdsSyncService and sets up
48 simulation behaviour for Simulator.
50 Registered hooks are run once and then removed before executed.
51 Each hook is a callable that takes the result from the default implementation
52 as well as the arguments given to the original implementation.
53 The hook can then choose to modify the existing result or replace it.
64 def RecStart(self, properties: RecProperties) -> RecStatus:
65 """@implements RecCmds.StartDaq"""
66 rec_id = properties.getId()
67 logging.info(
"Request: StartDaq(%s)", rec_id)
69 raise ExceptionErr(rec_id,
"Recording with id already exist")
71 logging.info(
"Request: StartDaq(%s) ref=%s", rec_id, id(rec))
72 rec.status = RecStatusNames.Active
78 """@implements RecCmds.RecStop"""
80 raise ExceptionErr(1234,
"No current recording active")
82 logging.info(
"Request: RecStop(%s)", rec_id)
85 if rec.status
in (RecStatusNames.Completed, RecStatusNames.Stopped):
87 "Request: RecStop(%s): Recording already complete. Returning error", rec_id
92 "Request: RecStop(%s): ... NOT because MAL bug prevents me to", rec_id
95 rec.dp_files = [
"/tmp/%s.fits" % rec_id]
96 rec.status = RecStatusNames.Stopped
104 """@implements RecCmds.RecAbort"""
106 raise ExceptionErr(1234,
"No current recording active")
109 logging.info(
"Request: RecAbort(%s)", rec_id)
111 rec.status = RecStatusNames.Aborted
117 def RecWait(self, spec: RecWaitSpec) -> RecStatus:
118 """@implements RecCmds.RecWait
120 For the moment we simply simulate that the recording was completed
121 as soon as this request was received.
124 logging.info(
"Request: RecWait(%s)", rec_id)
128 def RecStatus(self, rec_id: str) -> RecStatus:
129 """@implements RecCmds.RecStatus"""
130 logging.info(
"Request: RecStatus(%s)", rec_id)
135 """Get recording or raise ExceptionErr."""
138 raise ExceptionErr(rec_id,
"Unknown recording id '%s'" % rec_id)
142 <struct name="RecStatus">
143 <member name="dpFiles" type="string" arrayDimensions="(32)"/>
144 <member name="endTime" type="double"/>
145 <member name="filesGenerated" type="int32_t"/>
146 <member name="framesProcessed" type="int32_t"/>
147 <member name="framesRemaining" type="int32_t"/>
148 <member name="id" type="string"/>
149 <member name="info" type="string"/>
150 <member name="remainingTime" type="double"/>
151 <member name="sizeRecorded" type="int32_t"/>
152 <member name="startTime" type="double"/>
153 <member name="status" type="nonBasic" nonBasicTypeName="RecStatusNames"/>
154 <member name="timeElapsed" type="double"/>
157 logging.debug(
"Creating return type: RecStatus")
159 status = self.
mal.createDataEntity(RecStatus)
164 """Populates RecStatus from status"""
165 logging.debug(
"Populating return type: RecStatus: id=%s, status=%r", rec.id, rec.status)
166 status.setDpFiles(rec.dp_files)
167 status.setEndTime(rec.end_time)
168 status.setFilesGenerated(rec.files_generated)
169 status.setFramesProcessed(rec.frames_processed)
170 status.setFramesRemaining(rec.frames_remaining)
172 status.setInfo(rec.info)
173 status.setRemainingTime(rec.remaining_time)
174 status.setSizeRecorded(rec.size_recorded)
175 status.setStartTime(rec.start_time)
176 status.setStatus(rec.status)
177 status.setTimeElapsed(rec.time_elapsed)
180 """Creates RecWaitStatus and populates attributes"""
181 logging.debug(
"Creating return type: RecWaitStatus")
183 status = self.
mal.createDataEntity(RecWaitStatus)
185 if rec.status
in (RecStatusNames.Completed, RecStatusNames.Stopped):
186 logging.debug(
"Recording is Completed or Stopped, RecWaitStatus set to success")
187 status.setStatus(RecWaitStatusNames.Success)
189 status.setStatus(RecWaitStatusNames.Timeout)
193 """Add the simulation hook `hook` for the specified command `cmd_name` (e.g.
196 Any previous hooks will be replaced.
201 """Reset simulator to initial default state."""
207 """Remove all simulation hooks."""
211 """Runs simulation hook that may modify or replace the default implementation.
213 The hook to execute is automatically determined from the call stack, so
214 this should only ever be executed directly from the service command
215 implementation method.
217 cmd_name = inspect.stack()[1][3]
219 logging.debug(
"Checking for hook for command %s", cmd_name)
221 logging.debug(
"Running simulation hook for command %s", cmd_name)
223 return hook(result, *args)
228 """Simulator controller that implements ModDaqsimif and sets up
229 simulation behaviour for Simulator.
238 logging.info(
"Registering service 'rec'")
239 self.
server.registerService(
"rec", RecCmdsSyncService, self.
sim)
241 def Setup(self, spec):
242 """@implements SimCtl.Setup."""
243 logging.info(
'SimCtl.Setup: spec="%s"', spec)
246 cmd = s.get(
"command",
"")
247 action = s.get(
"action",
"")
248 if action ==
"complete-recording":
250 rec = self.
sim.current_rec
251 logging.info(
"SimCtl.Setup: Marking %s as Completed ref=%s", rec.id, id(rec))
252 rec.status = RecStatusNames.Completed
253 rec.dp_files = [
"/tmp/auto-%s.fits" % rec.id]
254 elif action ==
"throw":
256 def throw(res, *args):
257 raise ExceptionErr(self.
sim.current_rec.id,
"Simulated error")
259 self.
sim.add_sim_hook(cmd, throw)
261 raise SimCtlError(
"Unknown action '%s' provided" % action)
262 logging.info(
"SimCtl.Setup: Returning empty string")
263 return json.dumps(
"")
266 except Exception
as e:
267 raise SimCtlError(
'"%s"' % str(e))
270 """@implements SimCtl.Reset"""
273 except Exception
as e:
274 raise SimCtlError(str(e))
277 """@implements SimCtl.ForceExit."""
279 logging.warning(
"Force Exiting without cleanup!")