##// END OF EJS Templates
Add profile model to user
Juan C. Espinoza -
r319:f3ab02e8e413
parent child
Show More
@@ -1,10 +1,11
1 from django.contrib import admin
1 from django.contrib import admin
2 from .models import Device, DeviceType, Experiment, Campaign, Location, RunningExperiment
2 from .models import Device, DeviceType, Experiment, Campaign, Location, RunningExperiment, Profile
3
3
4 # Register your models here.
4 # Register your models here.
5 admin.site.register(Campaign)
5 admin.site.register(Campaign)
6 admin.site.register(Experiment)
6 admin.site.register(Experiment)
7 admin.site.register(Device)
7 admin.site.register(Device)
8 admin.site.register(DeviceType)
8 admin.site.register(DeviceType)
9 admin.site.register(Location)
9 admin.site.register(Location)
10 admin.site.register(RunningExperiment)
10 admin.site.register(RunningExperiment)
11 admin.site.register(Profile) No newline at end of file
@@ -1,794 +1,809
1
1
2 import os
2 import os
3 import json
3 import json
4 import requests
4 import requests
5 import time
5 import time
6 from datetime import datetime
6 from datetime import datetime
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.core.urlresolvers import reverse
15 from django.core.urlresolvers import reverse
16 from django.core.validators import MinValueValidator, MaxValueValidator
16 from django.core.validators import MinValueValidator, MaxValueValidator
17 from django.shortcuts import get_object_or_404
17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 from django.contrib.auth.models import User
19 from django.db.models.signals import post_save
20 from django.dispatch import receiver
19
21
20 from apps.main.utils import Params
22 from apps.main.utils import Params
21 from apps.rc.utils import RCFile
23 from apps.rc.utils import RCFile
22 from apps.jars.utils import RacpFile
24 from apps.jars.utils import RacpFile
23 from devices.dds import api as dds_api
25 from devices.dds import api as dds_api
24 from devices.dds import data as dds_data
26 from devices.dds import data as dds_data
25
27
26
28
27 DEV_PORTS = {
29 DEV_PORTS = {
28 'rc' : 2000,
30 'rc' : 2000,
29 'dds' : 2000,
31 'dds' : 2000,
30 'jars' : 2000,
32 'jars' : 2000,
31 'usrp' : 2000,
33 'usrp' : 2000,
32 'cgs' : 8080,
34 'cgs' : 8080,
33 'abs' : 8080
35 'abs' : 8080
34 }
36 }
35
37
36 RADAR_STATES = (
38 RADAR_STATES = (
37 (0, 'No connected'),
39 (0, 'No connected'),
38 (1, 'Connected'),
40 (1, 'Connected'),
39 (2, 'Configured'),
41 (2, 'Configured'),
40 (3, 'Running'),
42 (3, 'Running'),
41 (4, 'Scheduled'),
43 (4, 'Scheduled'),
42 )
44 )
43
45
44 EXPERIMENT_TYPE = (
46 EXPERIMENT_TYPE = (
45 (0, 'RAW_DATA'),
47 (0, 'RAW_DATA'),
46 (1, 'PDATA'),
48 (1, 'PDATA'),
47 )
49 )
48
50
49 DECODE_TYPE = (
51 DECODE_TYPE = (
50 (0, 'None'),
52 (0, 'None'),
51 (1, 'TimeDomain'),
53 (1, 'TimeDomain'),
52 (2, 'FreqDomain'),
54 (2, 'FreqDomain'),
53 (3, 'InvFreqDomain'),
55 (3, 'InvFreqDomain'),
54 )
56 )
55
57
56 DEV_STATES = (
58 DEV_STATES = (
57 (0, 'No connected'),
59 (0, 'No connected'),
58 (1, 'Connected'),
60 (1, 'Connected'),
59 (2, 'Configured'),
61 (2, 'Configured'),
60 (3, 'Running'),
62 (3, 'Running'),
61 (4, 'Unknown'),
63 (4, 'Unknown'),
62 )
64 )
63
65
64 DEV_TYPES = (
66 DEV_TYPES = (
65 ('', 'Select a device type'),
67 ('', 'Select a device type'),
66 ('rc', 'Radar Controller'),
68 ('rc', 'Radar Controller'),
67 ('dds', 'Direct Digital Synthesizer'),
69 ('dds', 'Direct Digital Synthesizer'),
68 ('jars', 'Jicamarca Radar Acquisition System'),
70 ('jars', 'Jicamarca Radar Acquisition System'),
69 ('usrp', 'Universal Software Radio Peripheral'),
71 ('usrp', 'Universal Software Radio Peripheral'),
70 ('cgs', 'Clock Generator System'),
72 ('cgs', 'Clock Generator System'),
71 ('abs', 'Automatic Beam Switching'),
73 ('abs', 'Automatic Beam Switching'),
72 )
74 )
73
75
74 EXP_STATES = (
76 EXP_STATES = (
75 (0,'Error'), #RED
77 (0,'Error'), #RED
76 (1,'Configured'), #BLUE
78 (1,'Configured'), #BLUE
77 (2,'Running'), #GREEN
79 (2,'Running'), #GREEN
78 (3,'Scheduled'), #YELLOW
80 (3,'Scheduled'), #YELLOW
79 (4,'Not Configured'), #WHITE
81 (4,'Not Configured'), #WHITE
80 )
82 )
81
83
82 CONF_TYPES = (
84 CONF_TYPES = (
83 (0, 'Active'),
85 (0, 'Active'),
84 (1, 'Historical'),
86 (1, 'Historical'),
85 )
87 )
86
88
89 class Profile(models.Model):
90 user = models.OneToOneField(User, on_delete=models.CASCADE)
91 theme = models.CharField(max_length=30, default='yeti')
92
93 @receiver(post_save, sender=User)
94 def create_user_profile(sender, instance, created, **kwargs):
95 if created:
96 Profile.objects.create(user=instance)
97
98 @receiver(post_save, sender=User)
99 def save_user_profile(sender, instance, **kwargs):
100 instance.profile.save()
101
102
87 class Location(models.Model):
103 class Location(models.Model):
88
104
89 name = models.CharField(max_length = 30)
105 name = models.CharField(max_length = 30)
90 description = models.TextField(blank=True, null=True)
106 description = models.TextField(blank=True, null=True)
91
107
92 class Meta:
108 class Meta:
93 db_table = 'db_location'
109 db_table = 'db_location'
94
110
95 def __str__(self):
111 def __str__(self):
96 return u'%s' % self.name
112 return u'%s' % self.name
97
113
98 def get_absolute_url(self):
114 def get_absolute_url(self):
99 return reverse('url_location', args=[str(self.id)])
115 return reverse('url_location', args=[str(self.id)])
100
116
101
117
102 class DeviceType(models.Model):
118 class DeviceType(models.Model):
103
119
104 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
120 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
105 sequence = models.PositiveSmallIntegerField(default=1000)
121 sequence = models.PositiveSmallIntegerField(default=1000)
106 description = models.TextField(blank=True, null=True)
122 description = models.TextField(blank=True, null=True)
107
123
108 class Meta:
124 class Meta:
109 db_table = 'db_device_types'
125 db_table = 'db_device_types'
110
126
111 def __str__(self):
127 def __str__(self):
112 return u'%s' % self.get_name_display()
128 return u'%s' % self.get_name_display()
113
129
114 class Device(models.Model):
130 class Device(models.Model):
115
131
116 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
132 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
117 location = models.ForeignKey(Location, on_delete=models.CASCADE)
133 location = models.ForeignKey(Location, on_delete=models.CASCADE)
118 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
134 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
119 port_address = models.PositiveSmallIntegerField(default=2000)
135 port_address = models.PositiveSmallIntegerField(default=2000)
120 description = models.TextField(blank=True, null=True)
136 description = models.TextField(blank=True, null=True)
121 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
137 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
122
138
123 class Meta:
139 class Meta:
124 db_table = 'db_devices'
140 db_table = 'db_devices'
125
141
126 def __str__(self):
142 def __str__(self):
127 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
143 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
128
144
129 return ret
145 return ret
130
146
131 @property
147 @property
132 def name(self):
148 def name(self):
133 return str(self)
149 return str(self)
134
150
135 def get_status(self):
151 def get_status(self):
136 return self.status
152 return self.status
137
153
138 @property
154 @property
139 def status_color(self):
155 def status_color(self):
140 color = 'muted'
156 color = 'muted'
141 if self.status == 0:
157 if self.status == 0:
142 color = "danger"
158 color = "danger"
143 elif self.status == 1:
159 elif self.status == 1:
144 color = "warning"
160 color = "warning"
145 elif self.status == 2:
161 elif self.status == 2:
146 color = "info"
162 color = "info"
147 elif self.status == 3:
163 elif self.status == 3:
148 color = "success"
164 color = "success"
149
165
150 return color
166 return color
151
167
152 def url(self, path=None):
168 def url(self, path=None):
153
169
154 if path:
170 if path:
155 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
171 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
156 else:
172 else:
157 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
173 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
158
174
159 def get_absolute_url(self):
175 def get_absolute_url(self):
160 return reverse('url_device', args=[str(self.id)])
176 return reverse('url_device', args=[str(self.id)])
161
177
162 def get_absolute_url_edit(self):
178 def get_absolute_url_edit(self):
163 return reverse('url_edit_device', args=[str(self.id)])
179 return reverse('url_edit_device', args=[str(self.id)])
164
180
165 def get_absolute_url_delete(self):
181 def get_absolute_url_delete(self):
166 return reverse('url_delete_device', args=[str(self.id)])
182 return reverse('url_delete_device', args=[str(self.id)])
167
183
168 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
184 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
169
185
170 if self.device_type.name=='dds':
186 if self.device_type.name=='dds':
171 try:
187 try:
172 answer = dds_api.change_ip(ip = self.ip_address,
188 answer = dds_api.change_ip(ip = self.ip_address,
173 port = self.port_address,
189 port = self.port_address,
174 new_ip = ip_address,
190 new_ip = ip_address,
175 mask = mask,
191 mask = mask,
176 gateway = gateway)
192 gateway = gateway)
177 if answer[0]=='1':
193 if answer[0]=='1':
178 self.message = '25|DDS - {}'.format(answer)
194 self.message = '25|DDS - {}'.format(answer)
179 self.ip_address = ip_address
195 self.ip_address = ip_address
180 self.save()
196 self.save()
181 else:
197 else:
182 self.message = '30|DDS - {}'.format(answer)
198 self.message = '30|DDS - {}'.format(answer)
183 return False
199 return False
184 except Exception as e:
200 except Exception as e:
185 self.message = '40|{}'.format(str(e))
201 self.message = '40|{}'.format(str(e))
186 return False
202 return False
187
203
188 elif self.device_type.name=='rc':
204 elif self.device_type.name=='rc':
189 headers = {'content-type': "application/json",
205 headers = {'content-type': "application/json",
190 'cache-control': "no-cache"}
206 'cache-control': "no-cache"}
191
207
192 ip = [int(x) for x in ip_address.split('.')]
208 ip = [int(x) for x in ip_address.split('.')]
193 dns = [int(x) for x in dns.split('.')]
209 dns = [int(x) for x in dns.split('.')]
194 gateway = [int(x) for x in gateway.split('.')]
210 gateway = [int(x) for x in gateway.split('.')]
195 subnet = [int(x) for x in mask.split('.')]
211 subnet = [int(x) for x in mask.split('.')]
196
212
197 payload = {
213 payload = {
198 "ip": ip,
214 "ip": ip,
199 "dns": dns,
215 "dns": dns,
200 "gateway": gateway,
216 "gateway": gateway,
201 "subnet": subnet
217 "subnet": subnet
202 }
218 }
203
219
204 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
220 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
205 try:
221 try:
206 answer = req.json()
222 answer = req.json()
207 if answer['changeip']=='ok':
223 if answer['changeip']=='ok':
208 self.message = '25|IP succesfully changed'
224 self.message = '25|IP succesfully changed'
209 self.ip_address = ip_address
225 self.ip_address = ip_address
210 self.save()
226 self.save()
211 else:
227 else:
212 self.message = '30|An error ocuur when changing IP'
228 self.message = '30|An error ocuur when changing IP'
213 except Exception as e:
229 except Exception as e:
214 self.message = '40|{}'.format(str(e))
230 self.message = '40|{}'.format(str(e))
215 else:
231 else:
216 self.message = 'Not implemented'
232 self.message = 'Not implemented'
217 return False
233 return False
218
234
219 return True
235 return True
220
236
221
237
222 class Campaign(models.Model):
238 class Campaign(models.Model):
223
239
224 template = models.BooleanField(default=False)
240 template = models.BooleanField(default=False)
225 name = models.CharField(max_length=60, unique=True)
241 name = models.CharField(max_length=60, unique=True)
226 start_date = models.DateTimeField(blank=True, null=True)
242 start_date = models.DateTimeField(blank=True, null=True)
227 end_date = models.DateTimeField(blank=True, null=True)
243 end_date = models.DateTimeField(blank=True, null=True)
228 tags = models.CharField(max_length=40, blank=True, null=True)
244 tags = models.CharField(max_length=40, blank=True, null=True)
229 description = models.TextField(blank=True, null=True)
245 description = models.TextField(blank=True, null=True)
230 experiments = models.ManyToManyField('Experiment', blank=True)
246 experiments = models.ManyToManyField('Experiment', blank=True)
231 author = models.ForeignKey(User, null=True, blank=True)
247 author = models.ForeignKey(User, null=True, blank=True)
232
248
233 class Meta:
249 class Meta:
234 db_table = 'db_campaigns'
250 db_table = 'db_campaigns'
235 ordering = ('name',)
251 ordering = ('name',)
236
252
237 def __str__(self):
253 def __str__(self):
238 if self.template:
254 if self.template:
239 return u'{} (template)'.format(self.name)
255 return u'{} (template)'.format(self.name)
240 else:
256 else:
241 return u'{}'.format(self.name)
257 return u'{}'.format(self.name)
242
258
243 def jsonify(self):
259 def jsonify(self):
244
260
245 data = {}
261 data = {}
246
262
247 ignored = ('template')
263 ignored = ('template')
248
264
249 for field in self._meta.fields:
265 for field in self._meta.fields:
250 if field.name in ignored:
266 if field.name in ignored:
251 continue
267 continue
252 data[field.name] = field.value_from_object(self)
268 data[field.name] = field.value_from_object(self)
253
269
254 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
270 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
255 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
271 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
256
272
257 return data
273 return data
258
274
259 def parms_to_dict(self):
275 def parms_to_dict(self):
260
276
261 params = Params({})
277 params = Params({})
262 params.add(self.jsonify(), 'campaigns')
278 params.add(self.jsonify(), 'campaigns')
263
279
264 for exp in Experiment.objects.filter(campaign = self):
280 for exp in Experiment.objects.filter(campaign = self):
265 params.add(exp.jsonify(), 'experiments')
281 params.add(exp.jsonify(), 'experiments')
266 configurations = Configuration.objects.filter(experiment=exp, type=0)
282 configurations = Configuration.objects.filter(experiment=exp, type=0)
267
283
268 for conf in configurations:
284 for conf in configurations:
269 params.add(conf.jsonify(), 'configurations')
285 params.add(conf.jsonify(), 'configurations')
270 if conf.device.device_type.name=='rc':
286 if conf.device.device_type.name=='rc':
271 for line in conf.get_lines():
287 for line in conf.get_lines():
272 params.add(line.jsonify(), 'lines')
288 params.add(line.jsonify(), 'lines')
273
289
274 return params.data
290 return params.data
275
291
276 def dict_to_parms(self, parms, CONF_MODELS):
292 def dict_to_parms(self, parms, CONF_MODELS):
277
293
278 experiments = Experiment.objects.filter(campaign = self)
294 experiments = Experiment.objects.filter(campaign = self)
279
295
280 if experiments:
296 if experiments:
281 for experiment in experiments:
297 for experiment in experiments:
282 experiment.delete()
298 experiment.delete()
283
299
284 for id_exp in parms['experiments']['allIds']:
300 for id_exp in parms['experiments']['allIds']:
285 exp_parms = parms['experiments']['byId'][id_exp]
301 exp_parms = parms['experiments']['byId'][id_exp]
286 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
302 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
287 exp = Experiment(name='{}'.format(dum))
303 exp = Experiment(name='{}'.format(dum))
288 exp.save()
304 exp.save()
289 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
305 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
290 self.experiments.add(exp)
306 self.experiments.add(exp)
291
307
292 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
308 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
293
309
294 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
310 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
295 self.start_date = camp_parms['start_date']
311 self.start_date = camp_parms['start_date']
296 self.end_date = camp_parms['end_date']
312 self.end_date = camp_parms['end_date']
297 self.tags = camp_parms['tags']
313 self.tags = camp_parms['tags']
298 self.save()
314 self.save()
299
315
300 return self
316 return self
301
317
302 def get_experiments_by_radar(self, radar=None):
318 def get_experiments_by_radar(self, radar=None):
303
319
304 ret = []
320 ret = []
305 if radar:
321 if radar:
306 locations = Location.objects.filter(pk=radar)
322 locations = Location.objects.filter(pk=radar)
307 else:
323 else:
308 locations = set([e.location for e in self.experiments.all()])
324 locations = set([e.location for e in self.experiments.all()])
309
325
310 for loc in locations:
326 for loc in locations:
311 dum = {}
327 dum = {}
312 dum['name'] = loc.name
328 dum['name'] = loc.name
313 dum['id'] = loc.pk
329 dum['id'] = loc.pk
314 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
330 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
315 ret.append(dum)
331 ret.append(dum)
316
332
317 return ret
333 return ret
318
334
319 def get_absolute_url(self):
335 def get_absolute_url(self):
320 return reverse('url_campaign', args=[str(self.id)])
336 return reverse('url_campaign', args=[str(self.id)])
321
337
322 def get_absolute_url_edit(self):
338 def get_absolute_url_edit(self):
323 return reverse('url_edit_campaign', args=[str(self.id)])
339 return reverse('url_edit_campaign', args=[str(self.id)])
324
340
325 def get_absolute_url_delete(self):
341 def get_absolute_url_delete(self):
326 return reverse('url_delete_campaign', args=[str(self.id)])
342 return reverse('url_delete_campaign', args=[str(self.id)])
327
343
328 def get_absolute_url_export(self):
344 def get_absolute_url_export(self):
329 return reverse('url_export_campaign', args=[str(self.id)])
345 return reverse('url_export_campaign', args=[str(self.id)])
330
346
331 def get_absolute_url_import(self):
347 def get_absolute_url_import(self):
332 return reverse('url_import_campaign', args=[str(self.id)])
348 return reverse('url_import_campaign', args=[str(self.id)])
333
349
334
350
335 class RunningExperiment(models.Model):
351 class RunningExperiment(models.Model):
336 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
352 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
337 running_experiment = models.ManyToManyField('Experiment', blank = True)
353 running_experiment = models.ManyToManyField('Experiment', blank = True)
338 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
354 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
339
355
340
356
341 class Experiment(models.Model):
357 class Experiment(models.Model):
342
358
343 template = models.BooleanField(default=False)
359 template = models.BooleanField(default=False)
344 name = models.CharField(max_length=40, default='', unique=True)
360 name = models.CharField(max_length=40, default='', unique=True)
345 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
361 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
346 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
362 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
347 start_time = models.TimeField(default='00:00:00')
363 start_time = models.TimeField(default='00:00:00')
348 end_time = models.TimeField(default='23:59:59')
364 end_time = models.TimeField(default='23:59:59')
349 task = models.CharField(max_length=36, default='', blank=True, null=True)
365 task = models.CharField(max_length=36, default='', blank=True, null=True)
350 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
366 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
351 author = models.ForeignKey(User, null=True, blank=True)
367 author = models.ForeignKey(User, null=True, blank=True)
352 hash = models.CharField(default='', max_length=64, null=True, blank=True)
368 hash = models.CharField(default='', max_length=64, null=True, blank=True)
353
369
354 class Meta:
370 class Meta:
355 db_table = 'db_experiments'
371 db_table = 'db_experiments'
356 ordering = ('template', 'name')
372 ordering = ('template', 'name')
357
373
358 def __str__(self):
374 def __str__(self):
359 if self.template:
375 if self.template:
360 return u'%s (template)' % (self.name[:8])
376 return u'%s (template)' % (self.name)
361 else:
377 else:
362 return u'%s' % (self.name[:10])
378 return u'%s' % (self.name)
363
379
364 def jsonify(self):
380 def jsonify(self):
365
381
366 data = {}
382 data = {}
367
383
368 ignored = ('template')
384 ignored = ('template')
369
385
370 for field in self._meta.fields:
386 for field in self._meta.fields:
371 if field.name in ignored:
387 if field.name in ignored:
372 continue
388 continue
373 data[field.name] = field.value_from_object(self)
389 data[field.name] = field.value_from_object(self)
374
390
375 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
391 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
376 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
392 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
377 data['location'] = self.location.name
393 data['location'] = self.location.name
378 data['configurations'] = ['{}'.format(conf.pk) for
394 data['configurations'] = ['{}'.format(conf.pk) for
379 conf in Configuration.objects.filter(experiment=self, type=0)]
395 conf in Configuration.objects.filter(experiment=self, type=0)]
380
396
381 return data
397 return data
382
398
383 @property
399 @property
384 def radar_system(self):
400 def radar_system(self):
385 return self.location
401 return self.location
386
402
387 def clone(self, **kwargs):
403 def clone(self, **kwargs):
388
404
389 confs = Configuration.objects.filter(experiment=self, type=0)
405 confs = Configuration.objects.filter(experiment=self, type=0)
390 self.pk = None
406 self.pk = None
391 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
407 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
392 for attr, value in kwargs.items():
408 for attr, value in kwargs.items():
393 setattr(self, attr, value)
409 setattr(self, attr, value)
394
410
395 self.save()
411 self.save()
396
412
397 for conf in confs:
413 for conf in confs:
398 conf.clone(experiment=self, template=False)
414 conf.clone(experiment=self, template=False)
399
415
400 return self
416 return self
401
417
402 def start(self):
418 def start(self):
403 '''
419 '''
404 Configure and start experiments's devices
420 Configure and start experiments's devices
405 ABS-CGS-DDS-RC-JARS
421 ABS-CGS-DDS-RC-JARS
406 '''
422 '''
407
423
408 result = 2
424 result = 2
409 confs = []
425 confs = []
410 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
426 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
411 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
427 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
412 if rc_mix:
428 if rc_mix:
413 for conf in allconfs:
429 for conf in allconfs:
414 if conf.device.device_type.name == 'rc' and not conf.mix:
430 if conf.device.device_type.name == 'rc' and not conf.mix:
415 continue
431 continue
416 confs.append(conf)
432 confs.append(conf)
417 else:
433 else:
418 confs = allconfs
434 confs = allconfs
419 #Only Configured Devices.
435 #Only Configured Devices.
420 for conf in confs:
436 for conf in confs:
421 if conf.device.status in (0, 4):
437 if conf.device.status in (0, 4):
422 result = 0
438 result = 0
423 return result
439 return result
424 for conf in confs:
440 for conf in confs:
425 conf.stop_device()
441 conf.stop_device()
426 conf.write_device()
442 conf.write_device()
427 conf.start_device()
443 conf.start_device()
428 time.sleep(1)
444 time.sleep(1)
429
445
430 return result
446 return result
431
447
432
448
433 def stop(self):
449 def stop(self):
434 '''
450 '''
435 Stop experiments's devices
451 Stop experiments's devices
436 DDS-JARS-RC-CGS-ABS
452 DDS-JARS-RC-CGS-ABS
437 '''
453 '''
438
454
439 result = 1
455 result = 1
440
456
441 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
457 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
442 confs=confs.exclude(device__device_type__name='cgs')
458 confs=confs.exclude(device__device_type__name='cgs')
443 for conf in confs:
459 for conf in confs:
444 if conf.device.status in (0, 4):
460 if conf.device.status in (0, 4):
445 result = 0
461 result = 0
446 continue
462 continue
447 conf.stop_device()
463 conf.stop_device()
448
464
449 return result
465 return result
450
466
451
467
452 def get_status(self):
468 def get_status(self):
453
469
454 if self.status == 3:
470 if self.status == 3:
455 return
471 return
456
472
457 confs = Configuration.objects.filter(experiment=self, type=0)
473 confs = Configuration.objects.filter(experiment=self, type=0)
458
474
459 for conf in confs:
475 for conf in confs:
460 conf.status_device()
476 conf.status_device()
461
477
462 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
478 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
463
479
464 if total==2*confs.count():
480 if total==2*confs.count():
465 status = 1
481 status = 1
466 elif total == 3*confs.count():
482 elif total == 3*confs.count():
467 status = 2
483 status = 2
468 else:
484 else:
469 status = 0
485 status = 0
470
486
471 self.status = status
487 self.status = status
472 self.save()
488 self.save()
473
489
474 def status_color(self):
490 def status_color(self):
475 color = 'muted'
491 color = 'muted'
476 if self.status == 0:
492 if self.status == 0:
477 color = "danger"
493 color = "danger"
478 elif self.status == 1:
494 elif self.status == 1:
479 color = "info"
495 color = "info"
480 elif self.status == 2:
496 elif self.status == 2:
481 color = "success"
497 color = "success"
482 elif self.status == 3:
498 elif self.status == 3:
483 color = "warning"
499 color = "warning"
484
500
485 return color
501 return color
486
502
487 def parms_to_dict(self):
503 def parms_to_dict(self):
488
504
489 params = Params({})
505 params = Params({})
490 params.add(self.jsonify(), 'experiments')
506 params.add(self.jsonify(), 'experiments')
491
507
492 configurations = Configuration.objects.filter(experiment=self, type=0)
508 configurations = Configuration.objects.filter(experiment=self, type=0)
493
509
494 for conf in configurations:
510 for conf in configurations:
495 params.add(conf.jsonify(), 'configurations')
511 params.add(conf.jsonify(), 'configurations')
496 if conf.device.device_type.name=='rc':
512 if conf.device.device_type.name=='rc':
497 for line in conf.get_lines():
513 for line in conf.get_lines():
498 params.add(line.jsonify(), 'lines')
514 params.add(line.jsonify(), 'lines')
499
515
500 return params.data
516 return params.data
501
517
502 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
518 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
503
519
504 configurations = Configuration.objects.filter(experiment=self)
520 configurations = Configuration.objects.filter(experiment=self)
505
521
506 if id_exp is not None:
522 if id_exp is not None:
507 exp_parms = parms['experiments']['byId'][id_exp]
523 exp_parms = parms['experiments']['byId'][id_exp]
508 else:
524 else:
509 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
525 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
510
526
511 if configurations:
527 if configurations:
512 for configuration in configurations:
528 for configuration in configurations:
513 configuration.delete()
529 configuration.delete()
514
530
515 for id_conf in exp_parms['configurations']:
531 for id_conf in exp_parms['configurations']:
516 conf_parms = parms['configurations']['byId'][id_conf]
532 conf_parms = parms['configurations']['byId'][id_conf]
517 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
533 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
518 model = CONF_MODELS[conf_parms['device_type']]
534 model = CONF_MODELS[conf_parms['device_type']]
519 conf = model(
535 conf = model(
520 experiment = self,
536 experiment = self,
521 device = device,
537 device = device,
522 )
538 )
523 conf.dict_to_parms(parms, id=id_conf)
539 conf.dict_to_parms(parms, id=id_conf)
524
540
525
541
526 location, created = Location.objects.get_or_create(name=exp_parms['location'])
542 location, created = Location.objects.get_or_create(name=exp_parms['location'])
527 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
543 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
528 self.location = location
544 self.location = location
529 self.start_time = exp_parms['start_time']
545 self.start_time = exp_parms['start_time']
530 self.end_time = exp_parms['end_time']
546 self.end_time = exp_parms['end_time']
531 self.save()
547 self.save()
532
548
533 return self
549 return self
534
550
535 def get_absolute_url(self):
551 def get_absolute_url(self):
536 return reverse('url_experiment', args=[str(self.id)])
552 return reverse('url_experiment', args=[str(self.id)])
537
553
538 def get_absolute_url_edit(self):
554 def get_absolute_url_edit(self):
539 return reverse('url_edit_experiment', args=[str(self.id)])
555 return reverse('url_edit_experiment', args=[str(self.id)])
540
556
541 def get_absolute_url_delete(self):
557 def get_absolute_url_delete(self):
542 return reverse('url_delete_experiment', args=[str(self.id)])
558 return reverse('url_delete_experiment', args=[str(self.id)])
543
559
544 def get_absolute_url_import(self):
560 def get_absolute_url_import(self):
545 return reverse('url_import_experiment', args=[str(self.id)])
561 return reverse('url_import_experiment', args=[str(self.id)])
546
562
547 def get_absolute_url_export(self):
563 def get_absolute_url_export(self):
548 return reverse('url_export_experiment', args=[str(self.id)])
564 return reverse('url_export_experiment', args=[str(self.id)])
549
565
550 def get_absolute_url_start(self):
566 def get_absolute_url_start(self):
551 return reverse('url_start_experiment', args=[str(self.id)])
567 return reverse('url_start_experiment', args=[str(self.id)])
552
568
553 def get_absolute_url_stop(self):
569 def get_absolute_url_stop(self):
554 return reverse('url_stop_experiment', args=[str(self.id)])
570 return reverse('url_stop_experiment', args=[str(self.id)])
555
571
556
572
557 class Configuration(PolymorphicModel):
573 class Configuration(PolymorphicModel):
558
574
559 template = models.BooleanField(default=False)
575 template = models.BooleanField(default=False)
560 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
576 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
561 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
577 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
562 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
578 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
563 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
579 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
564 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
580 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
565 created_date = models.DateTimeField(auto_now_add=True)
581 created_date = models.DateTimeField(auto_now_add=True)
566 programmed_date = models.DateTimeField(auto_now=True)
582 programmed_date = models.DateTimeField(auto_now=True)
567 parameters = models.TextField(default='{}')
583 parameters = models.TextField(default='{}')
568 author = models.ForeignKey(User, null=True, blank=True)
584 author = models.ForeignKey(User, null=True, blank=True)
569 hash = models.CharField(default='', max_length=64, null=True, blank=True)
585 hash = models.CharField(default='', max_length=64, null=True, blank=True)
570 message = ""
586 message = ""
571
587
572 class Meta:
588 class Meta:
573 db_table = 'db_configurations'
589 db_table = 'db_configurations'
574 ordering = ('device__device_type__name',)
590 ordering = ('device__device_type__name',)
575
591
576 def __str__(self):
592 def __str__(self):
577
593
578 ret = u'{} '.format(self.device.device_type.name.upper())
594 ret = u'{} '.format(self.device.device_type.name.upper())
579
595
580 if 'mix' in [f.name for f in self._meta.get_fields()]:
596 if 'mix' in [f.name for f in self._meta.get_fields()]:
581 if self.mix:
597 if self.mix:
582 ret = '{} MIX '.format(self.device.device_type.name.upper())
598 ret = '{} MIX '.format(self.device.device_type.name.upper())
583
599
584 if 'label' in [f.name for f in self._meta.get_fields()]:
600 if 'label' in [f.name for f in self._meta.get_fields()]:
585 ret += '{}'.format(self.label[:8])
601 ret += '{}'.format(self.label)
586
602
587 #ret += '[ {} ]'.format(self.device.location.name)
588 if self.template:
603 if self.template:
589 ret += ' (template)'
604 ret += ' (template)'
590
605
591 return ret
606 return ret
592
607
593 @property
608 @property
594 def name(self):
609 def name(self):
595
610
596 return str(self)
611 return str(self)
597
612
598 def jsonify(self):
613 def jsonify(self):
599
614
600 data = {}
615 data = {}
601
616
602 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
617 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
603 'created_date', 'programmed_date', 'template', 'device',
618 'created_date', 'programmed_date', 'template', 'device',
604 'experiment')
619 'experiment')
605
620
606 for field in self._meta.fields:
621 for field in self._meta.fields:
607 if field.name in ignored:
622 if field.name in ignored:
608 continue
623 continue
609 data[field.name] = field.value_from_object(self)
624 data[field.name] = field.value_from_object(self)
610
625
611 data['device_type'] = self.device.device_type.name
626 data['device_type'] = self.device.device_type.name
612
627
613 if self.device.device_type.name == 'rc':
628 if self.device.device_type.name == 'rc':
614 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
629 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
615 data['delays'] = self.get_delays()
630 data['delays'] = self.get_delays()
616 data['pulses'] = self.get_pulses()
631 data['pulses'] = self.get_pulses()
617
632
618 elif self.device.device_type.name == 'jars':
633 elif self.device.device_type.name == 'jars':
619 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
634 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
620
635
621 elif self.device.device_type.name == 'dds':
636 elif self.device.device_type.name == 'dds':
622 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
637 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
623 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
638 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
624 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
639 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
625 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
640 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
626
641
627 return data
642 return data
628
643
629 def clone(self, **kwargs):
644 def clone(self, **kwargs):
630
645
631 self.pk = None
646 self.pk = None
632 self.id = None
647 self.id = None
633 for attr, value in kwargs.items():
648 for attr, value in kwargs.items():
634 setattr(self, attr, value)
649 setattr(self, attr, value)
635
650
636 self.save()
651 self.save()
637
652
638 return self
653 return self
639
654
640 def parms_to_dict(self):
655 def parms_to_dict(self):
641
656
642 params = Params({})
657 params = Params({})
643 params.add(self.jsonify(), 'configurations')
658 params.add(self.jsonify(), 'configurations')
644
659
645 if self.device.device_type.name=='rc':
660 if self.device.device_type.name=='rc':
646 for line in self.get_lines():
661 for line in self.get_lines():
647 params.add(line.jsonify(), 'lines')
662 params.add(line.jsonify(), 'lines')
648
663
649 return params.data
664 return params.data
650
665
651 def parms_to_text(self):
666 def parms_to_text(self):
652
667
653 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
668 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
654
669
655
670
656 def parms_to_binary(self):
671 def parms_to_binary(self):
657
672
658 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
673 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
659
674
660
675
661 def dict_to_parms(self, parameters, id=None):
676 def dict_to_parms(self, parameters, id=None):
662
677
663 params = Params(parameters)
678 params = Params(parameters)
664
679
665 if id:
680 if id:
666 data = params.get_conf(id_conf=id)
681 data = params.get_conf(id_conf=id)
667 else:
682 else:
668 data = params.get_conf(dtype=self.device.device_type.name)
683 data = params.get_conf(dtype=self.device.device_type.name)
669
684
670 if data['device_type']=='rc':
685 if data['device_type']=='rc':
671 self.clean_lines()
686 self.clean_lines()
672 lines = data.pop('lines', None)
687 lines = data.pop('lines', None)
673 for line_id in lines:
688 for line_id in lines:
674 pass
689 pass
675
690
676 for key, value in data.items():
691 for key, value in data.items():
677 if key not in ('id', 'device_type'):
692 if key not in ('id', 'device_type'):
678 setattr(self, key, value)
693 setattr(self, key, value)
679
694
680 self.save()
695 self.save()
681
696
682
697
683 def export_to_file(self, format="json"):
698 def export_to_file(self, format="json"):
684
699
685 content_type = ''
700 content_type = ''
686
701
687 if format == 'racp':
702 if format == 'racp':
688 content_type = 'text/plain'
703 content_type = 'text/plain'
689 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
704 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
690 content = self.parms_to_text(file_format = 'racp')
705 content = self.parms_to_text(file_format = 'racp')
691
706
692 if format == 'text':
707 if format == 'text':
693 content_type = 'text/plain'
708 content_type = 'text/plain'
694 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
709 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
695 content = self.parms_to_text()
710 content = self.parms_to_text()
696
711
697 if format == 'binary':
712 if format == 'binary':
698 content_type = 'application/octet-stream'
713 content_type = 'application/octet-stream'
699 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
714 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
700 content = self.parms_to_binary()
715 content = self.parms_to_binary()
701
716
702 if not content_type:
717 if not content_type:
703 content_type = 'application/json'
718 content_type = 'application/json'
704 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
719 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
705 content = json.dumps(self.parms_to_dict(), indent=2)
720 content = json.dumps(self.parms_to_dict(), indent=2)
706
721
707 fields = {'content_type':content_type,
722 fields = {'content_type':content_type,
708 'filename':filename,
723 'filename':filename,
709 'content':content
724 'content':content
710 }
725 }
711
726
712 return fields
727 return fields
713
728
714 def import_from_file(self, fp):
729 def import_from_file(self, fp):
715
730
716 parms = {}
731 parms = {}
717
732
718 path, ext = os.path.splitext(fp.name)
733 path, ext = os.path.splitext(fp.name)
719
734
720 if ext == '.json':
735 if ext == '.json':
721 parms = json.load(fp)
736 parms = json.load(fp)
722
737
723 if ext == '.dds':
738 if ext == '.dds':
724 lines = fp.readlines()
739 lines = fp.readlines()
725 parms = dds_data.text_to_dict(lines)
740 parms = dds_data.text_to_dict(lines)
726
741
727 if ext == '.racp':
742 if ext == '.racp':
728 if self.device.device_type.name == 'jars':
743 if self.device.device_type.name == 'jars':
729 parms = RacpFile(fp).to_dict()
744 parms = RacpFile(fp).to_dict()
730 parms['filter_parms'] = json.loads(self.filter_parms)
745 parms['filter_parms'] = json.loads(self.filter_parms)
731 return parms
746 return parms
732 parms = RCFile(fp).to_dict()
747 parms = RCFile(fp).to_dict()
733
748
734 return parms
749 return parms
735
750
736 def status_device(self):
751 def status_device(self):
737
752
738 self.message = 'Function not implemented'
753 self.message = 'Function not implemented'
739 return False
754 return False
740
755
741
756
742 def stop_device(self):
757 def stop_device(self):
743
758
744 self.message = 'Function not implemented'
759 self.message = 'Function not implemented'
745 return False
760 return False
746
761
747
762
748 def start_device(self):
763 def start_device(self):
749
764
750 self.message = 'Function not implemented'
765 self.message = 'Function not implemented'
751 return False
766 return False
752
767
753
768
754 def write_device(self, parms):
769 def write_device(self, parms):
755
770
756 self.message = 'Function not implemented'
771 self.message = 'Function not implemented'
757 return False
772 return False
758
773
759
774
760 def read_device(self):
775 def read_device(self):
761
776
762 self.message = 'Function not implemented'
777 self.message = 'Function not implemented'
763 return False
778 return False
764
779
765
780
766 def get_absolute_url(self):
781 def get_absolute_url(self):
767 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
782 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
768
783
769 def get_absolute_url_edit(self):
784 def get_absolute_url_edit(self):
770 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
785 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
771
786
772 def get_absolute_url_delete(self):
787 def get_absolute_url_delete(self):
773 return reverse('url_delete_dev_conf', args=[str(self.id)])
788 return reverse('url_delete_dev_conf', args=[str(self.id)])
774
789
775 def get_absolute_url_import(self):
790 def get_absolute_url_import(self):
776 return reverse('url_import_dev_conf', args=[str(self.id)])
791 return reverse('url_import_dev_conf', args=[str(self.id)])
777
792
778 def get_absolute_url_export(self):
793 def get_absolute_url_export(self):
779 return reverse('url_export_dev_conf', args=[str(self.id)])
794 return reverse('url_export_dev_conf', args=[str(self.id)])
780
795
781 def get_absolute_url_write(self):
796 def get_absolute_url_write(self):
782 return reverse('url_write_dev_conf', args=[str(self.id)])
797 return reverse('url_write_dev_conf', args=[str(self.id)])
783
798
784 def get_absolute_url_read(self):
799 def get_absolute_url_read(self):
785 return reverse('url_read_dev_conf', args=[str(self.id)])
800 return reverse('url_read_dev_conf', args=[str(self.id)])
786
801
787 def get_absolute_url_start(self):
802 def get_absolute_url_start(self):
788 return reverse('url_start_dev_conf', args=[str(self.id)])
803 return reverse('url_start_dev_conf', args=[str(self.id)])
789
804
790 def get_absolute_url_stop(self):
805 def get_absolute_url_stop(self):
791 return reverse('url_stop_dev_conf', args=[str(self.id)])
806 return reverse('url_stop_dev_conf', args=[str(self.id)])
792
807
793 def get_absolute_url_status(self):
808 def get_absolute_url_status(self):
794 return reverse('url_status_dev_conf', args=[str(self.id)])
809 return reverse('url_status_dev_conf', args=[str(self.id)])
General Comments 0
You need to be logged in to leave comments. Login now