##// END OF EJS Templates
Improve RC pulses plot and Operation view...
Juan C. Espinoza -
r175:a7fbf14a85a6
parent child
Show More
@@ -124,6 +124,11 class Device(models.Model):
124 124
125 125 return color
126 126
127 @property
128 def url(self):
129
130 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
131
127 132 def get_absolute_url(self):
128 133 return reverse('url_device', args=[str(self.id)])
129 134
@@ -37,7 +37,7
37 37 <table class="table table-bordered">
38 38 <tr>
39 39 <th>Status</th>
40 <td>{%if status != "No connected" %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> {{status}} {% endif %}</td>
40 <td class="text-{{dev_conf.device.status_color}}"> {{dev_conf.device.get_status_display}} </td>
41 41 </tr>
42 42
43 43 {% for key in dev_conf_keys %}
@@ -57,11 +57,12
57 57
58 58 {% for item in location.experiments %}
59 59 {% if location.name in item.location.name %}
60
61 60 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" >
62 61 <td>{{ forloop.counter }}</td>
63 62 {% for key in experiment_keys %}
64 {% if 'status' in key %}
63 {% if 'name' in key %}
64 <td class="col-md-5">{{ item|value:key }}</td>
65 {% elif 'status' in key %}
65 66 <td class="text-{{item.status_color}}">{{ item|value:key }}</td>
66 67 {% else %}
67 68 <td>{{ item|value:key }}</td>
@@ -1399,6 +1399,7 def get_paginator(model, page, order, filters={}, n=10):
1399 1399 def operation(request, id_camp=None):
1400 1400
1401 1401 kwargs = {}
1402 kwargs['no_sidebar'] = True
1402 1403 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1403 1404 end_date__gte=datetime.now()).order_by('-start_date')
1404 1405
@@ -1412,8 +1413,6 def operation(request, id_camp=None):
1412 1413 kwargs['form'] = form
1413 1414 return render(request, 'operation.html', kwargs)
1414 1415
1415
1416
1417 1416 #---Experiment
1418 1417 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1419 1418 kwargs['experiment_keys'] = keys[1:]
@@ -1423,7 +1422,7 def operation(request, id_camp=None):
1423 1422 #---Else
1424 1423 kwargs['title'] = 'Campaign'
1425 1424 kwargs['suptitle'] = campaign.name
1426 kwargs['form'] = form
1425 kwargs['form'] = form
1427 1426
1428 1427 return render(request, 'operation.html', kwargs)
1429 1428
@@ -1,7 +1,9
1 1
2 2 import ast
3 3 import json
4 import requests
4 5 import numpy as np
6 from base64 import b64encode
5 7
6 8 from django.db import models
7 9 from django.core.urlresolvers import reverse
@@ -258,60 +260,60 class RCConfiguration(Configuration):
258 260 def add_data(self, value):
259 261
260 262 return (254, value-1)
261
262 def parms_to_binary(self):
263
264 def parms_to_binary(self, dat=True):
263 265 '''
264 266 Create "dat" stream to be send to CR
265 267 '''
266 268
267 data = []
269 data = bytearray()
268 270 # create header
269 data.append(self.add_cmd('DISABLE'))
270 data.append(self.add_cmd('CONTINUE'))
271 data.append(self.add_cmd('RESTART'))
271 data.extend(self.add_cmd('DISABLE'))
272 data.extend(self.add_cmd('CONTINUE'))
273 data.extend(self.add_cmd('RESTART'))
272 274
273 275 if self.control_sw:
274 data.append(self.add_cmd('SW_ONE'))
276 data.extend(self.add_cmd('SW_ONE'))
275 277 else:
276 data.append(self.add_cmd('SW_ZERO'))
278 data.extend(self.add_cmd('SW_ZERO'))
277 279
278 280 if self.control_tx:
279 data.append(self.add_cmd('TX_ONE'))
281 data.extend(self.add_cmd('TX_ONE'))
280 282 else:
281 data.append(self.add_cmd('TX_ZERO'))
283 data.extend(self.add_cmd('TX_ZERO'))
282 284
283 285 # write divider
284 data.append(self.add_cmd('CLOCK_DIVIDER'))
285 data.append(self.add_data(self.clock_divider))
286 data.extend(self.add_cmd('CLOCK_DIVIDER'))
287 data.extend(self.add_data(self.clock_divider))
286 288
287 289 # write delays
288 data.append(self.add_cmd('DELAY_START'))
290 data.extend(self.add_cmd('DELAY_START'))
289 291 # first delay is always zero
290 data.append(self.add_data(1))
292 data.extend(self.add_data(1))
291 293
292 294 delays = self.get_delays()
293 295
294 296 for delay in delays:
295 297 while delay>252:
296 data.append(self.add_data(253))
298 data.extend(self.add_data(253))
297 299 delay -= 253
298 data.append(self.add_data(delay))
300 data.extend(self.add_data(int(delay)))
299 301
300 302 # write flips
301 data.append(self.add_cmd('FLIP_START'))
303 data.extend(self.add_cmd('FLIP_START'))
302 304
303 305 states = self.get_pulses(binary=False)
304 306
305 307 for flips, delay in zip(states, delays):
306 308 flips.reverse()
307 309 flip = int(''.join([str(x) for x in flips]), 2)
308 data.append(self.add_data(flip+1))
310 data.extend(self.add_data(flip+1))
309 311 while delay>252:
310 data.append(self.add_data(1))
312 data.extend(self.add_data(1))
311 313 delay -= 253
312 314
313 315 # write sampling period
314 data.append(self.add_cmd('SAMPLING_PERIOD'))
316 data.extend(self.add_cmd('SAMPLING_PERIOD'))
315 317 wins = self.get_lines(line_type__name='windows')
316 318 if wins:
317 319 win_params = json.loads(wins[0].params)['params']
@@ -321,12 +323,16 class RCConfiguration(Configuration):
321 323 dh = 1
322 324 else:
323 325 dh = 1
324 data.append(self.add_data(dh))
326 data.extend(self.add_data(dh))
325 327
326 328 # write enable
327 data.append(self.add_cmd('ENABLE'))
329 data.extend(self.add_cmd('ENABLE'))
330
331 if not dat:
332 return data
333
334 return '\n'.join(['{}'.format(x) for x in data])
328 335
329 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
330 336
331 337 def update_from_file(self, filename):
332 338 '''
@@ -342,7 +348,7 class RCConfiguration(Configuration):
342 348 for line in self.get_lines():
343 349 line.update_pulses()
344 350
345 def plot_pulses(self, km=False):
351 def plot_pulses2(self, km=False):
346 352
347 353 import matplotlib.pyplot as plt
348 354 from bokeh.resources import CDN
@@ -354,7 +360,7 class RCConfiguration(Configuration):
354 360
355 361 N = len(lines)
356 362 npoints = self.total_units/self.km2unit if km else self.total_units
357 fig = plt.figure(figsize=(10, 2+N*0.5))
363 fig = plt.figure(figsize=(12, 2+N*0.5))
358 364 ax = fig.add_subplot(111)
359 365 labels = ['IPP']
360 366
@@ -377,52 +383,138 class RCConfiguration(Configuration):
377 383 ax.set_yticks(range(len(labels)))
378 384 ax.set_yticklabels(labels)
379 385 ax.set_xlabel = 'Units'
380 plot = to_bokeh(fig, use_pandas=False)
386 plot = to_bokeh(fig, use_pandas=False)
381 387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
382 388 plot.toolbar_location="above"
383 389
384 390 return components(plot, CDN)
385 391
386 def status_device(self):
392 def plot_pulses(self, km=False):
387 393
388 return 0
394 from bokeh.plotting import figure
395 from bokeh.resources import CDN
396 from bokeh.embed import components
397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 from bokeh.models.sources import ColumnDataSource
389 400
390 def stop_device(self):
401 lines = self.get_lines().reverse()
402
403 N = len(lines)
404 npoints = self.total_units/self.km2unit if km else self.total_units
405 ipp = self.ipp if km else self.ipp*self.km2unit
406
407 hover = HoverTool(tooltips=[("Line", "@name"),
408 ("IPP", "@ipp"),
409 ("X", "@left")])
410
411 tools = [PanTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
413 hover, SaveTool()]
414
415 plot = figure(width=1000,
416 height=40+N*50,
417 y_range = (0, N),
418 tools=tools,
419 toolbar_location='above',
420 toolbar_sticky=False,)
421
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 plot.yaxis.axis_label = 'Pulses'
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427
428 for i, line in enumerate(lines):
429
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431
432 source = ColumnDataSource(data = dict(
433 bottom = [i for tup in points],
434 top = [i+0.5 for tup in points],
435 left = [tup[0] for tup in points],
436 right = [tup[1] for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
438 name = [line.get_name() for tup in points]
439 ))
440
441 plot.quad(
442 bottom = 'bottom',
443 top = 'top',
444 left = 'left',
445 right = 'right',
446 source = source,
447 fill_alpha = 0,
448 #line_color = 'blue',
449 )
450
451 plot.line([0, npoints], [i, i])#, color='blue')
452
453 return components(plot, CDN)
391 454
392 answer = api.disable(ip = self.device.ip_address,
393 port = self.device.port_address)
455 def status_device(self):
394 456
395 if answer[0] != "1":
396 self.message = answer[0:]
457 try:
458 req = requests.get(self.device.url)
459 payload = req.json()
460 if payload['status']=='ok':
461 self.device.status = 3
462 else:
463 self.device.status = 1
464 except:
465 self.device.status = 0
466
467 self.device.save()
468
469 return self.device.status
470
471
472 def reset_device(self):
473
474 payload = bytearray()
475 payload.extend(self.add_cmd('RESTART'))
476 data = b64encode(payload)
477 req = requests.put(self.device.url, data)
478
479 if data==req.text.encode('utf8'):
480 return 1
481 else:
397 482 return 0
483
484 def stop_device(self):
398 485
399 self.message = answer[2:]
400 return 1
486 payload = bytearray()
487 payload.extend(self.add_cmd('DISABLE'))
488 data = b64encode(payload)
489 req = requests.put(self.device.url, data)
490
491 if data==req.text.encode('utf8'):
492 return 1
493 else:
494 return 0
401 495
402 496 def start_device(self):
403 497
404 answer = api.enable(ip = self.device.ip_address,
405 port = self.device.port_address)
406
407 if answer[0] != "1":
408 self.message = answer[0:]
498 payload = bytearray()
499 payload.extend(self.add_cmd('ENABLE'))
500 data = b64encode(payload)
501 req = requests.put(self.device.url, data)
502
503 if data==req.text.encode('utf8'):
504 return 1
505 else:
409 506 return 0
410 507
411 self.message = answer[2:]
412 return 1
413
414 508 def write_device(self):
415 answer = api.write_config(ip = self.device.ip_address,
416 port = self.device.port_address,
417 parms = self.parms_to_dict())
418
419 if answer[0] != "1":
420 self.message = answer[0:]
509
510 data = b64encode(self.parms_to_binary(dat=False))
511 req = requests.put(self.device.url, data)
512 print(req.text)
513 if data==req.text.encode('utf8'):
514 return 1
515 else:
421 516 return 0
422 517
423 self.message = answer[2:]
424 return 1
425
426 518
427 519 class RCLineCode(models.Model):
428 520
@@ -550,7 +642,7 class RCLine(models.Model):
550 642 km2unit = self.rc_configuration.km2unit
551 643 us2unit = self.rc_configuration.us2unit
552 644 ipp = self.rc_configuration.ipp
553 ntx = self.rc_configuration.ntx
645 ntx = int(self.rc_configuration.ntx)
554 646 ipp_u = int(ipp*km2unit)
555 647 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
556 648 y = []
@@ -7,6 +7,7 urlpatterns = (
7 7 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'),
8 8 url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'),
9 9 url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'),
10 url(r'^(?P<conf_id>-?\d+)/plot2/$', views.plot_pulses2, name='url_plot_rc_pulses'),
10 11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
11 12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
12 13
@@ -360,7 +360,31 def plot_pulses(request, conf_id):
360 360 script, div = conf.plot_pulses(km=km)
361 361
362 362 kwargs = {}
363 kwargs['no_sidebar'] = True
364 kwargs['title'] = 'RC Pulses'
365 kwargs['suptitle'] = conf.name
366 kwargs['div'] = mark_safe(div)
367 kwargs['script'] = mark_safe(script)
368 kwargs['units'] = conf.km2unit
369 kwargs['kms'] = 1/conf.km2unit
370
371 if km:
372 kwargs['km_selected'] = True
373
374 if 'json' in request.GET:
375 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
376 else:
377 return render(request, 'rc_pulses.html', kwargs)
378
379 def plot_pulses2(request, conf_id):
363 380
381 conf = get_object_or_404(RCConfiguration, pk=conf_id)
382 km = True if 'km' in request.GET else False
383
384 script, div = conf.plot_pulses2(km=km)
385
386 kwargs = {}
387 kwargs['no_sidebar'] = True
364 388 kwargs['title'] = 'RC Pulses'
365 389 kwargs['suptitle'] = conf.name
366 390 kwargs['div'] = mark_safe(div)
General Comments 0
You need to be logged in to leave comments. Login now