@@ -124,6 +124,11 class Device(models.Model): | |||||
124 |
|
124 | |||
125 | return color |
|
125 | return color | |
126 |
|
126 | |||
|
127 | @property | |||
|
128 | def url(self): | |||
|
129 | ||||
|
130 | return 'http://{}:{}/'.format(self.ip_address, self.port_address) | |||
|
131 | ||||
127 | def get_absolute_url(self): |
|
132 | def get_absolute_url(self): | |
128 | return reverse('url_device', args=[str(self.id)]) |
|
133 | return reverse('url_device', args=[str(self.id)]) | |
129 |
|
134 |
@@ -37,7 +37,7 | |||||
37 | <table class="table table-bordered"> |
|
37 | <table class="table table-bordered"> | |
38 | <tr> |
|
38 | <tr> | |
39 | <th>Status</th> |
|
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 | </tr> |
|
41 | </tr> | |
42 |
|
42 | |||
43 | {% for key in dev_conf_keys %} |
|
43 | {% for key in dev_conf_keys %} |
@@ -57,11 +57,12 | |||||
57 |
|
57 | |||
58 | {% for item in location.experiments %} |
|
58 | {% for item in location.experiments %} | |
59 | {% if location.name in item.location.name %} |
|
59 | {% if location.name in item.location.name %} | |
60 |
|
||||
61 | <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" > |
|
60 | <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" > | |
62 | <td>{{ forloop.counter }}</td> |
|
61 | <td>{{ forloop.counter }}</td> | |
63 | {% for key in experiment_keys %} |
|
62 | {% for key in experiment_keys %} | |
64 |
{% if ' |
|
63 | {% if 'name' in key %} | |
|
64 | <td class="col-md-5">{{ item|value:key }}</td> | |||
|
65 | {% elif 'status' in key %} | |||
65 | <td class="text-{{item.status_color}}">{{ item|value:key }}</td> |
|
66 | <td class="text-{{item.status_color}}">{{ item|value:key }}</td> | |
66 | {% else %} |
|
67 | {% else %} | |
67 | <td>{{ item|value:key }}</td> |
|
68 | <td>{{ item|value:key }}</td> |
@@ -1399,6 +1399,7 def get_paginator(model, page, order, filters={}, n=10): | |||||
1399 | def operation(request, id_camp=None): |
|
1399 | def operation(request, id_camp=None): | |
1400 |
|
1400 | |||
1401 | kwargs = {} |
|
1401 | kwargs = {} | |
|
1402 | kwargs['no_sidebar'] = True | |||
1402 | campaigns = Campaign.objects.filter(start_date__lte=datetime.now(), |
|
1403 | campaigns = Campaign.objects.filter(start_date__lte=datetime.now(), | |
1403 | end_date__gte=datetime.now()).order_by('-start_date') |
|
1404 | end_date__gte=datetime.now()).order_by('-start_date') | |
1404 |
|
1405 | |||
@@ -1412,8 +1413,6 def operation(request, id_camp=None): | |||||
1412 | kwargs['form'] = form |
|
1413 | kwargs['form'] = form | |
1413 | return render(request, 'operation.html', kwargs) |
|
1414 | return render(request, 'operation.html', kwargs) | |
1414 |
|
1415 | |||
1415 |
|
||||
1416 |
|
||||
1417 | #---Experiment |
|
1416 | #---Experiment | |
1418 | keys = ['id', 'name', 'start_time', 'end_time', 'status'] |
|
1417 | keys = ['id', 'name', 'start_time', 'end_time', 'status'] | |
1419 | kwargs['experiment_keys'] = keys[1:] |
|
1418 | kwargs['experiment_keys'] = keys[1:] | |
@@ -1423,7 +1422,7 def operation(request, id_camp=None): | |||||
1423 | #---Else |
|
1422 | #---Else | |
1424 | kwargs['title'] = 'Campaign' |
|
1423 | kwargs['title'] = 'Campaign' | |
1425 | kwargs['suptitle'] = campaign.name |
|
1424 | kwargs['suptitle'] = campaign.name | |
1426 | kwargs['form'] = form |
|
1425 | kwargs['form'] = form | |
1427 |
|
1426 | |||
1428 | return render(request, 'operation.html', kwargs) |
|
1427 | return render(request, 'operation.html', kwargs) | |
1429 |
|
1428 |
@@ -1,7 +1,9 | |||||
1 |
|
1 | |||
2 | import ast |
|
2 | import ast | |
3 | import json |
|
3 | import json | |
|
4 | import requests | |||
4 | import numpy as np |
|
5 | import numpy as np | |
|
6 | from base64 import b64encode | |||
5 |
|
7 | |||
6 | from django.db import models |
|
8 | from django.db import models | |
7 | from django.core.urlresolvers import reverse |
|
9 | from django.core.urlresolvers import reverse | |
@@ -258,60 +260,60 class RCConfiguration(Configuration): | |||||
258 | def add_data(self, value): |
|
260 | def add_data(self, value): | |
259 |
|
261 | |||
260 | return (254, value-1) |
|
262 | return (254, value-1) | |
261 |
|
263 | |||
262 | def parms_to_binary(self): |
|
264 | def parms_to_binary(self, dat=True): | |
263 | ''' |
|
265 | ''' | |
264 | Create "dat" stream to be send to CR |
|
266 | Create "dat" stream to be send to CR | |
265 | ''' |
|
267 | ''' | |
266 |
|
268 | |||
267 |
data = |
|
269 | data = bytearray() | |
268 | # create header |
|
270 | # create header | |
269 |
data. |
|
271 | data.extend(self.add_cmd('DISABLE')) | |
270 |
data. |
|
272 | data.extend(self.add_cmd('CONTINUE')) | |
271 |
data. |
|
273 | data.extend(self.add_cmd('RESTART')) | |
272 |
|
274 | |||
273 | if self.control_sw: |
|
275 | if self.control_sw: | |
274 |
data. |
|
276 | data.extend(self.add_cmd('SW_ONE')) | |
275 | else: |
|
277 | else: | |
276 |
data. |
|
278 | data.extend(self.add_cmd('SW_ZERO')) | |
277 |
|
279 | |||
278 | if self.control_tx: |
|
280 | if self.control_tx: | |
279 |
data. |
|
281 | data.extend(self.add_cmd('TX_ONE')) | |
280 | else: |
|
282 | else: | |
281 |
data. |
|
283 | data.extend(self.add_cmd('TX_ZERO')) | |
282 |
|
284 | |||
283 | # write divider |
|
285 | # write divider | |
284 |
data. |
|
286 | data.extend(self.add_cmd('CLOCK_DIVIDER')) | |
285 |
data. |
|
287 | data.extend(self.add_data(self.clock_divider)) | |
286 |
|
288 | |||
287 | # write delays |
|
289 | # write delays | |
288 |
data. |
|
290 | data.extend(self.add_cmd('DELAY_START')) | |
289 | # first delay is always zero |
|
291 | # first delay is always zero | |
290 |
data. |
|
292 | data.extend(self.add_data(1)) | |
291 |
|
293 | |||
292 | delays = self.get_delays() |
|
294 | delays = self.get_delays() | |
293 |
|
295 | |||
294 | for delay in delays: |
|
296 | for delay in delays: | |
295 | while delay>252: |
|
297 | while delay>252: | |
296 |
data. |
|
298 | data.extend(self.add_data(253)) | |
297 | delay -= 253 |
|
299 | delay -= 253 | |
298 |
data. |
|
300 | data.extend(self.add_data(int(delay))) | |
299 |
|
301 | |||
300 | # write flips |
|
302 | # write flips | |
301 |
data. |
|
303 | data.extend(self.add_cmd('FLIP_START')) | |
302 |
|
304 | |||
303 | states = self.get_pulses(binary=False) |
|
305 | states = self.get_pulses(binary=False) | |
304 |
|
306 | |||
305 | for flips, delay in zip(states, delays): |
|
307 | for flips, delay in zip(states, delays): | |
306 | flips.reverse() |
|
308 | flips.reverse() | |
307 | flip = int(''.join([str(x) for x in flips]), 2) |
|
309 | flip = int(''.join([str(x) for x in flips]), 2) | |
308 |
data. |
|
310 | data.extend(self.add_data(flip+1)) | |
309 | while delay>252: |
|
311 | while delay>252: | |
310 |
data. |
|
312 | data.extend(self.add_data(1)) | |
311 | delay -= 253 |
|
313 | delay -= 253 | |
312 |
|
314 | |||
313 | # write sampling period |
|
315 | # write sampling period | |
314 |
data. |
|
316 | data.extend(self.add_cmd('SAMPLING_PERIOD')) | |
315 | wins = self.get_lines(line_type__name='windows') |
|
317 | wins = self.get_lines(line_type__name='windows') | |
316 | if wins: |
|
318 | if wins: | |
317 | win_params = json.loads(wins[0].params)['params'] |
|
319 | win_params = json.loads(wins[0].params)['params'] | |
@@ -321,12 +323,16 class RCConfiguration(Configuration): | |||||
321 | dh = 1 |
|
323 | dh = 1 | |
322 | else: |
|
324 | else: | |
323 | dh = 1 |
|
325 | dh = 1 | |
324 |
data. |
|
326 | data.extend(self.add_data(dh)) | |
325 |
|
327 | |||
326 | # write enable |
|
328 | # write enable | |
327 |
data. |
|
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 | def update_from_file(self, filename): |
|
337 | def update_from_file(self, filename): | |
332 | ''' |
|
338 | ''' | |
@@ -342,7 +348,7 class RCConfiguration(Configuration): | |||||
342 | for line in self.get_lines(): |
|
348 | for line in self.get_lines(): | |
343 | line.update_pulses() |
|
349 | line.update_pulses() | |
344 |
|
350 | |||
345 | def plot_pulses(self, km=False): |
|
351 | def plot_pulses2(self, km=False): | |
346 |
|
352 | |||
347 | import matplotlib.pyplot as plt |
|
353 | import matplotlib.pyplot as plt | |
348 | from bokeh.resources import CDN |
|
354 | from bokeh.resources import CDN | |
@@ -354,7 +360,7 class RCConfiguration(Configuration): | |||||
354 |
|
360 | |||
355 | N = len(lines) |
|
361 | N = len(lines) | |
356 | npoints = self.total_units/self.km2unit if km else self.total_units |
|
362 | npoints = self.total_units/self.km2unit if km else self.total_units | |
357 |
fig = plt.figure(figsize=(1 |
|
363 | fig = plt.figure(figsize=(12, 2+N*0.5)) | |
358 | ax = fig.add_subplot(111) |
|
364 | ax = fig.add_subplot(111) | |
359 | labels = ['IPP'] |
|
365 | labels = ['IPP'] | |
360 |
|
366 | |||
@@ -377,52 +383,138 class RCConfiguration(Configuration): | |||||
377 | ax.set_yticks(range(len(labels))) |
|
383 | ax.set_yticks(range(len(labels))) | |
378 | ax.set_yticklabels(labels) |
|
384 | ax.set_yticklabels(labels) | |
379 | ax.set_xlabel = 'Units' |
|
385 | ax.set_xlabel = 'Units' | |
380 | plot = to_bokeh(fig, use_pandas=False) |
|
386 | plot = to_bokeh(fig, use_pandas=False) | |
381 | plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()] |
|
387 | plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()] | |
382 | plot.toolbar_location="above" |
|
388 | plot.toolbar_location="above" | |
383 |
|
389 | |||
384 | return components(plot, CDN) |
|
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, |
|
455 | def status_device(self): | |
393 | port = self.device.port_address) |
|
|||
394 |
|
456 | |||
395 | if answer[0] != "1": |
|
457 | try: | |
396 | self.message = answer[0:] |
|
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 | return 0 |
|
482 | return 0 | |
|
483 | ||||
|
484 | def stop_device(self): | |||
398 |
|
485 | |||
399 | self.message = answer[2:] |
|
486 | payload = bytearray() | |
400 | return 1 |
|
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 | def start_device(self): |
|
496 | def start_device(self): | |
403 |
|
497 | |||
404 | answer = api.enable(ip = self.device.ip_address, |
|
498 | payload = bytearray() | |
405 | port = self.device.port_address) |
|
499 | payload.extend(self.add_cmd('ENABLE')) | |
406 |
|
500 | data = b64encode(payload) | ||
407 | if answer[0] != "1": |
|
501 | req = requests.put(self.device.url, data) | |
408 | self.message = answer[0:] |
|
502 | ||
|
503 | if data==req.text.encode('utf8'): | |||
|
504 | return 1 | |||
|
505 | else: | |||
409 | return 0 |
|
506 | return 0 | |
410 |
|
507 | |||
411 | self.message = answer[2:] |
|
|||
412 | return 1 |
|
|||
413 |
|
||||
414 | def write_device(self): |
|
508 | def write_device(self): | |
415 | answer = api.write_config(ip = self.device.ip_address, |
|
509 | ||
416 | port = self.device.port_address, |
|
510 | data = b64encode(self.parms_to_binary(dat=False)) | |
417 | parms = self.parms_to_dict()) |
|
511 | req = requests.put(self.device.url, data) | |
418 |
|
512 | print(req.text) | ||
419 | if answer[0] != "1": |
|
513 | if data==req.text.encode('utf8'): | |
420 | self.message = answer[0:] |
|
514 | return 1 | |
|
515 | else: | |||
421 | return 0 |
|
516 | return 0 | |
422 |
|
517 | |||
423 | self.message = answer[2:] |
|
|||
424 | return 1 |
|
|||
425 |
|
||||
426 |
|
518 | |||
427 | class RCLineCode(models.Model): |
|
519 | class RCLineCode(models.Model): | |
428 |
|
520 | |||
@@ -550,7 +642,7 class RCLine(models.Model): | |||||
550 | km2unit = self.rc_configuration.km2unit |
|
642 | km2unit = self.rc_configuration.km2unit | |
551 | us2unit = self.rc_configuration.us2unit |
|
643 | us2unit = self.rc_configuration.us2unit | |
552 | ipp = self.rc_configuration.ipp |
|
644 | ipp = self.rc_configuration.ipp | |
553 | ntx = self.rc_configuration.ntx |
|
645 | ntx = int(self.rc_configuration.ntx) | |
554 | ipp_u = int(ipp*km2unit) |
|
646 | ipp_u = int(ipp*km2unit) | |
555 | total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units |
|
647 | total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units | |
556 | y = [] |
|
648 | y = [] |
@@ -7,6 +7,7 urlpatterns = ( | |||||
7 | url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'), |
|
7 | url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'), | |
8 | url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'), |
|
8 | url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'), | |
9 | url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'), |
|
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 | #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'), |
|
11 | #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'), | |
11 | #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'), |
|
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 | script, div = conf.plot_pulses(km=km) |
|
360 | script, div = conf.plot_pulses(km=km) | |
361 |
|
361 | |||
362 | kwargs = {} |
|
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 | kwargs['title'] = 'RC Pulses' |
|
388 | kwargs['title'] = 'RC Pulses' | |
365 | kwargs['suptitle'] = conf.name |
|
389 | kwargs['suptitle'] = conf.name | |
366 | kwargs['div'] = mark_safe(div) |
|
390 | kwargs['div'] = mark_safe(div) |
General Comments 0
You need to be logged in to leave comments.
Login now