##// END OF EJS Templates
Se unió ATRAD al SIR
Renato Huallpa -
r380:34e7637f39b2
parent child
Show More
@@ -0,0 +1,2
1 from . import mqtt
2 mqtt.client.loop_start() No newline at end of file
@@ -0,0 +1,6
1 from django.contrib import admin
2 from .models import ATRADConfiguration
3
4 # Register your models here.
5
6 admin.site.register(ATRADConfiguration)
@@ -0,0 +1,6
1 #from django.apps import AppConfig
2
3
4 #class AtradConfig(AppConfig):#
5 # default_auto_field = 'django.db.models.BigAutoField'
6 # name = 'atrad'
@@ -0,0 +1,19
1 import json
2
3 def read_json_file(fp):
4
5 kwargs = {}
6
7 json_data = fp
8 data = json.load(json_data)
9 json_data.close()
10
11 topic = data["topic"][0][1]
12
13 kwargs['topic'] = topic
14
15 return kwargs
16
17
18 def write_json_file(filename):
19 pass No newline at end of file
@@ -0,0 +1,27
1 from django import forms
2 from apps.main.models import Device
3 from .models import ATRADConfiguration
4
5 class ATRADConfigurationForm(forms.ModelForm):
6
7 def __init__(self, *args, **kwargs):
8 super(ATRADConfigurationForm, self).__init__(*args, **kwargs)
9 instance = getattr(self, 'instance', None)
10
11 if instance and instance.pk:
12 devices = Device.objects.filter(device_type__name='atrad')
13 if instance.experiment:
14 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
15 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
16
17 def clean(self):
18 return
19
20 class Meta:
21 model = ATRADConfiguration
22 exclude = ('type', 'parameters', 'status', 'author', 'hash')
23
24
25 class UploadFileForm(forms.Form):
26 title = forms.CharField(label='Extension Type', widget=forms.TextInput(attrs={'readonly':'readonly'}))
27 file = forms.FileField()
@@ -0,0 +1,175
1 from django.db import models
2 from apps.main.models import Configuration
3 from apps.main.utils import Params
4 from django.core.validators import MinValueValidator, MaxValueValidator
5
6 from .files import read_json_file
7 import requests
8 # Create your models here. validators=[MinValueValidator(62.5e6), MaxValueValidator(450e6)]
9
10 class ATRADConfiguration(Configuration):
11
12 topic = models.PositiveIntegerField(verbose_name='Topic',validators=[MaxValueValidator(10)], default = 0)
13
14 def verify_frequencies(self):
15
16 return True
17
18
19 def status_device(self):
20
21 ip=self.device.ip_address
22 port=self.device.port_address
23
24 route = "http://" + str(ip) + ":" + str(port) + "/status/"
25 try:
26 r = requests.get(route, timeout=0.7)
27 except Exception as e:
28 self.device.status = 0
29 self.device.save()
30 self.message = 'Could not read TX status: ' + str(e)
31 return False
32
33 response = r.json()
34 self.device.status = response['status']
35 self.message = response['message']
36 self.device.save()
37
38 if response['components_status']==0:
39 return False
40
41 return True
42
43
44 def start_device(self):
45
46 ip=self.device.ip_address
47 port=self.device.port_address
48
49 #---Device must be configured
50 if not self.device.status == 2:
51 self.message = 'TX Device must be configured.'
52 return False
53 #---Frequencies from form
54 post_data = self.parms_to_dict()
55 route = "http://" + str(ip) + ":" + str(port) + "/write/"
56
57 try:
58 r = requests.post(route, post_data, timeout=0.7)
59 except Exception as e:
60 self.message = "Could not start TX device. "+str(e)
61 return False
62
63 response = r.json()
64 if response['status']==1:
65 self.device.status = 1
66 self.device.save()
67 self.message = response['message']
68 return False
69
70 self.device.status = response['status']
71 self.device.save()
72 self.message = response['message']
73
74 return True
75
76
77 def stop_device(self):
78
79 ip=self.device.ip_address
80 port=self.device.port_address
81
82 if self.device.status == 2: #Configured
83 self.message = 'TX device is already stopped.'
84 return False
85
86 post_data = {"topic":0}
87 route = "http://" + str(ip) + ":" + str(port) + "/write/"
88
89 try:
90 r = requests.post(route, post_data, timeout=0.7)
91 except Exception as e:
92 self.message = "Could not write TX parameters. "+str(e)
93 self.device.status = 0
94 self.device.save()
95 return False
96
97 response = r.json()
98 status = response['status']
99 if status == 1:
100 self.device.status = status
101 self.device.save()
102 self.message = 'Could not stop TX device.'
103 return False
104
105 self.message = 'TX device has been stopped successfully.'
106 self.device.status = 2
107 self.device.save()
108
109 return True
110
111
112 def read_device(self):
113
114 ip=self.device.ip_address
115 port=self.device.port_address
116
117 route = "http://" + str(ip) + ":" + str(port) + "/read/"
118 try:
119 frequencies = requests.get(route,timeout=0.7)
120 except:
121 self.message = "Could not read TX parameters from this device"
122 return None
123
124 frequencies = frequencies.json()
125 if frequencies:
126 frequencies = frequencies.get("Frequencies")
127 topic = frequencies.get("topic")
128
129 parms = {'topic': topic}
130
131 self.message = "TX parameters have been successfully read"
132 return parms
133 else:
134 self.message = "Error reading TX parameters"
135 return None
136
137
138 def write_device(self):
139
140 ip=self.device.ip_address
141 port=self.device.port_address
142
143 #---Frequencies from form
144 parms = self.parms_to_dict()['configurations']
145 for parm in parms['allIds']:
146 byid = parm
147 frequencies = parms['byId'][byid]
148 post_data = {}
149 for data in frequencies:
150 if data in ['topic']:
151 post_data[data] = frequencies[data]
152
153 route = "http://" + str(ip) + ":" + str(port) + "/write/"
154 print (post_data)
155 try:
156 r = requests.post(route, post_data, timeout=0.7)
157 except:
158 self.message = "Could not write TX parameters"
159 self.device.status = 0
160 self.device.save()
161 return False
162
163 response = r.json()
164 self.message = response['message']
165 self.device.status = response['status']
166 self.device.save()
167
168 if self.device.status==1:
169 return False
170
171 return True
172
173
174 class Meta:
175 db_table = 'atrad_configurations' No newline at end of file
@@ -0,0 +1,38
1 import paho.mqtt.client as mqtt
2 from radarsys import settings
3 from radarsys.socketconfig import sio as sio
4 import numpy as np
5
6 def on_connect(mqtt_client, userdata, flags, rc):
7 if rc == 0:
8 print('Connected successfully')
9 mqtt_client.subscribe('atrad/test3')
10 else:
11 print('Bad connection. Code:', rc)
12
13 def maxima_temp(trs):
14 np_array = [np.array(i) for i in trs]
15 temps = [max(i[i<40]) for i in np_array]
16 return max(temps)
17
18 def on_message(mqtt_client, userdata, msg):
19 print(f'Received message on topic: {msg.topic} with payload: {msg.payload}', flush=True)
20 trsi = [[],[],[],[]]
21 mensaje = str(msg.payload)
22 datos = [i for i in mensaje[21:-1].split("*")]
23 status=''.join([datos[i][3] for i in [0,1,2,3]])
24 for trs,i in zip(datos,[0,1,2,3]) :
25 trsi[i]= [int(i) for i in trs[1:-1].split(",")]
26 potencias = [trsi[0][34],trsi[0][36],trsi[2][32],trsi[2][34]]
27 tmax = maxima_temp(trsi)
28 sio.emit('test', data={'time':mensaje[2:21],'num':trsi[0][0],'pow':potencias,'tmax':str(tmax),'status':status})
29
30 client = mqtt.Client()
31 client.on_connect = on_connect
32 client.on_message = on_message
33 client.username_pw_set(settings.MQTT_USER, settings.MQTT_PASSWORD)
34 client.connect(
35 host=settings.MQTT_SERVER,
36 port=settings.MQTT_PORT,
37 keepalive=settings.MQTT_KEEPALIVE
38 ) No newline at end of file
@@ -0,0 +1,288
1 {% extends "dev_conf.html" %}
2 {% block extra-head %}
3 <style>
4 .dot {
5 height: 25px;
6 width: 25px;
7 background-color: #b0b3af;
8 border-radius: 50%;
9 display: inline-block;
10 }
11 </style>
12 {% endblock %}
13
14 {% block extra-content %}
15 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
16 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js"></script>
17
18 <div class="container-fluid">
19 <div class="row">
20 <div class="col-xs-12">
21 <h1>Atrad Monitor</h1>
22 </div>
23 </div>
24
25 <div class="row ">
26 <!-- Potencia -->
27 <div class="col col-xs-12">
28 <div class="row">
29 <div class="panel panel-default" style="width:100%;">
30 <div class="panel-heading">
31 <h3 class="panel-title">Potencia</h3>
32 </div>
33 <div class="panel-body">
34 <div class="col-xs-12">
35 <div class="row">
36 <div id="plot-pot"></div>
37 </div>
38 </div>
39 </div>
40 <div class="panel-footer">
41 <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#Pot1">T1</button>
42 <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#Pot2">T2</button>
43 </div>
44 </div>
45 </div>
46 </div>
47 <div class="col col-xs-12">
48 <div class="panel panel-default">
49 <div class="panel-heading">
50 <h3 class="panel-title">Status</h3>
51 </div>
52 <div class="panel-body">
53 <table class="table table-borderless" style="max-width: 300px;">
54 <tbody>
55 <tr>
56 <th scope="row">Tx1</th>
57 <td><span id="status1" class="dot"></span></td>
58 <td><p id="status-text1" class="font-weight-bold">Sin envio de datos</p></td>
59 </tr>
60 <tr>
61 <th scope="row">Tx2</th>
62 <td><span id="status2" class="dot"></span></td>
63 <td><p id="status-text2" class="font-weight-bold">Sin envio de datos</p></td>
64 </tr>
65 </tbody>
66 </table>
67 </div>
68 </div>
69 </div>
70 </div>
71
72 <!-- Temperatura -->
73 <div class="row">
74 <div class="col-xs-12">
75 <div class="panel panel-default">
76 <div class="panel-heading">
77 <h3 class="panel-title">Temperatura</h3>
78 </div>
79 <div class="panel-body">
80 <div class="col-xs-12">
81 <div class="row">
82 <div id="plot-temp"></div>
83 </div>
84 </div>
85 </div>
86 </div>
87 </div>
88 </div>
89
90 <div class="row">
91 <!-- Controles -->
92 <div class="col-xs-6">
93 <div class="panel panel-default">
94 <div class="panel-heading">
95 <h3 class="panel-title">Control</h3>
96 </div>
97 <div class="panel-body">
98 <div class="col-xs-12">
99 <div class="form-row">
100 <div class="form-group col-xs-6">
101 <form id="controlON" method="POST" action=''>
102 <button type="summit" class="btn btn-secondary btn-lg">Prender</button>
103 </form>
104 </div>
105 <div class="form-group col-xs-6">
106 <form id="controlOFF" method="POST" action=''>
107 <button type="summit" class="btn btn-secondary btn-lg">Apagar</button>
108 </form>
109 </div>
110 </div>
111 </div>
112 </div>
113 </div>
114 </div>
115
116 <div class="col-xs-6">
117 <div class="panel panel-default">
118 <div class="panel-heading">
119 </div>
120 </div>
121 </div>
122 </div>
123 </div>
124
125 <!--Modales-->
126 <div class="modal fade" id="Pot1" role="dialog">
127 <div class="modal-dialog modal-md" style="min-width:760px">
128 <div class="modal-content">
129 <div class="modal-header">
130 <h4 class="modal-title">Potencia incidente - Transmisor 1</h4>
131 <button type="button" class="close" data-dismiss="modal">&times;</button>
132 </div>
133 <div class="modal-body">
134 <div class="col-xs-12">
135 <div id="plot-pot-t1"></div>
136 </div>
137 <div clas="col-xs-12">
138 <table class="table table-borderless">
139 <tbody>
140 <tr>
141 <th scope="row">P1</th>
142 <td>e</td>
143 <td>e</td>
144 </tr>
145 <tr>
146 <th scope="row">P2</th>
147 <td>e</td>
148 <td>e</td>
149 </tr>
150 <tr>
151 <th scope="row">P3</th>
152 <td>e</td>
153 <td>e</td>
154 </tr>
155 <tr>
156 <th scope="row">P4</th>
157 <td>e</td>
158 <td>e</td>
159 </tr>
160 </tbody>
161 </table>
162 </div>
163 </div>
164 </div>
165 </div>
166 </div>
167
168 <div class="modal fade" id="Pot2" role="dialog">
169 <div class="modal-dialog modal-md" style="min-width:760px">
170 <div class="modal-content">
171 <div class="modal-header">
172 <h4 class="modal-title">Potencia incidente - Transmisor 2</h4>
173 <button type="button" class="close" data-dismiss="modal">&times;</button>
174 </div>
175 <div class="modal-body">
176 <div class="col-xs-12">
177 <div id="plot-pot-t2"></div>
178 </div>
179 </div>
180 </div>
181 </div>
182 </div>
183
184 <script type="text/javascript" charset="utf-8">
185 $(document).ready(function() {
186 var socket = io.connect('http://' + document.domain + ':' + location.port);
187
188 socket.on('connect', function(data) {
189 console.log('Connecting... OK');
190 makePlot("plot-temp",2,["T1","T2"],[14, 45])
191 makePlot("plot-pot",2,["T1","T2"],[70,100])
192 makePlot("plot-pot-t1",4,["P1","P2","P3","P4"],[0,26])
193 makePlot("plot-pot-t2",4,["P1","P2","P3","P4"],[0,26])
194 })
195
196 socket.on('test', function(data) {
197 let total = data.pow.reduce((a, b) => a + b, 0);
198 var id = (data.num/4)>>0;
199 streamPlot("plot-pot",data.time,total/1000.0,id,81);
200 streamPlot("plot-temp",data.time,data.tmax,id>>0,40);
201 if(id == 0){streamPlot2("plot-pot-t1",data.time,data.pow);ligthStatus('status1','status-text1',data.status);}
202 if(id == 1){streamPlot2("plot-pot-t2",data.time,data.pow);ligthStatus('status2','status-text2',data.status);}
203 })
204 $('form#controlON').submit(function(event) {
205 socket.emit('control_event', {data: 1});
206 return false;
207 });
208 $('form#controlOFF').submit(function(event) {
209 socket.emit('control_event', {data: 0});
210 return false;
211 });
212 $("#btn1").click(function(){
213 $("#box").animate({height: "300px"});
214 });
215 $("#btn2").click(function(){
216 $("#box").animate({height: "100px"});
217 });
218 });
219
220 function makePlot(div, n=1, names=["", ""],ranges){
221 var plotDiv = document.getElementById(div);
222 var traces = [];
223 for (let i = 0; i < n; i++) {
224 traces.push({x: [], y: [],mode: 'lines', name: names[i]});
225 }
226 traces.push({x: [], y: [],mode: 'lines',line: {color:'rgb(219, 64, 82)',dash: 'dot',width: 2},name:"nominal",showlegend: false});
227 var yrange = ranges;
228 var layout = {
229 height: 350,
230 font: {size: 12},
231 margin: { t: 10, b:50},
232 xaxis: {
233 type: 'date'
234 },
235 yaxis: {
236 range: yrange,
237 },
238 };
239
240 Plotly.plot(plotDiv, traces, layout);
241 };
242
243 function streamPlot(div,x,y,ind,val){
244 var plotDiv = document.getElementById(div);
245 if (plotDiv.data[ind].x.length > 8){
246 plotDiv.data[2].x = plotDiv.data[2].x.slice(-23)
247 plotDiv.data[2].y = plotDiv.data[2].y.slice(-23)
248 plotDiv.data[ind].x = plotDiv.data[ind].x.slice(-11)
249 plotDiv.data[ind].y = plotDiv.data[ind].y.slice(-11)
250 }
251 var tm = [x];
252 var values = [y];
253 var data_update = {x: [tm,tm], y: [values,[val]]}
254 Plotly.extendTraces(plotDiv, data_update,[ind,2])
255 };
256 function streamPlot2(div,x,y){
257 var plotDiv = document.getElementById(div);
258 if (plotDiv.data[0].x.length > 8){
259 for(let i=0;i<4;i++){
260 plotDiv.data[i].x = plotDiv.data[i].x.slice(-11)
261 plotDiv.data[i].y = plotDiv.data[i].y.slice(-11)
262 }
263 }
264 var tm = [x];
265 var values = [];
266 for(let i=0;i<4;i++){
267 values[i]=[y[i]/1000.0];
268 }
269 var data_update = {x: [tm,tm,tm,tm], y: values}
270 Plotly.extendTraces(plotDiv, data_update,[0,1,2,3])
271 };
272 function ligthStatus(div1,div2,status){
273 if(status==='0000'){
274 document.getElementById(div1).style.backgroundColor = "green";
275 document.getElementById(div2).innerHTML = "Desabilitado";
276 }
277 else if(status==='1111'){
278 document.getElementById(div1).style.backgroundColor = "green";
279 document.getElementById(div2).innerHTML = "Habilitado";
280 }
281 else{
282 document.getElementById(div1).style.backgroundColor = "yellow";
283 document.getElementById(div2).innerHTML = "Incompleto";
284 }
285 }
286
287 </script>
288 {% endblock %} No newline at end of file
1 NO CONTENT: new file 100644
@@ -0,0 +1,7
1 {% extends "dev_conf_edit.html" %}
2 {% load django_bootstrap5 %}
3 {% load static %}
4 {% load main_tags %}
5
6 {% block extra-js%}
7 {% endblock %} No newline at end of file
@@ -0,0 +1,15
1 {% extends "base.html" %}
2 {% block mainactive %}active{% endblock %}
3
4 {% block content-title %}TITLE{% endblock %}
5 {% block content-suptitle %}Suptitle{% endblock %}
6
7 {% block content %}
8 <p class="text-justify">
9 {% lorem %}
10 </p>
11 {% endblock %}
12
13 {% block sidebar%}
14
15 {% endblock %}
@@ -0,0 +1,46
1 {% extends "base.html" %}
2 {% load django_bootstrap5 %}
3 {% block mainactive %}active{% endblock %}
4
5 {% block content-title %}DEVICE CGS{% endblock %}
6 {% block content-suptitle %}CLOCK GENERATOR AND SYNCHRONIZER{% endblock %}
7
8 {% block content %}
9 <p class="text-justify">
10 Ingresar Frecuencias
11 </p>
12
13
14
15 <!-- Agregado 30-11-2015 -->
16 {% if form.is_multipart %}
17
18 <script type="text/javascript">
19
20 </script>
21
22 <form id="{{ idform }}" enctype="multipart/form-data" method="{{ submit_method|default:'post' }}" action="" class="form">
23 {% else %}
24 <form method="{{ submit_method|default:'post' }}" action="" class="form">
25 {% endif %}
26
27 {% if step_field %}
28 <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
29 {% endif %}
30
31 {% if submit_method != 'GET' and submit_method != 'get' %}
32 {% csrf_token %}
33 {% endif %}
34 <!-- Agregado 30-11-2015 -->
35
36
37
38 <div class='col-md-8'>
39 {% bootstrap_form form size='md' %}
40 <button type="submit" class="btn btn-primary pull-right">Submit</button>
41 </div>
42 {% endblock %}
43
44 {% block sidebar%}
45
46 {% endblock %} No newline at end of file
@@ -0,0 +1,3
1 from django.test import TestCase
2
3 # Create your tests here.
@@ -0,0 +1,8
1 from django.urls import path
2
3 from . import views
4
5 urlpatterns = (
6 path('<int:id_conf>/', views.atrad_conf, name='url_atrad_conf'),
7 path('<int:id_conf>/edit/', views.atrad_conf_edit, name='url_edit_atrad_conf'),
8 ) No newline at end of file
@@ -0,0 +1,108
1 from django.shortcuts import redirect, render, get_object_or_404
2 from django.contrib import messages
3 from django.http import HttpResponse
4
5 from apps.main.models import Experiment
6 from .models import ATRADConfiguration
7
8 from .forms import ATRADConfigurationForm, UploadFileForm
9 from apps.main.views import sidebar
10
11 import requests
12 import json
13
14 import os
15 from django.http import JsonResponse
16 from .mqtt import client as mqtt_client
17 from radarsys.socketconfig import sio as sio
18
19
20 def atrad_conf(request, id_conf):
21
22 conf = get_object_or_404(ATRADConfiguration, pk=id_conf)
23
24 ip=conf.device.ip_address
25 port=conf.device.port_address
26
27 kwargs = {}
28
29 kwargs['status'] = conf.device.get_status_display()
30
31 kwargs['dev_conf'] = conf
32 kwargs['dev_conf_keys'] = ['label',
33 'topic']
34
35 kwargs['title'] = 'ATRAD Configuration'
36 kwargs['suptitle'] = 'Details'
37
38 kwargs['button'] = 'Edit Configuration'
39
40 #kwargs['no_play'] = True
41
42 ###### SIDEBAR ######
43 kwargs.update(sidebar(conf=conf))
44
45 return render(request, 'atrad_conf.html', kwargs)
46
47 def atrad_conf_edit(request, id_conf):
48
49 conf = get_object_or_404(ATRADConfiguration, pk=id_conf)
50
51 if request.method=='GET':
52 form = ATRADConfigurationForm(instance=conf)
53
54 if request.method=='POST':
55 form = ATRADConfigurationForm(request.POST, instance=conf)
56
57 if form.is_valid():
58 if conf.topic == None: conf.topic = 0
59
60 conf = form.save(commit=False)
61
62 if conf.verify_frequencies():
63 conf.save()
64 return redirect('url_atrad_conf', id_conf=conf.id)
65
66 kwargs = {}
67 kwargs['id_dev'] = conf.id
68 kwargs['form'] = form
69 kwargs['title'] = 'Device Configuration'
70 kwargs['suptitle'] = 'Edit'
71 kwargs['button'] = 'Save'
72
73 return render(request, 'atrad_conf_edit.html', kwargs)
74
75 import os
76 from django.http import HttpResponse#
77
78 def publish_message(request):
79 rc, mid = mqtt_client.publish('test/data2',1)
80 return JsonResponse({'code1': 'HIKA', 'code2': 'LUCAS'})
81
82 def monitor(request):
83 kwargs = {'no_sidebar': True}
84 return render(request, 'monitor.html', kwargs)
85
86 def prueba(request):
87 kwargs = {'no_sidebar': True}
88 return render(request, 'prueba.html', kwargs)
89
90 @sio.on('connection-bind')
91 def connection_bind(sid, data):
92 print("sid:",sid,"data",data)
93
94 @sio.on('disconnect')
95 def test_disconnect(sid):
96 print("Disconnected")
97
98 @sio.event
99 def control_event(sid,message):
100 mqtt_client.publish('test/data2',message['data'])
101
102 def hello(data):
103 try:
104 rc, mid = mqtt_client.publish('test/data2', 'Hello')
105 sio.emit('test', data={'topic':mid, 'status': 'Not Running'})
106 except:
107 print('ERROR', flush=True)
108 return HttpResponse("Hello") No newline at end of file
@@ -0,0 +1,6
1 import os
2 import socketio
3 async_mode = None
4
5 basedir = os.path.dirname(os.path.realpath(__file__))
6 sio = socketio.Server(async_mode='eventlet') No newline at end of file
@@ -1,138 +1,146
1 1 [
2 2 {
3 3 "fields": {
4 4 "name": "JRO",
5 5 "description": ""
6 6 },
7 7 "model": "main.location",
8 8 "pk": 1
9 9 },
10 10 {
11 11 "fields": {
12 12 "name": "JASMET",
13 13 "description": ""
14 14 },
15 15 "model": "main.location",
16 16 "pk": 2
17 17 },
18 18 {
19 19 "fields": {
20 20 "name": "SOUSY",
21 21 "description": ""
22 22 },
23 23 "model": "main.location",
24 24 "pk": 3
25 25 },
26 26 {
27 27 "fields": {
28 28 "name": "JULIA",
29 29 "description": ""
30 30 },
31 31 "model": "main.location",
32 32 "pk": 4
33 33 },
34 34 {
35 35 "fields": {
36 36 "name": "CLAIRE",
37 37 "description": ""
38 38 },
39 39 "model": "main.location",
40 40 "pk": 5
41 41 },
42 42 {
43 43 "fields": {
44 44 "name": "IDI",
45 45 "description": ""
46 46 },
47 47 "model": "main.location",
48 48 "pk": 6
49 49 },
50 50 {
51 51 "fields": {
52 52 "name": "rc",
53 53 "description": ""
54 54 },
55 55 "model": "main.devicetype",
56 56 "pk": 1
57 57 },
58 58 {
59 59 "fields": {
60 60 "name": "dds",
61 61 "description": ""
62 62 },
63 63 "model": "main.devicetype",
64 64 "pk": 2
65 65 },
66 66 {
67 67 "fields": {
68 68 "name": "cgs",
69 69 "description": ""
70 70 },
71 71 "model": "main.devicetype",
72 72 "pk": 3
73 73 },
74 74 {
75 75 "fields": {
76 76 "name": "jars",
77 77 "description": ""
78 78 },
79 79 "model": "main.devicetype",
80 80 "pk": 4
81 81 },
82 82 {
83 83 "fields": {
84 84 "name": "abs",
85 85 "description": ""
86 86 },
87 87 "model": "main.devicetype",
88 88 "pk": 5
89 89 },
90 90 {
91 91 "fields": {
92 92 "name": "dds_rest",
93 93 "description": ""
94 94 },
95 95 "model": "main.devicetype",
96 96 "pk": 6
97 },
98 {
99 "fields": {
100 "name": "atrad",
101 "description": ""
102 },
103 "model": "main.devicetype",
104 "pk": 7
97 105 },
98 106 {
99 107 "fields": {
100 108 "name": "Operator"
101 109 },
102 110 "model": "auth.group",
103 111 "pk": 1
104 112 },
105 113 {
106 114 "fields": {
107 115 "name": "Developer"
108 116 },
109 117 "model": "auth.group",
110 118 "pk": 2
111 119 },
112 120 {
113 121 "fields": {
114 122 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
115 123 "last_login": null,
116 124 "is_superuser": true,
117 125 "username": "admin",
118 126 "first_name": "Administrador",
119 127 "last_name": "IDI",
120 128 "email": "admin@admin.com",
121 129 "is_staff": true,
122 130 "is_active": true,
123 131 "date_joined": "2017-01-12T16:10:24.383",
124 132 "groups": [],
125 133 "user_permissions": []
126 134 },
127 135 "model": "auth.user",
128 136 "pk": 1
129 137 },
130 138 {
131 139 "fields": {
132 140 "user": 1,
133 141 "theme": "spacelab"
134 142 },
135 143 "model": "main.profile",
136 144 "pk": 1
137 145 }
138 146 ]
@@ -1,818 +1,819
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.urls import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 18 from django.contrib.auth.models import User
19 19 from django.db.models.signals import post_save
20 20 from django.dispatch import receiver
21 21
22 22 from apps.main.utils import Params
23 23 from apps.rc.utils import RCFile
24 24 from apps.jars.utils import RacpFile
25 25 from devices.dds import api as dds_api
26 26 from devices.dds import data as dds_data
27 27
28 28
29 29 DEV_PORTS = {
30 30 'rc' : 2000,
31 31 'dds' : 2000,
32 32 'jars' : 2000,
33 33 'usrp' : 2000,
34 34 'cgs' : 8080,
35 35 'abs' : 8080,
36 36 'dds_rest': 80
37 37 }
38 38
39 39 RADAR_STATES = (
40 40 (0, 'No connected'),
41 41 (1, 'Connected'),
42 42 (2, 'Configured'),
43 43 (3, 'Running'),
44 44 (4, 'Scheduled'),
45 45 )
46 46
47 47 EXPERIMENT_TYPE = (
48 48 (0, 'RAW_DATA'),
49 49 (1, 'PDATA'),
50 50 )
51 51
52 52 DECODE_TYPE = (
53 53 (0, 'None'),
54 54 (1, 'TimeDomain'),
55 55 (2, 'FreqDomain'),
56 56 (3, 'InvFreqDomain'),
57 57 )
58 58
59 59 DEV_STATES = (
60 60 (0, 'No connected'),
61 61 (1, 'Connected'),
62 62 (2, 'Configured'),
63 63 (3, 'Running'),
64 64 (4, 'Unknown'),
65 65 )
66 66
67 67 DEV_TYPES = (
68 68 ('', 'Select a device type'),
69 69 ('rc', 'Radar Controller'),
70 70 ('dds', 'Direct Digital Synthesizer'),
71 71 ('jars', 'Jicamarca Radar Acquisition System'),
72 72 ('usrp', 'Universal Software Radio Peripheral'),
73 73 ('cgs', 'Clock Generator System'),
74 74 ('abs', 'Automatic Beam Switching'),
75 75 ('dds_rest', 'Direct Digital Synthesizer_REST'),
76 ('atrad', 'Transmitter ATRAD'),
76 77 )
77 78
78 79 EXP_STATES = (
79 80 (0,'Error'), #RED
80 81 (1,'Cancelled'), #YELLOW
81 82 (2,'Running'), #GREEN
82 83 (3,'Scheduled'), #BLUE
83 84 (4,'Unknown'), #WHITE
84 85 )
85 86
86 87 CONF_TYPES = (
87 88 (0, 'Active'),
88 89 (1, 'Historical'),
89 90 )
90 91
91 92 class Profile(models.Model):
92 93 user = models.OneToOneField(User, on_delete=models.CASCADE)
93 94 theme = models.CharField(max_length=30, default='spacelab')
94 95
95 96
96 97 @receiver(post_save, sender=User)
97 98 def create_user_profile(sender, instance, created, **kwargs):
98 99 if created:
99 100 Profile.objects.create(user=instance)
100 101
101 102 @receiver(post_save, sender=User)
102 103 def save_user_profile(sender, instance, **kwargs):
103 104 instance.profile.save()
104 105
105 106
106 107 class Location(models.Model):
107 108
108 109 name = models.CharField(max_length = 30)
109 110 description = models.TextField(blank=True, null=True)
110 111
111 112 class Meta:
112 113 db_table = 'db_location'
113 114
114 115 def __str__(self):
115 116 return u'%s' % self.name
116 117
117 118 def get_absolute_url(self):
118 119 return reverse('url_location', args=[str(self.id)])
119 120
120 121
121 122 class DeviceType(models.Model):
122 123
123 124 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
124 125 sequence = models.PositiveSmallIntegerField(default=55)
125 126 description = models.TextField(blank=True, null=True)
126 127
127 128 class Meta:
128 129 db_table = 'db_device_types'
129 130
130 131 def __str__(self):
131 132 return u'%s' % self.get_name_display()
132 133
133 134 class Device(models.Model):
134 135
135 136 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
136 137 location = models.ForeignKey('Location', on_delete=models.CASCADE)
137 138 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
138 139 port_address = models.PositiveSmallIntegerField(default=2000)
139 140 description = models.TextField(blank=True, null=True)
140 141 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
141 142 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
142 143
143 144 class Meta:
144 145 db_table = 'db_devices'
145 146
146 147 def __str__(self):
147 148 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
148 149
149 150 return ret
150 151
151 152 @property
152 153 def name(self):
153 154 return str(self)
154 155
155 156 def get_status(self):
156 157 return self.status
157 158
158 159 @property
159 160 def status_color(self):
160 161 color = 'muted'
161 162 if self.status == 0:
162 163 color = "danger"
163 164 elif self.status == 1:
164 165 color = "warning"
165 166 elif self.status == 2:
166 167 color = "info"
167 168 elif self.status == 3:
168 169 color = "success"
169 170
170 171 return color
171 172
172 173 def url(self, path=None):
173 174
174 175 if path:
175 176 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
176 177 else:
177 178 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
178 179
179 180 def get_absolute_url(self):
180 181 return reverse('url_device', args=[str(self.id)])
181 182
182 183 def get_absolute_url_edit(self):
183 184 return reverse('url_edit_device', args=[str(self.id)])
184 185
185 186 def get_absolute_url_delete(self):
186 187 return reverse('url_delete_device', args=[str(self.id)])
187 188
188 189 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
189 190
190 191 if self.device_type.name=='dds':
191 192 try:
192 193 answer = dds_api.change_ip(ip = self.ip_address,
193 194 port = self.port_address,
194 195 new_ip = ip_address,
195 196 mask = mask,
196 197 gateway = gateway)
197 198 if answer[0]=='1':
198 199 self.message = '25|DDS - {}'.format(answer)
199 200 self.ip_address = ip_address
200 201 self.save()
201 202 else:
202 203 self.message = '30|DDS - {}'.format(answer)
203 204 return False
204 205 except Exception as e:
205 206 self.message = '40|{}'.format(str(e))
206 207 return False
207 208
208 209 elif self.device_type.name=='rc':
209 210 headers = {'content-type': "application/json",
210 211 'cache-control': "no-cache"}
211 212
212 213 ip = [int(x) for x in ip_address.split('.')]
213 214 dns = [int(x) for x in dns.split('.')]
214 215 gateway = [int(x) for x in gateway.split('.')]
215 216 subnet = [int(x) for x in mask.split('.')]
216 217
217 218 payload = {
218 219 "ip": ip,
219 220 "dns": dns,
220 221 "gateway": gateway,
221 222 "subnet": subnet
222 223 }
223 224
224 225 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
225 226 try:
226 227 answer = req.json()
227 228 if answer['changeip']=='ok':
228 229 self.message = '25|IP succesfully changed'
229 230 self.ip_address = ip_address
230 231 self.save()
231 232 else:
232 233 self.message = '30|An error ocuur when changing IP'
233 234 except Exception as e:
234 235 self.message = '40|{}'.format(str(e))
235 236 else:
236 237 self.message = 'Not implemented'
237 238 return False
238 239
239 240 return True
240 241
241 242
242 243 class Campaign(models.Model):
243 244
244 245 template = models.BooleanField(default=False)
245 246 name = models.CharField(max_length=60, unique=True)
246 247 start_date = models.DateTimeField(blank=True, null=True)
247 248 end_date = models.DateTimeField(blank=True, null=True)
248 249 tags = models.CharField(max_length=40, blank=True, null=True)
249 250 description = models.TextField(blank=True, null=True)
250 251 experiments = models.ManyToManyField('Experiment', blank=True)
251 252 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
252 253
253 254 class Meta:
254 255 db_table = 'db_campaigns'
255 256 ordering = ('name',)
256 257
257 258 def __str__(self):
258 259 if self.template:
259 260 return u'{} (template)'.format(self.name)
260 261 else:
261 262 return u'{}'.format(self.name)
262 263
263 264 def jsonify(self):
264 265
265 266 data = {}
266 267
267 268 ignored = ('template')
268 269
269 270 for field in self._meta.fields:
270 271 if field.name in ignored:
271 272 continue
272 273 data[field.name] = field.value_from_object(self)
273 274
274 275 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
275 276 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
276 277
277 278 return data
278 279
279 280 def parms_to_dict(self):
280 281
281 282 params = Params({})
282 283 params.add(self.jsonify(), 'campaigns')
283 284
284 285 for exp in Experiment.objects.filter(campaign = self):
285 286 params.add(exp.jsonify(), 'experiments')
286 287 configurations = Configuration.objects.filter(experiment=exp, type=0)
287 288
288 289 for conf in configurations:
289 290 params.add(conf.jsonify(), 'configurations')
290 291 if conf.device.device_type.name=='rc':
291 292 for line in conf.get_lines():
292 293 params.add(line.jsonify(), 'lines')
293 294
294 295 return params.data
295 296
296 297 def dict_to_parms(self, parms, CONF_MODELS):
297 298
298 299 experiments = Experiment.objects.filter(campaign = self)
299 300
300 301 if experiments:
301 302 for experiment in experiments:
302 303 experiment.delete()
303 304
304 305 for id_exp in parms['experiments']['allIds']:
305 306 exp_parms = parms['experiments']['byId'][id_exp]
306 307 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
307 308 exp = Experiment(name='{}'.format(dum))
308 309 exp.save()
309 310 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
310 311 self.experiments.add(exp)
311 312
312 313 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
313 314
314 315 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
315 316 self.start_date = camp_parms['start_date']
316 317 self.end_date = camp_parms['end_date']
317 318 self.tags = camp_parms['tags']
318 319 self.save()
319 320
320 321 return self
321 322
322 323 def get_experiments_by_radar(self, radar=None):
323 324
324 325 ret = []
325 326 if radar:
326 327 locations = Location.objects.filter(pk=radar)
327 328 else:
328 329 locations = set([e.location for e in self.experiments.all()])
329 330
330 331 for loc in locations:
331 332 dum = {}
332 333 dum['name'] = loc.name
333 334 dum['id'] = loc.pk
334 335 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
335 336 ret.append(dum)
336 337
337 338 return ret
338 339
339 340 def get_absolute_url(self):
340 341 return reverse('url_campaign', args=[str(self.id)])
341 342
342 343 def get_absolute_url_edit(self):
343 344 return reverse('url_edit_campaign', args=[str(self.id)])
344 345
345 346 def get_absolute_url_delete(self):
346 347 return reverse('url_delete_campaign', args=[str(self.id)])
347 348
348 349 def get_absolute_url_export(self):
349 350 return reverse('url_export_campaign', args=[str(self.id)])
350 351
351 352 def get_absolute_url_import(self):
352 353 return reverse('url_import_campaign', args=[str(self.id)])
353 354
354 355
355 356 class RunningExperiment(models.Model):
356 357 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
357 358 running_experiment = models.ManyToManyField('Experiment', blank = True)
358 359 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
359 360
360 361
361 362 class Experiment(models.Model):
362 363
363 364 template = models.BooleanField(default=False)
364 365 name = models.CharField(max_length=40, default='', unique=True)
365 366 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
366 367 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
367 368 start_time = models.TimeField(default='00:00:00')
368 369 end_time = models.TimeField(default='23:59:59')
369 370 task = models.CharField(max_length=36, default='', blank=True, null=True)
370 371 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
371 372 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
372 373 hash = models.CharField(default='', max_length=64, null=True, blank=True)
373 374
374 375 class Meta:
375 376 db_table = 'db_experiments'
376 377 ordering = ('template', 'name')
377 378
378 379 def __str__(self):
379 380 if self.template:
380 381 return u'%s (template)' % (self.name)
381 382 else:
382 383 return u'%s' % (self.name)
383 384
384 385 def jsonify(self):
385 386
386 387 data = {}
387 388
388 389 ignored = ('template')
389 390
390 391 for field in self._meta.fields:
391 392 if field.name in ignored:
392 393 continue
393 394 data[field.name] = field.value_from_object(self)
394 395
395 396 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
396 397 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
397 398 data['location'] = self.location.name
398 399 data['configurations'] = ['{}'.format(conf.pk) for
399 400 conf in Configuration.objects.filter(experiment=self, type=0)]
400 401
401 402 return data
402 403
403 404 @property
404 405 def radar_system(self):
405 406 return self.location
406 407
407 408 def clone(self, **kwargs):
408 409
409 410 confs = Configuration.objects.filter(experiment=self, type=0)
410 411 self.pk = None
411 412 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
412 413 for attr, value in kwargs.items():
413 414 setattr(self, attr, value)
414 415
415 416 self.save()
416 417
417 418 for conf in confs:
418 419 conf.clone(experiment=self, template=False)
419 420
420 421 return self
421 422
422 423 def start(self):
423 424 '''
424 425 Configure and start experiments's devices
425 426 ABS-CGS-DDS-RC-JARS
426 427 '''
427 428
428 429 confs = []
429 430 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
430 431 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
431 432 if rc_mix:
432 433 for conf in allconfs:
433 434 if conf.device.device_type.name == 'rc' and not conf.mix:
434 435 continue
435 436 confs.append(conf)
436 437 else:
437 438 confs = allconfs
438 439
439 440 print("confs: ",confs)
440 441 #try:
441 442 for conf in confs:
442 443 print("conf->",conf)
443 444 conf.stop_device()
444 445 conf.write_device()
445 446 conf.device.conf_active = conf.pk
446 447 conf.device.save()
447 448 conf.start_device()
448 449 time.sleep(1)
449 450 #except:
450 451 #return 0
451 452 return 2
452 453
453 454
454 455 def stop(self):
455 456 '''
456 457 Stop experiments's devices
457 458 DDS-JARS-RC-CGS-ABS
458 459 '''
459 460
460 461 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
461 462 confs = confs.exclude(device__device_type__name='cgs')
462 463 try:
463 464 for conf in confs:
464 465 conf.stop_device()
465 466 except:
466 467 return 0
467 468 return 1
468 469
469 470 def get_status(self):
470 471
471 472 if self.status == 3:
472 473 return
473 474
474 475 confs = Configuration.objects.filter(experiment=self, type=0)
475 476
476 477 for conf in confs:
477 478 conf.status_device()
478 479
479 480 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
480 481
481 482 if total==2*confs.count():
482 483 status = 1
483 484 elif total == 3*confs.count():
484 485 status = 2
485 486 else:
486 487 status = 0
487 488
488 489 self.status = status
489 490 self.save()
490 491
491 492 def status_color(self):
492 493 color = 'muted'
493 494 if self.status == 0:
494 495 color = "danger"
495 496 elif self.status == 1:
496 497 color = "warning"
497 498 elif self.status == 2:
498 499 color = "success"
499 500 elif self.status == 3:
500 501 color = "info"
501 502
502 503 return color
503 504
504 505 def parms_to_dict(self):
505 506
506 507 params = Params({})
507 508 params.add(self.jsonify(), 'experiments')
508 509
509 510 configurations = Configuration.objects.filter(experiment=self, type=0)
510 511
511 512 for conf in configurations:
512 513 params.add(conf.jsonify(), 'configurations')
513 514 if conf.device.device_type.name=='rc':
514 515 for line in conf.get_lines():
515 516 params.add(line.jsonify(), 'lines')
516 517
517 518 return params.data
518 519
519 520 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
520 521
521 522 configurations = Configuration.objects.filter(experiment=self)
522 523
523 524 if id_exp is not None:
524 525 exp_parms = parms['experiments']['byId'][id_exp]
525 526 else:
526 527 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
527 528
528 529 if configurations:
529 530 for configuration in configurations:
530 531 configuration.delete()
531 532
532 533 for id_conf in exp_parms['configurations']:
533 534 conf_parms = parms['configurations']['byId'][id_conf]
534 535 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
535 536 model = CONF_MODELS[conf_parms['device_type']]
536 537 conf = model(
537 538 experiment = self,
538 539 device = device,
539 540 )
540 541 conf.dict_to_parms(parms, id=id_conf)
541 542
542 543
543 544 location, created = Location.objects.get_or_create(name=exp_parms['location'])
544 545 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
545 546 self.location = location
546 547 self.start_time = exp_parms['start_time']
547 548 self.end_time = exp_parms['end_time']
548 549 self.save()
549 550
550 551 return self
551 552
552 553 def get_absolute_url(self):
553 554 return reverse('url_experiment', args=[str(self.id)])
554 555
555 556 def get_absolute_url_edit(self):
556 557 return reverse('url_edit_experiment', args=[str(self.id)])
557 558
558 559 def get_absolute_url_delete(self):
559 560 return reverse('url_delete_experiment', args=[str(self.id)])
560 561
561 562 def get_absolute_url_import(self):
562 563 return reverse('url_import_experiment', args=[str(self.id)])
563 564
564 565 def get_absolute_url_export(self):
565 566 return reverse('url_export_experiment', args=[str(self.id)])
566 567
567 568 def get_absolute_url_start(self):
568 569 return reverse('url_start_experiment', args=[str(self.id)])
569 570
570 571 def get_absolute_url_stop(self):
571 572 return reverse('url_stop_experiment', args=[str(self.id)])
572 573
573 574
574 575 class Configuration(PolymorphicModel):
575 576
576 577 template = models.BooleanField(default=False)
577 578 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
578 579 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
579 580 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
580 581 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
581 582 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
582 583 created_date = models.DateTimeField(auto_now_add=True)
583 584 programmed_date = models.DateTimeField(auto_now=True)
584 585 parameters = models.TextField(default='{}')
585 586 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
586 587 hash = models.CharField(default='', max_length=64, null=True, blank=True)
587 588 message = ""
588 589
589 590 class Meta:
590 591 db_table = 'db_configurations'
591 592 ordering = ('device__device_type__name',)
592 593
593 594 def __str__(self):
594 595
595 596 ret = u'{} '.format(self.device.device_type.name.upper())
596 597
597 598 if 'mix' in [f.name for f in self._meta.get_fields()]:
598 599 if self.mix:
599 600 ret = '{} MIX '.format(self.device.device_type.name.upper())
600 601
601 602 if 'label' in [f.name for f in self._meta.get_fields()]:
602 603 ret += '{}'.format(self.label)
603 604
604 605 if self.template:
605 606 ret += ' (template)'
606 607
607 608 return ret
608 609
609 610 @property
610 611 def name(self):
611 612
612 613 return str(self)
613 614
614 615 def jsonify(self):
615 616
616 617 data = {}
617 618
618 619 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
619 620 'created_date', 'programmed_date', 'template', 'device',
620 621 'experiment')
621 622
622 623 for field in self._meta.fields:
623 624 if field.name in ignored:
624 625 continue
625 626 data[field.name] = field.value_from_object(self)
626 627
627 628 data['device_type'] = self.device.device_type.name
628 629
629 630 if self.device.device_type.name == 'rc':
630 631 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
631 632 data['delays'] = self.get_delays()
632 633 data['pulses'] = self.get_pulses()
633 634
634 635 elif self.device.device_type.name == 'jars':
635 636 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
636 637
637 638 elif self.device.device_type.name == 'dds':
638 639 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
639 640 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
640 641 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
641 642 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
642 643
643 644 elif self.device.device_type.name == 'dds_rest':
644 645 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
645 646 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
646 647 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
647 648 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
648 649 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
649 650 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
650 651 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
651 652 return data
652 653
653 654 def clone(self, **kwargs):
654 655
655 656 self.pk = None
656 657 self.id = None
657 658 for attr, value in kwargs.items():
658 659 setattr(self, attr, value)
659 660
660 661 self.save()
661 662
662 663 return self
663 664
664 665 def parms_to_dict(self):
665 666
666 667 params = Params({})
667 668 params.add(self.jsonify(), 'configurations')
668 669
669 670 if self.device.device_type.name=='rc':
670 671 for line in self.get_lines():
671 672 params.add(line.jsonify(), 'lines')
672 673
673 674 return params.data
674 675
675 676 def parms_to_text(self):
676 677
677 678 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
678 679
679 680
680 681 def parms_to_binary(self):
681 682
682 683 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
683 684
684 685
685 686 def dict_to_parms(self, parameters, id=None):
686 687
687 688 params = Params(parameters)
688 689
689 690 if id:
690 691 data = params.get_conf(id_conf=id)
691 692 else:
692 693 data = params.get_conf(dtype=self.device.device_type.name)
693 694
694 695 if data['device_type']=='rc':
695 696 self.clean_lines()
696 697 lines = data.pop('lines', None)
697 698 for line_id in lines:
698 699 pass
699 700
700 701 for key, value in data.items():
701 702 if key not in ('id', 'device_type'):
702 703 setattr(self, key, value)
703 704
704 705 self.save()
705 706
706 707
707 708 def export_to_file(self, format="json"):
708 709
709 710 content_type = ''
710 711
711 712 if format == 'racp':
712 713 content_type = 'text/plain'
713 714 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
714 715 content = self.parms_to_text(file_format = 'racp')
715 716
716 717 if format == 'text':
717 718 content_type = 'text/plain'
718 719 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
719 720 content = self.parms_to_text()
720 721
721 722 if format == 'binary':
722 723 content_type = 'application/octet-stream'
723 724 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
724 725 content = self.parms_to_binary()
725 726
726 727 if not content_type:
727 728 content_type = 'application/json'
728 729 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
729 730 content = json.dumps(self.parms_to_dict(), indent=2)
730 731
731 732 fields = {'content_type':content_type,
732 733 'filename':filename,
733 734 'content':content
734 735 }
735 736
736 737 return fields
737 738
738 739 def import_from_file(self, fp):
739 740
740 741 parms = {}
741 742
742 743 path, ext = os.path.splitext(fp.name)
743 744
744 745 if ext == '.json':
745 746 parms = json.load(fp)
746 747
747 748 if ext == '.dds':
748 749 lines = fp.readlines()
749 750 parms = dds_data.text_to_dict(lines)
750 751
751 752 if ext == '.racp':
752 753 if self.device.device_type.name == 'jars':
753 754 parms = RacpFile(fp).to_dict()
754 755 parms['filter_parms'] = json.loads(self.filter_parms)
755 756 return parms
756 757 parms = RCFile(fp).to_dict()
757 758
758 759 return parms
759 760
760 761 def status_device(self):
761 762
762 763 self.message = 'Function not implemented'
763 764 return False
764 765
765 766
766 767 def stop_device(self):
767 768
768 769 self.message = 'Function not implemented'
769 770 return False
770 771
771 772
772 773 def start_device(self):
773 774
774 775 self.message = 'Function not implemented'
775 776 return False
776 777
777 778
778 779 def write_device(self, parms):
779 780
780 781 self.message = 'Function not implemented'
781 782 return False
782 783
783 784
784 785 def read_device(self):
785 786
786 787 self.message = 'Function not implemented'
787 788 return False
788 789
789 790
790 791 def get_absolute_url(self):
791 792 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
792 793
793 794 def get_absolute_url_edit(self):
794 795 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
795 796
796 797 def get_absolute_url_delete(self):
797 798 return reverse('url_delete_dev_conf', args=[str(self.id)])
798 799
799 800 def get_absolute_url_import(self):
800 801 return reverse('url_import_dev_conf', args=[str(self.id)])
801 802
802 803 def get_absolute_url_export(self):
803 804 return reverse('url_export_dev_conf', args=[str(self.id)])
804 805
805 806 def get_absolute_url_write(self):
806 807 return reverse('url_write_dev_conf', args=[str(self.id)])
807 808
808 809 def get_absolute_url_read(self):
809 810 return reverse('url_read_dev_conf', args=[str(self.id)])
810 811
811 812 def get_absolute_url_start(self):
812 813 return reverse('url_start_dev_conf', args=[str(self.id)])
813 814
814 815 def get_absolute_url_stop(self):
815 816 return reverse('url_stop_dev_conf', args=[str(self.id)])
816 817
817 818 def get_absolute_url_status(self):
818 819 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,2029 +1,2033
1 1 import ast
2 2 import json
3 3 import hashlib
4 4 from datetime import datetime, timedelta
5 5
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7 from django.utils.safestring import mark_safe
8 8 from django.http import HttpResponseRedirect
9 9 from django.urls import reverse
10 10 from django.db.models import Q
11 11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 12 from django.contrib import messages
13 13 from django.http.request import QueryDict
14 14 from django.contrib.auth.decorators import login_required, user_passes_test
15 15
16 16 from django.utils.timezone import is_aware
17 17
18 18 try:
19 19 from urllib.parse import urlencode
20 20 except ImportError:
21 21 from urllib import urlencode
22 22
23 23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25 25
26 26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 27 from apps.dds.forms import DDSConfigurationForm
28 28 from apps.jars.forms import JARSConfigurationForm
29 29 from apps.cgs.forms import CGSConfigurationForm
30 30 from apps.abs.forms import ABSConfigurationForm
31 31 from apps.usrp.forms import USRPConfigurationForm
32 32 from apps.dds_rest.forms import DDSRestConfigurationForm
33 from apps.atrad.forms import ATRADConfigurationForm
33 34 from .utils import Params
34 35
35 36 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
36 37 from apps.cgs.models import CGSConfiguration
37 38 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
38 39 from apps.usrp.models import USRPConfiguration
39 40 from apps.abs.models import ABSConfiguration
40 41 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
41 42 from apps.dds.models import DDSConfiguration
42 43 from apps.dds_rest.models import DDSRestConfiguration
44 from apps.atrad.models import ATRADConfiguration
43 45
44 46 #from .tasks import task_start
45 47 from radarsys.celery import app
46 48
47 49 #comentario test
48 50 CONF_FORMS = {
49 51 'rc': RCConfigurationForm,
50 52 'dds': DDSConfigurationForm,
51 53 'dds_rest': DDSRestConfigurationForm,
52 54 'jars': JARSConfigurationForm,
53 55 'cgs': CGSConfigurationForm,
54 56 'abs': ABSConfigurationForm,
55 57 'usrp': USRPConfigurationForm,
58 'atrad': ATRADConfigurationForm,
56 59 }
57 60
58 61 CONF_MODELS = {
59 62 'rc': RCConfiguration,
60 63 'dds': DDSConfiguration,
61 64 'dds_rest': DDSRestConfiguration,
62 65 'jars': JARSConfiguration,
63 66 'cgs': CGSConfiguration,
64 67 'abs': ABSConfiguration,
65 68 'usrp': USRPConfiguration,
69 'atrad': ATRADConfiguration,
66 70 }
67 71
68 72 MIX_MODES = {
69 73 '0': 'P',
70 74 '1': 'S',
71 75 }
72 76
73 77 MIX_OPERATIONS = {
74 78 '0': 'OR',
75 79 '1': 'XOR',
76 80 '2': 'AND',
77 81 '3': 'NAND',
78 82 }
79 83
80 84
81 85 def is_developer(user):
82 86
83 87 groups = [str(g.name) for g in user.groups.all()]
84 88 return 'Developer' in groups or user.is_staff
85 89
86 90
87 91 def is_operator(user):
88 92
89 93 groups = [str(g.name) for g in user.groups.all()]
90 94 return 'Operator' in groups or user.is_staff
91 95
92 96
93 97 def has_been_modified(model):
94 98
95 99 prev_hash = model.hash
96 100 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
97 101 if prev_hash != new_hash:
98 102 model.hash = new_hash
99 103 model.save()
100 104 return True
101 105 return False
102 106
103 107
104 108 def index(request):
105 109 kwargs = {'no_sidebar': True}
106 110
107 111 return render(request, 'index.html', kwargs)
108 112
109 113
110 114 def locations(request):
111 115
112 116 page = request.GET.get('page')
113 117 order = ('name',)
114 118
115 119 kwargs = get_paginator(Location, page, order)
116 120
117 121 kwargs['keys'] = ['name', 'description']
118 122 kwargs['title'] = 'Radar System'
119 123 kwargs['suptitle'] = 'List'
120 124 kwargs['no_sidebar'] = True
121 125
122 126 return render(request, 'base_list.html', kwargs)
123 127
124 128
125 129 def location(request, id_loc):
126 130
127 131 location = get_object_or_404(Location, pk=id_loc)
128 132
129 133 kwargs = {}
130 134 kwargs['location'] = location
131 135 kwargs['location_keys'] = ['name', 'description']
132 136
133 137 kwargs['title'] = 'Location'
134 138 kwargs['suptitle'] = 'Details'
135 139
136 140 return render(request, 'location.html', kwargs)
137 141
138 142
139 143 @login_required
140 144 def location_new(request):
141 145
142 146 if request.method == 'GET':
143 147 form = LocationForm()
144 148
145 149 if request.method == 'POST':
146 150 form = LocationForm(request.POST)
147 151
148 152 if form.is_valid():
149 153 form.save()
150 154 return redirect('url_locations')
151 155
152 156 kwargs = {}
153 157 kwargs['form'] = form
154 158 kwargs['title'] = 'Radar System'
155 159 kwargs['suptitle'] = 'New'
156 160 kwargs['button'] = 'Create'
157 161
158 162 return render(request, 'base_edit.html', kwargs)
159 163
160 164
161 165 @login_required
162 166 def location_edit(request, id_loc):
163 167
164 168 location = get_object_or_404(Location, pk=id_loc)
165 169
166 170 if request.method == 'GET':
167 171 form = LocationForm(instance=location)
168 172
169 173 if request.method == 'POST':
170 174 form = LocationForm(request.POST, instance=location)
171 175
172 176 if form.is_valid():
173 177 form.save()
174 178 return redirect('url_locations')
175 179
176 180 kwargs = {}
177 181 kwargs['form'] = form
178 182 kwargs['title'] = 'Location'
179 183 kwargs['suptitle'] = 'Edit'
180 184 kwargs['button'] = 'Update'
181 185
182 186 return render(request, 'base_edit.html', kwargs)
183 187
184 188
185 189 @login_required
186 190 def location_delete(request, id_loc):
187 191
188 192 location = get_object_or_404(Location, pk=id_loc)
189 193
190 194 if request.method == 'POST':
191 195
192 196 if is_developer(request.user):
193 197 location.delete()
194 198 return redirect('url_locations')
195 199
196 200 messages.error(request, 'Not enough permission to delete this object')
197 201 return redirect(location.get_absolute_url())
198 202
199 203 kwargs = {
200 204 'title': 'Delete',
201 205 'suptitle': 'Location',
202 206 'object': location,
203 207 'delete': True
204 208 }
205 209
206 210 return render(request, 'confirm.html', kwargs)
207 211
208 212
209 213 def devices(request):
210 214
211 215 page = request.GET.get('page')
212 216 order = ('location', 'device_type')
213 217
214 218 filters = request.GET.copy()
215 219 kwargs = get_paginator(Device, page, order, filters)
216 220 form = FilterForm(initial=request.GET, extra_fields=['tags'])
217 221
218 222 kwargs['keys'] = ['device_type', 'location',
219 223 'ip_address', 'port_address', 'actions']
220 224 kwargs['title'] = 'Device'
221 225 kwargs['suptitle'] = 'List'
222 226 kwargs['no_sidebar'] = True
223 227 kwargs['form'] = form
224 228 kwargs['add_url'] = reverse('url_add_device')
225 229 filters.pop('page', None)
226 230 kwargs['q'] = urlencode(filters)
227 231 kwargs['menu_devices'] = 'active'
228 232 return render(request, 'base_list.html', kwargs)
229 233
230 234
231 235 def device(request, id_dev):
232 236
233 237 device = get_object_or_404(Device, pk=id_dev)
234 238
235 239 kwargs = {}
236 240 kwargs['device'] = device
237 241 kwargs['device_keys'] = ['device_type',
238 242 'ip_address', 'port_address', 'description']
239 243
240 244 kwargs['title'] = 'Device'
241 245 kwargs['suptitle'] = 'Details'
242 246 kwargs['menu_devices'] = 'active'
243 247
244 248 return render(request, 'device.html', kwargs)
245 249
246 250
247 251 @login_required
248 252 def device_new(request):
249 253
250 254 if request.method == 'GET':
251 255 form = DeviceForm()
252 256
253 257 if request.method == 'POST':
254 258 form = DeviceForm(request.POST)
255 259
256 260 if form.is_valid():
257 261 form.save()
258 262 return redirect('url_devices')
259 263
260 264 kwargs = {}
261 265 kwargs['form'] = form
262 266 kwargs['title'] = 'Device'
263 267 kwargs['suptitle'] = 'New_2'
264 268 kwargs['button'] = 'Create'
265 269 kwargs['menu_devices'] = 'active'
266 270
267 271 return render(request, 'base_edit.html', kwargs)
268 272
269 273
270 274 @login_required
271 275 def device_edit(request, id_dev):
272 276
273 277 device = get_object_or_404(Device, pk=id_dev)
274 278
275 279 if request.method == 'GET':
276 280 form = DeviceForm(instance=device)
277 281
278 282 if request.method == 'POST':
279 283 form = DeviceForm(request.POST, instance=device)
280 284
281 285 if form.is_valid():
282 286 form.save()
283 287 return redirect(device.get_absolute_url())
284 288
285 289 kwargs = {}
286 290 kwargs['form'] = form
287 291 kwargs['title'] = 'Device'
288 292 kwargs['suptitle'] = 'Edit'
289 293 kwargs['button'] = 'Update'
290 294 kwargs['menu_devices'] = 'active'
291 295
292 296 return render(request, 'base_edit.html', kwargs)
293 297
294 298
295 299 @login_required
296 300 def device_delete(request, id_dev):
297 301
298 302 device = get_object_or_404(Device, pk=id_dev)
299 303
300 304 if request.method == 'POST':
301 305
302 306 if is_developer(request.user):
303 307 device.delete()
304 308 return redirect('url_devices')
305 309
306 310 messages.error(request, 'Not enough permission to delete this object')
307 311 return redirect(device.get_absolute_url())
308 312
309 313 kwargs = {
310 314 'title': 'Delete',
311 315 'suptitle': 'Device',
312 316 'object': device,
313 317 'delete': True
314 318 }
315 319 kwargs['menu_devices'] = 'active'
316 320
317 321 return render(request, 'confirm.html', kwargs)
318 322
319 323
320 324 @login_required
321 325 def device_change_ip(request, id_dev):
322 326
323 327 device = get_object_or_404(Device, pk=id_dev)
324 328
325 329 if request.method == 'POST':
326 330
327 331 if is_developer(request.user):
328 332 device.change_ip(**request.POST.dict())
329 333
330 334 print(device.ip_address, device.message)
331 335
332 336 level, message = device.message.split('|')
333 337 messages.add_message(request, level, message)
334 338 else:
335 339 messages.error(
336 340 request, 'Not enough permission to delete this object')
337 341 return redirect(device.get_absolute_url())
338 342
339 343 kwargs = {
340 344 'title': 'Device',
341 345 'suptitle': 'Change IP',
342 346 'object': device,
343 347 'previous': device.get_absolute_url(),
344 348 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
345 349 'message': ' ',
346 350 }
347 351 kwargs['menu_devices'] = 'active'
348 352
349 353 return render(request, 'confirm.html', kwargs)
350 354
351 355
352 356 def campaigns(request):
353 357
354 358 page = request.GET.get('page')
355 359 order = ('-start_date',)
356 360 filters = request.GET.copy()
357 361
358 362 kwargs = get_paginator(Campaign, page, order, filters)
359 363
360 364 form = FilterForm(initial=request.GET, extra_fields=[
361 365 'range_date', 'tags', 'template'])
362 366 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
363 367 kwargs['title'] = 'Campaign'
364 368 kwargs['suptitle'] = 'List'
365 369 kwargs['no_sidebar'] = True
366 370 kwargs['form'] = form
367 371 kwargs['add_url'] = reverse('url_add_campaign')
368 372 filters.pop('page', None)
369 373 kwargs['q'] = urlencode(filters)
370 374 kwargs['menu_campaigns'] = 'active'
371 375
372 376 return render(request, 'base_list.html', kwargs)
373 377
374 378
375 379 def campaign(request, id_camp):
376 380
377 381 campaign = get_object_or_404(Campaign, pk=id_camp)
378 382 experiments = Experiment.objects.filter(campaign=campaign)
379 383
380 384 form = CampaignForm(instance=campaign)
381 385
382 386 kwargs = {}
383 387 kwargs['campaign'] = campaign
384 388 kwargs['campaign_keys'] = ['template', 'name',
385 389 'start_date', 'end_date', 'tags', 'description']
386 390
387 391 kwargs['experiments'] = experiments
388 392 kwargs['experiment_keys'] = [
389 393 'name', 'radar_system', 'start_time', 'end_time']
390 394
391 395 kwargs['title'] = 'Campaign'
392 396 kwargs['suptitle'] = 'Details'
393 397
394 398 kwargs['form'] = form
395 399 kwargs['button'] = 'Add Experiment'
396 400 kwargs['menu_campaigns'] = 'active'
397 401
398 402 return render(request, 'campaign.html', kwargs)
399 403
400 404
401 405 @login_required
402 406 def campaign_new(request):
403 407
404 408 kwargs = {}
405 409
406 410 if request.method == 'GET':
407 411
408 412 if 'template' in request.GET:
409 413 if request.GET['template'] == '0':
410 414 form = NewForm(initial={'create_from': 2},
411 415 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
412 416 else:
413 417 kwargs['button'] = 'Create'
414 418 kwargs['experiments'] = Configuration.objects.filter(
415 419 experiment=request.GET['template'])
416 420 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
417 421 camp = Campaign.objects.get(pk=request.GET['template'])
418 422 form = CampaignForm(instance=camp,
419 423 initial={'name': '{}_{:%Y%m%d%H%M%S}'.format(camp.name, datetime.now()),
420 424 'template': False})
421 425 elif 'blank' in request.GET:
422 426 kwargs['button'] = 'Create'
423 427 form = CampaignForm()
424 428 else:
425 429 form = NewForm()
426 430
427 431 if request.method == 'POST':
428 432 kwargs['button'] = 'Create'
429 433 post = request.POST.copy()
430 434 experiments = []
431 435
432 436 for id_exp in post.getlist('experiments'):
433 437 exp = Experiment.objects.get(pk=id_exp)
434 438 new_exp = exp.clone(template=False)
435 439 experiments.append(new_exp)
436 440
437 441 post.setlist('experiments', [])
438 442
439 443 form = CampaignForm(post)
440 444
441 445 if form.is_valid():
442 446 campaign = form.save(commit=False)
443 447 campaign.author = request.user
444 448 campaign.save()
445 449 for exp in experiments:
446 450 campaign.experiments.add(exp)
447 451
448 452 return redirect('url_campaign', id_camp=campaign.id)
449 453
450 454 kwargs['form'] = form
451 455 kwargs['title'] = 'Campaign'
452 456 kwargs['suptitle'] = 'New'
453 457 kwargs['menu_campaigns'] = 'active'
454 458
455 459 return render(request, 'campaign_edit.html', kwargs)
456 460
457 461
458 462 @login_required
459 463 def campaign_edit(request, id_camp):
460 464
461 465 campaign = get_object_or_404(Campaign, pk=id_camp)
462 466
463 467 if request.method == 'GET':
464 468 form = CampaignForm(instance=campaign)
465 469
466 470 if request.method == 'POST':
467 471 exps = campaign.experiments.all().values_list('pk', flat=True)
468 472 post = request.POST.copy()
469 473 new_exps = post.getlist('experiments')
470 474 post.setlist('experiments', [])
471 475 form = CampaignForm(post, instance=campaign)
472 476
473 477 if form.is_valid():
474 478 camp = form.save()
475 479 for id_exp in new_exps:
476 480 if int(id_exp) in exps:
477 481 exps.pop(id_exp)
478 482 else:
479 483 exp = Experiment.objects.get(pk=id_exp)
480 484 if exp.template:
481 485 camp.experiments.add(exp.clone(template=False))
482 486 else:
483 487 camp.experiments.add(exp)
484 488
485 489 for id_exp in exps:
486 490 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
487 491
488 492 return redirect('url_campaign', id_camp=id_camp)
489 493
490 494 kwargs = {}
491 495 kwargs['form'] = form
492 496 kwargs['title'] = 'Campaign'
493 497 kwargs['suptitle'] = 'Edit'
494 498 kwargs['button'] = 'Update'
495 499 kwargs['menu_campaigns'] = 'active'
496 500
497 501 return render(request, 'campaign_edit.html', kwargs)
498 502
499 503
500 504 @login_required
501 505 def campaign_delete(request, id_camp):
502 506
503 507 campaign = get_object_or_404(Campaign, pk=id_camp)
504 508
505 509 if request.method == 'POST':
506 510 if is_developer(request.user):
507 511
508 512 for exp in campaign.experiments.all():
509 513 for conf in Configuration.objects.filter(experiment=exp):
510 514 conf.delete()
511 515 exp.delete()
512 516 campaign.delete()
513 517
514 518 return redirect('url_campaigns')
515 519
516 520 messages.error(request, 'Not enough permission to delete this object')
517 521 return redirect(campaign.get_absolute_url())
518 522
519 523 kwargs = {
520 524 'title': 'Delete',
521 525 'suptitle': 'Campaign',
522 526 'object': campaign,
523 527 'delete': True
524 528 }
525 529 kwargs['menu_campaigns'] = 'active'
526 530
527 531 return render(request, 'confirm.html', kwargs)
528 532
529 533
530 534 @login_required
531 535 def campaign_export(request, id_camp):
532 536
533 537 campaign = get_object_or_404(Campaign, pk=id_camp)
534 538 content = campaign.parms_to_dict()
535 539 content_type = 'application/json'
536 540 filename = '%s_%s.json' % (campaign.name, campaign.id)
537 541
538 542 response = HttpResponse(content_type=content_type)
539 543 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
540 544 response.write(json.dumps(content, indent=2))
541 545
542 546 return response
543 547
544 548
545 549 @login_required
546 550 def campaign_import(request, id_camp):
547 551
548 552 campaign = get_object_or_404(Campaign, pk=id_camp)
549 553
550 554 if request.method == 'GET':
551 555 file_form = UploadFileForm()
552 556
553 557 if request.method == 'POST':
554 558 file_form = UploadFileForm(request.POST, request.FILES)
555 559
556 560 if file_form.is_valid():
557 561 new_camp = campaign.dict_to_parms(
558 562 json.load(request.FILES['file']), CONF_MODELS)
559 563 messages.success(
560 564 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
561 565 return redirect(new_camp.get_absolute_url_edit())
562 566
563 567 messages.error(request, "Could not import parameters from file")
564 568
565 569 kwargs = {}
566 570 kwargs['title'] = 'Campaign'
567 571 kwargs['form'] = file_form
568 572 kwargs['suptitle'] = 'Importing file'
569 573 kwargs['button'] = 'Import'
570 574 kwargs['menu_campaigns'] = 'active'
571 575
572 576 return render(request, 'campaign_import.html', kwargs)
573 577
574 578
575 579 def experiments(request):
576 580
577 581 page = request.GET.get('page')
578 582 order = ('location',)
579 583 filters = request.GET.copy()
580 584
581 585 if 'my experiments' in filters:
582 586 filters.pop('my experiments', None)
583 587 filters['mine'] = request.user.id
584 588
585 589 kwargs = get_paginator(Experiment, page, order, filters)
586 590
587 591 fields = ['tags', 'template']
588 592 if request.user.is_authenticated:
589 593 fields.append('my experiments')
590 594
591 595 form = FilterForm(initial=request.GET, extra_fields=fields)
592 596
593 597 kwargs['keys'] = ['name', 'radar_system',
594 598 'start_time', 'end_time', 'actions']
595 599 kwargs['title'] = 'Experiment'
596 600 kwargs['suptitle'] = 'List'
597 601 kwargs['no_sidebar'] = True
598 602 kwargs['form'] = form
599 603 kwargs['add_url'] = reverse('url_add_experiment')
600 604 filters = request.GET.copy()
601 605 filters.pop('page', None)
602 606 kwargs['q'] = urlencode(filters)
603 607 kwargs['menu_experiments'] = 'active'
604 608
605 609 return render(request, 'base_list.html', kwargs)
606 610
607 611
608 612 def experiment(request, id_exp):
609 613
610 614 experiment = get_object_or_404(Experiment, pk=id_exp)
611 615
612 616 configurations = Configuration.objects.filter(
613 617 experiment=experiment, type=0)
614 618
615 619 kwargs = {}
616 620
617 621 kwargs['experiment_keys'] = ['template', 'radar_system',
618 622 'name', 'freq', 'start_time', 'end_time']
619 623 kwargs['experiment'] = experiment
620 624 kwargs['configuration_keys'] = ['name', 'device__ip_address',
621 625 'device__port_address', 'device__status']
622 626 kwargs['configurations'] = configurations
623 627 kwargs['title'] = 'Experiment'
624 628 kwargs['suptitle'] = 'Details'
625 629 kwargs['button'] = 'Add Configuration'
626 630 kwargs['menu_experiments'] = 'active'
627 631
628 632 ###### SIDEBAR ######
629 633 kwargs.update(sidebar(experiment=experiment))
630 634
631 635 return render(request, 'experiment.html', kwargs)
632 636
633 637
634 638 @login_required
635 639 def experiment_new(request, id_camp=None):
636 640
637 641 if not is_developer(request.user):
638 642 messages.error(
639 643 request, 'Developer required, to create new Experiments')
640 644 return redirect('index')
641 645 kwargs = {}
642 646
643 647 if request.method == 'GET':
644 648 if 'template' in request.GET:
645 649 if request.GET['template'] == '0':
646 650 form = NewForm(initial={'create_from': 2},
647 651 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
648 652 else:
649 653 kwargs['button'] = 'Create'
650 654 kwargs['configurations'] = Configuration.objects.filter(
651 655 experiment=request.GET['template'])
652 656 kwargs['configuration_keys'] = ['name', 'device__name',
653 657 'device__ip_address', 'device__port_address']
654 658 exp = Experiment.objects.get(pk=request.GET['template'])
655 659 form = ExperimentForm(instance=exp,
656 660 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
657 661 'template': False})
658 662 elif 'blank' in request.GET:
659 663 kwargs['button'] = 'Create'
660 664 form = ExperimentForm()
661 665 else:
662 666 form = NewForm()
663 667
664 668 if request.method == 'POST':
665 669 form = ExperimentForm(request.POST)
666 670 if form.is_valid():
667 671 experiment = form.save(commit=False)
668 672 experiment.author = request.user
669 673 experiment.save()
670 674
671 675 if 'template' in request.GET:
672 676 configurations = Configuration.objects.filter(
673 677 experiment=request.GET['template'], type=0)
674 678 for conf in configurations:
675 679 conf.clone(experiment=experiment, template=False)
676 680
677 681 return redirect('url_experiment', id_exp=experiment.id)
678 682
679 683 kwargs['form'] = form
680 684 kwargs['title'] = 'Experiment'
681 685 kwargs['suptitle'] = 'New'
682 686 kwargs['menu_experiments'] = 'active'
683 687
684 688 return render(request, 'experiment_edit.html', kwargs)
685 689
686 690
687 691 @login_required
688 692 def experiment_edit(request, id_exp):
689 693
690 694 experiment = get_object_or_404(Experiment, pk=id_exp)
691 695
692 696 if request.method == 'GET':
693 697 form = ExperimentForm(instance=experiment)
694 698
695 699 if request.method == 'POST':
696 700 form = ExperimentForm(request.POST, instance=experiment)
697 701
698 702 if form.is_valid():
699 703 experiment = form.save()
700 704 return redirect('url_experiment', id_exp=experiment.id)
701 705
702 706 kwargs = {}
703 707 kwargs['form'] = form
704 708 kwargs['title'] = 'Experiment'
705 709 kwargs['suptitle'] = 'Edit'
706 710 kwargs['button'] = 'Update'
707 711 kwargs['menu_experiments'] = 'active'
708 712
709 713 return render(request, 'experiment_edit.html', kwargs)
710 714
711 715
712 716 @login_required
713 717 def experiment_delete(request, id_exp):
714 718
715 719 experiment = get_object_or_404(Experiment, pk=id_exp)
716 720
717 721 if request.method == 'POST':
718 722 if is_developer(request.user):
719 723 for conf in Configuration.objects.filter(experiment=experiment):
720 724 conf.delete()
721 725 experiment.delete()
722 726 return redirect('url_experiments')
723 727
724 728 messages.error(request, 'Not enough permission to delete this object')
725 729 return redirect(experiment.get_absolute_url())
726 730
727 731 kwargs = {
728 732 'title': 'Delete',
729 733 'suptitle': 'Experiment',
730 734 'object': experiment,
731 735 'delete': True
732 736 }
733 737
734 738 return render(request, 'confirm.html', kwargs)
735 739
736 740
737 741 @login_required
738 742 def experiment_export(request, id_exp):
739 743
740 744 experiment = get_object_or_404(Experiment, pk=id_exp)
741 745 content = experiment.parms_to_dict()
742 746 content_type = 'application/json'
743 747 filename = '%s_%s.json' % (experiment.name, experiment.id)
744 748
745 749 response = HttpResponse(content_type=content_type)
746 750 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
747 751 response.write(json.dumps(content, indent=2))
748 752
749 753 return response
750 754
751 755
752 756 @login_required
753 757 def experiment_import(request, id_exp):
754 758
755 759 experiment = get_object_or_404(Experiment, pk=id_exp)
756 760 configurations = Configuration.objects.filter(experiment=experiment)
757 761
758 762 if request.method == 'GET':
759 763 file_form = UploadFileForm()
760 764
761 765 if request.method == 'POST':
762 766 file_form = UploadFileForm(request.POST, request.FILES)
763 767
764 768 if file_form.is_valid():
765 769 new_exp = experiment.dict_to_parms(
766 770 json.load(request.FILES['file']), CONF_MODELS)
767 771 messages.success(
768 772 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
769 773 return redirect(new_exp.get_absolute_url_edit())
770 774
771 775 messages.error(request, "Could not import parameters from file")
772 776
773 777 kwargs = {}
774 778 kwargs['title'] = 'Experiment'
775 779 kwargs['form'] = file_form
776 780 kwargs['suptitle'] = 'Importing file'
777 781 kwargs['button'] = 'Import'
778 782 kwargs['menu_experiments'] = 'active'
779 783
780 784 kwargs.update(sidebar(experiment=experiment))
781 785
782 786 return render(request, 'experiment_import.html', kwargs)
783 787
784 788
785 789 @login_required
786 790 def experiment_start(request, id_exp):
787 791
788 792 exp = get_object_or_404(Experiment, pk=id_exp)
789 793
790 794 if exp.status == 2:
791 795 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
792 796 else:
793 797 exp.status = exp.start()
794 798 if exp.status == 0:
795 799 messages.error(request, 'Experiment {} not start'.format(exp))
796 800 if exp.status == 2:
797 801 messages.success(request, 'Experiment {} started'.format(exp))
798 802
799 803 exp.save()
800 804
801 805 return redirect(exp.get_absolute_url())
802 806
803 807
804 808 @login_required
805 809 def experiment_stop(request, id_exp):
806 810
807 811 exp = get_object_or_404(Experiment, pk=id_exp)
808 812
809 813 if exp.status == 2:
810 814 exp.status = exp.stop()
811 815 exp.save()
812 816 messages.success(request, 'Experiment {} stopped'.format(exp))
813 817 else:
814 818 messages.error(request, 'Experiment {} not running'.format(exp))
815 819
816 820 return redirect(exp.get_absolute_url())
817 821
818 822
819 823 def experiment_status(request, id_exp):
820 824
821 825 exp = get_object_or_404(Experiment, pk=id_exp)
822 826
823 827 exp.get_status()
824 828
825 829 return redirect(exp.get_absolute_url())
826 830
827 831
828 832 @login_required
829 833 def experiment_mix(request, id_exp):
830 834
831 835 experiment = get_object_or_404(Experiment, pk=id_exp)
832 836 rc_confs = [conf for conf in RCConfiguration.objects.filter(
833 837 experiment=id_exp,
834 838 type=0,
835 839 mix=False)]
836 840
837 841 if len(rc_confs) < 2:
838 842 messages.warning(
839 843 request, 'You need at least two RC Configurations to make a mix')
840 844 return redirect(experiment.get_absolute_url())
841 845
842 846 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
843 847
844 848 if mix_confs:
845 849 mix = mix_confs[0]
846 850 else:
847 851 mix = RCConfiguration(experiment=experiment,
848 852 device=rc_confs[0].device,
849 853 ipp=rc_confs[0].ipp,
850 854 clock_in=rc_confs[0].clock_in,
851 855 clock_divider=rc_confs[0].clock_divider,
852 856 mix=True,
853 857 parameters='')
854 858 mix.save()
855 859
856 860 line_type = RCLineType.objects.get(name='mix')
857 861 print("VIew obteniendo len getlines")
858 862 print(len(rc_confs[0].get_lines()))
859 863 for i in range(len(rc_confs[0].get_lines())):
860 864 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
861 865 line.save()
862 866
863 867 initial = {'name': mix.name,
864 868 'result': parse_mix_result(mix.parameters),
865 869 'delay': 0,
866 870 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
867 871 }
868 872
869 873 if request.method == 'GET':
870 874 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
871 875
872 876 if request.method == 'POST':
873 877 result = mix.parameters
874 878
875 879 if '{}|'.format(request.POST['experiment']) in result:
876 880 messages.error(request, 'Configuration already added')
877 881 else:
878 882 if 'operation' in request.POST:
879 883 operation = MIX_OPERATIONS[request.POST['operation']]
880 884 else:
881 885 operation = ' '
882 886
883 887 mode = MIX_MODES[request.POST['mode']]
884 888
885 889 if result:
886 890 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
887 891 request.POST['experiment'],
888 892 mode,
889 893 operation,
890 894 float(
891 895 request.POST['delay']),
892 896 parse_mask(
893 897 request.POST.getlist('mask'))
894 898 )
895 899 else:
896 900 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
897 901 mode,
898 902 operation,
899 903 float(request.POST['delay']),
900 904 parse_mask(
901 905 request.POST.getlist('mask'))
902 906 )
903 907
904 908 mix.parameters = result
905 909 mix.save()
906 910 mix.update_pulses()
907 911
908 912 initial['result'] = parse_mix_result(result)
909 913 initial['name'] = mix.name
910 914
911 915 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
912 916
913 917 kwargs = {
914 918 'title': 'Experiment',
915 919 'suptitle': 'Mix Configurations',
916 920 'form': form,
917 921 'extra_button': 'Delete',
918 922 'button': 'Add',
919 923 'cancel': 'Back',
920 924 'previous': experiment.get_absolute_url(),
921 925 'id_exp': id_exp,
922 926
923 927 }
924 928 kwargs['menu_experiments'] = 'active'
925 929
926 930 return render(request, 'experiment_mix.html', kwargs)
927 931
928 932
929 933 @login_required
930 934 def experiment_mix_delete(request, id_exp):
931 935
932 936 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
933 937 values = conf.parameters.split('-')
934 938 conf.parameters = '-'.join(values[:-1])
935 939 conf.save()
936 940
937 941 return redirect('url_mix_experiment', id_exp=id_exp)
938 942
939 943
940 944 def experiment_summary(request, id_exp):
941 945
942 946 experiment = get_object_or_404(Experiment, pk=id_exp)
943 947 configurations = Configuration.objects.filter(
944 948 experiment=experiment, type=0)
945 949
946 950 kwargs = {}
947 951 kwargs['experiment_keys'] = ['radar_system',
948 952 'name', 'freq', 'start_time', 'end_time']
949 953 kwargs['experiment'] = experiment
950 954 kwargs['configurations'] = []
951 955 kwargs['title'] = 'Experiment Summary'
952 956 kwargs['suptitle'] = 'Details'
953 957 kwargs['button'] = 'Verify Parameters'
954 958
955 959 c_vel = 3.0*(10**8) # m/s
956 960 ope_freq = experiment.freq*(10**6) # 1/s
957 961 radar_lambda = c_vel/ope_freq # m
958 962 kwargs['radar_lambda'] = radar_lambda
959 963
960 964 ipp = None
961 965 nsa = 1
962 966 code_id = 0
963 967 tx_line = {}
964 968
965 969 for configuration in configurations.filter(device__device_type__name = 'rc'):
966 970
967 971 if configuration.mix:
968 972 continue
969 973 conf = {'conf': configuration}
970 974 conf['keys'] = []
971 975 conf['NTxs'] = configuration.ntx
972 976 conf['keys'].append('NTxs')
973 977 ipp = configuration.ipp
974 978 conf['IPP'] = ipp
975 979 conf['keys'].append('IPP')
976 980 lines = configuration.get_lines(line_type__name='tx')
977 981
978 982 for tx_line in lines:
979 983 tx_params = json.loads(tx_line.params)
980 984 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
981 985 conf['keys'].append(tx_line.get_name())
982 986 delays = tx_params['delays']
983 987 if delays not in ('', '0'):
984 988 n = len(delays.split(','))
985 989 taus = '{} Taus: {}'.format(n, delays)
986 990 else:
987 991 taus = '-'
988 992 conf['Taus ({})'.format(tx_line.get_name())] = taus
989 993 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
990 994 for code_line in configuration.get_lines(line_type__name='codes'):
991 995 code_params = json.loads(code_line.params)
992 996 code_id = code_params['code']
993 997 if tx_line.pk == int(code_params['TX_ref']):
994 998 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
995 999 '-'.join(code_params['codes']))
996 1000 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
997 1001
998 1002 for windows_line in configuration.get_lines(line_type__name='windows'):
999 1003 win_params = json.loads(windows_line.params)
1000 1004 if tx_line.pk == int(win_params['TX_ref']):
1001 1005 windows = ''
1002 1006 nsa = win_params['params'][0]['number_of_samples']
1003 1007 for i, params in enumerate(win_params['params']):
1004 1008 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1005 1009 i, **params)
1006 1010 conf['Window'] = mark_safe(windows)
1007 1011 conf['keys'].append('Window')
1008 1012
1009 1013 kwargs['configurations'].append(conf)
1010 1014
1011 1015 for configuration in configurations.filter(device__device_type__name = 'jars'):
1012 1016
1013 1017 conf = {'conf': configuration}
1014 1018 conf['keys'] = []
1015 1019 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1016 1020 conf['keys'].append('Type of Data')
1017 1021 channels_number = configuration.channels_number
1018 1022 exp_type = configuration.exp_type
1019 1023 fftpoints = configuration.fftpoints
1020 1024 filter_parms = json.loads(configuration.filter_parms)
1021 1025 spectral_number = configuration.spectral_number
1022 1026 acq_profiles = configuration.acq_profiles
1023 1027 cohe_integr = configuration.cohe_integr
1024 1028 profiles_block = configuration.profiles_block
1025 1029
1026 1030 conf['Num of Profiles'] = acq_profiles
1027 1031 conf['keys'].append('Num of Profiles')
1028 1032
1029 1033 conf['Prof per Block'] = profiles_block
1030 1034 conf['keys'].append('Prof per Block')
1031 1035
1032 1036 conf['Blocks per File'] = configuration.raw_data_blocks
1033 1037 conf['keys'].append('Blocks per File')
1034 1038
1035 1039 if exp_type == 0: # Short
1036 1040 bytes_ = 2
1037 1041 b = nsa*2*bytes_*channels_number
1038 1042 else: # Float
1039 1043 bytes_ = 4
1040 1044 channels = channels_number + spectral_number
1041 1045 b = nsa*2*bytes_*fftpoints*channels
1042 1046
1043 1047 codes_num = 7
1044 1048 if code_id == 2:
1045 1049 codes_num = 7
1046 1050 elif code_id == 12:
1047 1051 codes_num = 15
1048 1052
1049 1053 #Jars filter values:
1050 1054
1051 1055 clock = float(filter_parms['clock'])
1052 1056 filter_2 = int(filter_parms['cic_2'])
1053 1057 filter_5 = int(filter_parms['cic_5'])
1054 1058 filter_fir = int(filter_parms['fir'])
1055 1059 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1056 1060
1057 1061 #Jars values:
1058 1062 if ipp is not None:
1059 1063 IPP_units = ipp/0.15*Fs_MHz
1060 1064 IPP_us = IPP_units / Fs_MHz
1061 1065 IPP_s = IPP_units / (Fs_MHz * (10**6))
1062 1066 Ts = 1/(Fs_MHz*(10**6))
1063 1067
1064 1068 Va = radar_lambda/(4*Ts*cohe_integr)
1065 1069 rate_bh = ((nsa-codes_num)*channels_number*2 *
1066 1070 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1067 1071 rate_gh = rate_bh/(1024*1024*1024)
1068 1072
1069 1073 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1070 1074 conf['keys'].append('Time per Block')
1071 1075 conf['Acq time'] = IPP_s * acq_profiles
1072 1076 conf['keys'].append('Acq time')
1073 1077 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1074 1078 conf['keys'].append('Data rate')
1075 1079 conf['Va (m/s)'] = Va
1076 1080 conf['keys'].append('Va (m/s)')
1077 1081 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1078 1082 conf['keys'].append('Vrange (m/s)')
1079 1083
1080 1084 kwargs['configurations'].append(conf)
1081 1085 kwargs['menu_experiments'] = 'active'
1082 1086
1083 1087 ###### SIDEBAR ######
1084 1088 kwargs.update(sidebar(experiment=experiment))
1085 1089
1086 1090 return render(request, 'experiment_summary.html', kwargs)
1087 1091
1088 1092
1089 1093 @login_required
1090 1094 def experiment_verify(request, id_exp):
1091 1095
1092 1096 experiment = get_object_or_404(Experiment, pk=id_exp)
1093 1097 experiment_data = experiment.parms_to_dict()
1094 1098 configurations = Configuration.objects.filter(
1095 1099 experiment=experiment, type=0)
1096 1100
1097 1101 kwargs = {}
1098 1102
1099 1103 kwargs['experiment_keys'] = ['template',
1100 1104 'radar_system', 'name', 'start_time', 'end_time']
1101 1105 kwargs['experiment'] = experiment
1102 1106
1103 1107 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1104 1108 'device__port_address', 'device__status']
1105 1109 kwargs['configurations'] = configurations
1106 1110 kwargs['experiment_data'] = experiment_data
1107 1111
1108 1112 kwargs['title'] = 'Verify Experiment'
1109 1113 kwargs['suptitle'] = 'Parameters'
1110 1114
1111 1115 kwargs['button'] = 'Update'
1112 1116
1113 1117 jars_conf = False
1114 1118 rc_conf = False
1115 1119 dds_conf = False
1116 1120
1117 1121 for configuration in configurations:
1118 1122 #-------------------- JARS -----------------------:
1119 1123 if configuration.device.device_type.name == 'jars':
1120 1124 jars_conf = True
1121 1125 jars = configuration
1122 1126 kwargs['jars_conf'] = jars_conf
1123 1127 filter_parms = json.loads(jars.filter_parms)
1124 1128 kwargs['filter_parms'] = filter_parms
1125 1129 #--Sampling Frequency
1126 1130 clock = filter_parms['clock']
1127 1131 filter_2 = filter_parms['cic_2']
1128 1132 filter_5 = filter_parms['cic_5']
1129 1133 filter_fir = filter_parms['fir']
1130 1134 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1131 1135
1132 1136 kwargs['samp_freq_jars'] = samp_freq_jars
1133 1137 kwargs['jars'] = configuration
1134 1138
1135 1139 #--------------------- RC ----------------------:
1136 1140 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1137 1141 rc_conf = True
1138 1142 rc = configuration
1139 1143
1140 1144 rc_parms = configuration.parms_to_dict()
1141 1145
1142 1146 win_lines = rc.get_lines(line_type__name='windows')
1143 1147 if win_lines:
1144 1148 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1145 1149 #--Sampling Frequency
1146 1150 samp_freq_rc = 0.15/dh
1147 1151 kwargs['samp_freq_rc'] = samp_freq_rc
1148 1152
1149 1153 kwargs['rc_conf'] = rc_conf
1150 1154 kwargs['rc'] = configuration
1151 1155
1152 1156 #-------------------- DDS ----------------------:
1153 1157 if configuration.device.device_type.name == 'dds':
1154 1158 dds_conf = True
1155 1159 dds = configuration
1156 1160 dds_parms = configuration.parms_to_dict()
1157 1161
1158 1162 kwargs['dds_conf'] = dds_conf
1159 1163 kwargs['dds'] = configuration
1160 1164
1161 1165 #------------Validation------------:
1162 1166 #Clock
1163 1167 if dds_conf and rc_conf and jars_conf:
1164 1168 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1165 1169 messages.warning(request, "Devices don't have the same clock.")
1166 1170 elif rc_conf and jars_conf:
1167 1171 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1168 1172 messages.warning(request, "Devices don't have the same clock.")
1169 1173 elif rc_conf and dds_conf:
1170 1174 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1171 1175 messages.warning(request, "Devices don't have the same clock.")
1172 1176 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1173 1177 messages.warning(
1174 1178 request, "Devices don't have the same Frequency A.")
1175 1179
1176 1180 #------------POST METHOD------------:
1177 1181 if request.method == 'POST':
1178 1182 if request.POST['suggest_clock']:
1179 1183 try:
1180 1184 suggest_clock = float(request.POST['suggest_clock'])
1181 1185 except:
1182 1186 messages.warning(request, "Invalid value in CLOCK IN.")
1183 1187 return redirect('url_verify_experiment', id_exp=experiment.id)
1184 1188 else:
1185 1189 suggest_clock = ""
1186 1190 if suggest_clock:
1187 1191 if rc_conf:
1188 1192 rc.clock_in = suggest_clock
1189 1193 rc.save()
1190 1194 if jars_conf:
1191 1195 filter_parms = jars.filter_parms
1192 1196 filter_parms = ast.literal_eval(filter_parms)
1193 1197 filter_parms['clock'] = suggest_clock
1194 1198 jars.filter_parms = json.dumps(filter_parms)
1195 1199 jars.save()
1196 1200 kwargs['filter_parms'] = filter_parms
1197 1201 if dds_conf:
1198 1202 dds.clock = suggest_clock
1199 1203 dds.save()
1200 1204
1201 1205 if request.POST['suggest_frequencyA']:
1202 1206 try:
1203 1207 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1204 1208 except:
1205 1209 messages.warning(request, "Invalid value in FREQUENCY A.")
1206 1210 return redirect('url_verify_experiment', id_exp=experiment.id)
1207 1211 else:
1208 1212 suggest_frequencyA = ""
1209 1213 if suggest_frequencyA:
1210 1214 if jars_conf:
1211 1215 filter_parms = jars.filter_parms
1212 1216 filter_parms = ast.literal_eval(filter_parms)
1213 1217 filter_parms['fch'] = suggest_frequencyA
1214 1218 jars.filter_parms = json.dumps(filter_parms)
1215 1219 jars.save()
1216 1220 kwargs['filter_parms'] = filter_parms
1217 1221 if dds_conf:
1218 1222 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1219 1223 dds.save()
1220 1224
1221 1225 kwargs['menu_experiments'] = 'active'
1222 1226 kwargs.update(sidebar(experiment=experiment))
1223 1227 return render(request, 'experiment_verify.html', kwargs)
1224 1228
1225 1229
1226 1230 def parse_mix_result(s):
1227 1231
1228 1232 values = s.split('-')
1229 1233 html = 'EXP MOD OPE DELAY MASK\r\n'
1230 1234
1231 1235 if not values or values[0] in ('', ' '):
1232 1236 return mark_safe(html)
1233 1237
1234 1238 for i, value in enumerate(values):
1235 1239 if not value:
1236 1240 continue
1237 1241 pk, mode, operation, delay, mask = value.split('|')
1238 1242 conf = RCConfiguration.objects.get(pk=pk)
1239 1243 if i == 0:
1240 1244 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1241 1245 conf.name,
1242 1246 mode,
1243 1247 ' ',
1244 1248 delay,
1245 1249 mask)
1246 1250 else:
1247 1251 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1248 1252 conf.name,
1249 1253 mode,
1250 1254 operation,
1251 1255 delay,
1252 1256 mask)
1253 1257
1254 1258 return mark_safe(html)
1255 1259
1256 1260
1257 1261 def parse_mask(l):
1258 1262
1259 1263 values = []
1260 1264
1261 1265 for x in range(16):
1262 1266 if '{}'.format(x) in l:
1263 1267 values.append(1)
1264 1268 else:
1265 1269 values.append(0)
1266 1270
1267 1271 values.reverse()
1268 1272
1269 1273 return int(''.join([str(x) for x in values]), 2)
1270 1274
1271 1275
1272 1276 def dev_confs(request):
1273 1277
1274 1278 page = request.GET.get('page')
1275 1279 order = ('-programmed_date', )
1276 1280 filters = request.GET.copy()
1277 1281 if 'my configurations' in filters:
1278 1282 filters.pop('my configurations', None)
1279 1283 filters['mine'] = request.user.id
1280 1284 kwargs = get_paginator(Configuration, page, order, filters)
1281 1285 fields = ['tags', 'template', 'historical']
1282 1286 if request.user.is_authenticated:
1283 1287 fields.append('my configurations')
1284 1288 form = FilterForm(initial=request.GET, extra_fields=fields)
1285 1289 kwargs['keys'] = ['name', 'experiment',
1286 1290 'type', 'programmed_date', 'actions']
1287 1291 kwargs['title'] = 'Configuration'
1288 1292 kwargs['suptitle'] = 'List'
1289 1293 kwargs['no_sidebar'] = True
1290 1294 kwargs['form'] = form
1291 1295 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1292 1296 filters = request.GET.copy()
1293 1297 filters.pop('page', None)
1294 1298 kwargs['q'] = urlencode(filters)
1295 1299 kwargs['menu_configurations'] = 'active'
1296 1300
1297 1301 return render(request, 'base_list.html', kwargs)
1298 1302
1299 1303
1300 1304 def dev_conf(request, id_conf):
1301 1305
1302 1306 conf = get_object_or_404(Configuration, pk=id_conf)
1303 1307
1304 1308 return redirect(conf.get_absolute_url())
1305 1309
1306 1310
1307 1311 @login_required
1308 1312 def dev_conf_new(request, id_exp=0, id_dev=0):
1309 1313
1310 1314 if not is_developer(request.user):
1311 1315 messages.error(
1312 1316 request, 'Developer required, to create new configurations')
1313 1317 return redirect('index')
1314 1318
1315 1319 initial = {}
1316 1320 kwargs = {}
1317 1321
1318 1322 if id_exp != 0:
1319 1323 initial['experiment'] = id_exp
1320 1324
1321 1325 if id_dev != 0:
1322 1326 initial['device'] = id_dev
1323 1327
1324 1328 if request.method == 'GET':
1325 1329
1326 1330 if id_dev:
1327 1331 kwargs['button'] = 'Create'
1328 1332 device = Device.objects.get(pk=id_dev)
1329 1333 DevConfForm = CONF_FORMS[device.device_type.name]
1330 1334 initial['name'] = request.GET['name']
1331 1335 form = DevConfForm(initial=initial)
1332 1336 else:
1333 1337 if 'template' in request.GET:
1334 1338 if request.GET['template'] == '0':
1335 1339 choices = [(conf.pk, '{}'.format(conf))
1336 1340 for conf in Configuration.objects.filter(template=True)]
1337 1341 form = NewForm(initial={'create_from': 2},
1338 1342 template_choices=choices)
1339 1343 else:
1340 1344 kwargs['button'] = 'Create'
1341 1345 conf = Configuration.objects.get(
1342 1346 pk=request.GET['template'])
1343 1347 id_dev = conf.device.pk
1344 1348 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1345 1349 form = DevConfForm(instance=conf,
1346 1350 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1347 1351 'template': False,
1348 1352 'experiment': id_exp})
1349 1353 elif 'blank' in request.GET:
1350 1354 kwargs['button'] = 'Create'
1351 1355 form = ConfigurationForm(initial=initial)
1352 1356 else:
1353 1357 form = NewForm()
1354 1358
1355 1359 if request.method == 'POST':
1356 1360
1357 1361 device = Device.objects.get(pk=request.POST['device'])
1358 1362 DevConfForm = CONF_FORMS[device.device_type.name]
1359 1363
1360 1364 form = DevConfForm(request.POST)
1361 1365 kwargs['button'] = 'Create'
1362 1366 if form.is_valid():
1363 1367 conf = form.save(commit=False)
1364 1368 conf.author = request.user
1365 1369 conf.save()
1366 1370
1367 1371 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1368 1372 lines = RCLine.objects.filter(
1369 1373 rc_configuration=request.GET['template'])
1370 1374 for line in lines:
1371 1375 line.clone(rc_configuration=conf)
1372 1376
1373 1377 new_lines = conf.get_lines()
1374 1378 for line in new_lines:
1375 1379 line_params = json.loads(line.params)
1376 1380 if 'TX_ref' in line_params:
1377 1381 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1378 1382 line_params['TX_ref'] = ['{}'.format(
1379 1383 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1380 1384 line.params = json.dumps(line_params)
1381 1385 line.save()
1382 1386 elif conf.device.device_type.name == 'rc':
1383 1387 clk = RCClock(rc_configuration=conf)
1384 1388 clk.save()
1385 1389
1386 1390 return redirect('url_dev_conf', id_conf=conf.pk)
1387 1391
1388 1392 kwargs['id_exp'] = id_exp
1389 1393 kwargs['form'] = form
1390 1394 kwargs['title'] = 'Configuration'
1391 1395 kwargs['suptitle'] = 'New'
1392 1396 kwargs['menu_configurations'] = 'active'
1393 1397
1394 1398 if id_dev != 0:
1395 1399 device = Device.objects.get(pk=id_dev)
1396 1400 kwargs['device'] = device.device_type.name
1397 1401 print(id_exp)
1398 1402 return render(request, 'dev_conf_edit.html', kwargs)
1399 1403
1400 1404
1401 1405 @login_required
1402 1406 def dev_conf_edit(request, id_conf):
1403 1407
1404 1408 conf = get_object_or_404(Configuration, pk=id_conf)
1405 1409
1406 1410 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1407 1411
1408 1412 if request.method == 'GET':
1409 1413 form = DevConfForm(instance=conf)
1410 1414
1411 1415 if request.method == 'POST':
1412 1416 form = DevConfForm(request.POST, instance=conf)
1413 1417
1414 1418 if form.is_valid():
1415 1419 form.save()
1416 1420 return redirect('url_dev_conf', id_conf=id_conf)
1417 1421
1418 1422 kwargs = {}
1419 1423 kwargs['form'] = form
1420 1424 kwargs['title'] = 'Device Configuration'
1421 1425 kwargs['suptitle'] = 'Edit'
1422 1426 kwargs['button'] = 'Update'
1423 1427 kwargs['menu_configurations'] = 'active'
1424 1428
1425 1429 ###### SIDEBAR ######
1426 1430 kwargs.update(sidebar(conf=conf))
1427 1431
1428 1432 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1429 1433
1430 1434
1431 1435 @login_required
1432 1436 def dev_conf_start(request, id_conf):
1433 1437
1434 1438 conf = get_object_or_404(Configuration, pk=id_conf)
1435 1439
1436 1440 if conf.start_device():
1437 1441 messages.success(request, conf.message)
1438 1442 else:
1439 1443 messages.error(request, conf.message)
1440 1444
1441 1445 #conf.status_device()
1442 1446
1443 1447 return redirect(conf.get_absolute_url())
1444 1448
1445 1449
1446 1450 @login_required
1447 1451 def dev_conf_stop(request, id_conf):
1448 1452
1449 1453 conf = get_object_or_404(Configuration, pk=id_conf)
1450 1454
1451 1455 if conf.stop_device():
1452 1456 messages.success(request, conf.message)
1453 1457 else:
1454 1458 messages.error(request, conf.message)
1455 1459
1456 1460 #conf.status_device()
1457 1461
1458 1462 return redirect(conf.get_absolute_url())
1459 1463
1460 1464
1461 1465 @login_required
1462 1466 def dev_conf_status(request, id_conf):
1463 1467
1464 1468 conf = get_object_or_404(Configuration, pk=id_conf)
1465 1469
1466 1470 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1467 1471 if conf_active!=conf:
1468 1472 url = '#' if conf_active is None else conf_active.get_absolute_url()
1469 1473 label = 'None' if conf_active is None else conf_active.label
1470 1474 messages.warning(
1471 1475 request,
1472 1476 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1473 1477 url,
1474 1478 label
1475 1479 ))
1476 1480 )
1477 1481
1478 1482 return redirect(conf.get_absolute_url())
1479 1483
1480 1484 if conf.status_device():
1481 1485 messages.success(request, conf.message)
1482 1486 else:
1483 1487 messages.error(request, conf.message)
1484 1488
1485 1489 return redirect(conf.get_absolute_url())
1486 1490
1487 1491
1488 1492 @login_required
1489 1493 def dev_conf_reset(request, id_conf):
1490 1494
1491 1495 conf = get_object_or_404(Configuration, pk=id_conf)
1492 1496
1493 1497 if conf.reset_device():
1494 1498 messages.success(request, conf.message)
1495 1499 else:
1496 1500 messages.error(request, conf.message)
1497 1501
1498 1502 return redirect(conf.get_absolute_url())
1499 1503
1500 1504
1501 1505 @login_required
1502 1506 def dev_conf_write(request, id_conf):
1503 1507
1504 1508 conf = get_object_or_404(Configuration, pk=id_conf)
1505 1509
1506 1510 if request.method == 'POST':
1507 1511 if conf.write_device():
1508 1512 conf.device.conf_active = conf.pk
1509 1513 conf.device.save()
1510 1514 messages.success(request, conf.message)
1511 1515 if has_been_modified(conf):
1512 1516 conf.clone(type=1, template=False)
1513 1517 else:
1514 1518 messages.error(request, conf.message)
1515 1519
1516 1520 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1517 1521
1518 1522 kwargs = {
1519 1523 'title': 'Write Configuration',
1520 1524 'suptitle': conf.label,
1521 1525 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1522 1526 'delete': False
1523 1527 }
1524 1528 kwargs['menu_configurations'] = 'active'
1525 1529
1526 1530 return render(request, 'confirm.html', kwargs)
1527 1531
1528 1532
1529 1533 @login_required
1530 1534 def dev_conf_read(request, id_conf):
1531 1535
1532 1536 conf = get_object_or_404(Configuration, pk=id_conf)
1533 1537
1534 1538 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1535 1539
1536 1540 if request.method == 'GET':
1537 1541
1538 1542 parms = conf.read_device()
1539 1543 #conf.status_device()
1540 1544
1541 1545 if not parms:
1542 1546 messages.error(request, conf.message)
1543 1547 return redirect(conf.get_absolute_url())
1544 1548
1545 1549 form = DevConfForm(initial=parms, instance=conf)
1546 1550
1547 1551 if request.method == 'POST':
1548 1552 form = DevConfForm(request.POST, instance=conf)
1549 1553
1550 1554 if form.is_valid():
1551 1555 form.save()
1552 1556 return redirect(conf.get_absolute_url())
1553 1557
1554 1558 messages.error(request, "Parameters could not be saved")
1555 1559
1556 1560 kwargs = {}
1557 1561 kwargs['id_dev'] = conf.id
1558 1562 kwargs['form'] = form
1559 1563 kwargs['title'] = 'Device Configuration'
1560 1564 kwargs['suptitle'] = 'Parameters read from device'
1561 1565 kwargs['button'] = 'Save'
1562 1566
1563 1567 ###### SIDEBAR ######
1564 1568 kwargs.update(sidebar(conf=conf))
1565 1569
1566 1570 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1567 1571
1568 1572
1569 1573 @login_required
1570 1574 def dev_conf_import(request, id_conf):
1571 1575
1572 1576 conf = get_object_or_404(Configuration, pk=id_conf)
1573 1577 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1574 1578
1575 1579 if request.method == 'GET':
1576 1580 file_form = UploadFileForm()
1577 1581
1578 1582 if request.method == 'POST':
1579 1583 file_form = UploadFileForm(request.POST, request.FILES)
1580 1584
1581 1585 if file_form.is_valid():
1582 1586
1583 1587 data = conf.import_from_file(request.FILES['file'])
1584 1588 parms = Params(data=data).get_conf(
1585 1589 dtype=conf.device.device_type.name)
1586 1590
1587 1591 if parms:
1588 1592
1589 1593 form = DevConfForm(initial=parms, instance=conf)
1590 1594
1591 1595 kwargs = {}
1592 1596 kwargs['id_dev'] = conf.id
1593 1597 kwargs['form'] = form
1594 1598 kwargs['title'] = 'Device Configuration'
1595 1599 kwargs['suptitle'] = 'Parameters imported'
1596 1600 kwargs['button'] = 'Save'
1597 1601 kwargs['action'] = conf.get_absolute_url_edit()
1598 1602 kwargs['previous'] = conf.get_absolute_url()
1599 1603
1600 1604 ###### SIDEBAR ######
1601 1605 kwargs.update(sidebar(conf=conf))
1602 1606
1603 1607 messages.success(
1604 1608 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1605 1609
1606 1610 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1607 1611
1608 1612 messages.error(request, "Could not import parameters from file")
1609 1613
1610 1614 kwargs = {}
1611 1615 kwargs['id_dev'] = conf.id
1612 1616 kwargs['title'] = 'Device Configuration'
1613 1617 kwargs['form'] = file_form
1614 1618 kwargs['suptitle'] = 'Importing file'
1615 1619 kwargs['button'] = 'Import'
1616 1620 kwargs['menu_configurations'] = 'active'
1617 1621
1618 1622 kwargs.update(sidebar(conf=conf))
1619 1623
1620 1624 return render(request, 'dev_conf_import.html', kwargs)
1621 1625
1622 1626
1623 1627 @login_required
1624 1628 def dev_conf_export(request, id_conf):
1625 1629
1626 1630 conf = get_object_or_404(Configuration, pk=id_conf)
1627 1631
1628 1632 if request.method == 'GET':
1629 1633 file_form = DownloadFileForm(conf.device.device_type.name)
1630 1634
1631 1635 if request.method == 'POST':
1632 1636 file_form = DownloadFileForm(
1633 1637 conf.device.device_type.name, request.POST)
1634 1638
1635 1639 if file_form.is_valid():
1636 1640 fields = conf.export_to_file(
1637 1641 format=file_form.cleaned_data['format'])
1638 1642 if not fields['content']:
1639 1643 messages.error(request, conf.message)
1640 1644 return redirect(conf.get_absolute_url_export())
1641 1645 response = HttpResponse(content_type=fields['content_type'])
1642 1646 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1643 1647 response.write(fields['content'])
1644 1648
1645 1649 return response
1646 1650
1647 1651 messages.error(request, "Could not export parameters")
1648 1652
1649 1653 kwargs = {}
1650 1654 kwargs['id_dev'] = conf.id
1651 1655 kwargs['title'] = 'Device Configuration'
1652 1656 kwargs['form'] = file_form
1653 1657 kwargs['suptitle'] = 'Exporting file'
1654 1658 kwargs['button'] = 'Export'
1655 1659 kwargs['menu_configurations'] = 'active'
1656 1660
1657 1661 return render(request, 'dev_conf_export.html', kwargs)
1658 1662
1659 1663
1660 1664 @login_required
1661 1665 def dev_conf_delete(request, id_conf):
1662 1666
1663 1667 conf = get_object_or_404(Configuration, pk=id_conf)
1664 1668
1665 1669 if request.method == 'POST':
1666 1670 if is_developer(request.user):
1667 1671 conf.delete()
1668 1672 return redirect('url_dev_confs')
1669 1673
1670 1674 messages.error(request, 'Not enough permission to delete this object')
1671 1675 return redirect(conf.get_absolute_url())
1672 1676
1673 1677 kwargs = {
1674 1678 'title': 'Delete',
1675 1679 'suptitle': 'Configuration',
1676 1680 'object': conf,
1677 1681 'delete': True
1678 1682 }
1679 1683 kwargs['menu_configurations'] = 'active'
1680 1684
1681 1685 return render(request, 'confirm.html', kwargs)
1682 1686
1683 1687
1684 1688 def sidebar(**kwargs):
1685 1689
1686 1690 side_data = {}
1687 1691
1688 1692 conf = kwargs.get('conf', None)
1689 1693 experiment = kwargs.get('experiment', None)
1690 1694
1691 1695 if not experiment:
1692 1696 experiment = conf.experiment
1693 1697
1694 1698 if experiment:
1695 1699 side_data['experiment'] = experiment
1696 1700 campaign = experiment.campaign_set.all()
1697 1701 if campaign:
1698 1702 side_data['campaign'] = campaign[0]
1699 1703 experiments = campaign[0].experiments.all().order_by('name')
1700 1704 else:
1701 1705 experiments = [experiment]
1702 1706 configurations = experiment.configuration_set.filter(type=0)
1703 1707 side_data['side_experiments'] = experiments
1704 1708 side_data['side_configurations'] = configurations.order_by(
1705 1709 'device__device_type__name')
1706 1710
1707 1711 return side_data
1708 1712
1709 1713 def get_paginator(model, page, order, filters={}, n=8):
1710 1714 kwargs = {}
1711 1715 query = Q()
1712 1716 if isinstance(filters, QueryDict):
1713 1717 filters = filters.dict()
1714 1718 copy_filters=filters.copy()
1715 1719 [filters.pop(key) for key in copy_filters.keys() if copy_filters[key] in (' ', ' ')]
1716 1720 filters.pop('page', None)
1717 1721
1718 1722 fields = [f.name for f in model._meta.get_fields()]
1719 1723
1720 1724 if 'template' in copy_filters:
1721 1725 filters['template'] = True
1722 1726 if 'historical' in copy_filters:
1723 1727 filters.pop('historical')
1724 1728 filters['type'] = 1
1725 1729 elif 'type' in fields:
1726 1730 filters['type'] = 0
1727 1731 if 'start_date' in copy_filters:
1728 1732 filters['start_date__gte'] =filters.pop('start_date')
1729 1733 if 'end_date' in copy_filters:
1730 1734 filters['start_date__lte'] =filters.pop('end_date')
1731 1735 if 'tags' in copy_filters:
1732 1736 tags =filters.pop('tags')
1733 1737 if 'tags' in fields:
1734 1738 query = query | Q(tags__icontains=tags)
1735 1739 if 'label' in fields:
1736 1740 query = query | Q(label__icontains=tags)
1737 1741 if 'location' in fields:
1738 1742 query = query | Q(location__name__icontains=tags)
1739 1743 if 'device' in fields:
1740 1744 query = query | Q(device__device_type__name__icontains=tags)
1741 1745 query = query | Q(device__location__name__icontains=tags)
1742 1746 if 'device_type' in fields:
1743 1747 query = query | Q(device_type__name__icontains=tags)
1744 1748
1745 1749 if 'mine' in copy_filters:
1746 1750 filters['author_id'] =filters['mine']
1747 1751 filters.pop('mine')
1748 1752 object_list = model.objects.filter(query, **filters).order_by(*order)
1749 1753 paginator = Paginator(object_list, n)
1750 1754
1751 1755 try:
1752 1756 objects = paginator.page(page)
1753 1757 except PageNotAnInteger:
1754 1758 objects = paginator.page(1)
1755 1759 except EmptyPage:
1756 1760 objects = paginator.page(paginator.num_pages)
1757 1761
1758 1762 kwargs['objects'] = objects
1759 1763 kwargs['offset'] = (int(page)-1)*n if page else 0
1760 1764
1761 1765 return kwargs
1762 1766
1763 1767 # def get_paginator(model, page, order, filters={}, n=8):
1764 1768 # kwargs = {}
1765 1769 # query = Q()
1766 1770 # if isinstance(filters, QueryDict):
1767 1771 # filters = filters.dict()
1768 1772 # [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1769 1773 # filters.pop('page', None)
1770 1774
1771 1775 # fields = [f.name for f in model._meta.get_fields()]
1772 1776
1773 1777 # if 'template' in filters:
1774 1778 # filters['template'] = True
1775 1779 # if 'historical' in filters:
1776 1780 # filters.pop('historical')
1777 1781 # filters['type'] = 1
1778 1782 # elif 'type' in fields:
1779 1783 # filters['type'] = 0
1780 1784 # if 'start_date' in filters:
1781 1785 # filters['start_date__gte'] = filters.pop('start_date')
1782 1786 # if 'end_date' in filters:
1783 1787 # filters['start_date__lte'] = filters.pop('end_date')
1784 1788 # if 'tags' in filters:
1785 1789 # tags = filters.pop('tags')
1786 1790 # if 'tags' in fields:
1787 1791 # query = query | Q(tags__icontains=tags)
1788 1792 # if 'label' in fields:
1789 1793 # query = query | Q(label__icontains=tags)
1790 1794 # if 'location' in fields:
1791 1795 # query = query | Q(location__name__icontains=tags)
1792 1796 # if 'device' in fields:
1793 1797 # query = query | Q(device__device_type__name__icontains=tags)
1794 1798 # query = query | Q(device__location__name__icontains=tags)
1795 1799 # if 'device_type' in fields:
1796 1800 # query = query | Q(device_type__name__icontains=tags)
1797 1801
1798 1802 # if 'mine' in filters:
1799 1803 # filters['author_id'] = filters['mine']
1800 1804 # filters.pop('mine')
1801 1805 # object_list = model.objects.filter(query, **filters).order_by(*order)
1802 1806 # paginator = Paginator(object_list, n)
1803 1807
1804 1808 # try:
1805 1809 # objects = paginator.page(page)
1806 1810 # except PageNotAnInteger:
1807 1811 # objects = paginator.page(1)
1808 1812 # except EmptyPage:
1809 1813 # objects = paginator.page(paginator.num_pages)
1810 1814
1811 1815 # kwargs['objects'] = objects
1812 1816 # kwargs['offset'] = (int(page)-1)*n if page else 0
1813 1817
1814 1818 # return kwargs
1815 1819
1816 1820
1817 1821 def operation(request, id_camp=None):
1818 1822
1819 1823 kwargs = {}
1820 1824 kwargs['title'] = 'Radars Operation'
1821 1825 kwargs['no_sidebar'] = True
1822 1826 kwargs['menu_operation'] = 'active'
1823 1827 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1824 1828 end_date__gte=datetime.now()).order_by('-start_date')
1825 1829
1826 1830 if id_camp:
1827 1831 campaign = get_object_or_404(Campaign, pk=id_camp)
1828 1832 form = OperationForm(
1829 1833 initial={'campaign': campaign.id}, campaigns=campaigns)
1830 1834 kwargs['campaign'] = campaign
1831 1835 else:
1832 1836 # form = OperationForm(campaigns=campaigns)
1833 1837 kwargs['campaigns'] = campaigns
1834 1838 return render(request, 'operation.html', kwargs)
1835 1839
1836 1840 #---Experiment
1837 1841 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1838 1842 kwargs['experiment_keys'] = keys[1:]
1839 1843 kwargs['experiments'] = experiments
1840 1844 #---Radar
1841 1845 kwargs['locations'] = campaign.get_experiments_by_radar()
1842 1846 kwargs['form'] = form
1843 1847
1844 1848 return render(request, 'operation.html', kwargs)
1845 1849
1846 1850
1847 1851 @login_required
1848 1852 def radar_start(request, id_camp, id_radar):
1849 1853
1850 1854 campaign = get_object_or_404(Campaign, pk=id_camp)
1851 1855 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1852 1856 now = datetime.now()
1853 1857
1854 1858 for exp in experiments:
1855 1859 #app.control.revoke(exp.task)
1856 1860 print("----------------------")
1857 1861 print("status:->", exp.status)
1858 1862 start = datetime.combine(datetime.now().date(), exp.start_time)
1859 1863 end = datetime.combine(datetime.now().date(), exp.end_time)
1860 1864 print("start exp: ",exp.start_time)
1861 1865 print("end exp: ",exp.end_time)
1862 1866
1863 1867 print("start comb: ",start)
1864 1868 print("end comb: ",end)
1865 1869 print(is_aware(start))
1866 1870 print("start camp",campaign.start_date)
1867 1871 print("end camp",campaign.end_date)
1868 1872 print(is_aware(campaign.start_date))
1869 1873 if end < start:
1870 1874 end += timedelta(1)
1871 1875
1872 1876 if exp.status == 2:
1873 1877 messages.warning(
1874 1878 request, 'Experiment {} already running'.format(exp))
1875 1879 #continue
1876 1880
1877 1881 if exp.status == 3:
1878 1882 messages.warning(
1879 1883 request, 'Experiment {} already programmed'.format(exp))
1880 1884 #continue
1881 1885
1882 1886 if exp.status == 1:
1883 1887 messages.warning(
1884 1888 request, 'Experiment {} stopped'.format(exp))
1885 1889 #continue
1886 1890
1887 1891 if start > campaign.end_date:
1888 1892 messages.warning(
1889 1893 request, 'Experiment {} out of date'.format(exp))
1890 1894
1891 1895 #app.control.revoke(exp.task)
1892 1896 print("Llego luego del revoke")
1893 1897 if now >= start and now <= end:
1894 1898
1895 1899 print("Caso now > start and < end -- (1)")
1896 1900
1897 1901 # -------------------------------------------
1898 1902
1899 1903 # task = task_start.delay(exp.id)
1900 1904 # exp.task = task.id
1901 1905 # exp.status = task.get()
1902 1906 # -------------------------------------------
1903 1907
1904 1908 #exp.status = task.wait()
1905 1909
1906 1910 if exp.status == 0:
1907 1911 messages.error(request, 'Experiment {} not start'.format(exp))
1908 1912 if exp.status == 2:
1909 1913 messages.success(request, 'Experiment {} started'.format(exp))
1910 1914 elif now < start:
1911 1915 print("Caso now <= start -- (2)",exp.pk)
1912 1916 #task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1913 1917 # task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))#)
1914 1918 # exp.task = task.id
1915 1919 # exp.status = 3
1916 1920 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1917 1921 else:
1918 1922 print("Caso now > end -- (3)")
1919 1923 exp.status = 4
1920 1924 messages.warning(
1921 1925 request, 'Experiment {} out of date'.format(exp))
1922 1926
1923 1927 exp.save()
1924 1928
1925 1929 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1926 1930
1927 1931
1928 1932 @login_required
1929 1933 def radar_stop(request, id_camp, id_radar):
1930 1934
1931 1935 campaign = get_object_or_404(Campaign, pk=id_camp)
1932 1936 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1933 1937 print("Ingreso en stop radar_stop")
1934 1938 #for exp in experiments:
1935 1939
1936 1940 # if exp.task:
1937 1941 # print("Ingreso antes de revoke stop")
1938 1942 # app.control.revoke(exp.task)
1939 1943
1940 1944
1941 1945 # if exp.status == 2: #status 2 es started
1942 1946 # print("llama a exp.stop")
1943 1947 # exp.stop()
1944 1948 # messages.warning(request, 'Experiment {} stopped'.format(exp))
1945 1949 # exp.status = 1
1946 1950 # exp.save()
1947 1951
1948 1952 #return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1949 1953
1950 1954
1951 1955 @login_required
1952 1956 def radar_refresh(request, id_camp, id_radar):
1953 1957
1954 1958 campaign = get_object_or_404(Campaign, pk=id_camp)
1955 1959 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1956 1960
1957 1961 i = app.control.inspect()
1958 1962 print("inspect",i)
1959 1963 print(i.scheduled())
1960 1964 print(i.scheduled().values())
1961 1965 scheduled = list(i.scheduled().values())[0]
1962 1966 revoked = list(i.revoked().values())[0]
1963 1967
1964 1968 # for exp in experiments:
1965 1969 # if exp.task in revoked:
1966 1970 # exp.status = 1
1967 1971 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
1968 1972 # exp.status = 2
1969 1973 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
1970 1974 # exp.status = 3
1971 1975 # else:
1972 1976 # exp.status = 4
1973 1977 # exp.save()
1974 1978 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1975 1979
1976 1980 #@login_required
1977 1981 # def revoke_tasks(request, id_camp):
1978 1982
1979 1983 # i = app.control.inspect()
1980 1984 # scheduled = list(i.scheduled().values())[0]
1981 1985 # revoked = list(i.revoked().values())[0]
1982 1986
1983 1987 # for t in scheduled:
1984 1988 # if t['request']['id'] in revoked:
1985 1989 # continue
1986 1990 # app.control.revoke(t['request']['id'])
1987 1991 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1988 1992 # eta = t['eta']
1989 1993 # #task = t['request']['name'].split('.')[-1]
1990 1994 # messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1991 1995
1992 1996 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1993 1997
1994 1998 # @login_required
1995 1999 # def show_tasks(request, id_camp):
1996 2000
1997 2001 # i = app.control.inspect()
1998 2002 # scheduled = list(i.scheduled().values())[0]
1999 2003 # revoked = list(i.revoked().values())[0]
2000 2004
2001 2005 # for t in scheduled:
2002 2006 # if t['request']['id'] in revoked:
2003 2007 # continue
2004 2008 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2005 2009 # eta = t['eta']
2006 2010 # #task = t['request']['name'].split('.')[-1]
2007 2011 # #messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
2008 2012
2009 2013 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2010 2014
2011 2015 def real_time(request):
2012 2016
2013 2017 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
2014 2018
2015 2019 kwargs = {}
2016 2020 kwargs['title'] = 'CLAIRE'
2017 2021 kwargs['suptitle'] = 'Real Time'
2018 2022 kwargs['no_sidebar'] = True
2019 2023 kwargs['graphic_path'] = graphic_path
2020 2024 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
2021 2025
2022 2026 return render(request, 'real_time.html', kwargs)
2023 2027
2024 2028 def theme(request, theme):
2025 2029
2026 2030 user = request.user
2027 2031 user.profile.theme = theme
2028 2032 user.save()
2029 2033 return redirect('index')
@@ -1,70 +1,70
1 1 version: '3'
2 2 services:
3 3 # Django app
4 4 radarsys:
5 5 container_name: 'radarsys'
6 6 build: .
7 7 restart: always
8 8 image: radarsys
9 9 #command: gunicorn radarsys.wsgi:application -w 2 -b :8000
10 10 #command: python manage.py runserver 0.0.0.0:8000
11 11 ports:
12 12 - 8000:8000
13 13 #ports:
14 14 # - 8030:8030
15 15 env_file: .env
16 16
17 17 links:
18 18 # - redis
19 19 - postgres
20 20 volumes:
21 21 - './:/radarsys'
22 22 - '${DOCKER_DATA}/static:/radarsys/static'
23 23 depends_on:
24 24 # - redis
25 25 - postgres
26 26
27 27 # redis:
28 28 # container_name: 'radarsys-redis'
29 29 # image: 'redis:3.2-alpine'
30 30 # volumes:
31 31 # - '${DOCKER_DATA}/redis:/data'
32 32
33 33 # celery_worker:
34 34 # container_name: 'radarsys-celery'
35 35 # image: radarsys
36 36 # env_file: .env
37 37 # command: celery -A radarsys worker -l info
38 38 # volumes_from:
39 39 # - web
40 40 # depends_on:
41 41 # - web
42 42
43 43 # PostgreSQL
44 44 postgres:
45 45 container_name: 'radarsys-postgres'
46 46 build: ./postgres/
47 47 volumes:
48 48 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
49 49 - pgdata:/var/lib/postgresql/data
50 50 ports:
51 51 - 5432:5432
52 52 env_file: .env
53 53
54 54 #Web Server
55 nginx:
55 radarsys-nginx:
56 56 container_name: 'radarsys-nginx'
57 57 restart: always
58 58 build: ./nginx/
59 59 ports:
60 - '8030:8030'
60 - '0.0.0.0:80:80'
61 61 volumes_from:
62 62 - radarsys
63 63 links:
64 64 - radarsys:radarsys
65 65 depends_on:
66 66 - radarsys
67 67
68 68 volumes:
69 69 pgdata:
70 70 driver: local
@@ -1,12 +1,12
1 1 #!/bin/sh
2 2 python3 manage.py makemigrations --no-input
3 3 python3 manage.py migrate --no-input
4 4 python3 manage.py loaddata apps/main/fixtures/main_initial_data.json
5 5 python3 manage.py loaddata apps/rc/fixtures/rc_initial_data.json
6 6 python3 manage.py loaddata apps/jars/fixtures/initial_filters_data.json
7 7 python3 manage.py collectstatic --no-input
8 8
9 9 #DJANGO_SUPERUSER_PASSWORD=$SUPER_USER_PASSWORD python manage.py createsuperuser --username $SUPER_USER_NAME --email $SUPER_USER_EMAIL --noinput
10 10
11 gunicorn radarsys.wsgi:application -w 2 -b :8000
11 gunicorn -k eventlet radarsys.wsgi:application --bind 0.0.0.0:8000
12 12 No newline at end of file
@@ -1,20 +1,28
1 upstream django {
2 server radarsys:8000;
3 }
4
1 5 server {
2 6
3 listen 8030;
7 listen 80;
4 8 server_name localhost;
5 9
6 access_log /dev/stdout;
7 error_log /dev/stdout info;
10 #access_log /dev/stdout;
11 #error_log /dev/stdout info;
8 12
9 13 location /static {
10 14 alias /radarsys/static;
11 15 }
12 16
13 17 location / {
14 proxy_set_header Host "localhost";
15 proxy_pass http://radarsys:8000;
16 # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
17
18 proxy_pass http://django;
19 proxy_set_header X-Real-IP $remote_addr;
20 proxy_set_header Host $host;
21 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
22 proxy_set_header X-Forwarded-Proto $scheme;
23 proxy_http_version 1.1;
24 proxy_set_header Upgrade $http_upgrade;
25 proxy_set_header Connection "upgrade";
18 26 }
19 27
20 }
28 } No newline at end of file
@@ -1,170 +1,177
1 1 """
2 2 Django settings for radarsys project.
3 3
4 4 Generated by 'django-admin startproject' using Django 1.8.6.
5 5
6 6 For more information on this file, see
7 7 https://docs.djangoproject.com/en/1.8/topics/settings/
8 8
9 9 For the full list of settings and their values, see
10 10 https://docs.djangoproject.com/en/1.8/ref/settings/
11 11 """
12 12
13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 14 import os
15 15
16 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 17
18 18 # Quick-start development settings - unsuitable for production
19 19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
20 20
21 21 # SECURITY WARNING: keep the secret key used in production secret!
22 22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
23 23
24 24 # SECURITY WARNING: don't run with debug turned on in production!
25 25 DEBUG = True
26 26
27 27 ALLOWED_HOSTS = ['*']
28 28
29 29 CSRF_TRUSTED_ORIGINS=[
30 30 "http://*.localhost:8030",
31 31 "http://localhost:8030",
32 32 "http://127.0.0.1:8030"
33 33 ]
34 34 #Si se requiere que la aplicación salga de este entorno, para otros usuarios es necesario hacer una API request https://fractalideas.com/blog/making-react-and-django-play-well-together-single-page-app-model/
35 35
36 36 # Application definition
37 37
38 38 INSTALLED_APPS = [
39 39 'django.contrib.admin',
40 40 'django.contrib.auth',
41 41 'django.contrib.contenttypes',
42 42 'django.contrib.sessions',
43 43 'django.contrib.messages',
44 44 'django.contrib.staticfiles',
45 45 'apps.accounts',
46 46 'apps.main',
47 47 'apps.misc',
48 48 'apps.rc',
49 49 'apps.dds',
50 50 'apps.jars',
51 51 'apps.usrp',
52 52 'apps.abs',
53 53 'apps.cgs',
54 54 'apps.dds_rest',
55 'apps.atrad',
55 56 "django_bootstrap5",
56 57 'polymorphic',
57 'channels',
58 'radarsys',
58 59 ]
59 60
60 61 MIDDLEWARE = [
61 62 'django.middleware.security.SecurityMiddleware',
62 63 'django.contrib.sessions.middleware.SessionMiddleware',
63 64 'django.middleware.common.CommonMiddleware',
64 65 'django.middleware.csrf.CsrfViewMiddleware',
65 66 'django.contrib.auth.middleware.AuthenticationMiddleware',
66 67 'django.contrib.messages.middleware.MessageMiddleware',
67 68 'django.middleware.clickjacking.XFrameOptionsMiddleware',
68 69
69 70 ]
70 71
71 72 ROOT_URLCONF = 'radarsys.urls'
72 73
73 74 TEMPLATES = [
74 75 {
75 76 'BACKEND': 'django.template.backends.django.DjangoTemplates',
76 77 'DIRS': [os.path.join(BASE_DIR, "templates")],
77 78 'APP_DIRS': True,
78 79 'OPTIONS': {
79 80 'context_processors': [
80 81 'django.template.context_processors.debug',
81 82 'django.template.context_processors.request',
82 83 'django.contrib.auth.context_processors.auth',
83 84 'django.contrib.messages.context_processors.messages',
84 85 'apps.main.processors.radarsys_globals',
85 86 ],
86 87 },
87 88 },
88 89 ]
89 90
90 91 WSGI_APPLICATION = 'radarsys.wsgi.application'
91 92 ASGI_APPLICATION = 'radarsys.asgi.application'
92 93
93 94 # Database
94 95 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
95 96
96 97 DATABASES = {
97 98 # 'default': {
98 99 # 'ENGINE': 'django.db.backends.sqlite3',
99 100 # 'NAME': 'radarsys.sqlite',
100 101 # }
101 102 'default': {
102 103 'ENGINE': 'django.db.backends.postgresql_psycopg2',
103 104 'NAME': os.environ.get('DB_NAME', 'radarsys'),
104 105 'USER': os.environ.get('DB_USER', 'docker'),
105 106 'PASSWORD': os.environ.get('DB_PASSWORD', 'docker'),
106 107 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'localhost'),
107 108 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', '5432'),
108 109 }
109 110 }
110 111
111 112 # Internationalization
112 113 # https://docs.djangoproject.com/en/1.8/topics/i18n/
113 114
114 115 LANGUAGE_CODE = 'en-us'
115 116
116 117 USE_TZ = False #True
117 118
118 119 TIME_ZONE = os.environ.get('TZ', 'America/Lima')
119 120
120 121 USE_I18N = True
121 122
122 123 USE_L10N = True
123 124
124 125 # Static files (CSS, JavaScript, Images)
125 126 # https://docs.djangoproject.com/en/1.8/howto/static-files/
126 127
127 128 MEDIA_URL = '/media/'
128 129 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
129 130
130 131 STATICFILES_DIRS = [
131 132 os.path.join(BASE_DIR, 'radarsys/static/')
132 133 ]
133 134
134 135 STATIC_URL = '/static/'
135 136 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
136 137
137 138 LOGIN_URL = '/accounts/login'
138 139 LOGOUT_URL = 'logout'
139 140 LOGIN_REDIRECT_URL = '/admin'
140 141 LOGOUT_REDIRECT_URL = '/'
141 142
142 143 STATICFILES_FINDERS = (
143 144 'django.contrib.staticfiles.finders.FileSystemFinder',
144 145 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
145 146 )
146 147
147 148 # # Celery stuff
148 149
149 150 # REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
150 151 # #REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
151 152 # REDIS_PORT = os.environ.get('REDIS_PORT', 6379)
152 153
153 154 # BROKER_TRANSPORT = 'redis'
154 155 # #BROKER_URL = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
155 156 # BROKER_URL = 'redis://{}:{}'.format(REDIS_HOST, REDIS_PORT)
156 157
157 158 # CELERY_RESULT_BACKEND = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
158 159 # CELERY_BROKER_TRANSPORT = BROKER_URL
159 160 # CELERY_ACCEPT_CONTENT = ['application/json']
160 161 # CELERY_TASK_SERIALIZER = 'json'
161 162 # CELERY_RESULT_SERIALIZER = 'json'
162 163 # CELERY_ENABLE_UTC = False
163 164 # CELERY_TIMEZONE = 'America/Lima'
164 165
165 166 import django
166 167 from django.utils.encoding import force_str
167 168 django.utils.encoding.force_text = force_str
168 169
169 170 # choose of auto-created primary keys
170 171 DEFAULT_AUTO_FIELD='django.db.models.AutoField'
172
173 MQTT_SERVER = '10.10.10.99'
174 MQTT_PORT = 1883
175 MQTT_KEEPALIVE = 60
176 MQTT_USER = ''
177 MQTT_PASSWORD = '' No newline at end of file
@@ -1,20 +1,20
1 1 from django.urls import include, path
2 2 from django.contrib import admin
3 3 #from django.contrib.staticfiles.urls import staticfiles_urlpatterns
4 4
5 5 urlpatterns = [
6 6 path('admin/',admin.site.urls),
7 7 path('accounts/', include('apps.accounts.urls')),
8 8 path('', include('apps.main.urls')),
9 9 path('rc/', include('apps.rc.urls')),
10 10 path('dds/', include('apps.dds.urls')),
11 11 path('cgs/', include('apps.cgs.urls')),
12 12 path('jars/',include('apps.jars.urls')),
13 13 path('usrp/', include('apps.usrp.urls')),
14 14 path('abs/', include('apps.abs.urls')),
15 15 path('misc/',include('apps.misc.urls')),
16 16 path('dds_rest/', include('apps.dds_rest.urls')),
17
17 path('atrad/', include('apps.atrad.urls')),
18 18 ]
19 19
20 20 #urlpatterns += staticfiles_urlpatterns()
@@ -1,16 +1,19
1 1 """
2 2 WSGI config for radarsys project.
3 3
4 4 It exposes the WSGI callable as a module-level variable named ``application``.
5 5
6 6 For more information on this file, see
7 7 https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
8 8 """
9 9
10 10 import os
11 11
12 12 from django.core.wsgi import get_wsgi_application
13 from .socketconfig import sio
14 import socketio
13 15
14 16 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "radarsys.settings")
15 17
16 18 application = get_wsgi_application()
19 application = socketio.WSGIApp(sio, application)
@@ -1,14 +1,18
1 1 Django==4.1.5
2 2 django-bootstrap5==22.2
3 3 psycopg2-binary==2.9.5
4 4 django-polymorphic==3.1
5 5 bokeh==3.0.3
6 6 numpy==1.24.1
7 7 matplotlib==3.6.3
8 8 scipy==1.10.0
9 9 celery==5.2.7
10 10 gunicorn==20.1.0
11 11 requests==2.28.2
12 12 redis==4.4.2
13 channels==4.0.0
14 daphne==4.0.0 No newline at end of file
13
14 paho-mqtt==1.6.1
15
16 eventlet==0.30.2
17 python-engineio
18 python-socketio No newline at end of file
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now