@@ -8,5 +8,5 POSTGRES_PASSWORD=docker | |||||
8 | PGDATA=/var/lib/postgresql/data |
|
8 | PGDATA=/var/lib/postgresql/data | |
9 | LC_ALL=C.UTF-8 |
|
9 | LC_ALL=C.UTF-8 | |
10 | TZ=America/Lima |
|
10 | TZ=America/Lima | |
11 |
DOCKER_DATA=/ |
|
11 | DOCKER_DATA=/data/dockers/radarsys/ | |
12 | LOCAL_IP=192.168.1.128 |
|
12 | LOCAL_IP=192.168.1.128 |
@@ -1,4 +1,5 | |||||
1 | migrations/ |
|
1 | migrations/ | |
|
2 | *.sqlite | |||
2 | .vscode/ |
|
3 | .vscode/ | |
3 | *.pyc |
|
4 | *.pyc | |
4 | .env |
|
5 | .env |
@@ -256,19 +256,11 class JARSConfiguration(Configuration): | |||||
256 | if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'): |
|
256 | if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'): | |
257 | data['configurations']['allIds'].remove(key) |
|
257 | data['configurations']['allIds'].remove(key) | |
258 | data['configurations']['byId'].pop(key) |
|
258 | data['configurations']['byId'].pop(key) | |
259 | elif data['configurations']['byId'][key]['device_type'] == 'jars': |
|
|||
260 | data['configurations']['byId'][key] = self.parms_to_dict()['configurations']['byId'][str(self.pk)] |
|
|||
261 | elif data['configurations']['byId'][key]['device_type'] == 'rc': |
|
259 | elif data['configurations']['byId'][key]['device_type'] == 'rc': | |
262 | data['configurations']['byId'][key]['pulses'] = '' |
|
260 | data['configurations']['byId'][key]['pulses'] = '' | |
263 | data['configurations']['byId'][key]['delays'] = '' |
|
261 | data['configurations']['byId'][key]['delays'] = '' | |
264 | rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc'] |
|
262 | rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc'] | |
265 | mix_ids = [pk for pk in rc_ids if data['configurations']['byId'][pk]['mix']] |
|
263 | if len(rc_ids)==0: | |
266 | if mix_ids: |
|
|||
267 | params = data['configurations']['byId'][mix_ids[0]]['parameters'] |
|
|||
268 | rc = data['configurations']['byId'][params.split('-')[0].split('|')[0]] |
|
|||
269 | rc['mix'] = True |
|
|||
270 | data['configurations']['byId'][rc['id']] = rc |
|
|||
271 | elif len(rc_ids)==0: |
|
|||
272 | self.message = 'Missing RC configuration' |
|
264 | self.message = 'Missing RC configuration' | |
273 | return False |
|
265 | return False | |
274 |
|
266 |
@@ -93,7 +93,7 class ExperimentForm(forms.ModelForm): | |||||
93 |
|
93 | |||
94 | class Meta: |
|
94 | class Meta: | |
95 | model = Experiment |
|
95 | model = Experiment | |
96 | exclude = ['status'] |
|
96 | exclude = ['task', 'status'] | |
97 |
|
97 | |||
98 | class LocationForm(forms.ModelForm): |
|
98 | class LocationForm(forms.ModelForm): | |
99 | class Meta: |
|
99 | class Meta: |
@@ -248,7 +248,7 class Campaign(models.Model): | |||||
248 |
|
248 | |||
249 | def parms_to_dict(self): |
|
249 | def parms_to_dict(self): | |
250 |
|
250 | |||
251 | params = Params() |
|
251 | params = Params({}) | |
252 | params.add(self.jsonify(), 'campaigns') |
|
252 | params.add(self.jsonify(), 'campaigns') | |
253 |
|
253 | |||
254 | for exp in Experiment.objects.filter(campaign = self): |
|
254 | for exp in Experiment.objects.filter(campaign = self): | |
@@ -334,6 +334,7 class Experiment(models.Model): | |||||
334 | freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200) |
|
334 | freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200) | |
335 | start_time = models.TimeField(default='00:00:00') |
|
335 | start_time = models.TimeField(default='00:00:00') | |
336 | end_time = models.TimeField(default='23:59:59') |
|
336 | end_time = models.TimeField(default='23:59:59') | |
|
337 | task = models.CharField(max_length=36, default='', blank=True, null=True) | |||
337 | status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES) |
|
338 | status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES) | |
338 |
|
339 | |||
339 | class Meta: |
|
340 | class Meta: | |
@@ -373,7 +374,7 class Experiment(models.Model): | |||||
373 |
|
374 | |||
374 | confs = Configuration.objects.filter(experiment=self, type=0) |
|
375 | confs = Configuration.objects.filter(experiment=self, type=0) | |
375 | self.pk = None |
|
376 | self.pk = None | |
376 |
self.name = '{} [{:%Y |
|
377 | self.name = '{} [{:%Y-%m-%d}]'.format(self.name, datetime.now()) | |
377 | for attr, value in kwargs.items(): |
|
378 | for attr, value in kwargs.items(): | |
378 | setattr(self, attr, value) |
|
379 | setattr(self, attr, value) | |
379 |
|
380 | |||
@@ -391,8 +392,16 class Experiment(models.Model): | |||||
391 | ''' |
|
392 | ''' | |
392 |
|
393 | |||
393 | result = 2 |
|
394 | result = 2 | |
394 |
|
395 | confs = [] | ||
395 | confs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence') |
|
396 | allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence') | |
|
397 | rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix] | |||
|
398 | if rc_mix: | |||
|
399 | for conf in allconfs: | |||
|
400 | if conf.device.device_type.name == 'rc' and not conf.mix: | |||
|
401 | continue | |||
|
402 | confs.append(conf) | |||
|
403 | else: | |||
|
404 | confs = allconfs | |||
396 | #Only Configured Devices. |
|
405 | #Only Configured Devices. | |
397 | for conf in confs: |
|
406 | for conf in confs: | |
398 | if conf.device.status in (0, 4): |
|
407 | if conf.device.status in (0, 4): | |
@@ -400,9 +409,9 class Experiment(models.Model): | |||||
400 | return result |
|
409 | return result | |
401 | for conf in confs: |
|
410 | for conf in confs: | |
402 | conf.stop_device() |
|
411 | conf.stop_device() | |
403 |
|
|
412 | conf.write_device() | |
404 | conf.start_device() |
|
413 | conf.start_device() | |
405 | print conf.device.name+' has started...' |
|
414 | time.sleep(1) | |
406 |
|
415 | |||
407 | return result |
|
416 | return result | |
408 |
|
417 | |||
@@ -422,7 +431,6 class Experiment(models.Model): | |||||
422 | result = 0 |
|
431 | result = 0 | |
423 | continue |
|
432 | continue | |
424 | conf.stop_device() |
|
433 | conf.stop_device() | |
425 | print conf.device.name+' has stopped...' |
|
|||
426 |
|
434 | |||
427 | return result |
|
435 | return result | |
428 |
|
436 | |||
@@ -464,7 +472,7 class Experiment(models.Model): | |||||
464 |
|
472 | |||
465 | def parms_to_dict(self): |
|
473 | def parms_to_dict(self): | |
466 |
|
474 | |||
467 | params = Params() |
|
475 | params = Params({}) | |
468 | params.add(self.jsonify(), 'experiments') |
|
476 | params.add(self.jsonify(), 'experiments') | |
469 |
|
477 | |||
470 | configurations = Configuration.objects.filter(experiment=self, type=0) |
|
478 | configurations = Configuration.objects.filter(experiment=self, type=0) | |
@@ -532,19 +540,13 class Experiment(models.Model): | |||||
532 | class Configuration(PolymorphicModel): |
|
540 | class Configuration(PolymorphicModel): | |
533 |
|
541 | |||
534 | template = models.BooleanField(default=False) |
|
542 | template = models.BooleanField(default=False) | |
535 |
|
||||
536 | name = models.CharField(verbose_name="Configuration Name", max_length=40, default='') |
|
543 | name = models.CharField(verbose_name="Configuration Name", max_length=40, default='') | |
537 |
|
||||
538 | experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE) |
|
544 | experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE) | |
539 | device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE) |
|
545 | device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE) | |
540 |
|
||||
541 | type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES) |
|
546 | type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES) | |
542 |
|
||||
543 | created_date = models.DateTimeField(auto_now_add=True) |
|
547 | created_date = models.DateTimeField(auto_now_add=True) | |
544 | programmed_date = models.DateTimeField(auto_now=True) |
|
548 | programmed_date = models.DateTimeField(auto_now=True) | |
545 |
|
||||
546 | parameters = models.TextField(default='{}') |
|
549 | parameters = models.TextField(default='{}') | |
547 |
|
||||
548 | message = "" |
|
550 | message = "" | |
549 |
|
551 | |||
550 | class Meta: |
|
552 | class Meta: | |
@@ -607,7 +609,7 class Configuration(PolymorphicModel): | |||||
607 |
|
609 | |||
608 | def parms_to_dict(self): |
|
610 | def parms_to_dict(self): | |
609 |
|
611 | |||
610 | params = Params() |
|
612 | params = Params({}) | |
611 | params.add(self.jsonify(), 'configurations') |
|
613 | params.add(self.jsonify(), 'configurations') | |
612 |
|
614 | |||
613 | if self.device.device_type.name=='rc': |
|
615 | if self.device.device_type.name=='rc': |
@@ -1,5 +1,6 | |||||
1 | from __future__ import absolute_import |
|
1 | from __future__ import absolute_import | |
2 |
|
2 | |||
|
3 | from radarsys.celery import app | |||
3 | from celery import task |
|
4 | from celery import task | |
4 | from datetime import timedelta, datetime |
|
5 | from datetime import timedelta, datetime | |
5 |
|
6 | |||
@@ -7,25 +8,47 from .models import Experiment | |||||
7 |
|
8 | |||
8 | @task |
|
9 | @task | |
9 | def task_start(id_exp): |
|
10 | def task_start(id_exp): | |
10 |
|
||||
11 | exp = Experiment.objects.get(pk=id_exp) |
|
11 | exp = Experiment.objects.get(pk=id_exp) | |
12 |
|
12 | status = exp.status | ||
13 | return exp.start() |
|
13 | if exp.status == 2: | |
|
14 | print('Experiment {} already running start task not executed'.format(exp)) | |||
|
15 | return 2 | |||
|
16 | if status == 3: | |||
|
17 | now = datetime.now() | |||
|
18 | start = datetime.combine(now.date(), exp.start_time) | |||
|
19 | end = datetime.combine(now.date(), exp.end_time) | |||
|
20 | if end < start: | |||
|
21 | end += timedelta(1) | |||
|
22 | try: | |||
|
23 | print('Starting exp:{}'.format(exp)) | |||
|
24 | exp.status = exp.start() | |||
|
25 | except: | |||
|
26 | print('Error') | |||
|
27 | exp.status = 0 | |||
|
28 | if exp.status == 2: | |||
|
29 | task = task_stop.apply_async((id_exp,), eta=end+timedelta(hours=5)) | |||
|
30 | exp.task = task.id | |||
|
31 | exp.save() | |||
|
32 | return exp.status | |||
14 |
|
33 | |||
15 | @task |
|
34 | @task | |
16 | def task_stop(id_exp): |
|
35 | def task_stop(id_exp): | |
17 |
|
||||
18 | exp = Experiment.objects.get(pk=id_exp) |
|
36 | exp = Experiment.objects.get(pk=id_exp) | |
|
37 | if exp.status == 2: | |||
|
38 | try: | |||
|
39 | print('Stopping exp:{}'.format(exp)) | |||
|
40 | exp.status = exp.stop() | |||
|
41 | except: | |||
|
42 | print('Error') | |||
|
43 | exp.status = 0 | |||
19 |
|
44 | |||
20 | return exp.stop() |
|
45 | now = datetime.now() | |
21 |
|
46 | start = datetime.combine(now.date()+timedelta(1), exp.start_time) | ||
22 | def kill_tasks(): |
|
47 | task = task_start.apply_async((id_exp, ), eta=start+timedelta(hours=5)) | |
23 |
|
48 | exp.task = task.id | ||
24 | i = task.control.inspect() |
|
49 | exp.status = 3 | |
25 | tasks = i.scheduled() |
|
50 | exp.save() | |
26 | print tasks |
|
51 | return exp.status | |
27 | #if tasks: |
|
|||
28 | # print dir(tasks[0]) |
|
|||
29 |
|
52 | |||
30 | #Task to get status |
|
53 | #Task to get status | |
31 | @task |
|
54 | @task |
@@ -70,7 +70,11 | |||||
70 | <i class="fa fa-3x fa-puzzle-piece"></i> |
|
70 | <i class="fa fa-3x fa-puzzle-piece"></i> | |
71 | {%endif%} |
|
71 | {%endif%} | |
72 | <h4>{{item}}<br><small>{{item.device.ip_address}}</small> |
|
72 | <h4>{{item}}<br><small>{{item.device.ip_address}}</small> | |
|
73 | {%if experiment.status == 3 %} | |||
|
74 | <span class="label label-info">Configured</span> | |||
|
75 | {%else%} | |||
73 |
|
|
76 | <span class="label label-{{item.device.status_color}}">{{item.device.get_status_display}}</span> | |
|
77 | {%endif%} | |||
74 | </h4> |
|
78 | </h4> | |
75 | </a> |
|
79 | </a> | |
76 | </div> |
|
80 | </div> |
@@ -18,7 +18,6 | |||||
18 |
|
18 | |||
19 | <h3>Current Campaigns</h3> |
|
19 | <h3>Current Campaigns</h3> | |
20 | <br> |
|
20 | <br> | |
21 |
|
||||
22 |
|
|
21 | <div class="bootcards-list"> | |
23 |
|
|
22 | <div class="panel panel-default"> | |
24 |
|
|
23 | <div class="list-group"> | |
@@ -34,6 +33,7 | |||||
34 |
|
|
33 | <p class="list-group-item-text">From: {{item.start_date}}</p> | |
35 |
|
|
34 | <p class="list-group-item-text">To: {{item.end_date}}</p> | |
36 |
|
|
35 | </div> | |
|
36 | ||||
37 |
|
|
37 | </div> | |
38 |
|
|
38 | </a> | |
39 |
|
|
39 | {% endfor %} | |
@@ -41,8 +41,6 | |||||
41 |
|
|
41 | </div> | |
42 |
|
|
42 | </div> | |
43 |
|
43 | |||
44 |
|
||||
45 |
|
||||
46 | {% endif %} |
|
44 | {% endif %} | |
47 |
|
45 | |||
48 |
|
46 |
@@ -19,7 +19,7 except ImportError: | |||||
19 | from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm |
|
19 | from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm | |
20 | from .forms import OperationSearchForm, FilterForm, ChangeIpForm |
|
20 | from .forms import OperationSearchForm, FilterForm, ChangeIpForm | |
21 |
|
21 | |||
22 |
from .tasks import task_start |
|
22 | from .tasks import task_start | |
23 |
|
23 | |||
24 | from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm |
|
24 | from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm | |
25 | from apps.dds.forms import DDSConfigurationForm |
|
25 | from apps.dds.forms import DDSConfigurationForm | |
@@ -37,6 +37,8 from apps.abs.models import ABSConfiguration | |||||
37 | from apps.rc.models import RCConfiguration, RCLine, RCLineType |
|
37 | from apps.rc.models import RCConfiguration, RCLine, RCLineType | |
38 | from apps.dds.models import DDSConfiguration |
|
38 | from apps.dds.models import DDSConfiguration | |
39 |
|
39 | |||
|
40 | from radarsys.celery import app | |||
|
41 | ||||
40 | from django.contrib.auth.decorators import login_required |
|
42 | from django.contrib.auth.decorators import login_required | |
41 | from django.contrib.auth.decorators import user_passes_test |
|
43 | from django.contrib.auth.decorators import user_passes_test | |
42 | from django.contrib.admin.views.decorators import staff_member_required |
|
44 | from django.contrib.admin.views.decorators import staff_member_required | |
@@ -836,7 +838,7 def experiment_mix(request, id_exp): | |||||
836 | @user_passes_test(lambda u:u.is_staff) |
|
838 | @user_passes_test(lambda u:u.is_staff) | |
837 | def experiment_mix_delete(request, id_exp): |
|
839 | def experiment_mix_delete(request, id_exp): | |
838 |
|
840 | |||
839 | conf = RCConfiguration.objects.get(experiment=id_exp, mix=True) |
|
841 | conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0) | |
840 | values = conf.parameters.split('-') |
|
842 | values = conf.parameters.split('-') | |
841 | conf.parameters = '-'.join(values[:-1]) |
|
843 | conf.parameters = '-'.join(values[:-1]) | |
842 | conf.save() |
|
844 | conf.save() | |
@@ -1653,7 +1655,7 def radar_start(request, id_camp, id_radar): | |||||
1653 | now = datetime.now() |
|
1655 | now = datetime.now() | |
1654 | for exp in experiments: |
|
1656 | for exp in experiments: | |
1655 | start = datetime.combine(datetime.now().date(), exp.start_time) |
|
1657 | start = datetime.combine(datetime.now().date(), exp.start_time) | |
1656 |
end = datetime.combine(datetime.now().date(), exp. |
|
1658 | end = datetime.combine(datetime.now().date(), exp.end_time) | |
1657 | if end < start: |
|
1659 | if end < start: | |
1658 | end += timedelta(1) |
|
1660 | end += timedelta(1) | |
1659 |
|
1661 | |||
@@ -1670,16 +1672,17 def radar_start(request, id_camp, id_radar): | |||||
1670 | continue |
|
1672 | continue | |
1671 |
|
1673 | |||
1672 | if now > start and now <= end: |
|
1674 | if now > start and now <= end: | |
1673 | task = task_start.delay(exp.pk) |
|
1675 | exp.status = 3 | |
|
1676 | exp.save() | |||
|
1677 | task = task_start.delay(exp.id) | |||
1674 | exp.status = task.wait() |
|
1678 | exp.status = task.wait() | |
1675 | if exp.status==0: |
|
1679 | if exp.status==0: | |
1676 | messages.error(request, 'Experiment {} not start'.format(exp)) |
|
1680 | messages.error(request, 'Experiment {} not start'.format(exp)) | |
1677 | if exp.status==2: |
|
1681 | if exp.status==2: | |
1678 | task = task_stop.apply_async((exp.pk,), eta=end+timedelta(hours=5)) |
|
|||
1679 | messages.success(request, 'Experiment {} started'.format(exp)) |
|
1682 | messages.success(request, 'Experiment {} started'.format(exp)) | |
1680 | else: |
|
1683 | else: | |
1681 | task = task_start.apply_async((exp.pk,), eta=start+timedelta(hours=5)) |
|
1684 | task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5)) | |
1682 | task = task_stop.apply_async((exp.pk,), eta=end+timedelta(hours=5)) |
|
1685 | exp.task = task.id | |
1683 | exp.status = 3 |
|
1686 | exp.status = 3 | |
1684 | messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start)) |
|
1687 | messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start)) | |
1685 |
|
1688 | |||
@@ -1696,14 +1699,13 def radar_stop(request, id_camp, id_radar): | |||||
1696 |
|
1699 | |||
1697 | for exp in experiments: |
|
1700 | for exp in experiments: | |
1698 |
|
1701 | |||
|
1702 | if exp.task: | |||
|
1703 | app.control.revoke(exp.task) | |||
1699 | if exp.status == 2: |
|
1704 | if exp.status == 2: | |
1700 | task = task_stop.delay(exp.pk) |
|
1705 | exp.stop() | |
1701 | exp.status = task.wait() |
|
|||
1702 | messages.warning(request, 'Experiment {} stopped'.format(exp)) |
|
1706 | messages.warning(request, 'Experiment {} stopped'.format(exp)) | |
|
1707 | exp.status = 1 | |||
1703 |
|
|
1708 | exp.save() | |
1704 | else: |
|
|||
1705 | messages.error(request, 'Experiment {} not running'.format(exp)) |
|
|||
1706 | kill_tasks() |
|
|||
1707 |
|
1709 | |||
1708 | return HttpResponseRedirect(reverse('url_operation', args=[id_camp])) |
|
1710 | return HttpResponseRedirect(reverse('url_operation', args=[id_camp])) | |
1709 |
|
1711 |
@@ -10,6 +10,7 app = Celery('radarsys') | |||||
10 | # Using a string here means the worker will not have to |
|
10 | # Using a string here means the worker will not have to | |
11 | # pickle the object when using Windows. |
|
11 | # pickle the object when using Windows. | |
12 | app.config_from_object('django.conf:settings') |
|
12 | app.config_from_object('django.conf:settings') | |
|
13 | app.conf.broker_transport_options = {'visibility_timeout': 86400} | |||
13 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) |
|
14 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) | |
14 |
|
15 | |||
15 |
|
16 |
General Comments 0
You need to be logged in to leave comments.
Login now