models.py
229 lines
| 7.5 KiB
| text/x-python
|
PythonLexer
|
r0 | from django.db import models | ||
|
r6 | from apps.main.models import Configuration | ||
|
r0 | # Create your models here. | ||
|
r6 | |||
|
r12 | from django.core.validators import MinValueValidator, MaxValueValidator | ||
|
r26 | from django.core.exceptions import ValidationError | ||
|
r12 | |||
|
r57 | from devices.dds import api, data | ||
|
r32 | |||
|
r55 | ENABLE_TYPE = ( | ||
(False, 'Disabled'), | ||||
(True, 'Enabled'), | ||||
) | ||||
|
r13 | MOD_TYPES = ( | ||
|
r55 | (0, 'Single Tone'), | ||
(1, 'FSK'), | ||||
(2, 'Ramped FSK'), | ||||
(3, 'Chirp'), | ||||
(4, 'BPSK'), | ||||
) | ||||
|
r172 | |||
|
r6 | class DDSConfiguration(Configuration): | ||
|
r172 | |||
|
r26 | DDS_NBITS = 48 | ||
|
r172 | |||
|
r145 | clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60) | ||
|
r13 | multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4) | ||
|
r26 | |||
|
r97 | frequencyA_Mhz = models.DecimalField(verbose_name='Frequency A (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True, default=49.9200) | ||
frequencyA = models.BigIntegerField(verbose_name='Frequency A (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True) | ||||
|
r55 | |||
frequencyB_Mhz = models.DecimalField(verbose_name='Frequency B (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True) | ||||
frequencyB = models.BigIntegerField(verbose_name='Frequency B (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True) | ||||
|
r172 | |||
|
r55 | phaseA_degrees = models.FloatField(verbose_name='Phase A (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0) | ||
|
r172 | |||
|
r57 | phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True) | ||
|
r172 | |||
|
r30 | modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0) | ||
|
r172 | |||
|
r55 | amplitude_enabled = models.BooleanField(verbose_name='Amplitude Control', choices=ENABLE_TYPE, default=False) | ||
|
r172 | |||
|
r55 | amplitudeI = models.PositiveIntegerField(verbose_name='Amplitude CH1',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True) | ||
amplitudeQ = models.PositiveIntegerField(verbose_name='Amplitude CH2',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True) | ||||
|
r172 | |||
|
r26 | def get_nbits(self): | ||
|
r172 | |||
|
r26 | return self.DDS_NBITS | ||
|
r172 | |||
|
r26 | def clean(self): | ||
|
r172 | |||
|
r26 | if self.modulation in [1,2,3]: | ||
|
r55 | if self.frequencyB is None or self.frequencyB_Mhz is None: | ||
|
r26 | raise ValidationError({ | ||
|
r55 | 'frequencyB': 'Frequency modulation has to be defined when FSK or Chirp modulation is selected' | ||
|
r26 | }) | ||
|
r172 | |||
|
r26 | if self.modulation in [4,]: | ||
|
r55 | if self.phaseB_degrees is None: | ||
|
r26 | raise ValidationError({ | ||
|
r55 | 'phaseB': 'Phase modulation has to be defined when BPSK modulation is selected' | ||
|
r26 | }) | ||
|
r172 | |||
|
r57 | self.frequencyA_Mhz = data.binary_to_freq(self.frequencyA, self.clock*self.multiplier) | ||
self.frequencyB_Mhz = data.binary_to_freq(self.frequencyB, self.clock*self.multiplier) | ||||
|
r172 | |||
|
r26 | def verify_frequencies(self): | ||
|
r172 | |||
|
r26 | return True | ||
|
r172 | |||
|
r55 | def parms_to_dict(self): | ||
|
r172 | |||
|
r55 | parameters = {} | ||
|
r172 | |||
|
r108 | parameters['device_id'] = self.device.id | ||
|
r172 | |||
|
r55 | parameters['clock'] = float(self.clock) | ||
parameters['multiplier'] = int(self.multiplier) | ||||
|
r172 | |||
|
r55 | parameters['frequencyA'] = int(self.frequencyA) | ||
|
r57 | parameters['frequencyA_Mhz'] = float(self.frequencyA_Mhz) | ||
|
r172 | |||
|
r55 | parameters['phaseA'] = data.phase_to_binary(self.phaseA_degrees) | ||
parameters['phaseA_degrees'] = float(self.phaseA_degrees) | ||||
|
r172 | |||
|
r55 | parameters['modulation'] = int(self.modulation) | ||
|
r57 | parameters['amplitude_enabled'] = bool(self.amplitude_enabled) | ||
|
r172 | |||
|
r57 | if self.frequencyB: | ||
parameters['frequencyB'] = int(self.frequencyB) | ||||
parameters['frequencyB_Mhz'] = float(self.frequencyB_Mhz) | ||||
else: | ||||
parameters['frequencyB'] = 0 | ||||
parameters['frequencyB_Mhz'] = 0 | ||||
|
r172 | |||
|
r57 | if self.phaseB_degrees: | ||
parameters['phaseB_degrees'] = float(self.phaseB_degrees) | ||||
parameters['phaseB'] = data.phase_to_binary(self.phaseB_degrees) | ||||
else: | ||||
parameters['phaseB_degrees'] = 0 | ||||
parameters['phaseB'] = 0 | ||||
|
r172 | |||
|
r55 | if self.amplitudeI: | ||
parameters['amplitudeI'] = int(self.amplitudeI) | ||||
else: | ||||
parameters['amplitudeI'] = 0 | ||||
|
r172 | |||
|
r55 | if self.amplitudeQ: | ||
parameters['amplitudeQ'] = int(self.amplitudeQ) | ||||
else: | ||||
parameters['amplitudeQ'] = 0 | ||||
|
r172 | |||
|
r55 | return parameters | ||
|
r172 | |||
|
r57 | def parms_to_text(self): | ||
|
r172 | |||
|
r57 | my_dict = self.parms_to_dict() | ||
|
r172 | |||
|
r57 | text = data.dict_to_text(my_dict) | ||
|
r172 | |||
|
r57 | return text | ||
|
r172 | |||
|
r55 | def dict_to_parms(self, parameters): | ||
|
r172 | |||
|
r55 | self.clock = parameters['clock'] | ||
self.multiplier = parameters['multiplier'] | ||||
self.frequencyA = parameters['frequencyA'] | ||||
self.frequencyB = parameters['frequencyB'] | ||||
self.frequencyA_Mhz = parameters['frequencyA_Mhz'] | ||||
self.frequencyB_Mhz = parameters['frequencyB_Mhz'] | ||||
self.phaseA_degrees = parameters['phaseA_degrees'] | ||||
self.phaseB_degrees = parameters['phaseB_degrees'] | ||||
self.modulation = parameters['modulation'] | ||||
self.amplitude_enabled = parameters['amplitude_enabled'] | ||||
|
r172 | |||
|
r55 | def import_from_file(self, fp): | ||
|
r172 | |||
|
r57 | import os, json | ||
|
r172 | |||
|
r55 | parms = {} | ||
|
r172 | |||
|
r57 | path, ext = os.path.splitext(fp.name) | ||
|
r172 | |||
|
r55 | if ext == '.json': | ||
|
r57 | parms = json.load(fp) | ||
|
r172 | |||
|
r55 | if ext == '.dds': | ||
|
r57 | lines = fp.readlines() | ||
parms = data.text_to_dict(lines) | ||||
|
r172 | |||
|
r55 | return parms | ||
|
r172 | |||
|
r55 | def status_device(self): | ||
|
r172 | |||
|
r55 | answer = api.status(ip = self.device.ip_address, | ||
port = self.device.port_address) | ||||
|
r172 | |||
|
r55 | self.device.status = int(answer[0]) | ||
self.message = answer[2:] | ||||
|
r172 | |||
|
r55 | self.device.save() | ||
|
r172 | |||
|
r55 | return self.device.status | ||
|
r172 | |||
|
r55 | def reset_device(self): | ||
|
r172 | |||
|
r55 | answer = api.reset(ip = self.device.ip_address, | ||
port = self.device.port_address) | ||||
|
r172 | |||
|
r55 | if answer[0] != "1": | ||
self.message = answer[0:] | ||||
return 0 | ||||
|
r172 | |||
|
r55 | self.message = answer[2:] | ||
return 1 | ||||
|
r172 | |||
|
r55 | def stop_device(self): | ||
|
r172 | |||
|
r55 | answer = api.disable_rf(ip = self.device.ip_address, | ||
port = self.device.port_address) | ||||
|
r172 | |||
|
r55 | if answer[0] != "1": | ||
self.message = answer[0:] | ||||
return 0 | ||||
|
r172 | |||
|
r55 | self.message = answer[2:] | ||
return 1 | ||||
|
r172 | |||
|
r55 | def start_device(self): | ||
|
r172 | |||
|
r55 | answer = api.enable_rf(ip = self.device.ip_address, | ||
port = self.device.port_address) | ||||
|
r172 | |||
|
r55 | if answer[0] != "1": | ||
self.message = answer[0:] | ||||
return 0 | ||||
|
r172 | |||
|
r55 | self.message = answer[2:] | ||
return 1 | ||||
|
r172 | |||
|
r55 | def read_device(self): | ||
|
r172 | |||
|
r55 | parms = api.read_config(ip = self.device.ip_address, | ||
port = self.device.port_address) | ||||
|
r172 | |||
|
r55 | if not parms: | ||
self.message = "Could not read DDS parameters from this device" | ||||
return parms | ||||
|
r172 | |||
|
r55 | self.message = "" | ||
return parms | ||||
|
r172 | |||
|
r55 | def write_device(self): | ||
|
r172 | |||
|
r55 | answer = api.write_config(ip = self.device.ip_address, | ||
port = self.device.port_address, | ||||
parms = self.parms_to_dict()) | ||||
|
r172 | |||
|
r55 | if answer[0] != "1": | ||
self.message = answer[0:] | ||||
return 0 | ||||
|
r172 | |||
|
r55 | self.message = answer[2:] | ||
return 1 | ||||
|
r172 | |||
|
r6 | class Meta: | ||
db_table = 'dds_configurations' | ||||