from django.shortcuts import render, redirect, get_object_or_404, HttpResponse from datetime import datetime from django.db import models from polymorphic import PolymorphicModel from django.core.urlresolvers import reverse CONF_STATES = ( (0, 'Disconnected'), (1, 'Connected'), (2, 'Running'), ) EXP_STATES = ( (0,'Error'), #RED (1,'Configured'), #BLUE (2,'Running'), #GREEN (3,'Waiting'), #YELLOW (4,'Not Configured'), #WHITE ) CONF_TYPES = ( (0, 'Active'), (1, 'Historical'), ) DEV_STATES = ( (0, 'No connected'), (1, 'Connected'), (2, 'Configured'), (3, 'Running'), ) DEV_TYPES = ( ('', 'Select a device type'), ('rc', 'Radar Controller'), ('rc_mix', 'Radar Controller (Mix)'), ('dds', 'Direct Digital Synthesizer'), ('jars', 'Jicamarca Radar Acquisition System'), ('usrp', 'Universal Software Radio Peripheral'), ('cgs', 'Clock Generator System'), ('abs', 'Automatic Beam Switching'), ) DEV_PORTS = { 'rc' : 2000, 'rc_mix': 2000, 'dds' : 2000, 'jars' : 2000, 'usrp' : 2000, 'cgs' : 8080, 'abs' : 8080 } RADAR_STATES = ( (0, 'No connected'), (1, 'Connected'), (2, 'Configured'), (3, 'Running'), (4, 'Scheduled'), ) # Create your models here. class Location(models.Model): name = models.CharField(max_length = 30) description = models.TextField(blank=True, null=True) class Meta: db_table = 'db_location' def __unicode__(self): return u'%s' % self.name def get_absolute_url(self): return reverse('url_location', args=[str(self.id)]) class DeviceType(models.Model): name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc') description = models.TextField(blank=True, null=True) class Meta: db_table = 'db_device_types' def __unicode__(self): return u'%s' % self.get_name_display() class Device(models.Model): device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE) location = models.ForeignKey(Location, on_delete=models.CASCADE) name = models.CharField(max_length=40, default='') ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0') port_address = models.PositiveSmallIntegerField(default=2000) description = models.TextField(blank=True, null=True) status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES) class Meta: db_table = 'db_devices' def __unicode__(self): return u'[{}]: {}'.format(self.device_type.name.upper(), self.name) def get_status(self): return self.status @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" return color def get_absolute_url(self): return reverse('url_device', args=[str(self.id)]) class Campaign(models.Model): template = models.BooleanField(default=False) name = models.CharField(max_length=60, unique=True) start_date = models.DateTimeField(blank=True, null=True) end_date = models.DateTimeField(blank=True, null=True) tags = models.CharField(max_length=40) description = models.TextField(blank=True, null=True) experiments = models.ManyToManyField('Experiment', blank=True) class Meta: db_table = 'db_campaigns' ordering = ('name',) def __unicode__(self): if self.template: return u'{} (template)'.format(self.name) else: return u'{}'.format(self.name) def parms_to_dict(self): import json parameters = {} exp_parameters = {} experiments = Experiment.objects.filter(campaign = self) i=1 for experiment in experiments: exp_parameters['experiment-'+str(i)] = json.loads(experiment.parms_to_dict()) i += 1 parameters['experiments'] = exp_parameters parameters['end_date'] = self.end_date.strftime("%Y-%m-%d") parameters['start_date'] = self.start_date.strftime("%Y-%m-%d") parameters['campaign'] = self.__unicode__() parameters['tags'] =self.tags parameters = json.dumps(parameters, indent=2, sort_keys=False) return parameters def import_from_file(self, fp): import os, json parms = {} path, ext = os.path.splitext(fp.name) if ext == '.json': parms = json.load(fp) return parms def dict_to_parms(self, parms, CONF_MODELS): experiments = Experiment.objects.filter(campaign = self) configurations = Configuration.objects.filter(experiment = experiments) if configurations: for configuration in configurations: configuration.delete() if experiments: for experiment in experiments: experiment.delete() for parms_exp in parms['experiments']: location = Location.objects.get(name = parms['experiments'][parms_exp]['radar']) new_exp = Experiment( name = parms['experiments'][parms_exp]['experiment'], location = location, start_time = parms['experiments'][parms_exp]['start_time'], end_time = parms['experiments'][parms_exp]['end_time'], ) new_exp.save() new_exp.dict_to_parms(parms['experiments'][parms_exp],CONF_MODELS) new_exp.save() self.name = parms['campaign'] self.start_date = parms['start_date'] self.end_date = parms['end_date'] self.tags = parms['tags'] self.experiments.add(new_exp) self.save() return self def get_absolute_url(self): return reverse('url_campaign', args=[str(self.id)]) def get_absolute_url_edit(self): return reverse('url_edit_campaign', args=[str(self.id)]) def get_absolute_url_export(self): return reverse('url_export_campaign', args=[str(self.id)]) def get_absolute_url_import(self): return reverse('url_import_campaign', args=[str(self.id)]) class RunningExperiment(models.Model): radar = models.OneToOneField('Location', on_delete=models.CASCADE) running_experiment = models.ManyToManyField('Experiment', blank = True) status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES) class Experiment(models.Model): template = models.BooleanField(default=False) name = models.CharField(max_length=40, default='', unique=True) location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE) start_time = models.TimeField(default='00:00:00') end_time = models.TimeField(default='23:59:59') status = models.PositiveSmallIntegerField(default=0, choices=EXP_STATES) class Meta: db_table = 'db_experiments' ordering = ('template', 'name') def __unicode__(self): if self.template: return u'%s (template)' % (self.name) else: return u'%s' % (self.name) @property def radar_system(self): return self.location def clone(self, **kwargs): confs = Configuration.objects.filter(experiment=self, type=0) self.pk = None self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now()) for attr, value in kwargs.items(): setattr(self, attr, value) self.save() for conf in confs: conf.clone(experiment=self, template=False) return self def get_status(self): configurations = Configuration.objects.filter(experiment=self) exp_status=[] for conf in configurations: print conf.status_device() exp_status.append(conf.status_device()) if not exp_status: #No Configuration self.status = 4 self.save() return total = 1 for e_s in exp_status: total = total*e_s if total == 0: #Error status = 0 elif total == (3**len(exp_status)): #Running status = 2 else: status = 1 #Configurated self.status = status self.save() def status_color(self): color = 'muted' if self.status == 0: color = "danger" elif self.status == 1: color = "info" elif self.status == 2: color = "success" elif self.status == 3: color = "warning" return color def get_absolute_url(self): return reverse('url_experiment', args=[str(self.id)]) def parms_to_dict(self): import json configurations = Configuration.objects.filter(experiment=self) conf_parameters = {} parameters={} for configuration in configurations: if 'cgs' in configuration.device.device_type.name: conf_parameters['cgs'] = configuration.parms_to_dict() if 'dds' in configuration.device.device_type.name: conf_parameters['dds'] = configuration.parms_to_dict() if 'rc' in configuration.device.device_type.name: conf_parameters['rc'] = configuration.parms_to_dict() if 'jars' in configuration.device.device_type.name: conf_parameters['jars'] = configuration.parms_to_dict() if 'usrp' in configuration.device.device_type.name: conf_parameters['usrp'] = configuration.parms_to_dict() if 'abs' in configuration.device.device_type.name: conf_parameters['abs'] = configuration.parms_to_dict() parameters['configurations'] = conf_parameters parameters['end_time'] = self.end_time.strftime("%H:%M:%S") parameters['start_time'] = self.start_time.strftime("%H:%M:%S") parameters['radar'] = self.radar_system.name parameters['experiment'] = self.name parameters = json.dumps(parameters, indent=2) return parameters def import_from_file(self, fp): import os, json parms = {} path, ext = os.path.splitext(fp.name) if ext == '.json': parms = json.load(fp) return parms def dict_to_parms(self, parms, CONF_MODELS): configurations = Configuration.objects.filter(experiment=self) if configurations: for configuration in configurations: configuration.delete() for conf_type in parms['configurations']: #--For ABS Device: #--For USRP Device: #--For JARS Device: if conf_type == 'jars': device = get_object_or_404(Device, pk=parms['configurations']['jars']['device_id']) DevConfModel = CONF_MODELS[conf_type] confjars_form = DevConfModel( experiment = self, name = 'JARS', device=device, ) confjars_form.dict_to_parms(parms['configurations']['jars']) confjars_form.save() #--For RC Device: if conf_type == 'rc': device = get_object_or_404(Device, pk=parms['configurations']['rc']['device_id']) DevConfModel = CONF_MODELS[conf_type] confrc_form = DevConfModel( experiment = self, name = 'RC', device=device, ) confrc_form.dict_to_parms(parms['configurations']['rc']) confrc_form.save() #--For DDS Device: if conf_type == 'dds': device = get_object_or_404(Device, pk=parms['configurations']['dds']['device_id']) DevConfModel = CONF_MODELS[conf_type] confdds_form = DevConfModel( experiment = self, name = 'DDS', device=device, ) confdds_form.dict_to_parms(parms['configurations']['dds']) confdds_form.save() #--For CGS Device: if conf_type == 'cgs': device = get_object_or_404(Device, pk=parms['configurations']['cgs']['device_id']) DevConfModel = CONF_MODELS[conf_type] confcgs_form = DevConfModel( experiment = self, name = 'CGS', device=device, ) confcgs_form.dict_to_parms(parms['configurations']['cgs']) confcgs_form.save() location = Location.objects.get(name = parms['radar']) self.name = parms['experiment'] self.location = location self.start_time = parms['start_time'] self.end_time = parms['end_time'] self.save() return self def get_absolute_url_edit(self): return reverse('url_edit_experiment', args=[str(self.id)]) def get_absolute_url_import(self): return reverse('url_import_experiment', args=[str(self.id)]) def get_absolute_url_export(self): return reverse('url_export_experiment', args=[str(self.id)]) class Configuration(PolymorphicModel): template = models.BooleanField(default=False) name = models.CharField(verbose_name="Configuration Name", max_length=40, default='') 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) type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES) created_date = models.DateTimeField(auto_now_add=True) programmed_date = models.DateTimeField(auto_now=True) parameters = models.TextField(default='{}') message = "" class Meta: db_table = 'db_configurations' def __unicode__(self): device = '{}:'.format(self.device.device_type.name.upper()) if 'mix' in self._meta.get_all_field_names(): if self.mix: device = '{} MIXED:'.format(self.device.device_type.name.upper()) if self.template: return u'{} {} (template)'.format(device, self.name) else: return u'{} {}'.format(device, self.name) def clone(self, **kwargs): self.pk = None self.id = None for attr, value in kwargs.items(): setattr(self, attr, value) self.save() return self def parms_to_dict(self): parameters = {} for key in self.__dict__.keys(): parameters[key] = getattr(self, key) return parameters def parms_to_text(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return '' def parms_to_binary(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return '' def dict_to_parms(self, parameters): if type(parameters) != type({}): return for key in parameters.keys(): setattr(self, key, parameters[key]) def export_to_file(self, format="json"): import json content_type = '' if format == 'text': content_type = 'text/plain' filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name) content = self.parms_to_text() if format == 'binary': content_type = 'application/octet-stream' filename = '%s_%s.bin' %(self.device.device_type.name, self.name) content = self.parms_to_binary() if not content_type: content_type = 'application/json' filename = '%s_%s.json' %(self.device.device_type.name, self.name) content = json.dumps(self.parms_to_dict(), indent=2) fields = {'content_type':content_type, 'filename':filename, 'content':content } return fields def import_from_file(self, fp): import os, json parms = {} path, ext = os.path.splitext(fp.name) if ext == '.json': parms = json.load(fp) return parms def status_device(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return None def stop_device(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return None def start_device(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return None def write_device(self, parms): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return None def read_device(self): raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper() return None def get_absolute_url(self): return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)]) def get_absolute_url_edit(self): return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)]) def get_absolute_url_import(self): return reverse('url_import_dev_conf', args=[str(self.id)]) def get_absolute_url_export(self): return reverse('url_export_dev_conf', args=[str(self.id)]) def get_absolute_url_write(self): return reverse('url_write_dev_conf', args=[str(self.id)]) def get_absolute_url_read(self): return reverse('url_read_dev_conf', args=[str(self.id)]) def get_absolute_url_start(self): return reverse('url_start_dev_conf', args=[str(self.id)]) def get_absolute_url_stop(self): return reverse('url_stop_dev_conf', args=[str(self.id)]) def get_absolute_url_status(self): return reverse('url_status_dev_conf', args=[str(self.id)])