models.py
804 lines
| 24.6 KiB
| text/x-python
|
PythonLexer
|
r185 | |||
|
r266 | import os | ||
import json | ||||
|
r236 | import requests | ||
|
r266 | import time | ||
|
r85 | from datetime import datetime | ||
|
r185 | try: | ||
from polymorphic.models import PolymorphicModel | ||||
except: | ||||
from polymorphic import PolymorphicModel | ||||
|
r0 | |||
|
r266 | from django.template.base import kwarg_re | ||
|
r185 | from django.db import models | ||
|
r32 | from django.core.urlresolvers import reverse | ||
|
r266 | from django.core.validators import MinValueValidator, MaxValueValidator | ||
|
r185 | from django.shortcuts import get_object_or_404 | ||
|
r316 | from django.contrib.auth.models import User | ||
|
r319 | from django.db.models.signals import post_save | ||
from django.dispatch import receiver | ||||
|
r108 | |||
|
r266 | from apps.main.utils import Params | ||
from apps.rc.utils import RCFile | ||||
|
r275 | from apps.jars.utils import RacpFile | ||
|
r219 | from devices.dds import api as dds_api | ||
|
r266 | from devices.dds import data as dds_data | ||
|
r72 | |||
|
r266 | |||
DEV_PORTS = { | ||||
'rc' : 2000, | ||||
'dds' : 2000, | ||||
'jars' : 2000, | ||||
'usrp' : 2000, | ||||
'cgs' : 8080, | ||||
'abs' : 8080 | ||||
} | ||||
RADAR_STATES = ( | ||||
(0, 'No connected'), | ||||
(1, 'Connected'), | ||||
(2, 'Configured'), | ||||
(3, 'Running'), | ||||
(4, 'Scheduled'), | ||||
|
r47 | ) | ||
|
r41 | |||
|
r266 | EXPERIMENT_TYPE = ( | ||
(0, 'RAW_DATA'), | ||||
(1, 'PDATA'), | ||||
) | ||||
DECODE_TYPE = ( | ||||
(0, 'None'), | ||||
(1, 'TimeDomain'), | ||||
(2, 'FreqDomain'), | ||||
(3, 'InvFreqDomain'), | ||||
|
r47 | ) | ||
|
r16 | |||
|
r226 | DEV_STATES = ( | ||
|
r47 | (0, 'No connected'), | ||
(1, 'Connected'), | ||||
(2, 'Configured'), | ||||
(3, 'Running'), | ||||
|
r185 | (4, 'Unknown'), | ||
|
r47 | ) | ||
|
r2 | |||
|
r13 | DEV_TYPES = ( | ||
|
r47 | ('', 'Select a device type'), | ||
|
r226 | ('rc', 'Radar Controller'), | ||
|
r47 | ('dds', 'Direct Digital Synthesizer'), | ||
('jars', 'Jicamarca Radar Acquisition System'), | ||||
('usrp', 'Universal Software Radio Peripheral'), | ||||
('cgs', 'Clock Generator System'), | ||||
('abs', 'Automatic Beam Switching'), | ||||
) | ||||
|
r266 | EXP_STATES = ( | ||
(0,'Error'), #RED | ||||
|
r329 | (1,'Cancelled'), #YELLOW | ||
|
r266 | (2,'Running'), #GREEN | ||
|
r329 | (3,'Scheduled'), #BLUE | ||
(4,'Unknown'), #WHITE | ||||
|
r49 | ) | ||
|
r216 | |||
|
r266 | CONF_TYPES = ( | ||
(0, 'Active'), | ||||
(1, 'Historical'), | ||||
) | ||||
|
r162 | |||
|
r319 | class Profile(models.Model): | ||
user = models.OneToOneField(User, on_delete=models.CASCADE) | ||||
|
r326 | theme = models.CharField(max_length=30, default='spacelab') | ||
|
r319 | |||
@receiver(post_save, sender=User) | ||||
def create_user_profile(sender, instance, created, **kwargs): | ||||
if created: | ||||
Profile.objects.create(user=instance) | ||||
@receiver(post_save, sender=User) | ||||
def save_user_profile(sender, instance, **kwargs): | ||||
instance.profile.save() | ||||
|
r53 | class Location(models.Model): | ||
name = models.CharField(max_length = 30) | ||||
description = models.TextField(blank=True, null=True) | ||||
class Meta: | ||||
db_table = 'db_location' | ||||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r53 | return u'%s' % self.name | ||
|
r89 | def get_absolute_url(self): | ||
|
r138 | return reverse('url_location', args=[str(self.id)]) | ||
|
r89 | |||
|
r2 | class DeviceType(models.Model): | ||
|
r13 | name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc') | ||
|
r196 | sequence = models.PositiveSmallIntegerField(default=1000) | ||
|
r13 | description = models.TextField(blank=True, null=True) | ||
|
r2 | |||
class Meta: | ||||
|
r13 | db_table = 'db_device_types' | ||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r22 | return u'%s' % self.get_name_display() | ||
|
r162 | |||
|
r2 | class Device(models.Model): | ||
|
r53 | device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE) | ||
location = models.ForeignKey(Location, on_delete=models.CASCADE) | ||||
|
r6 | ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0') | ||
|
r13 | port_address = models.PositiveSmallIntegerField(default=2000) | ||
|
r226 | description = models.TextField(blank=True, null=True) | ||
|
r16 | status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES) | ||
|
r329 | conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration') | ||
|
r2 | |||
class Meta: | ||||
|
r13 | db_table = 'db_devices' | ||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r316 | ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name) | ||
return ret | ||||
@property | ||||
def name(self): | ||||
return str(self) | ||||
|
r162 | |||
def get_status(self): | ||||
|
r47 | return self.status | ||
|
r162 | |||
|
r120 | @property | ||
def status_color(self): | ||||
color = 'muted' | ||||
if self.status == 0: | ||||
color = "danger" | ||||
elif self.status == 1: | ||||
color = "warning" | ||||
elif self.status == 2: | ||||
color = "info" | ||||
elif self.status == 3: | ||||
color = "success" | ||||
|
r162 | |||
|
r120 | return color | ||
|
r226 | |||
|
r185 | def url(self, path=None): | ||
|
r226 | |||
|
r185 | if path: | ||
return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path) | ||||
else: | ||||
return 'http://{}:{}/'.format(self.ip_address, self.port_address) | ||||
|
r226 | |||
|
r89 | def get_absolute_url(self): | ||
return reverse('url_device', args=[str(self.id)]) | ||||
|
r162 | |||
|
r316 | def get_absolute_url_edit(self): | ||
return reverse('url_edit_device', args=[str(self.id)]) | ||||
def get_absolute_url_delete(self): | ||||
return reverse('url_delete_device', args=[str(self.id)]) | ||||
|
r266 | def change_ip(self, ip_address, mask, gateway, dns, **kwargs): | ||
|
r226 | |||
|
r219 | if self.device_type.name=='dds': | ||
|
r243 | try: | ||
|
r219 | answer = dds_api.change_ip(ip = self.ip_address, | ||
port = self.port_address, | ||||
new_ip = ip_address, | ||||
mask = mask, | ||||
|
r226 | gateway = gateway) | ||
if answer[0]=='1': | ||||
|
r236 | self.message = '25|DDS - {}'.format(answer) | ||
|
r219 | self.ip_address = ip_address | ||
|
r226 | self.save() | ||
|
r219 | else: | ||
|
r236 | self.message = '30|DDS - {}'.format(answer) | ||
|
r219 | return False | ||
except Exception as e: | ||||
|
r236 | self.message = '40|{}'.format(str(e)) | ||
|
r226 | return False | ||
|
r243 | |||
|
r236 | elif self.device_type.name=='rc': | ||
|
r266 | headers = {'content-type': "application/json", | ||
'cache-control': "no-cache"} | ||||
ip = [int(x) for x in ip_address.split('.')] | ||||
dns = [int(x) for x in dns.split('.')] | ||||
gateway = [int(x) for x in gateway.split('.')] | ||||
subnet = [int(x) for x in mask.split('.')] | ||||
payload = { | ||||
"ip": ip, | ||||
"dns": dns, | ||||
"gateway": gateway, | ||||
"subnet": subnet | ||||
} | ||||
req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers) | ||||
|
r236 | try: | ||
answer = req.json() | ||||
|
r243 | if answer['changeip']=='ok': | ||
|
r236 | self.message = '25|IP succesfully changed' | ||
self.ip_address = ip_address | ||||
self.save() | ||||
else: | ||||
self.message = '30|An error ocuur when changing IP' | ||||
except Exception as e: | ||||
self.message = '40|{}'.format(str(e)) | ||||
|
r219 | else: | ||
self.message = 'Not implemented' | ||||
return False | ||||
|
r226 | |||
|
r219 | return True | ||
|
r13 | |||
class Campaign(models.Model): | ||||
|
r162 | template = models.BooleanField(default=False) | ||
|
r85 | name = models.CharField(max_length=60, unique=True) | ||
|
r13 | start_date = models.DateTimeField(blank=True, null=True) | ||
end_date = models.DateTimeField(blank=True, null=True) | ||||
|
r316 | tags = models.CharField(max_length=40, blank=True, null=True) | ||
|
r13 | description = models.TextField(blank=True, null=True) | ||
|
r85 | experiments = models.ManyToManyField('Experiment', blank=True) | ||
|
r316 | author = models.ForeignKey(User, null=True, blank=True) | ||
|
r13 | class Meta: | ||
db_table = 'db_campaigns' | ||||
|
r85 | ordering = ('name',) | ||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r138 | if self.template: | ||
return u'{} (template)'.format(self.name) | ||||
else: | ||||
return u'{}'.format(self.name) | ||||
|
r72 | |||
|
r266 | def jsonify(self): | ||
|
r162 | |||
|
r266 | data = {} | ||
|
r162 | |||
|
r266 | ignored = ('template') | ||
|
r162 | |||
|
r266 | for field in self._meta.fields: | ||
if field.name in ignored: | ||||
continue | ||||
data[field.name] = field.value_from_object(self) | ||||
|
r162 | |||
|
r266 | data['start_date'] = data['start_date'].strftime('%Y-%m-%d') | ||
data['end_date'] = data['end_date'].strftime('%Y-%m-%d') | ||||
|
r162 | |||
|
r266 | return data | ||
|
r162 | |||
|
r266 | def parms_to_dict(self): | ||
|
r162 | |||
r311 | params = Params({}) | |||
|
r266 | params.add(self.jsonify(), 'campaigns') | ||
|
r162 | |||
|
r266 | for exp in Experiment.objects.filter(campaign = self): | ||
params.add(exp.jsonify(), 'experiments') | ||||
configurations = Configuration.objects.filter(experiment=exp, type=0) | ||||
|
r162 | |||
|
r266 | for conf in configurations: | ||
params.add(conf.jsonify(), 'configurations') | ||||
if conf.device.device_type.name=='rc': | ||||
for line in conf.get_lines(): | ||||
params.add(line.jsonify(), 'lines') | ||||
|
r162 | |||
|
r266 | return params.data | ||
|
r162 | |||
|
r109 | def dict_to_parms(self, parms, CONF_MODELS): | ||
|
r162 | |||
|
r109 | experiments = Experiment.objects.filter(campaign = self) | ||
|
r162 | |||
|
r109 | if experiments: | ||
for experiment in experiments: | ||||
experiment.delete() | ||||
|
r162 | |||
|
r266 | for id_exp in parms['experiments']['allIds']: | ||
exp_parms = parms['experiments']['byId'][id_exp] | ||||
dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds() | ||||
exp = Experiment(name='{}'.format(dum)) | ||||
exp.save() | ||||
exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp) | ||||
self.experiments.add(exp) | ||||
camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]] | ||||
self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d')) | ||||
self.start_date = camp_parms['start_date'] | ||||
self.end_date = camp_parms['end_date'] | ||||
self.tags = camp_parms['tags'] | ||||
self.save() | ||||
|
r162 | |||
return self | ||||
|
r267 | def get_experiments_by_radar(self, radar=None): | ||
|
r172 | |||
ret = [] | ||||
|
r196 | if radar: | ||
locations = Location.objects.filter(pk=radar) | ||||
else: | ||||
locations = set([e.location for e in self.experiments.all()]) | ||||
|
r226 | |||
|
r172 | for loc in locations: | ||
dum = {} | ||||
dum['name'] = loc.name | ||||
dum['id'] = loc.pk | ||||
dum['experiments'] = [e for e in self.experiments.all() if e.location==loc] | ||||
ret.append(dum) | ||||
return ret | ||||
|
r108 | def get_absolute_url(self): | ||
return reverse('url_campaign', args=[str(self.id)]) | ||||
|
r162 | |||
|
r108 | def get_absolute_url_edit(self): | ||
return reverse('url_edit_campaign', args=[str(self.id)]) | ||||
|
r162 | |||
|
r316 | def get_absolute_url_delete(self): | ||
return reverse('url_delete_campaign', args=[str(self.id)]) | ||||
|
r100 | def get_absolute_url_export(self): | ||
return reverse('url_export_campaign', args=[str(self.id)]) | ||||
|
r162 | |||
|
r108 | def get_absolute_url_import(self): | ||
return reverse('url_import_campaign', args=[str(self.id)]) | ||||
|
r162 | |||
|
r84 | class RunningExperiment(models.Model): | ||
radar = models.OneToOneField('Location', on_delete=models.CASCADE) | ||||
|
r92 | running_experiment = models.ManyToManyField('Experiment', blank = True) | ||
|
r84 | status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES) | ||
|
r162 | |||
|
r2 | class Experiment(models.Model): | ||
|
r162 | template = models.BooleanField(default=False) | ||
|
r85 | name = models.CharField(max_length=40, default='', unique=True) | ||
|
r53 | location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE) | ||
|
r267 | freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200) | ||
|
r13 | start_time = models.TimeField(default='00:00:00') | ||
end_time = models.TimeField(default='23:59:59') | ||||
r311 | task = models.CharField(max_length=36, default='', blank=True, null=True) | |||
|
r196 | status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES) | ||
|
r316 | author = models.ForeignKey(User, null=True, blank=True) | ||
hash = models.CharField(default='', max_length=64, null=True, blank=True) | ||||
|
r2 | |||
class Meta: | ||||
|
r13 | db_table = 'db_experiments' | ||
|
r91 | ordering = ('template', 'name') | ||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r91 | if self.template: | ||
|
r319 | return u'%s (template)' % (self.name) | ||
|
r91 | else: | ||
|
r319 | return u'%s' % (self.name) | ||
|
r162 | |||
|
r266 | def jsonify(self): | ||
data = {} | ||||
ignored = ('template') | ||||
for field in self._meta.fields: | ||||
if field.name in ignored: | ||||
continue | ||||
data[field.name] = field.value_from_object(self) | ||||
data['start_time'] = data['start_time'].strftime('%H:%M:%S') | ||||
data['end_time'] = data['end_time'].strftime('%H:%M:%S') | ||||
data['location'] = self.location.name | ||||
data['configurations'] = ['{}'.format(conf.pk) for | ||||
|
r306 | conf in Configuration.objects.filter(experiment=self, type=0)] | ||
|
r266 | |||
return data | ||||
|
r89 | @property | ||
|
r138 | def radar_system(self): | ||
|
r89 | return self.location | ||
|
r162 | |||
|
r85 | def clone(self, **kwargs): | ||
|
r162 | |||
|
r85 | confs = Configuration.objects.filter(experiment=self, type=0) | ||
self.pk = None | ||||
|
r316 | self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now()) | ||
|
r85 | for attr, value in kwargs.items(): | ||
setattr(self, attr, value) | ||||
|
r162 | |||
|
r85 | self.save() | ||
|
r162 | |||
|
r85 | for conf in confs: | ||
conf.clone(experiment=self, template=False) | ||||
|
r162 | |||
return self | ||||
|
r196 | def start(self): | ||
''' | ||||
|
r226 | Configure and start experiments's devices | ||
|
r250 | ABS-CGS-DDS-RC-JARS | ||
|
r196 | ''' | ||
|
r226 | |||
r311 | confs = [] | |||
allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence') | ||||
rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix] | ||||
if rc_mix: | ||||
for conf in allconfs: | ||||
if conf.device.device_type.name == 'rc' and not conf.mix: | ||||
continue | ||||
confs.append(conf) | ||||
else: | ||||
confs = allconfs | ||||
|
r329 | |||
try: | ||||
for conf in confs: | ||||
conf.stop_device() | ||||
conf.write_device() | ||||
conf.start_device() | ||||
time.sleep(0.1) | ||||
except: | ||||
return 0 | ||||
return 2 | ||||
|
r226 | |||
|
r250 | |||
|
r226 | def stop(self): | ||
|
r196 | ''' | ||
|
r226 | Stop experiments's devices | ||
|
r250 | DDS-JARS-RC-CGS-ABS | ||
|
r196 | ''' | ||
|
r226 | |||
|
r306 | confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence') | ||
|
r266 | confs=confs.exclude(device__device_type__name='cgs') | ||
|
r329 | try: | ||
for conf in confs: | ||||
conf.stop_device() | ||||
except: | ||||
return 0 | ||||
return 1 | ||||
|
r250 | |||
|
r196 | def get_status(self): | ||
|
r226 | |||
|
r306 | if self.status == 3: | ||
return | ||||
confs = Configuration.objects.filter(experiment=self, type=0) | ||||
|
r243 | |||
|
r240 | for conf in confs: | ||
conf.status_device() | ||||
|
r243 | |||
|
r216 | total = confs.aggregate(models.Sum('device__status'))['device__status__sum'] | ||
|
r162 | |||
|
r196 | if total==2*confs.count(): | ||
status = 1 | ||||
elif total == 3*confs.count(): | ||||
|
r84 | status = 2 | ||
else: | ||||
|
r196 | status = 0 | ||
|
r162 | |||
|
r306 | self.status = status | ||
self.save() | ||||
|
r162 | |||
|
r84 | def status_color(self): | ||
|
r121 | color = 'muted' | ||
|
r84 | if self.status == 0: | ||
color = "danger" | ||||
elif self.status == 1: | ||||
|
r329 | color = "warning" | ||
|
r84 | elif self.status == 2: | ||
|
r91 | color = "success" | ||
|
r84 | elif self.status == 3: | ||
|
r329 | color = "info" | ||
|
r162 | |||
|
r226 | return color | ||
|
r162 | |||
|
r100 | def parms_to_dict(self): | ||
|
r162 | |||
r311 | params = Params({}) | |||
|
r266 | params.add(self.jsonify(), 'experiments') | ||
|
r162 | |||
|
r266 | configurations = Configuration.objects.filter(experiment=self, type=0) | ||
|
r162 | |||
|
r266 | for conf in configurations: | ||
params.add(conf.jsonify(), 'configurations') | ||||
if conf.device.device_type.name=='rc': | ||||
for line in conf.get_lines(): | ||||
params.add(line.jsonify(), 'lines') | ||||
|
r162 | |||
|
r266 | return params.data | ||
|
r162 | |||
|
r266 | def dict_to_parms(self, parms, CONF_MODELS, id_exp=None): | ||
|
r162 | |||
|
r108 | configurations = Configuration.objects.filter(experiment=self) | ||
|
r162 | |||
|
r266 | if id_exp is not None: | ||
exp_parms = parms['experiments']['byId'][id_exp] | ||||
else: | ||||
exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]] | ||||
|
r108 | if configurations: | ||
|
r243 | for configuration in configurations: | ||
configuration.delete() | ||||
|
r266 | |||
for id_conf in exp_parms['configurations']: | ||||
conf_parms = parms['configurations']['byId'][id_conf] | ||||
device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0] | ||||
model = CONF_MODELS[conf_parms['device_type']] | ||||
conf = model( | ||||
experiment = self, | ||||
device = device, | ||||
) | ||||
conf.dict_to_parms(parms, id=id_conf) | ||||
location, created = Location.objects.get_or_create(name=exp_parms['location']) | ||||
self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d')) | ||||
self.location = location | ||||
self.start_time = exp_parms['start_time'] | ||||
self.end_time = exp_parms['end_time'] | ||||
|
r110 | self.save() | ||
|
r162 | |||
|
r110 | return self | ||
|
r226 | |||
|
r196 | def get_absolute_url(self): | ||
return reverse('url_experiment', args=[str(self.id)]) | ||||
|
r162 | |||
|
r108 | def get_absolute_url_edit(self): | ||
return reverse('url_edit_experiment', args=[str(self.id)]) | ||||
|
r162 | |||
|
r316 | def get_absolute_url_delete(self): | ||
return reverse('url_delete_experiment', args=[str(self.id)]) | ||||
|
r108 | def get_absolute_url_import(self): | ||
return reverse('url_import_experiment', args=[str(self.id)]) | ||||
|
r162 | |||
|
r100 | def get_absolute_url_export(self): | ||
return reverse('url_export_experiment', args=[str(self.id)]) | ||||
|
r162 | |||
|
r240 | def get_absolute_url_start(self): | ||
return reverse('url_start_experiment', args=[str(self.id)]) | ||||
def get_absolute_url_stop(self): | ||||
return reverse('url_stop_experiment', args=[str(self.id)]) | ||||
|
r162 | |||
|
r6 | class Configuration(PolymorphicModel): | ||
|
r2 | |||
|
r47 | template = models.BooleanField(default=False) | ||
|
r316 | # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='') | ||
label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True) | ||||
|
r138 | experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE) | ||
device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE) | ||||
|
r21 | type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES) | ||
|
r22 | created_date = models.DateTimeField(auto_now_add=True) | ||
programmed_date = models.DateTimeField(auto_now=True) | ||||
parameters = models.TextField(default='{}') | ||||
|
r316 | author = models.ForeignKey(User, null=True, blank=True) | ||
hash = models.CharField(default='', max_length=64, null=True, blank=True) | ||||
|
r53 | message = "" | ||
|
r162 | |||
|
r2 | class Meta: | ||
|
r13 | db_table = 'db_configurations' | ||
|
r316 | ordering = ('device__device_type__name',) | ||
|
r162 | |||
|
r172 | def __str__(self): | ||
|
r162 | |||
|
r316 | ret = u'{} '.format(self.device.device_type.name.upper()) | ||
|
r162 | |||
|
r172 | if 'mix' in [f.name for f in self._meta.get_fields()]: | ||
|
r138 | if self.mix: | ||
|
r316 | ret = '{} MIX '.format(self.device.device_type.name.upper()) | ||
if 'label' in [f.name for f in self._meta.get_fields()]: | ||||
|
r319 | ret += '{}'.format(self.label) | ||
|
r162 | |||
|
r138 | if self.template: | ||
|
r316 | ret += ' (template)' | ||
return ret | ||||
@property | ||||
def name(self): | ||||
return str(self) | ||||
|
r79 | |||
|
r266 | def jsonify(self): | ||
data = {} | ||||
ignored = ('type', 'polymorphic_ctype', 'configuration_ptr', | ||||
'created_date', 'programmed_date', 'template', 'device', | ||||
'experiment') | ||||
for field in self._meta.fields: | ||||
if field.name in ignored: | ||||
continue | ||||
data[field.name] = field.value_from_object(self) | ||||
data['device_type'] = self.device.device_type.name | ||||
if self.device.device_type.name == 'rc': | ||||
data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()] | ||||
data['delays'] = self.get_delays() | ||||
data['pulses'] = self.get_pulses() | ||||
elif self.device.device_type.name == 'jars': | ||||
data['decode_type'] = DECODE_TYPE[self.decode_data][1] | ||||
elif self.device.device_type.name == 'dds': | ||||
data['frequencyA_Mhz'] = float(data['frequencyA_Mhz']) | ||||
data['frequencyB_Mhz'] = float(data['frequencyB_Mhz']) | ||||
data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees']) | ||||
data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees']) | ||||
return data | ||||
|
r85 | def clone(self, **kwargs): | ||
|
r162 | |||
|
r85 | self.pk = None | ||
self.id = None | ||||
for attr, value in kwargs.items(): | ||||
setattr(self, attr, value) | ||||
|
r162 | |||
self.save() | ||||
|
r85 | |||
return self | ||||
|
r162 | |||
|
r53 | def parms_to_dict(self): | ||
|
r162 | |||
r311 | params = Params({}) | |||
|
r266 | params.add(self.jsonify(), 'configurations') | ||
|
r162 | |||
|
r266 | if self.device.device_type.name=='rc': | ||
for line in self.get_lines(): | ||||
params.add(line.jsonify(), 'lines') | ||||
|
r162 | |||
|
r266 | return params.data | ||
|
r162 | |||
|
r57 | def parms_to_text(self): | ||
|
r162 | |||
|
r172 | raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()) | ||
|
r162 | |||
|
r57 | def parms_to_binary(self): | ||
|
r162 | |||
|
r172 | raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()) | ||
|
r162 | |||
|
r266 | def dict_to_parms(self, parameters, id=None): | ||
params = Params(parameters) | ||||
if id: | ||||
data = params.get_conf(id_conf=id) | ||||
else: | ||||
data = params.get_conf(dtype=self.device.device_type.name) | ||||
|
r162 | |||
|
r266 | if data['device_type']=='rc': | ||
self.clean_lines() | ||||
lines = data.pop('lines', None) | ||||
for line_id in lines: | ||||
pass | ||||
|
r162 | |||
|
r266 | for key, value in data.items(): | ||
if key not in ('id', 'device_type'): | ||||
setattr(self, key, value) | ||||
|
r162 | |||
|
r266 | self.save() | ||
|
r162 | |||
|
r267 | |||
def export_to_file(self, format="json"): | ||||
|
r162 | |||
|
r57 | content_type = '' | ||
|
r162 | |||
|
r276 | if format == 'racp': | ||
content_type = 'text/plain' | ||||
filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp') | ||||
content = self.parms_to_text(file_format = 'racp') | ||||
|
r53 | if format == 'text': | ||
content_type = 'text/plain' | ||||
|
r57 | filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name) | ||
content = self.parms_to_text() | ||||
|
r162 | |||
|
r53 | if format == 'binary': | ||
content_type = 'application/octet-stream' | ||||
|
r266 | filename = '%s_%s.bin' %(self.device.device_type.name, self.name) | ||
|
r57 | content = self.parms_to_binary() | ||
|
r162 | |||
|
r57 | if not content_type: | ||
content_type = 'application/json' | ||||
filename = '%s_%s.json' %(self.device.device_type.name, self.name) | ||||
|
r79 | content = json.dumps(self.parms_to_dict(), indent=2) | ||
|
r162 | |||
|
r53 | fields = {'content_type':content_type, | ||
'filename':filename, | ||||
'content':content | ||||
} | ||||
|
r162 | |||
|
r53 | return fields | ||
|
r162 | |||
|
r267 | def import_from_file(self, fp): | ||
|
r162 | |||
|
r57 | parms = {} | ||
|
r162 | |||
|
r57 | path, ext = os.path.splitext(fp.name) | ||
|
r162 | |||
|
r57 | if ext == '.json': | ||
parms = json.load(fp) | ||||
|
r162 | |||
|
r266 | if ext == '.dds': | ||
lines = fp.readlines() | ||||
parms = dds_data.text_to_dict(lines) | ||||
if ext == '.racp': | ||||
|
r275 | if self.device.device_type.name == 'jars': | ||
parms = RacpFile(fp).to_dict() | ||||
parms['filter_parms'] = json.loads(self.filter_parms) | ||||
return parms | ||||
|
r266 | parms = RCFile(fp).to_dict() | ||
|
r57 | return parms | ||
|
r162 | |||
|
r53 | def status_device(self): | ||
|
r162 | |||
|
r185 | self.message = 'Function not implemented' | ||
return False | ||||
|
r162 | |||
|
r53 | def stop_device(self): | ||
|
r162 | |||
|
r185 | self.message = 'Function not implemented' | ||
return False | ||||
|
r162 | |||
|
r53 | def start_device(self): | ||
|
r162 | |||
|
r185 | self.message = 'Function not implemented' | ||
return False | ||||
|
r162 | |||
|
r53 | def write_device(self, parms): | ||
|
r162 | |||
|
r185 | self.message = 'Function not implemented' | ||
return False | ||||
|
r162 | |||
|
r53 | def read_device(self): | ||
|
r162 | |||
|
r185 | self.message = 'Function not implemented' | ||
return False | ||||
|
r162 | |||
|
r47 | def get_absolute_url(self): | ||
|
r23 | return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)]) | ||
|
r162 | |||
|
r30 | def get_absolute_url_edit(self): | ||
return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)]) | ||||
|
r162 | |||
|
r316 | def get_absolute_url_delete(self): | ||
return reverse('url_delete_dev_conf', args=[str(self.id)]) | ||||
|
r30 | def get_absolute_url_import(self): | ||
|
r53 | return reverse('url_import_dev_conf', args=[str(self.id)]) | ||
|
r162 | |||
|
r30 | def get_absolute_url_export(self): | ||
|
r53 | return reverse('url_export_dev_conf', args=[str(self.id)]) | ||
|
r162 | |||
|
r30 | def get_absolute_url_write(self): | ||
|
r53 | return reverse('url_write_dev_conf', args=[str(self.id)]) | ||
|
r162 | |||
|
r30 | def get_absolute_url_read(self): | ||
|
r53 | return reverse('url_read_dev_conf', args=[str(self.id)]) | ||
|
r162 | |||
|
r53 | def get_absolute_url_start(self): | ||
return reverse('url_start_dev_conf', args=[str(self.id)]) | ||||
|
r162 | |||
|
r53 | def get_absolute_url_stop(self): | ||
return reverse('url_stop_dev_conf', args=[str(self.id)]) | ||||
|
r162 | |||
|
r53 | def get_absolute_url_status(self): | ||
|
r162 | return reverse('url_status_dev_conf', args=[str(self.id)]) | ||