#!/usr/bin/env python """ Example of a basic midas frontend that has one periodic equipment. See `examples/multi_frontend.py` for an example that uses more features (frontend index, polled equipment, ODB settings etc). """ import midas import midas.frontend import midas.event import time, os, sys from datetime import datetime #import TRACE #TRACE_NAME = 'test_frontend.py' class MyPeriodicEquipment(midas.frontend.EquipmentBase): """ We define an "equipment" for each logically distinct task that this frontend performs. For example, you may have one equipment for reading data from a device and sending it to a midas buffer, and another equipment that updates summary statistics every 10s. Each equipment class you define should inherit from `midas.frontend.EquipmentBase`, and should define a `readout_func` function. If you're creating a "polled" equipment (rather than a periodic one), you should also define a `poll_func` function in addition to `readout_func`. """ def __init__(self, client): # The name of our equipment. This name will be used on the midas status # page, and our info will appear in /Equipment/MyPeriodicEquipment in # the ODB. equip_name = "MyPeriodicEquipment" # Define the "common" settings of a frontend. These will appear in # /Equipment/MyPeriodicEquipment/Common. The values you set here are # only used the very first time this frontend/equipment runs; after # that the ODB settings are used. default_common = midas.frontend.InitialEquipmentCommon() default_common.equip_type = midas.EQ_PERIODIC default_common.buffer_name = "SYSTEM" default_common.trigger_mask = 0 default_common.event_id = 1 default_common.period_ms = 100 default_common.read_when = midas.RO_ALWAYS default_common.log_history = 1 # You MUST call midas.frontend.EquipmentBase.__init__ in your equipment's __init__ method! midas.frontend.EquipmentBase.__init__(self, client, equip_name, default_common) # You can set the status of the equipment (appears in the midas status page) self.set_status("Initialized") self._verbose = 1; # --------------------------------------------------------------------- def Print(self,Name,level,Message): if(level>self._verbose): return 0; now = time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(time.time())) message = now+' [ GridSubmit::'+Name+' ] '+Message print(message) def readout_func(self): """ For a periodic equipment, this function will be called periodically (every 100ms in this case). It should return either a `cdms.event.Event` or None (if we shouldn't write an event). """ last_time = self.client.odb_get('/Mu2e/Offline/Ops/LastTime') self.Print('readout_func',1,f'last_time:{last_time}') # cmd = 'dqmTool print-numbers --source 5 --value 6 --expand' cmd = 'cat val_nightly.csv' self.Print('readout_func',1,'executing cmd:%s'%cmd) out=os.popen(cmd).readlines() event = None; for line in out: # print(line) words = line.strip().split(',') #------------------------------------------------------------------------------ # ['91', '5228', '0.0', '0 5', 'valNightly', 'reco', 'day', '0 6', 'ops', 'stats', 'CPU 11', '4', '0', '0', '0', '0', '2022-01-11 00:01:00-06:00', '2022-01-11 00:01:00-06:00'] #------------------------------------------------------------------------------ # In this example, we just make a simple event with one bank. dt = datetime.strptime(words[17], "%Y-%m-%d %H:%M:%S%z"); ts = dt.timestamp(); if (ts > last_time) : data = [] print(words); event = midas.event.Event() data.append(float(words[0])); data.append(float(words[1])); data.append(float(words[2])); event.create_bank("OFLN", midas.TID_FLOAT, data) event.header.timestamp = int(ts); self.client.odb_set('/Mu2e/Offline/Ops/LastTime',ts) print(f'SET_NEW last_time:{ts} dt:{dt}') # self.Print('readout_func',1,f'SET_NEW last_time:{ts} dt:{dt}') break; return event class MyFrontend(midas.frontend.FrontendBase): """ A frontend contains a collection of equipment. You can access self.client to access the ODB etc (see `midas.client.MidasClient`). """ def __init__(self): # You must call __init__ from the base class. midas.frontend.FrontendBase.__init__(self, "myfe_name") # You can add equipment at any time before you call `run()`, but doing # it in __init__() seems logical. self.add_equipment(MyPeriodicEquipment(self.client)) self._verbose = 1 def begin_of_run(self, run_number): """ This function will be called at the beginning of the run. You don't have to define it, but you probably should. You can access individual equipment classes through the `self.equipment` dict if needed. """ self.set_all_equipment_status("Running", "greenLight") self.client.msg("Frontend has seen start of run number %d" % run_number) return midas.status_codes["SUCCESS"] def end_of_run(self, run_number): self.set_all_equipment_status("Finished", "greenLight") self.client.msg("Frontend has seen end of run number %d" % run_number) return midas.status_codes["SUCCESS"] def frontend_exit(self): """ Most people won't need to define this function, but you can use it for final cleanup if needed. """ print("Goodbye from user code!") if __name__ == "__main__": # The main executable is very simple - just create the frontend object, # and call run() on it. print("EMOE"); # TRACE.TRACE(7,'EMOEM',TRACE_NAME) with MyFrontend() as my_fe: my_fe.run()