@@ -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 ' |
|
|
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. |
|
|
270 |
data. |
|
|
271 |
data. |
|
|
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. |
|
|
276 | data.extend(self.add_cmd('SW_ONE')) | |
|
275 | 277 | else: |
|
276 |
data. |
|
|
278 | data.extend(self.add_cmd('SW_ZERO')) | |
|
277 | 279 | |
|
278 | 280 | if self.control_tx: |
|
279 |
data. |
|
|
281 | data.extend(self.add_cmd('TX_ONE')) | |
|
280 | 282 | else: |
|
281 |
data. |
|
|
283 | data.extend(self.add_cmd('TX_ZERO')) | |
|
282 | 284 | |
|
283 | 285 | # write divider |
|
284 |
data. |
|
|
285 |
data. |
|
|
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. |
|
|
290 | data.extend(self.add_cmd('DELAY_START')) | |
|
289 | 291 | # first delay is always zero |
|
290 |
data. |
|
|
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. |
|
|
298 | data.extend(self.add_data(253)) | |
|
297 | 299 | delay -= 253 |
|
298 |
data. |
|
|
300 | data.extend(self.add_data(int(delay))) | |
|
299 | 301 | |
|
300 | 302 | # write flips |
|
301 |
data. |
|
|
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. |
|
|
310 | data.extend(self.add_data(flip+1)) | |
|
309 | 311 | while delay>252: |
|
310 |
data. |
|
|
312 | data.extend(self.add_data(1)) | |
|
311 | 313 | delay -= 253 |
|
312 | 314 | |
|
313 | 315 | # write sampling period |
|
314 |
data. |
|
|
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. |
|
|
326 | data.extend(self.add_data(dh)) | |
|
325 | 327 | |
|
326 | 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 | 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=(1 |
|
|
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