##// END OF EJS Templates
Fix power monitor
jespinoza -
r394:6790c8880a2c
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -129,6 +129,9 services:
129 context: ./volumes/proc/
129 context: ./volumes/proc/
130 environment:
130 environment:
131 - BROKER_URL=${BROKER_URL}
131 - BROKER_URL=${BROKER_URL}
132 - PEDESTAL_TOPIC=${PEDESTAL_TOPIC}
133 - TXA_SITE=${TXA_SITE}
134 - TXB_SITE=${TXB_SITE}
132 - VIRTUAL_HOST=${PROC_SITE}
135 - VIRTUAL_HOST=${PROC_SITE}
133 volumes:
136 volumes:
134 - 'sirm_proc:/app'
137 - 'sirm_proc:/app'
@@ -9,6 +9,7 from datetime import datetime
9 import random
9 import random
10 import eventlet
10 import eventlet
11 import json
11 import json
12 from json import JSONEncoder
12 import numpy
13 import numpy
13 import base64
14 import base64
14 import h5py
15 import h5py
@@ -43,6 +44,7 try:
43 mqtt = Mqtt(app)
44 mqtt = Mqtt(app)
44 except:
45 except:
45 pass
46 pass
47
46 socketio = SocketIO(app)
48 socketio = SocketIO(app)
47 bootstrap = Bootstrap(app)
49 bootstrap = Bootstrap(app)
48
50
@@ -66,30 +68,39 USHRT_MAX = 65535
66 DATA_PATH = '/data'
68 DATA_PATH = '/data'
67 RUNNING = False
69 RUNNING = False
68 EXPERIMENT = {'name': 'test'}
70 EXPERIMENT = {'name': 'test'}
71 DEBUG = False
72
73 class NumpyArrayEncoder(JSONEncoder):
74 def default(self, obj):
75 if isinstance(obj, numpy.ndarray):
76 return obj.tolist()
77 return JSONEncoder.default(self, obj)
69
78
70 class HDF5File():
79 class HDF5File():
71
80
72 def __init__(self):
81 def __init__(self):
73 self.data = {}
82 self.data = {}
83 self.data_pow = {'powa':[], 'powb':[], 'timestamp':[]}
84 self.power_ready = True
85 self.power_time = 0
74 self.raw = {}
86 self.raw = {}
75 self.timestamp = 0
87 self.timestamp = 0
76 self.enable = False
88 self.enable = False
77 self.metadata = None
89 self.metadata = None
78
90
79 def ready(self):
91 def reset(self):
80
92 self.data = {}
81 if len(self.az)<100 or len(self.el)<100 or len(self.saz)<100 or len(self.sel)<100:
93 self.data_pow = {'powa':[], 'powb':[], 'timestamp':[]}
82 return False
94 self.power_ready = True
83 return True
95 self.power_time = 0
96 self.raw = {}
97 self.timestamp = 0
84
98
85 def add_data(self, var, values):
99 def add_data(self, var, values):
86
100
87 if len(values) > 0:
101 if len(values) > 0:
88 delta = numpy.average(values[1:]-values[:-1])
102 delta = numpy.average(values[1:]-values[:-1])
89 n = 100 - len(values)
103 n = 100 - len(values)
90 # print(values[-1]+delta, values[0], delta, flush=True)
91 # missing = numpy.arange(values[-1]+delta, values[0], delta)
92 print(var, n, numpy.arange(1, n+1)*delta + values[-1], flush=True)
93 if n > 0:
104 if n > 0:
94 missing = numpy.arange(1, n+1)*delta + values[-1]
105 missing = numpy.arange(1, n+1)*delta + values[-1]
95 values = values.tolist()
106 values = values.tolist()
@@ -120,10 +131,11 class HDF5File():
120 dset = grp.create_dataset("azi_speed", data=numpy.array(self.data['saz']))
131 dset = grp.create_dataset("azi_speed", data=numpy.array(self.data['saz']))
121 dset = grp.create_dataset("ele_speed", data=numpy.array(self.data['sel']))
132 dset = grp.create_dataset("ele_speed", data=numpy.array(self.data['sel']))
122 dset = grp.create_dataset("utc", data=self.timestamp)
133 dset = grp.create_dataset("utc", data=self.timestamp)
123 filelog = filename.replace('.h5', '.txt')
134 if DEBUG:
124 f = open(filelog, 'w')
135 filelog = filename.replace('.h5', '.txt')
125 f.write(json.dumps(self.raw))
136 f = open(filelog, 'w')
126 f.close()
137 f.write(json.dumps(self.raw, cls=NumpyArrayEncoder))
138 f.close()
127
139
128 def write(self, data):
140 def write(self, data):
129
141
@@ -131,6 +143,35 class HDF5File():
131 self.update(data)
143 self.update(data)
132 self.create_file()
144 self.create_file()
133
145
146 def write_power(self, data):
147
148 if self.power_ready:
149 filex = "pow@%10.3f.h5" % (self.power_time if self.power_time else self.timestamp)
150 date_folder = datetime.fromtimestamp(self.timestamp).strftime('%Y-%m-%dT%H-00-00')
151 filename = os.path.join(DATA_PATH, EXPERIMENT['name'], 'power', date_folder, filex)
152 if not os.path.exists(os.path.dirname(filename)):
153 path = os.path.dirname(filename)
154 os.makedirs(path)
155 self.fp = h5py.File(filename, 'w')
156 self.power_ready = False
157
158 if datetime.fromtimestamp(self.timestamp).second == 0:
159 self.power_time = self.timestamp
160 grp = self.fp.create_group("Data")
161 dset = grp.create_dataset("powa", data=numpy.array(self.data_pow['powa']))
162 dset = grp.create_dataset("powb", data=numpy.array(self.data_pow['powb']))
163 dset = grp.create_dataset("utc", data=numpy.array(self.data_pow['timestamp']))
164 self.fp.close()
165 self.data_pow['powa'] = []
166 self.data_pow['powb'] = []
167 self.data_pow['timestamp'] = []
168 self.power_ready = True
169
170 self.data_pow['powa'].append(data['powa'])
171 self.data_pow['powb'].append(data['powb'])
172 self.data_pow['timestamp'].append(self.timestamp)
173
174
134 HDF = HDF5File()
175 HDF = HDF5File()
135
176
136 def getSpeedPosition(msg_b64):
177 def getSpeedPosition(msg_b64):
@@ -268,8 +309,11 def start_proc():
268 @app.route('/stop')
309 @app.route('/stop')
269 def stop_proc():
310 def stop_proc():
270
311
271 global RUNNING
312 global RUNNING, DEBUG, HDF
313
272 RUNNING = False
314 RUNNING = False
315 DEBUG = False
316 HDF.reset()
273
317
274 return jsonify({'stop': 'ok'})
318 return jsonify({'stop': 'ok'})
275
319
@@ -283,7 +327,9 def status_proc():
283 @app.route('/run')
327 @app.route('/run')
284 def run_proc():
328 def run_proc():
285
329
286 global RUNNING, EXPERIMENT
330 global RUNNING, EXPERIMENT, DEBUG
331 if request.args.get('debug', False):
332 DEBUG = True
287 path = os.path.join(DATA_PATH, 'TEST')
333 path = os.path.join(DATA_PATH, 'TEST')
288 if not os.path.exists(path):
334 if not os.path.exists(path):
289 os.makedirs(path)
335 os.makedirs(path)
@@ -313,14 +359,12 def handle_connect(client, userdata, flags, rc):
313 @mqtt.on_message()
359 @mqtt.on_message()
314 def handle_mqtt_message(client, userdata, message):
360 def handle_mqtt_message(client, userdata, message):
315
361
316 global RUNNING
362 global RUNNING, HDF
317
363
318 payload = message.payload.decode()
364 payload = message.payload.decode()
319 az, saz, el, sel, tm = getSpeedPosition(payload)
365 az, saz, el, sel, tm = getSpeedPosition(payload)
320 pwA = get_power(os.environ['TXA_SITE'])
366 powa = get_power(os.environ['TXA_SITE'])
321 pwB = get_power(os.environ['TXB_SITE'])
367 powb = get_power(os.environ['TXB_SITE'])
322 if RUNNING:
323 HDF.write({'az':az, 'el':el, 'saz':saz, 'sel':sel, 'timestamp':tm})
324 times = numpy.arange(tm, tm+1, 0.1, dtype=float)
368 times = numpy.arange(tm, tm+1, 0.1, dtype=float)
325
369
326 data = dict(
370 data = dict(
@@ -332,13 +376,17 def handle_mqtt_message(client, userdata, message):
332 payload = payload,
376 payload = payload,
333 qos = message.qos,
377 qos = message.qos,
334 timestamp = times.tolist(),
378 timestamp = times.tolist(),
335 pwa = [pwa],
379 powa = [powa],
336 pwb = [pwb],
380 powb = [powb],
337 status = 'Running' if RUNNING else 'Not Running'
381 status = 'Running' if RUNNING else 'Not Running'
338 )
382 )
339
383
340 socketio.emit('mqtt_message', data=data)
384 socketio.emit('mqtt_message', data=data)
341
385
386 if RUNNING:
387 HDF.write({'az':az, 'el':el, 'saz':saz, 'sel':sel, 'timestamp':tm, 'powa':powa, 'powb':powb})
388 HDF.write_power({'timestamp':tm, 'powa':powa, 'powb':powb})
389
342 @mqtt.on_log()
390 @mqtt.on_log()
343 def handle_logging(client, userdata, level, buf):
391 def handle_logging(client, userdata, level, buf):
344 # print(level, buf)
392 # print(level, buf)
@@ -15,12 +15,9
15
15
16 socket.on('connect', function(data) {
16 socket.on('connect', function(data) {
17 console.log('Initialazing plots...');
17 console.log('Initialazing plots...');
18 makePlot("plot-az");
18 makePlot("plot-pos", 2, ["Azimuth", "Elevation"]);
19 makePlot("plot-el");
19 makePlot("plot-speed", 2, ["AZ Speed", "EL Speed"]);
20 makePlot("plot-saz");
20 makePlot("plot-tx", 2, ["Power A", "Power B"]);
21 makePlot("plot-sel");
22 makePlot("plot-tx");
23
24 })
21 })
25
22
26 socket.on('mqtt_message', function(data) {
23 socket.on('mqtt_message', function(data) {
@@ -28,19 +25,18
28 var text = '(' + data['topic'] + ' qos: ' + data['qos'] + ') ' + data['payload'];
25 var text = '(' + data['topic'] + ' qos: ' + data['qos'] + ') ' + data['payload'];
29 $('#subscribe_messages').val(text);
26 $('#subscribe_messages').val(text);
30 $('#radar_status').val(data.status);
27 $('#radar_status').val(data.status);
31 streamPlot("plot-az", data.timestamp, data.az );
28 streamPlot2("plot-pos", data.timestamp, data.az, data.el );
32 streamPlot("plot-el", data.timestamp, data.el );
29 streamPlot2("plot-speed", data.timestamp, data.saz, data.sel );
33 streamPlot("plot-saz", data.timestamp, data.saz );
30 streamPlot2("plot-tx", data.timestamp, data.powa, data.powb );
34 streamPlot("plot-sel", data.timestamp, data.sel );
35 })
31 })
36 });
32 });
37
33
38 function makePlot(div){
34 function makePlot(div, n=1, names=["", ""]){
39 var plotDiv = document.getElementById(div);
35 var plotDiv = document.getElementById(div);
40 var traces = [{
36 var traces = [];
41 x: [],
37 for (let i = 0; i < n; i++) {
42 y: []
38 traces.push({x: [], y: [], name: names[i]});
43 }];
39 }
44 var layout = {
40 var layout = {
45 height: 350,
41 height: 350,
46 font: {size: 12},
42 font: {size: 12},
@@ -48,9 +44,6
48 xaxis: {
44 xaxis: {
49 type: 'date'
45 type: 'date'
50 },
46 },
51 //yaxis: {
52 // range: [0, 110]
53 //}
54 };
47 };
55
48
56 Plotly.plot(plotDiv, traces, layout);
49 Plotly.plot(plotDiv, traces, layout);
@@ -65,14 +58,23
65 var tm = x.map(i => new Date(i*1000));
58 var tm = x.map(i => new Date(i*1000));
66 var values = y.map(i => Math.round(i * 100) / 100);
59 var values = y.map(i => Math.round(i * 100) / 100);
67 var data_update = {x: [tm], y: [values]}
60 var data_update = {x: [tm], y: [values]}
68 //var windowDateObj = getWindow(x)
69 //var layout_update = {xaxis: {
70 // range: [windowDateObj, x[x.length - 1]],
71 // rangeslider: {range: [plot_start, x[x.length - 1]]}
72 //}};
73 //Plotly.update(plotDiv, {}, layout_update)
74 Plotly.extendTraces(plotDiv, data_update, [0])
61 Plotly.extendTraces(plotDiv, data_update, [0])
75 };
62 };
63
64 function streamPlot2(div, x, y1, y2 ){
65 var plotDiv = document.getElementById(div);
66 if (plotDiv.data[0].x.length > 499){
67 plotDiv.data[0].x = plotDiv.data[0].x.slice(-500)
68 plotDiv.data[0].y = plotDiv.data[0].y.slice(-500)
69 plotDiv.data[1].x = plotDiv.data[1].x.slice(-500)
70 plotDiv.data[1].y = plotDiv.data[1].y.slice(-500)
71 }
72 var tm = x.map(i => new Date(i*1000));
73 var values1 = y1.map(i => Math.round(i * 100) / 100);
74 var values2 = y2.map(i => Math.round(i * 100) / 100);
75 var data_update = {x: [tm, tm], y: [values1, values2]}
76 Plotly.extendTraces(plotDiv, data_update, [0, 1])
77 };
76
78
77 </script>
79 </script>
78 {% endblock %}
80 {% endblock %}
@@ -113,61 +115,46
113 </div>
115 </div>
114 </div>
116 </div>
115 </div>
117 </div>
116 <!--Azimuth-->
118 <!--RX LOG-->
117 <div class="col-xs-6">
118 <div class="panel panel-default">
119 <div class="panel-heading">
120 <h3 class="panel-title">Pedestal Azimuth</h3>
121 </div>
122 <div class="panel-body">
123 <div class="col-xs-12">
124 <div class="row">
125 <div id="plot-az"></div>
126 </div>
127 </div>
128 </div>
129 </div>
130 </div>
131 <!--Elevation-->
132 <div class="col-xs-6">
119 <div class="col-xs-6">
133 <div class="panel panel-default">
120 <div class="panel panel-default">
134 <div class="panel-heading">
121 <div class="panel-heading">
135 <h3 class="panel-title">Pedestal Elevation</h3>
122 <h3 class="panel-title">RX log</h3>
136 </div>
123 </div>
137 <div class="panel-body">
124 <div class="panel-body">
138 <div class="col-xs-12">
125 <div class="col-xs-12">
139 <div class="row">
126 <div class="row">
140 <div id="plot-el"></div>
127 <div></div>
141 </div>
128 </div>
142 </div>
129 </div>
143 </div>
130 </div>
144 </div>
131 </div>
145 </div>
132 </div>
146 <!--Azimuth Speed-->
133 <!--Position-->
147 <div class="col-xs-6">
134 <div class="col-xs-6">
148 <div class="panel panel-default">
135 <div class="panel panel-default">
149 <div class="panel-heading">
136 <div class="panel-heading">
150 <h3 class="panel-title">Pedestal Azimuth Speed</h3>
137 <h3 class="panel-title">Pedestal Position</h3>
151 </div>
138 </div>
152 <div class="panel-body">
139 <div class="panel-body">
153 <div class="col-xs-12">
140 <div class="col-xs-12">
154 <div class="row">
141 <div class="row">
155 <div id="plot-saz"></div>
142 <div id="plot-pos"></div>
156 </div>
143 </div>
157 </div>
144 </div>
158 </div>
145 </div>
159 </div>
146 </div>
160 </div>
147 </div>
161 <!--Elevation Speed-->
148 <!--Speed-->
162 <div class="col-xs-6">
149 <div class="col-xs-6">
163 <div class="panel panel-default">
150 <div class="panel panel-default">
164 <div class="panel-heading">
151 <div class="panel-heading">
165 <h3 class="panel-title">Pedestal Elevation Speed</h3>
152 <h3 class="panel-title">Pedestal Speed</h3>
166 </div>
153 </div>
167 <div class="panel-body">
154 <div class="panel-body">
168 <div class="col-xs-12">
155 <div class="col-xs-12">
169 <div class="row">
156 <div class="row">
170 <div id="plot-sel"></div>
157 <div id="plot-speed"></div>
171 </div>
158 </div>
172 </div>
159 </div>
173 </div>
160 </div>
General Comments 0
You need to be logged in to leave comments. Login now