##// END OF EJS Templates
receiver data modificado para web
José Chávez -
r904:1253852f58ac
parent child
Show More
@@ -1,388 +1,393
1 1 '''
2 2 @author: Juan C. Espinoza
3 3 '''
4 4
5 5 import time
6 6 import json
7 7 import numpy
8 8 import paho.mqtt.client as mqtt
9 9 import zmq
10 10 import cPickle as pickle
11 11 import datetime
12 12 from zmq.utils.monitor import recv_monitor_message
13 13 from functools import wraps
14 14 from threading import Thread
15 15 from multiprocessing import Process
16 16
17 17 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
18 18
19 19 MAXNUMX = 100
20 20 MAXNUMY = 100
21 21
22 22 class PrettyFloat(float):
23 23 def __repr__(self):
24 24 return '%.2f' % self
25 25
26 26 def roundFloats(obj):
27 27 if isinstance(obj, list):
28 28 return map(roundFloats, obj)
29 29 elif isinstance(obj, float):
30 30 return round(obj, 2)
31 31
32 def decimate(z):
33 # dx = int(len(self.x)/self.__MAXNUMX) + 1
34 dy = int(len(z[0])/MAXNUMY) + 1
35 return z[::, ::dy]
32 36
33 37 class throttle(object):
34 38 """Decorator that prevents a function from being called more than once every
35 39 time period.
36 40 To create a function that cannot be called more than once a minute, but
37 41 will sleep until it can be called:
38 42 @throttle(minutes=1)
39 43 def foo():
40 44 pass
41 45
42 46 for i in range(10):
43 47 foo()
44 48 print "This function has run %s times." % i
45 49 """
46 50
47 51 def __init__(self, seconds=0, minutes=0, hours=0):
48 52 self.throttle_period = datetime.timedelta(
49 53 seconds=seconds, minutes=minutes, hours=hours
50 54 )
51 55
52 56 self.time_of_last_call = datetime.datetime.min
53 57
54 58 def __call__(self, fn):
55 59 @wraps(fn)
56 60 def wrapper(*args, **kwargs):
57 61 now = datetime.datetime.now()
58 62 time_since_last_call = now - self.time_of_last_call
59 63 time_left = self.throttle_period - time_since_last_call
60 64
61 65 if time_left > datetime.timedelta(seconds=0):
62 66 return
63 67
64 68 self.time_of_last_call = datetime.datetime.now()
65 69 return fn(*args, **kwargs)
66 70
67 71 return wrapper
68 72
69 73
70 74 class PublishData(Operation):
71 75 """Clase publish."""
72 76
73 77 def __init__(self, **kwargs):
74 78 """Inicio."""
75 79 Operation.__init__(self, **kwargs)
76 80 self.isConfig = False
77 81 self.client = None
78 82 self.zeromq = None
79 83 self.mqtt = None
80 84
81 85 def on_disconnect(self, client, userdata, rc):
82 86 if rc != 0:
83 87 print("Unexpected disconnection.")
84 88 self.connect()
85 89
86 90 def connect(self):
87 91 print 'trying to connect'
88 92 try:
89 93 self.client.connect(
90 94 host=self.host,
91 95 port=self.port,
92 96 keepalive=60*10,
93 97 bind_address='')
94 98 self.client.loop_start()
95 99 # self.client.publish(
96 100 # self.topic + 'SETUP',
97 101 # json.dumps(setup),
98 102 # retain=True
99 103 # )
100 104 except:
101 105 print "MQTT Conection error."
102 106 self.client = False
103 107
104 108 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, **kwargs):
105 109 self.counter = 0
106 110 self.topic = kwargs.get('topic', 'schain')
107 111 self.delay = kwargs.get('delay', 0)
108 112 self.plottype = kwargs.get('plottype', 'spectra')
109 113 self.host = kwargs.get('host', "10.10.10.82")
110 114 self.port = kwargs.get('port', 3000)
111 115 self.clientId = clientId
112 116 self.cnt = 0
113 117 self.zeromq = zeromq
114 118 self.mqtt = kwargs.get('plottype', 0)
115 119 self.client = None
116 120 setup = []
117 121 if mqtt is 1:
118 122 self.client = mqtt.Client(
119 123 client_id=self.clientId + self.topic + 'SCHAIN',
120 124 clean_session=True)
121 125 self.client.on_disconnect = self.on_disconnect
122 126 self.connect()
123 127 for plot in self.plottype:
124 128 setup.append({
125 129 'plot': plot,
126 130 'topic': self.topic + plot,
127 131 'title': getattr(self, plot + '_' + 'title', False),
128 132 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
129 133 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
130 134 'xrange': getattr(self, plot + '_' + 'xrange', False),
131 135 'yrange': getattr(self, plot + '_' + 'yrange', False),
132 136 'zrange': getattr(self, plot + '_' + 'zrange', False),
133 137 })
134 138 if zeromq is 1:
135 139 context = zmq.Context()
136 140 self.zmq_socket = context.socket(zmq.PUSH)
137 141 server = kwargs.get('server', 'zmq.pipe')
138 142
139 143 if 'tcp://' in server:
140 144 address = server
141 145 else:
142 146 address = 'ipc:///tmp/%s' % server
143 147
144 148 self.zmq_socket.connect(address)
145 149 time.sleep(1)
146 150
147 151
148 152
149 153 def publish_data(self):
150 154 self.dataOut.finished = False
151 155 if self.mqtt is 1:
152 156 yData = self.dataOut.heightList[:2].tolist()
153 157 if self.plottype == 'spectra':
154 158 data = getattr(self.dataOut, 'data_spc')
155 159 z = data/self.dataOut.normFactor
156 160 zdB = 10*numpy.log10(z)
157 161 xlen, ylen = zdB[0].shape
158 162 dx = int(xlen/MAXNUMX) + 1
159 163 dy = int(ylen/MAXNUMY) + 1
160 164 Z = [0 for i in self.dataOut.channelList]
161 165 for i in self.dataOut.channelList:
162 166 Z[i] = zdB[i][::dx, ::dy].tolist()
163 167 payload = {
164 168 'timestamp': self.dataOut.utctime,
165 169 'data': roundFloats(Z),
166 170 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
167 171 'interval': self.dataOut.getTimeInterval(),
168 172 'type': self.plottype,
169 173 'yData': yData
170 174 }
171 175 # print payload
172 176
173 177 elif self.plottype in ('rti', 'power'):
174 178 data = getattr(self.dataOut, 'data_spc')
175 179 z = data/self.dataOut.normFactor
176 180 avg = numpy.average(z, axis=1)
177 181 avgdB = 10*numpy.log10(avg)
178 182 xlen, ylen = z[0].shape
179 183 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
180 184 AVG = [0 for i in self.dataOut.channelList]
181 185 for i in self.dataOut.channelList:
182 186 AVG[i] = avgdB[i][::dy].tolist()
183 187 payload = {
184 188 'timestamp': self.dataOut.utctime,
185 189 'data': roundFloats(AVG),
186 190 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
187 191 'interval': self.dataOut.getTimeInterval(),
188 192 'type': self.plottype,
189 193 'yData': yData
190 194 }
191 195 elif self.plottype == 'noise':
192 196 noise = self.dataOut.getNoise()/self.dataOut.normFactor
193 197 noisedB = 10*numpy.log10(noise)
194 198 payload = {
195 199 'timestamp': self.dataOut.utctime,
196 200 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
197 201 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
198 202 'interval': self.dataOut.getTimeInterval(),
199 203 'type': self.plottype,
200 204 'yData': yData
201 205 }
202 206 elif self.plottype == 'snr':
203 207 data = getattr(self.dataOut, 'data_SNR')
204 208 avgdB = 10*numpy.log10(data)
205 209
206 210 ylen = data[0].size
207 211 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
208 212 AVG = [0 for i in self.dataOut.channelList]
209 213 for i in self.dataOut.channelList:
210 214 AVG[i] = avgdB[i][::dy].tolist()
211 215 payload = {
212 216 'timestamp': self.dataOut.utctime,
213 217 'data': roundFloats(AVG),
214 218 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
215 219 'type': self.plottype,
216 220 'yData': yData
217 221 }
218 222 else:
219 223 print "Tipo de grafico invalido"
220 224 payload = {
221 225 'data': 'None',
222 226 'timestamp': 'None',
223 227 'type': None
224 228 }
225 229 # print 'Publishing data to {}'.format(self.host)
226 230 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
227 231
228 232 if self.zeromq is 1:
229 233 print '[Sending] {} - {}'.format(self.dataOut.type, self.dataOut.datatime)
230 234 self.zmq_socket.send_pyobj(self.dataOut)
231 235
232 236 def run(self, dataOut, **kwargs):
233 237 self.dataOut = dataOut
234 238 if not self.isConfig:
235 239 self.setup(**kwargs)
236 240 self.isConfig = True
237 241
238 242 self.publish_data()
239 243 time.sleep(self.delay)
240 244
241 245 def close(self):
242 246 if self.zeromq is 1:
243 247 self.dataOut.finished = True
244 248 self.zmq_socket.send_pyobj(self.dataOut)
245 249
246 250 if self.client:
247 251 self.client.loop_stop()
248 252 self.client.disconnect()
249 253
250 254
251 255 class ReceiverData(ProcessingUnit, Process):
252 256
253 257 throttle_value = 5
254 258
255 259 def __init__(self, **kwargs):
256 260
257 261 ProcessingUnit.__init__(self, **kwargs)
258 262 Process.__init__(self)
259 263 self.mp = False
260 264 self.isConfig = False
261 265 self.plottypes =[]
262 266 self.connections = 0
263 267 server = kwargs.get('server', 'zmq.pipe')
264 268 if 'tcp://' in server:
265 269 address = server
266 270 else:
267 271 address = 'ipc:///tmp/%s' % server
268 272
269 273 self.address = address
270 274 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
271 275 self.realtime = kwargs.get('realtime', False)
272 276 self.throttle_value = kwargs.get('throttle', 10)
273 277 self.sendData = self.initThrottle(self.throttle_value)
274 278 self.setup()
275 279
276 280 def setup(self):
277 281
278 282 self.data = {}
279 283 self.data['times'] = []
280 284 for plottype in self.plottypes:
281 285 self.data[plottype] = {}
282 286 self.data['noise'] = {}
283 287 self.data['throttle'] = self.throttle_value
284 288 self.data['ENDED'] = False
285 289 self.isConfig = True
286 290 self.data_web = {}
287 291
288 292 def event_monitor(self, monitor):
289 293
290 294 events = {}
291 295
292 296 for name in dir(zmq):
293 297 if name.startswith('EVENT_'):
294 298 value = getattr(zmq, name)
295 299 events[value] = name
296 300
297 301 while monitor.poll():
298 302 evt = recv_monitor_message(monitor)
299 303 if evt['event'] == 32:
300 304 self.connections += 1
301 305 if evt['event'] == 512:
302 306 pass
303 307 if self.connections == 0 and self.started is True:
304 308 self.ended = True
305 309 # send('ENDED')
306 310 evt.update({'description': events[evt['event']]})
307 311
308 312 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
309 313 break
310 314 monitor.close()
311 315 print("event monitor thread done!")
312 316
313 317 def initThrottle(self, throttle_value):
314 318
315 319 @throttle(seconds=throttle_value)
316 320 def sendDataThrottled(fn_sender, data):
317 321 fn_sender(data)
318 322
319 323 return sendDataThrottled
320 324
321 325 def send(self, data):
322 print '[sending] data=%s size=%s' % (data.keys(), len(data['times']))
326 # print '[sending] data=%s size=%s' % (data.keys(), len(data['times']))
323 327 self.sender.send_pyobj(data)
324 328
325 329 def update(self):
326 330
327 331 t = self.dataOut.ltctime
328 332 self.data['times'].append(t)
329 333 self.data['dataOut'] = self.dataOut
330 334 for plottype in self.plottypes:
331 335 if plottype == 'spc':
332 336 z = self.dataOut.data_spc/self.dataOut.normFactor
333 337 self.data[plottype] = 10*numpy.log10(z)
334 338 self.data['noise'][t] = 10*numpy.log10(self.dataOut.getNoise()/self.dataOut.normFactor)
335 339 if plottype == 'rti':
336 340 self.data[plottype][t] = self.dataOut.getPower()
337 341 if plottype == 'snr':
338 342 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_SNR)
339 343 if plottype == 'dop':
340 344 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_DOP)
341 345 if plottype == 'coh':
342 346 self.data[plottype][t] = self.dataOut.getCoherence()
343 347 if plottype == 'phase':
344 348 self.data[plottype][t] = self.dataOut.getCoherence(phase=True)
345 349 if self.realtime:
346 self.data_web[plottype] = self.data[plottype][t]
350 self.data_web[plottype] = roundFloats(decimate(self.data[plottype][t]).tolist())
347 351 self.data_web['time'] = t
348 352 def run(self):
349 353
350 354 print '[Starting] {} from {}'.format(self.name, self.address)
351 355
352 356 self.context = zmq.Context()
353 357 self.receiver = self.context.socket(zmq.PULL)
354 358 self.receiver.bind(self.address)
355 359 monitor = self.receiver.get_monitor_socket()
356 360 self.sender = self.context.socket(zmq.PUB)
357 361 if self.realtime:
358 362 self.sender_web = self.context.socket(zmq.PUB)
359 self.sender.bind("ipc:///tmp/zmq.web")
363 # self.sender_web.setsockopt(zmq.PUBLISH, 'realtime')
364 self.sender_web.bind("ipc:///tmp/zmq.web")
360 365 self.sender.bind("ipc:///tmp/zmq.plots")
361 366
362 t = Thread(target=self.event_monitor)
367 t = Thread(target=self.event_monitor, args=(monitor,))
363 368 t.start()
364 369
365 370 while True:
366 371 self.dataOut = self.receiver.recv_pyobj()
367 372 # print '[Receiving] {} - {}'.format(self.dataOut.type,
368 373 # self.dataOut.datatime.ctime())
369 374
370 375 self.update()
371 376
372 377 if self.dataOut.finished is True:
373 378 self.send(self.data)
374 379 self.connections -= 1
375 380 if self.connections == 0 and self.started:
376 381 self.ended = True
377 382 self.data['ENDED'] = True
378 383 self.send(self.data)
379 384 self.setup()
380 385 else:
381 386 if self.realtime:
382 387 self.send(self.data)
383 self.sender_web.send_json(json.dumps(self.data_web))
388 self.sender_web.send_string(json.dumps(self.data_web))
384 389 else:
385 390 self.sendData(self.send, self.data)
386 391 self.started = True
387 392
388 393 return
@@ -1,86 +1,86
1 1 import argparse
2 2
3 3 from schainpy.controller import Project, multiSchain
4 4
5 5 desc = "HF_EXAMPLE"
6 6
7 7 def fiber(cursor, skip, q, dt):
8 8
9 9 controllerObj = Project()
10 10
11 11 controllerObj.setup(id='191', name='test01', description=desc)
12 12
13 13 readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader',
14 14 path='/home/nanosat/data/hysell_data20/pdata',
15 15 startDate=dt,
16 16 endDate=dt,
17 17 startTime="00:00:00",
18 18 endTime="23:59:59",
19 19 online=0,
20 20 #set=1426485881,
21 21 delay=10,
22 22 walk=1,
23 23 queue=q,
24 24 cursor=cursor,
25 25 skip=skip,
26 26 #timezone=-5*3600
27 27 )
28 28
29 29 # #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
30 30 #
31 31 procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
32 32 # opObj11 = procUnitConfObj2.addParameter(name='pairsList', value='(0,1)', format='pairslist')
33 33 #
34 34 # procUnitConfObj3 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId())
35 35 # opObj11 = procUnitConfObj3.addOperation(name='SpectralMoments', optype='other')
36 36
37 37 #
38 38 # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
39 39 # opObj11.addParameter(name='id', value='1000', format='int')
40 40 # opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str')
41 41 # opObj11.addParameter(name='channelList', value='0', format='intlist')
42 42 # opObj11.addParameter(name='zmin', value='-120', format='float')
43 43 # opObj11.addParameter(name='zmax', value='-70', format='float')
44 44 # opObj11.addParameter(name='save', value='1', format='int')
45 45 # opObj11.addParameter(name='figpath', value=figpath, format='str')
46 46
47 47 # opObj11 = procUnitConfObj2.addOperation(name='RTIPlot', optype='other')
48 48 # opObj11.addParameter(name='id', value='2000', format='int')
49 49 # opObj11.addParameter(name='wintitzmaxle', value='HF_Jicamarca', format='str')
50 50 # opObj11.addParameter(name='showprofile', value='0', format='int')
51 51 # # opObj11.addParameter(name='channelList', value='0', format='intlist')
52 52 # # opObj11.addParameter(name='xmin', value='0', format='float')
53 53 # opObj11.addParameter(name='xmin', value='0', format='float')
54 54 # opObj11.addParameter(name='xmax', value='24', format='float')
55 55
56 56 # opObj11.addParameter(name='zmin', value='-110', format='float')
57 57 # opObj11.addParameter(name='zmax', value='-70', format='float')
58 58 # opObj11.addParameter(name='save', value='0', format='int')
59 59 # # opObj11.addParameter(name='figpath', value='/tmp/', format='str')
60 60 #
61 61 opObj12 = procUnitConfObj2.addOperation(name='PublishData', optype='other')
62 62 opObj12.addParameter(name='zeromq', value=1, format='int')
63 63
64 64 # opObj13 = procUnitConfObj3.addOperation(name='PublishData', optype='other')
65 65 # opObj13.addParameter(name='zeromq', value=1, format='int')
66 66 # opObj13.addParameter(name='server', value="juanca", format='str')
67 67
68 # opObj12.addParameter(name='delay', value=1, format='int')
68 opObj12.addParameter(name='delay', value=1, format='int')
69 69
70 70
71 71 # print "Escribiendo el archivo XML"
72 72 # controllerObj.writeXml(filename)
73 73 # print "Leyendo el archivo XML"
74 74 # controllerObj.readXml(filename)
75 75
76 76
77 77 # timeit.timeit('controllerObj.run()', number=2)
78 78
79 79 controllerObj.start()
80 80
81 81
82 82 if __name__ == '__main__':
83 83 parser = argparse.ArgumentParser(description='Set number of parallel processes')
84 parser.add_argument('--nProcess', default=2, type=int)
84 parser.add_argument('--nProcess', default=1, type=int)
85 85 args = parser.parse_args()
86 86 multiSchain(fiber, nProcess=args.nProcess, startDate='2015/09/26', endDate='2015/09/26')
@@ -1,50 +1,49
1 1 #!/usr/bin/env python
2 2 '''
3 3 Created on Jul 7, 2014
4 4
5 5 @author: roj-idl71
6 6 '''
7 7 import os, sys
8 8
9 9 from schainpy.controller import Project
10 10
11 11 if __name__ == '__main__':
12 12 desc = "Segundo Test"
13 13
14 14 controllerObj = Project()
15 15 controllerObj.setup(id='191', name='test01', description=desc)
16 16
17 17 proc1 = controllerObj.addProcUnit(name='ReceiverData')
18 18 proc1.addParameter(name='realtime', value='1', format='bool')
19
20 19 proc1.addParameter(name='plottypes', value='rti', format='str')
21 20 proc1.addParameter(name='throttle', value='10', format='int')
22 21 ## TODO Agregar direccion de server de publicacion a graficos como variable
23 22
24 23 # op1 = proc1.addOperation(name='PlotRTIData', optype='other')
25 24 # op1.addParameter(name='wintitle', value='Julia 150Km', format='str')
26 25 # op1.addParameter(name='save', value='/home/nanosat/Pictures', format='str')
27 26 #
28 27 # op2 = proc1.addOperation(name='PlotCOHData', optype='other')
29 28 # op2.addParameter(name='wintitle', value='Julia 150Km', format='str')
30 29 # op2.addParameter(name='save', value='/home/nanosat/Pictures', format='str')
31 30 # #
32 31 # op6 = proc1.addOperation(name='PlotPHASEData', optype='other')
33 32 # op6.addParameter(name='wintitle', value='Julia 150Km', format='str')
34 33 # op6.addParameter(name='save', value='/home/nanosat/Pictures', format='str')
35 34 #
36 35 # proc2 = controllerObj.addProcUnit(name='ReceiverData')
37 36 # proc2.addParameter(name='server', value='juanca', format='str')
38 37 # proc2.addParameter(name='plottypes', value='snr,dop', format='str')
39 38 #
40 39 # op3 = proc2.addOperation(name='PlotSNRData', optype='other')
41 40 # op3.addParameter(name='wintitle', value='Julia 150Km', format='str')
42 41 # op3.addParameter(name='save', value='/home/nanosat/Pictures', format='str')
43 42 #
44 43 # op4 = proc2.addOperation(name='PlotDOPData', optype='other')
45 44 # op4.addParameter(name='wintitle', value='Julia 150Km', format='str')
46 45 # op4.addParameter(name='save', value='/home/nanosat/Pictures', format='str')
47 46
48 47
49 48
50 49 controllerObj.start()
@@ -1,1 +1,1
1 <Project description="HF_EXAMPLE" id="191" name="test01"><ReadUnit datatype="SpectraReader" id="1911" inputId="0" name="SpectraReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="SpectraReader" /><Parameter format="str" id="191112" name="path" value="/home/nanosat/data/hysell_data20/pdata" /><Parameter format="date" id="191113" name="startDate" value="2015/09/26" /><Parameter format="date" id="191114" name="endDate" value="2015/09/26" /><Parameter format="time" id="191115" name="startTime" value="00:00:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:59" /><Parameter format="int" id="191118" name="cursor" value="3" /><Parameter format="int" id="191119" name="skip" value="360" /><Parameter format="int" id="191120" name="delay" value="10" /><Parameter format="int" id="191121" name="walk" value="1" /><Parameter format="int" id="191122" name="online" value="0" /></Operation></ReadUnit><ProcUnit datatype="Spectra" id="1912" inputId="1911" name="SpectraProc"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="PublishData" priority="2" type="other"><Parameter format="int" id="191221" name="zeromq" value="1" /></Operation></ProcUnit></Project> No newline at end of file
1 <Project description="HF_EXAMPLE" id="191" name="test01"><ReadUnit datatype="SpectraReader" id="1911" inputId="0" name="SpectraReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="SpectraReader" /><Parameter format="str" id="191112" name="path" value="/home/nanosat/data/hysell_data20/pdata" /><Parameter format="date" id="191113" name="startDate" value="2015/09/26" /><Parameter format="date" id="191114" name="endDate" value="2015/09/26" /><Parameter format="time" id="191115" name="startTime" value="00:00:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:59" /><Parameter format="int" id="191118" name="cursor" value="2" /><Parameter format="int" id="191119" name="skip" value="720" /><Parameter format="int" id="191120" name="delay" value="10" /><Parameter format="int" id="191121" name="walk" value="1" /><Parameter format="int" id="191122" name="online" value="0" /></Operation></ReadUnit><ProcUnit datatype="Spectra" id="1912" inputId="1911" name="SpectraProc"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="PublishData" priority="2" type="other"><Parameter format="int" id="191221" name="zeromq" value="1" /><Parameter format="int" id="191222" name="delay" value="1" /></Operation></ProcUnit></Project> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now