##// END OF EJS Templates
Add users and groups
eynilupu -
r445:046e9870ce02
parent child
Show More
@@ -0,0 +1,71
1 from django.core.management import BaseCommand
2 from django.contrib.auth.models import User, Group , Permission
3 import logging
4
5 GROUPS = {
6 "Developer": {
7 #General permissions
8 #"log entry" : ["add","delete","change","view"],
9 #"group" : ["add","delete","change","view"],
10 #"permission" : ["add","delete","change","view"],
11 #"user" : ["add","delete","change","view"],
12 #"content type" : ["add","delete","change","view"],
13 #"session" : ["add","delete","change","view"],
14
15 #Specific permissions
16 "profile" : ["add","delete","change","view"],
17 "experiment" : ["add","delete","change","view"],
18 "configuration" : ["add","delete","change","view"],
19 "device" : ["add","delete","change","view"],
20 "device type" : ["add","delete","change","view"],
21 "generator configuration" : ["add","delete","change","view"],
22 "pedestal configuration" : ["add","delete","change","view"],
23 "usrprx configuration" : ["add","delete","change","view"],
24 "tx code" : ["add","delete","change","view"],
25 "usrptx configuration" : ["add","delete","change","view"],
26 },
27
28 "Operator": {
29 #Specific permissions
30 "profile" : ["view"],
31 "experiment" : ["view"],
32 "configuration" : ["view"],
33 "device" : ["view"],
34 "device type" : ["view"],
35 "generator configuration" : ["view"],
36 "pedestal configuration" : ["view"],
37 "usrprx configuration" : ["view"],
38 "tx code" : ["view"],
39 "usrptx configuration" : ["view"],
40 },
41 }
42
43 class Command(BaseCommand):
44
45 help = "Creates read only default permission groups for users"
46
47 def handle(self, *args, **options):
48 for group_name in GROUPS:
49 try:
50 Group.objects.get(name=group_name)
51 self.stdout.write(f'Local group "{group_name}" currently exists')
52 continue
53 except:
54 new_group = Group.objects.create(name=group_name)
55 # Loop models in group
56 for app_model in GROUPS[group_name]:
57
58 # Loop permissions in group/model
59 for permission_name in GROUPS[group_name][app_model]:
60
61 # Generate permission name as Django would generate it
62 name = "Can {} {}".format(permission_name, app_model)
63 self.stdout.write(f'Creating "{name}"')
64
65 try:
66 model_add_perm = Permission.objects.get(name=name)
67 except Permission.DoesNotExist:
68 logging.warning("Permission not found with name '{}'.".format(name))
69 continue
70
71 new_group.permissions.add(model_add_perm) No newline at end of file
@@ -0,0 +1,60
1 import os
2 from django.core.management.base import BaseCommand
3 from django.contrib.auth.models import User, Group
4
5 class Command(BaseCommand):
6 """
7 Create a superuser and user if none exist
8 Example:
9 manage.py create_users
10 """
11
12 help = "Create a superuser and user if none exist"
13
14 def handle(self, *args, **options):
15
16 users = {
17 'Superuser': {
18 'username': os.environ.get('SIRM_SUPER_USER', 'superuser'),
19 'password': os.environ.get('SIRM_SUPER_PASSWORD', 'SuperuseROJ'),
20 'email' : os.environ.get('SIRM_SUPER_EMAIL', 'superuser@igp.gob.pe')},
21 'Developer': {
22 'username': os.environ.get('SIRM_DEV_USER', 'developer'),
23 'password': os.environ.get('SIRM_DEV_PASSWORD', 'DevelopeROJ'),
24 'email' : os.environ.get('SIRM_DEV_EMAIL', 'developer@igp.gob.pe')},
25 'Operator': {
26 'username': os.environ.get('SIRM_USER', 'operator'),
27 'password': os.environ.get('SIRM_PASSWORD', 'OperatoROJ'),
28 'email' : os.environ.get('SIRM_EMAIL', 'operator@igp.gob.pe')}
29 }
30
31 for key, value in users.items():
32 if key == 'Superuser':
33 if User.objects.filter(is_superuser=True):
34 self.stdout.write(f'Local {key} currently exists')
35 else:
36 user, created = User.objects.get_or_create(username=value["username"], first_name=value["username"], email=value["email"], is_superuser = True, is_staff = True)
37 if created:
38 user.set_password(value["password"])
39 user.save()
40 self.stdout.write(f'Local {key} "{value["username"]}" was created')
41 else:
42 self.stdout.write(f'Unable to create this local superuser: "superuser already exists"')
43 else:
44 if User.objects.filter(groups__name=key):
45 if User.objects.filter(groups__name=key, is_superuser=True):
46 self.stdout.write(f"{key} group must not have a superuser, remove superusers and create a new user")
47 else:
48 self.stdout.write(f"Local {key} currently exists")
49 else:
50 user, created = User.objects.get_or_create(username=value["username"], first_name=value["username"], email=value["email"])
51 if created:
52 user.set_password(value["password"])
53 user.save()
54 self.stdout.write(f'Local {key} "{value["username"]}" was created')
55
56 group = Group.objects.get(name=key)
57 group.user_set.add(user)
58 self.stdout.write(f'Local {key} "{value["username"]}" was added to {key} group')
59 else:
60 self.stdout.write(f'Unable to create and join to {key} group this local user: "user already exists"') No newline at end of file
@@ -1,39 +1,49
1 #General settings
1 #General settings
2 TZ=America/Lima
2 TZ=America/Lima
3 LC_ALL=C.UTF-8
3 LC_ALL=C.UTF-8
4 SIRM_SITE=<SIRM SITE>
4 SIRM_SITE=<SIRM SITE>
5 PROC_SITE=<PROC SITE>
5 PROC_SITE=<PROC SITE>
6 CAM_SITE=<CAM SITE>
6 CAM_SITE=<CAM SITE>
7 SCHAIN_SITE=<SCHAIN SITE>
7 SCHAIN_SITE=<SCHAIN SITE>
8 GENERAL_PORT=<GENERAL PORT>
8 GENERAL_PORT=<GENERAL PORT>
9 BROKER_URL=<BROKER SITE>
9 BROKER_URL=<BROKER SITE>
10 SOPHY_TOPIC=<SOPHY TOPIC>
10 SOPHY_TOPIC=<SOPHY TOPIC>
11 TXA_SITE=<IP TXA>
11 TXA_SITE=<IP TXA>
12 TXB_SITE=<IP TXB>
12 TXB_SITE=<IP TXB>
13 SIRM_MAX_UPLOAD_SIZE_MB=<SIZE MB>
13 SIRM_MAX_UPLOAD_SIZE_MB=<SIZE MB>
14
14
15 #Pedestal - az offset
15 #Pedestal - az offset
16 AZ_OFFSET=<AZ OFFSET>
16 AZ_OFFSET=<AZ OFFSET>
17
17
18 #Postgres settings
18 #Postgres settings
19 POSTGRES_PORT_5432_TCP_ADDR=sirm-postgres
19 POSTGRES_PORT_5432_TCP_ADDR=sirm-postgres
20 POSTGRES_PORT_5432_TCP_PORT=5432
20 POSTGRES_PORT_5432_TCP_PORT=5432
21 DB_NAME=radarsys
21 DB_NAME=radarsys
22 DB_USER=docker
22 DB_USER=docker
23 DB_PASSWORD=docker
23 DB_PASSWORD=docker
24 PGDATA=/var/lib/postgresql/data
24 PGDATA=/var/lib/postgresql/data
25
25
26 #Volumes - path
26 #Volumes - path
27 EXPOSE_SIRM=./volumes/sirm
27 EXPOSE_SIRM=./volumes/sirm
28 EXPOSE_PROC=./volumes/proc
28 EXPOSE_PROC=./volumes/proc
29 EXPOSE_CAM=/path/to/cam
29 EXPOSE_CAM=/path/to/cam
30 EXPOSE_SCHAIN=./volumes/schain
30 EXPOSE_SCHAIN=./volumes/schain
31 EXPOSE_NAS=/path/to/nas_data
31 EXPOSE_NAS=/path/to/nas_data
32 EXPOSE_PGDATA=/path/to/pg_data
32 EXPOSE_PGDATA=/path/to/pg_data
33 EXPOSE_CERTS=/path/to/certs
33 EXPOSE_CERTS=/path/to/certs
34 EXPOSE_DHPARAM=/path/to/dhparam
34 EXPOSE_DHPARAM=/path/to/dhparam
35
35
36 #Superuser settings
36 #Superuser settings
37 SIRM_SUPER_USER=*****
38 SIRM_SUPER_PASSWORD=*******
39 SIRM_SUPER_EMAIL=*****@igp.gob.pe
40
41 #Developer user settings
42 SIRM_DEV_USER=*****
43 SIRM_DEV_PASSWORD=*******
44 SIRM_DEV_EMAIL=*****@igp.gob.pe
45
46 #Operator user settings
37 SIRM_USER=*****
47 SIRM_USER=*****
38 SIRM_PASSWORD=*******
48 SIRM_PASSWORD=*******
39 SIRM_EMAIL=*****@igp.gob.pe No newline at end of file
49 SIRM_EMAIL=*****@igp.gob.pe
@@ -1,272 +1,278
1 # docker-compose up -d --build
1 # docker-compose up -d --build
2 version: '3'
2 version: '3'
3
3
4 volumes:
4 volumes:
5 sirm_web:
5 sirm_web:
6 name: sirm_web
6 name: sirm_web
7 driver: local
7 driver: local
8 driver_opts:
8 driver_opts:
9 type: "none"
9 type: "none"
10 o: "bind"
10 o: "bind"
11 device: "${EXPOSE_SIRM}"
11 device: "${EXPOSE_SIRM}"
12 sirm_pgdata:
12 sirm_pgdata:
13 name: sirm_pgdata
13 name: sirm_pgdata
14 driver: local
14 driver: local
15 driver_opts:
15 driver_opts:
16 type: "none"
16 type: "none"
17 o: "bind"
17 o: "bind"
18 device: "${EXPOSE_PGDATA}"
18 device: "${EXPOSE_PGDATA}"
19 sirm_certs:
19 sirm_certs:
20 name: sirm_certs
20 name: sirm_certs
21 driver: local
21 driver: local
22 driver_opts:
22 driver_opts:
23 type: "none"
23 type: "none"
24 o: "bind"
24 o: "bind"
25 device: "${EXPOSE_CERTS}"
25 device: "${EXPOSE_CERTS}"
26 sirm_dhparam:
26 sirm_dhparam:
27 name: sirm_dhparam
27 name: sirm_dhparam
28 driver: local
28 driver: local
29 driver_opts:
29 driver_opts:
30 type: "none"
30 type: "none"
31 o: "bind"
31 o: "bind"
32 device: "${EXPOSE_DHPARAM}"
32 device: "${EXPOSE_DHPARAM}"
33 sirm_proc:
33 sirm_proc:
34 name: sirm_proc
34 name: sirm_proc
35 driver: local
35 driver: local
36 driver_opts:
36 driver_opts:
37 type: "none"
37 type: "none"
38 o: "bind"
38 o: "bind"
39 device: "${EXPOSE_PROC}"
39 device: "${EXPOSE_PROC}"
40 sirm_nas:
40 sirm_nas:
41 name: sirm_nas
41 name: sirm_nas
42 driver: local
42 driver: local
43 driver_opts:
43 driver_opts:
44 type: "none"
44 type: "none"
45 o: "bind"
45 o: "bind"
46 device: "${EXPOSE_NAS}"
46 device: "${EXPOSE_NAS}"
47 sirm_cam:
47 sirm_cam:
48 name: sirm_cam
48 name: sirm_cam
49 driver: local
49 driver: local
50 driver_opts:
50 driver_opts:
51 type: "none"
51 type: "none"
52 o: "bind"
52 o: "bind"
53 device: "${EXPOSE_CAM}"
53 device: "${EXPOSE_CAM}"
54 sirm_schain:
54 sirm_schain:
55 name: sirm_schain
55 name: sirm_schain
56 driver: local
56 driver: local
57 driver_opts:
57 driver_opts:
58 type: "none"
58 type: "none"
59 o: "bind"
59 o: "bind"
60 device: "${EXPOSE_SCHAIN}"
60 device: "${EXPOSE_SCHAIN}"
61
61
62 services:
62 services:
63 sirm-nginx-proxy:
63 sirm-nginx-proxy:
64 container_name: sirm-nginx-proxy
64 container_name: sirm-nginx-proxy
65 restart: always
65 restart: always
66 build:
66 build:
67 context: ./images/
67 context: ./images/
68 dockerfile: nginx-proxy/Dockerfile
68 dockerfile: nginx-proxy/Dockerfile
69 args:
69 args:
70 - SIRM_MAX_UPLOAD_SIZE_MB=${SIRM_MAX_UPLOAD_SIZE_MB}
70 - SIRM_MAX_UPLOAD_SIZE_MB=${SIRM_MAX_UPLOAD_SIZE_MB}
71 depends_on:
71 depends_on:
72 - sirm-web
72 - sirm-web
73 networks:
73 networks:
74 - frontend_sirm
74 - frontend_sirm
75 - backend_sirm
75 - backend_sirm
76 ports:
76 ports:
77 - 0.0.0.0:${GENERAL_PORT}:80
77 - 0.0.0.0:${GENERAL_PORT}:80
78 volumes:
78 volumes:
79 - /var/run/docker.sock:/tmp/docker.sock:ro
79 - /var/run/docker.sock:/tmp/docker.sock:ro
80 - sirm_certs:/etc/nginx/certs:ro
80 - sirm_certs:/etc/nginx/certs:ro
81 - sirm_dhparam:/etc/nginx/dhparam
81 - sirm_dhparam:/etc/nginx/dhparam
82 logging:
82 logging:
83 driver: "json-file"
83 driver: "json-file"
84 options:
84 options:
85 max-size: "12m"
85 max-size: "12m"
86
86
87 sirm-web:
87 sirm-web:
88 container_name: 'sirm-web'
88 container_name: 'sirm-web'
89 restart: always
89 restart: always
90 build:
90 build:
91 context: .
91 context: .
92 environment:
92 environment:
93 - LC_ALL=${LC_ALL}
93 - LC_ALL=${LC_ALL}
94 - DB_USER=${DB_USER}
94 - DB_USER=${DB_USER}
95 - DB_NAME=${DB_NAME}
95 - DB_NAME=${DB_NAME}
96 - DB_PASSWORD=${DB_PASSWORD}
96 - DB_PASSWORD=${DB_PASSWORD}
97 - POSTGRES_PORT_5432_TCP_ADDR=${POSTGRES_PORT_5432_TCP_ADDR}
97 - POSTGRES_PORT_5432_TCP_ADDR=${POSTGRES_PORT_5432_TCP_ADDR}
98 - POSTGRES_PORT_5432_TCP_PORT=${POSTGRES_PORT_5432_TCP_PORT}
98 - POSTGRES_PORT_5432_TCP_PORT=${POSTGRES_PORT_5432_TCP_PORT}
99 - EXPOSE_NAS=${EXPOSE_NAS}
99 - EXPOSE_NAS=${EXPOSE_NAS}
100 - PROC_SITE=${PROC_SITE}
100 - PROC_SITE=${PROC_SITE}
101 - SCHAIN_SITE=${SCHAIN_SITE}
101 - SCHAIN_SITE=${SCHAIN_SITE}
102 - SIRM_SUPER_USER=${SIRM_SUPER_USER}
103 - SIRM_SUPER_PASSWORD=${SIRM_SUPER_PASSWORD}
104 - SIRM_SUPER_EMAIL=${SIRM_SUPER_EMAIL}
105 - SIRM_DEV_USER=${SIRM_DEV_USER}
106 - SIRM_DEV_PASSWORD=${SIRM_DEV_PASSWORD}
107 - SIRM_DEV_EMAIL=${SIRM_DEV_EMAIL}
102 - SIRM_USER=${SIRM_USER}
108 - SIRM_USER=${SIRM_USER}
103 - SIRM_PASSWORD=${SIRM_PASSWORD}
109 - SIRM_PASSWORD=${SIRM_PASSWORD}
104 - SIRM_EMAIL=${SIRM_EMAIL}
110 - SIRM_EMAIL=${SIRM_EMAIL}
105 - AZ_OFFSET=${AZ_OFFSET}
111 - AZ_OFFSET=${AZ_OFFSET}
106 - VIRTUAL_HOST=${SIRM_SITE}
112 - VIRTUAL_HOST=${SIRM_SITE}
107 volumes:
113 volumes:
108 - 'sirm_web:/workspace/sirm'
114 - 'sirm_web:/workspace/sirm'
109 - 'sirm_nas:/data'
115 - 'sirm_nas:/data'
110 depends_on:
116 depends_on:
111 - sirm-postgres
117 - sirm-postgres
112 networks:
118 networks:
113 - frontend_sirm
119 - frontend_sirm
114 - backend_sirm
120 - backend_sirm
115 labels:
121 labels:
116 ofelia.enabled: "true"
122 ofelia.enabled: "true"
117 ofelia.job-exec.restart-reception.schedule: "0 1/5 * * * *"
123 ofelia.job-exec.restart-reception.schedule: "0 1/5 * * * *"
118 ofelia.job-exec.restart-reception.command: "python manage.py restart_reception"
124 ofelia.job-exec.restart-reception.command: "python manage.py restart_reception"
119 ofelia.job-exec.restart-pedestal.schedule: "0 2/10 * * * *"
125 ofelia.job-exec.restart-pedestal.schedule: "0 2/10 * * * *"
120 ofelia.job-exec.restart-pedestal.command: "python manage.py restart_pedestal"
126 ofelia.job-exec.restart-pedestal.command: "python manage.py restart_pedestal"
121 ofelia.job-exec.restart-experiment.schedule: "0 0 5 * * *"
127 ofelia.job-exec.restart-experiment.schedule: "0 0 5 * * *"
122 ofelia.job-exec.restart-experiment.command: "python manage.py restart_experiment"
128 ofelia.job-exec.restart-experiment.command: "python manage.py restart_experiment"
123 logging:
129 logging:
124 driver: "json-file"
130 driver: "json-file"
125 options:
131 options:
126 max-size: "12m"
132 max-size: "12m"
127
133
128 sirm-job:
134 sirm-job:
129 container_name: 'sirm-job'
135 container_name: 'sirm-job'
130 image: mcuadros/ofelia:latest
136 image: mcuadros/ofelia:v0.3.6
131 depends_on:
137 depends_on:
132 - sirm-web
138 - sirm-web
133 networks:
139 networks:
134 - frontend_sirm
140 #- frontend_sirm
135 - backend_sirm
141 - backend_sirm
136 command: daemon --docker
142 command: daemon --docker
137 volumes:
143 volumes:
138 - /var/run/docker.sock:/var/run/docker.sock:ro
144 - /var/run/docker.sock:/var/run/docker.sock:ro
139 logging:
145 logging:
140 driver: "json-file"
146 driver: "json-file"
141 options:
147 options:
142 max-size: "12m"
148 max-size: "12m"
143
149
144 sirm-postgres:
150 sirm-postgres:
145 container_name: 'sirm-postgres'
151 container_name: 'sirm-postgres'
146 restart: always
152 restart: always
147 build:
153 build:
148 context: ./images/
154 context: ./images/
149 dockerfile: postgres/Dockerfile
155 dockerfile: postgres/Dockerfile
150 args:
156 args:
151 - PGDATA=${PGDATA}
157 - PGDATA=${PGDATA}
152 environment:
158 environment:
153 - LC_ALL=${LC_ALL}
159 - LC_ALL=${LC_ALL}
154 - DB_USER=${DB_USER}
160 - DB_USER=${DB_USER}
155 - DB_NAME=${DB_NAME}
161 - DB_NAME=${DB_NAME}
156 - DB_PASSWORD=${DB_PASSWORD}
162 - DB_PASSWORD=${DB_PASSWORD}
157 - POSTGRES_PORT_5432_TCP_ADDR=${POSTGRES_PORT_5432_TCP_ADDR}
163 - POSTGRES_PORT_5432_TCP_ADDR=${POSTGRES_PORT_5432_TCP_ADDR}
158 - POSTGRES_PORT_5432_TCP_PORT=${POSTGRES_PORT_5432_TCP_PORT}
164 - POSTGRES_PORT_5432_TCP_PORT=${POSTGRES_PORT_5432_TCP_PORT}
159 volumes:
165 volumes:
160 - sirm_pgdata:/var/lib/postgresql/data
166 - sirm_pgdata:/var/lib/postgresql/data
161 networks:
167 networks:
162 - backend_sirm
168 - backend_sirm
163 logging:
169 logging:
164 driver: "json-file"
170 driver: "json-file"
165 options:
171 options:
166 max-size: "12m"
172 max-size: "12m"
167
173
168 sirm-proc:
174 sirm-proc:
169 container_name: 'sirm-proc'
175 container_name: 'sirm-proc'
170 restart: always
176 restart: always
171 build:
177 build:
172 context: ./volumes/proc/
178 context: ./volumes/proc/
173 environment:
179 environment:
174 - BROKER_URL=${BROKER_URL}
180 - BROKER_URL=${BROKER_URL}
175 - SOPHY_TOPIC=${SOPHY_TOPIC}
181 - SOPHY_TOPIC=${SOPHY_TOPIC}
176 - TXA_SITE=${TXA_SITE}
182 - TXA_SITE=${TXA_SITE}
177 - TXB_SITE=${TXB_SITE}
183 - TXB_SITE=${TXB_SITE}
178 - SCHAIN_SITE=${SCHAIN_SITE}
184 - SCHAIN_SITE=${SCHAIN_SITE}
179 - VIRTUAL_HOST=${PROC_SITE}
185 - VIRTUAL_HOST=${PROC_SITE}
180 volumes:
186 volumes:
181 - 'sirm_proc:/app'
187 - 'sirm_proc:/app'
182 - 'sirm_nas:/data'
188 - 'sirm_nas:/data'
183 networks:
189 networks:
184 - frontend_sirm
190 - frontend_sirm
185 logging:
191 logging:
186 driver: "json-file"
192 driver: "json-file"
187 options:
193 options:
188 max-size: "12m"
194 max-size: "12m"
189
195
190 sirm-monitor:
196 sirm-monitor:
191 container_name: 'sirm-monitor'
197 container_name: 'sirm-monitor'
192 restart: always
198 restart: always
193 image: 'sirm_sirm-proc'
199 image: 'sirm_sirm-proc'
194 command: ["python", "monitor.py"]
200 command: ["python", "monitor.py"]
195 environment:
201 environment:
196 - BROKER_URL=${BROKER_URL}
202 - BROKER_URL=${BROKER_URL}
197 - TXA_SITE=${TXA_SITE}
203 - TXA_SITE=${TXA_SITE}
198 - TXB_SITE=${TXB_SITE}
204 - TXB_SITE=${TXB_SITE}
199 volumes:
205 volumes:
200 - 'sirm_proc:/app'
206 - 'sirm_proc:/app'
201 - 'sirm_nas:/data'
207 - 'sirm_nas:/data'
202 networks:
208 networks:
203 - frontend_sirm
209 - frontend_sirm
204 depends_on:
210 depends_on:
205 - sirm-proc
211 - sirm-proc
206 logging:
212 logging:
207 driver: "json-file"
213 driver: "json-file"
208 options:
214 options:
209 max-size: "12m"
215 max-size: "12m"
210
216
211 sirm-acq:
217 sirm-acq:
212 container_name: 'sirm-acq'
218 container_name: 'sirm-acq'
213 restart: always
219 restart: always
214 image: 'sirm_sirm-proc'
220 image: 'sirm_sirm-proc'
215 command: ["python", "acq.py"]
221 command: ["python", "acq.py"]
216 environment:
222 environment:
217 - BROKER_URL=${BROKER_URL}
223 - BROKER_URL=${BROKER_URL}
218 - TXA_SITE=${TXA_SITE}
224 - TXA_SITE=${TXA_SITE}
219 - TXB_SITE=${TXB_SITE}
225 - TXB_SITE=${TXB_SITE}
220 - PROC_SITE=${PROC_SITE}
226 - PROC_SITE=${PROC_SITE}
221 volumes:
227 volumes:
222 - 'sirm_proc:/app'
228 - 'sirm_proc:/app'
223 - 'sirm_nas:/data'
229 - 'sirm_nas:/data'
224 networks:
230 networks:
225 - frontend_sirm
231 - frontend_sirm
226 depends_on:
232 depends_on:
227 - sirm-proc
233 - sirm-proc
228 logging:
234 logging:
229 driver: "json-file"
235 driver: "json-file"
230 options:
236 options:
231 max-size: "12m"
237 max-size: "12m"
232
238
233 sirm-cam:
239 sirm-cam:
234 container_name: 'sirm-cam'
240 container_name: 'sirm-cam'
235 image: bkjaya1952/ivms4200-v2.8.2.2_ml-linux
241 image: bkjaya1952/ivms4200-v2.8.2.2_ml-linux
236 restart: always
242 restart: always
237 environment:
243 environment:
238 - VIRTUAL_HOST=${CAM_SITE}
244 - VIRTUAL_HOST=${CAM_SITE}
239 volumes:
245 volumes:
240 - 'sirm_cam:/root/.wine/drive_c/iVMS-4200'
246 - 'sirm_cam:/root/.wine/drive_c/iVMS-4200'
241 networks:
247 networks:
242 - frontend_sirm
248 - frontend_sirm
243 logging:
249 logging:
244 driver: "json-file"
250 driver: "json-file"
245 options:
251 options:
246 max-size: "12m"
252 max-size: "12m"
247
253
248 sirm-schain:
254 sirm-schain:
249 container_name: 'sirm-schain'
255 container_name: 'sirm-schain'
250 restart: always
256 restart: always
251 build:
257 build:
252 context: ./volumes/schain/
258 context: ./volumes/schain/
253 environment:
259 environment:
254 - BROKER_URL=${BROKER_URL}
260 - BROKER_URL=${BROKER_URL}
255 - BACKEND=Agg
261 - BACKEND=Agg
256 - TZ=${TZ}
262 - TZ=${TZ}
257 - VIRTUAL_HOST=${SCHAIN_SITE}
263 - VIRTUAL_HOST=${SCHAIN_SITE}
258 volumes:
264 volumes:
259 - 'sirm_nas:/data'
265 - 'sirm_nas:/data'
260 - 'sirm_schain:/app'
266 - 'sirm_schain:/app'
261 networks:
267 networks:
262 - frontend_sirm
268 - frontend_sirm
263 logging:
269 logging:
264 driver: "json-file"
270 driver: "json-file"
265 options:
271 options:
266 max-size: "12m"
272 max-size: "12m"
267
273
268 networks:
274 networks:
269 frontend_sirm:
275 frontend_sirm:
270 name: frontend_sirm
276 name: frontend_sirm
271 backend_sirm:
277 backend_sirm:
272 name: backend_sirm No newline at end of file
278 name: backend_sirm
@@ -1,32 +1,35
1 #!/bin/bash
1 #!/bin/bash
2
2
3 python ../setup/prerun.py || { echo '[DJANGO prerun] FAILED. Exiting...' ; exit 1; }
3 python ../setup/prerun.py || { echo '[DJANGO prerun] FAILED. Exiting...' ; exit 1; }
4
4
5 if [ -f .gitkeep ];
5 if [ -f .gitkeep ];
6 then
6 then
7 echo "The commands 'makemigrations', 'migrate' and '.gitkeep' were not exectued"
7 echo "The commands 'makemigrations', 'migrate' and '.gitkeep' were not exectued"
8 else
8 else
9 # Apply database makemigrations
9 # Apply database makemigrations
10 echo "Apply makemigrations"
10 echo "Apply makemigrations"
11 python manage.py makemigrations
11 python manage.py makemigrations
12
12
13 # Apply database migrations
13 # Apply database migrations
14 echo "Apply database migrations"
14 echo "Apply database migrations"
15 python manage.py migrate
15 python manage.py migrate
16 python manage.py loaddata main
16 python manage.py loaddata main
17 python manage.py loaddata tx
17 python manage.py loaddata tx
18
18
19 # Collect static files
19 # Collect static files
20 #echo "Collect static files"
20 #echo "Collect static files"
21 #python manage.py collectstatic --noinput
21 #python manage.py collectstatic --noinput
22
22
23 # Create ".gitkeep" file in "setup" folder
23 # Create ".gitkeep" file in "setup" folder
24 echo "Create .gitkeep"
24 echo "Create .gitkeep"
25 touch .gitkeep
25 touch .gitkeep
26 fi
26 fi
27
27
28 echo "Create Superuser"
28 echo "Create Groups"
29 python manage.py createsuperuser_if_none_exists
29 python manage.py create_groups
30
31 echo "Create User"
32 python manage.py create_users
30
33
31 echo "Run server"
34 echo "Run server"
32 python manage.py runserver 0.0.0.0:8080 No newline at end of file
35 python manage.py runserver 0.0.0.0:8080
@@ -1,101 +1,116
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import GeneratorConfiguration
12 from .models import GeneratorConfiguration
13 from .forms import GeneratorConfigurationForm, GeneratorImportForm
13 from .forms import GeneratorConfigurationForm, GeneratorImportForm
14
14
15 def is_developer(user):
16 groups = [str(g.name) for g in user.groups.all()]
17 #return 'Developer' in groups or user.is_staff
18 return 'Developer' in groups or user.is_superuser
19
20
21 def is_operator(user):
22 groups = [str(g.name) for g in user.groups.all()]
23 #return 'Operator' in groups or user.is_staff
24 return 'Operator' in groups or user.is_superuser
25
15
26
16 def conf(request, conf_id):
27 def conf(request, conf_id):
17
28
18 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
29 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
19
30
20 kwargs = {}
31 kwargs = {}
21 kwargs['dev_conf'] = conf
32 kwargs['dev_conf'] = conf
22
33
23 if conf.enable_2:
34 if conf.enable_2:
24 kwargs['dev_conf_keys'] = ['delay', 'periode_1', 'width_1', 'ntx_1', 'periode_2', 'width_2', 'ntx_2', 'selector']
35 kwargs['dev_conf_keys'] = ['delay', 'periode_1', 'width_1', 'ntx_1', 'periode_2', 'width_2', 'ntx_2', 'selector']
25 else:
36 else:
26 kwargs['dev_conf_keys'] = ['delay', 'periode_1', 'width_1', 'ntx_1', 'selector']
37 kwargs['dev_conf_keys'] = ['delay', 'periode_1', 'width_1', 'ntx_1', 'selector']
27
38
28 kwargs['title'] = 'Configuration'
39 kwargs['title'] = 'Configuration'
29 kwargs['suptitle'] = 'Detail'
40 kwargs['suptitle'] = 'Detail'
30
41
31 kwargs['button'] = 'Edit Configuration'
42 kwargs['button'] = 'Edit Configuration'
32
43
33 conf.status_device()
44 conf.status_device()
34
45
35 ###### SIDEBAR ######
46 ###### SIDEBAR ######
36 kwargs.update(sidebar(conf=conf))
47 kwargs.update(sidebar(conf=conf))
37
48
38 return render(request, 'generator_conf.html', kwargs)
49 return render(request, 'generator_conf.html', kwargs)
39
50
40 @login_required
51 @login_required
41 def conf_edit(request, conf_id):
52 def conf_edit(request, conf_id):
42
53
43 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
54 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
44
55
56 if not is_developer(request.user):
57 messages.error(request, 'You must be an developer to edit this configuration')
58 return redirect(conf.get_absolute_url())
59
45 if request.method=='GET':
60 if request.method=='GET':
46
61
47 form = GeneratorConfigurationForm(instance=conf)
62 form = GeneratorConfigurationForm(instance=conf)
48
63
49 elif request.method=='POST':
64 elif request.method=='POST':
50
65
51 form = GeneratorConfigurationForm(request.POST, instance=conf)
66 form = GeneratorConfigurationForm(request.POST, instance=conf)
52
67
53 if form.is_valid():
68 if form.is_valid():
54 form.save()
69 form.save()
55
70
56 messages.success(request, 'Generator configuration successfully updated')
71 messages.success(request, 'Generator configuration successfully updated')
57
72
58 return redirect(conf.get_absolute_url())
73 return redirect(conf.get_absolute_url())
59
74
60 kwargs = {}
75 kwargs = {}
61 kwargs['dev_conf'] = conf
76 kwargs['dev_conf'] = conf
62 kwargs['form'] = form
77 kwargs['form'] = form
63 kwargs['edit'] = True
78 kwargs['edit'] = True
64
79
65 kwargs['title'] = 'Generator Configuration'
80 kwargs['title'] = 'Generator Configuration'
66 kwargs['suptitle'] = 'Edit'
81 kwargs['suptitle'] = 'Edit'
67 kwargs['button'] = 'Update'
82 kwargs['button'] = 'Update'
68
83
69 return render(request, 'generator_conf_edit.html', kwargs)
84 return render(request, 'generator_conf_edit.html', kwargs)
70
85
71 def import_file(request, conf_id):
86 def import_file(request, conf_id):
72
87
73 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
88 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
74 if request.method=='POST':
89 if request.method=='POST':
75 form = GeneratorImportForm(request.POST, request.FILES)
90 form = GeneratorImportForm(request.POST, request.FILES)
76 if form.is_valid():
91 if form.is_valid():
77 try:
92 try:
78 data = conf.import_from_file(request.FILES['file_name'])
93 data = conf.import_from_file(request.FILES['file_name'])
79 conf.dict_to_parms(data)
94 conf.dict_to_parms(data)
80 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
95 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
81 return redirect(conf.get_absolute_url_edit())
96 return redirect(conf.get_absolute_url_edit())
82
97
83 except Exception as e:
98 except Exception as e:
84 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
99 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
85 else:
100 else:
86 messages.warning(request, 'Your current configuration will be replaced')
101 messages.warning(request, 'Your current configuration will be replaced')
87 form = GeneratorImportForm()
102 form = GeneratorImportForm()
88
103
89 kwargs = {}
104 kwargs = {}
90 kwargs['form'] = form
105 kwargs['form'] = form
91 kwargs['title'] = 'Generator Configuration'
106 kwargs['title'] = 'Generator Configuration'
92 kwargs['suptitle'] = 'Import file'
107 kwargs['suptitle'] = 'Import file'
93 kwargs['button'] = 'Upload'
108 kwargs['button'] = 'Upload'
94 kwargs['previous'] = conf.get_absolute_url()
109 kwargs['previous'] = conf.get_absolute_url()
95
110
96 return render(request, 'generator_import.html', kwargs)
111 return render(request, 'generator_import.html', kwargs)
97
112
98 def conf_raw(request, conf_id):
113 def conf_raw(request, conf_id):
99 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
114 conf = get_object_or_404(GeneratorConfiguration, pk=conf_id)
100 raw = conf.write_device(raw=True)
115 raw = conf.write_device(raw=True)
101 return HttpResponse(raw, content_type='application/json') No newline at end of file
116 return HttpResponse(raw, content_type='application/json')
@@ -1,655 +1,655
1 import os
1 import os
2 import json
2 import json
3 import requests
3 import requests
4 import time
4 import time
5 from datetime import datetime
5 from datetime import datetime
6 import base64
6 import base64
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.urls import reverse
15 from django.urls import reverse
16 from django.core.validators import MinValueValidator, MaxValueValidator
16 from django.core.validators import MinValueValidator, MaxValueValidator
17 from django.shortcuts import get_object_or_404
17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 from django.contrib.auth.models import User
19 from django.db.models.signals import post_save
19 from django.db.models.signals import post_save
20 from django.dispatch import receiver
20 from django.dispatch import receiver
21
21
22 from apps.main.utils import Params
22 from apps.main.utils import Params
23
23
24 DEV_PORTS = {
24 DEV_PORTS = {
25 'pedestal' : 80,
25 'pedestal' : 80,
26 'pedestal_dev' : 80,
26 'pedestal_dev' : 80,
27 'generator' : 80,
27 'generator' : 80,
28 'usrp_rx' : 2000,
28 'usrp_rx' : 2000,
29 'usrp_tx' : 2000,
29 'usrp_tx' : 2000,
30 }
30 }
31
31
32 RADAR_STATES = (
32 RADAR_STATES = (
33 (0, 'No connected'),
33 (0, 'No connected'),
34 (1, 'Connected'),
34 (1, 'Connected'),
35 (2, 'Configured'),
35 (2, 'Configured'),
36 (3, 'Running'),
36 (3, 'Running'),
37 (4, 'Scheduled'),
37 (4, 'Scheduled'),
38 )
38 )
39
39
40 EXPERIMENT_TYPE = (
40 EXPERIMENT_TYPE = (
41 (0, 'RAW_DATA'),
41 (0, 'RAW_DATA'),
42 (1, 'PDATA'),
42 (1, 'PDATA'),
43 )
43 )
44
44
45 DECODE_TYPE = (
45 DECODE_TYPE = (
46 (0, 'None'),
46 (0, 'None'),
47 (1, 'TimeDomain'),
47 (1, 'TimeDomain'),
48 (2, 'FreqDomain'),
48 (2, 'FreqDomain'),
49 (3, 'InvFreqDomain'),
49 (3, 'InvFreqDomain'),
50 )
50 )
51
51
52 DEV_STATES = (
52 DEV_STATES = (
53 (0, 'Unknown'),
53 (0, 'Unknown'),
54 (1, 'Connected'),
54 (1, 'Connected'),
55 (2, 'Configured'),
55 (2, 'Configured'),
56 (3, 'Running'),
56 (3, 'Running'),
57 (4, 'Offline'),
57 (4, 'Offline'),
58 )
58 )
59
59
60 DEV_TYPES = (
60 DEV_TYPES = (
61 ('', 'Select a device type'),
61 ('', 'Select a device type'),
62 ('pedestal', 'Pedestal Controller'),
62 ('pedestal', 'Pedestal Controller'),
63 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
63 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
64 ('generator', 'Pulse Generator'),
64 ('generator', 'Pulse Generator'),
65 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
65 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
66 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
66 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
67 )
67 )
68
68
69 EXP_STATES = (
69 EXP_STATES = (
70 (0,'Error'), #RED
70 (0,'Error'), #RED
71 (1,'Cancelled'), #YELLOW
71 (1,'Cancelled'), #YELLOW
72 (2,'Running'), #GREEN
72 (2,'Running'), #GREEN
73 (3,'Scheduled'), #BLUE
73 (3,'Scheduled'), #BLUE
74 (4,'Unknown'), #WHITE
74 (4,'Unknown'), #WHITE
75 (5,'Other'), #ORANGE
75 (5,'Other'), #ORANGE
76 )
76 )
77
77
78 CONF_TYPES = (
78 CONF_TYPES = (
79 (0, 'Active'),
79 (0, 'Active'),
80 (1, 'Historical'),
80 (1, 'Historical'),
81 )
81 )
82
82
83 class Profile(models.Model):
83 class Profile(models.Model):
84 user = models.OneToOneField(User, on_delete=models.CASCADE)
84 user = models.OneToOneField(User, on_delete=models.CASCADE)
85 theme = models.CharField(max_length=30, default='spacelab')
85 theme = models.CharField(max_length=30, default='spacelab')
86
86
87
87
88 @receiver(post_save, sender=User)
88 @receiver(post_save, sender=User)
89 def create_user_profile(sender, instance, created, **kwargs):
89 def create_user_profile(sender, instance, created, **kwargs):
90 if created:
90 if created:
91 Profile.objects.create(user=instance)
91 Profile.objects.create(user=instance)
92
92
93 @receiver(post_save, sender=User)
93 @receiver(post_save, sender=User)
94 def save_user_profile(sender, instance, **kwargs):
94 def save_user_profile(sender, instance, **kwargs):
95 instance.profile.save()
95 instance.profile.save()
96
96
97
97
98 class DeviceType(models.Model):
98 class DeviceType(models.Model):
99
99
100 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
100 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
101 sequence = models.PositiveSmallIntegerField(default=55)
101 sequence = models.PositiveSmallIntegerField(default=55)
102 description = models.TextField(blank=True, null=True)
102 description = models.TextField(blank=True, null=True)
103
103
104 class Meta:
104 class Meta:
105 db_table = 'db_device_types'
105 db_table = 'db_device_types'
106
106
107 def __str__(self):
107 def __str__(self):
108 return u'%s' % self.name.title()
108 return u'%s' % self.name.title()
109
109
110 class Device(models.Model):
110 class Device(models.Model):
111
111
112 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
112 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
113 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
113 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
114 port_address = models.PositiveSmallIntegerField(default=2000)
114 port_address = models.PositiveSmallIntegerField(default=2000)
115 description = models.TextField(blank=True, null=True)
115 description = models.TextField(blank=True, null=True)
116 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
116 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
117 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
117 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
118
118
119 class Meta:
119 class Meta:
120 db_table = 'db_devices'
120 db_table = 'db_devices'
121
121
122 def __str__(self):
122 def __str__(self):
123 ret = self.device_type
123 ret = self.device_type
124 return str(ret)
124 return str(ret)
125
125
126 @property
126 @property
127 def name(self):
127 def name(self):
128 return str(self)
128 return str(self)
129
129
130 def get_status(self):
130 def get_status(self):
131 return self.status
131 return self.status
132
132
133 @property
133 @property
134 def status_color(self):
134 def status_color(self):
135 color = 'muted'
135 color = 'muted'
136 if self.status == 0:
136 if self.status == 0:
137 color = "danger"
137 color = "danger"
138 elif self.status == 1:
138 elif self.status == 1:
139 color = "primary"
139 color = "primary"
140 elif self.status == 2:
140 elif self.status == 2:
141 color = "info"
141 color = "info"
142 elif self.status == 3:
142 elif self.status == 3:
143 color = "success"
143 color = "success"
144
144
145 return color
145 return color
146
146
147 def url(self, path=None):
147 def url(self, path=None):
148
148
149 if path:
149 if path:
150 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
150 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
151 else:
151 else:
152 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
152 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
153
153
154 def get_absolute_url(self):
154 def get_absolute_url(self):
155 return reverse('url_device', args=[str(self.id)])
155 return reverse('url_device', args=[str(self.id)])
156
156
157 def get_absolute_url_edit(self):
157 def get_absolute_url_edit(self):
158 return reverse('url_edit_device', args=[str(self.id)])
158 return reverse('url_edit_device', args=[str(self.id)])
159
159
160 def get_absolute_url_delete(self):
160 def get_absolute_url_delete(self):
161 return reverse('url_delete_device', args=[str(self.id)])
161 return reverse('url_delete_device', args=[str(self.id)])
162
162
163 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
163 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
164
164
165 if self.device_type.name=='pedestal':
165 if self.device_type.name=='pedestal':
166 headers = {'content-type': "application/json",
166 headers = {'content-type': "application/json",
167 'cache-control': "no-cache"}
167 'cache-control': "no-cache"}
168
168
169 ip = [int(x) for x in ip_address.split('.')]
169 ip = [int(x) for x in ip_address.split('.')]
170 dns = [int(x) for x in dns.split('.')]
170 dns = [int(x) for x in dns.split('.')]
171 gateway = [int(x) for x in gateway.split('.')]
171 gateway = [int(x) for x in gateway.split('.')]
172 subnet = [int(x) for x in mask.split('.')]
172 subnet = [int(x) for x in mask.split('.')]
173
173
174 payload = {
174 payload = {
175 "ip": ip,
175 "ip": ip,
176 "dns": dns,
176 "dns": dns,
177 "gateway": gateway,
177 "gateway": gateway,
178 "subnet": subnet
178 "subnet": subnet
179 }
179 }
180
180
181 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
181 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
182 try:
182 try:
183 answer = req.json()
183 answer = req.json()
184 if answer['changeip']=='ok':
184 if answer['changeip']=='ok':
185 self.message = '25|IP succesfully changed'
185 self.message = '25|IP succesfully changed'
186 self.ip_address = ip_address
186 self.ip_address = ip_address
187 self.save()
187 self.save()
188 else:
188 else:
189 self.message = '30|An error ocuur when changing IP'
189 self.message = '30|An error ocuur when changing IP'
190 except Exception as e:
190 except Exception as e:
191 self.message = '40|{}'.format(str(e))
191 self.message = '40|{}'.format(str(e))
192 else:
192 else:
193 self.message = 'Not implemented'
193 self.message = 'Not implemented'
194 return False
194 return False
195
195
196 return True
196 return True
197
197
198
198
199 class Experiment(PolymorphicModel):
199 class Experiment(PolymorphicModel):
200
200
201 name = models.CharField(max_length=40, default='', unique=True)
201 name = models.CharField(max_length=40, default='', unique=True)
202 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "pedestal_conf")
202 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "pedestal_conf")
203 generator = models.ForeignKey('Device', null=False, blank=False, on_delete=models.PROTECT, default=2, editable=False, limit_choices_to={'device_type__name': 'generator'}, related_name = "generator_conf")
203 generator = models.ForeignKey('Device', null=False, blank=False, on_delete=models.PROTECT, default=2, editable=False, limit_choices_to={'device_type__name': 'generator'}, related_name = "generator_conf")
204 reception_rx = models.ForeignKey('usrp_rx.USRPRXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "usrp_rx_CONF")
204 reception_rx = models.ForeignKey('usrp_rx.USRPRXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "usrp_rx_CONF")
205 transmission_tx = models.ForeignKey('usrp_tx.USRPTXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "usrp_tx")
205 transmission_tx = models.ForeignKey('usrp_tx.USRPTXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'type': 0}, related_name = "usrp_tx")
206 task = models.CharField(max_length=36, default='', blank=True, null=True)
206 task = models.CharField(max_length=36, default='', blank=True, null=True)
207 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
207 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
208 author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
208 author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
209 hash = models.CharField(default='', max_length=64, null=True, blank=True)
209 hash = models.CharField(default='', max_length=64, null=True, blank=True)
210 latitude = models.FloatField(null=False, blank=False, default=0, editable=False)
210 latitude = models.FloatField(null=False, blank=False, default=0, editable=False)
211 longitude = models.FloatField(null=False, blank=False, default=0, editable=False)
211 longitude = models.FloatField(null=False, blank=False, default=0, editable=False)
212 altitude = models.FloatField(null=False, blank=False, default=0, editable=False)
212 altitude = models.FloatField(null=False, blank=False, default=0, editable=False)
213 heading = models.FloatField(null=True, blank=True)
213 heading = models.FloatField(null=True, blank=True)
214 mode_stop = models.CharField(max_length=3, null=False, blank=False, default='web', editable=False)
214 mode_stop = models.CharField(max_length=3, null=False, blank=False, default='web', editable=False)
215
215
216 class Meta:
216 class Meta:
217 db_table = 'db_experiments'
217 db_table = 'db_experiments'
218 ordering = ('name',)
218 ordering = ('name',)
219
219
220 def __str__(self):
220 def __str__(self):
221 return u'%s' % (self.name)
221 return u'%s' % (self.name)
222
222
223 def jsonify(self):
223 def jsonify(self):
224
224
225 data = {}
225 data = {}
226
226
227 ignored = []
227 ignored = []
228
228
229 for field in self._meta.fields:
229 for field in self._meta.fields:
230 if field.name in ignored:
230 if field.name in ignored:
231 continue
231 continue
232 data[field.name] = field.value_from_object(self)
232 data[field.name] = field.value_from_object(self)
233
233
234 data['configurations'] = ['{}'.format(conf.pk) for
234 data['configurations'] = ['{}'.format(conf.pk) for
235 conf in Configuration.objects.filter(experiment=self, type=0)]
235 conf in Configuration.objects.filter(experiment=self, type=0)]
236
236
237 return data
237 return data
238
238
239 def clone(self, **kwargs):
239 def clone(self, **kwargs):
240
240
241 confs = Configuration.objects.filter(experiment=self, type=0)
241 confs = Configuration.objects.filter(experiment=self, type=0)
242 self.pk = None
242 self.pk = None
243 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
243 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
244 for attr, value in kwargs.items():
244 for attr, value in kwargs.items():
245 setattr(self, attr, value)
245 setattr(self, attr, value)
246
246
247 self.save()
247 self.save()
248
248
249 for conf in confs:
249 for conf in confs:
250 conf.clone(experiment=self)
250 conf.clone(experiment=self)
251
251
252 return self
252 return self
253
253
254
254
255 def generator_start(self):
255 def generator_start(self):
256 try:
256 try:
257 experiment = get_object_or_404(Experiment, pk=self.id)
257 experiment = get_object_or_404(Experiment, pk=self.id)
258 generator_url = experiment.generator.url()
258 generator_url = experiment.generator.url()
259
259
260 period = self.transmission_tx.ipp*2/0.3
260 period = self.transmission_tx.ipp*2/0.3
261 if self.transmission_tx.enable_2:
261 if self.transmission_tx.enable_2:
262 payload = {"Delay": 1 + self.transmission_tx.delay, "periode1": period, "width1": self.transmission_tx.pulse_1 + 6, "repeatability1": self.transmission_tx.repetitions_1, "periode2": period, "width2": self.transmission_tx.pulse_2 + 6, "repeatability2": self.transmission_tx.repetitions_2, "enable": 1}
262 payload = {"Delay": 1 + self.transmission_tx.delay, "periode1": period, "width1": self.transmission_tx.pulse_1 + 6, "repeatability1": self.transmission_tx.repetitions_1, "periode2": period, "width2": self.transmission_tx.pulse_2 + 6, "repeatability2": self.transmission_tx.repetitions_2, "enable": 1}
263 else:
263 else:
264 payload = {"Delay": 1 + self.transmission_tx.delay, "periode1": period, "width1": self.transmission_tx.pulse_1 + 6, "repeatability1": 1, "periode2": period, "width2": self.transmission_tx.pulse_1 + 6, "repeatability2": 1, "enable": 1}
264 payload = {"Delay": 1 + self.transmission_tx.delay, "periode1": period, "width1": self.transmission_tx.pulse_1 + 6, "repeatability1": 1, "periode2": period, "width2": self.transmission_tx.pulse_1 + 6, "repeatability2": 1, "enable": 1}
265
265
266 json_trmode = json.dumps(payload)
266 json_trmode = json.dumps(payload)
267
267
268 base64_trmode = base64.standard_b64encode(json_trmode.encode('ascii'))
268 base64_trmode = base64.standard_b64encode(json_trmode.encode('ascii'))
269
269
270 trmode_url = generator_url + "trmode?params="
270 trmode_url = generator_url + "trmode?params="
271 complete_url_trmode = trmode_url + base64_trmode.decode('ascii')
271 complete_url_trmode = trmode_url + base64_trmode.decode('ascii')
272
272
273 requests.get(complete_url_trmode)
273 requests.get(complete_url_trmode)
274 except:
274 except:
275 return False
275 return False
276 return True
276 return True
277
277
278 def generator_stop(self):
278 def generator_stop(self):
279 try:
279 try:
280 experiment = get_object_or_404(Experiment, pk=self.id)
280 experiment = get_object_or_404(Experiment, pk=self.id)
281 generator_url = experiment.generator.url()
281 generator_url = experiment.generator.url()
282
282
283 payload = {"enable": 0}
283 payload = {"enable": 0}
284
284
285 json_trmode_selector = json.dumps(payload)
285 json_trmode_selector = json.dumps(payload)
286 base64_trmode_selector = base64.standard_b64encode(json_trmode_selector.encode('ascii'))
286 base64_trmode_selector = base64.standard_b64encode(json_trmode_selector.encode('ascii'))
287
287
288 trmode_url = generator_url + "trmode?params="
288 trmode_url = generator_url + "trmode?params="
289 url_trmode_selector = trmode_url + base64_trmode_selector.decode('ascii')
289 url_trmode_selector = trmode_url + base64_trmode_selector.decode('ascii')
290 requests.get(url_trmode_selector)
290 requests.get(url_trmode_selector)
291 except:
291 except:
292 return False
292 return False
293 return True
293 return True
294
294
295 def start(self):
295 def start(self):
296 '''
296 '''
297 Configure and start experiments's devices
297 Configure and start experiments's devices
298 '''
298 '''
299 all_status = Experiment.objects.filter(status=2)
299 all_status = Experiment.objects.filter(status=2)
300
300
301 if self.status != 2:
301 if self.status != 2:
302 if len(all_status) == 0:
302 if len(all_status) == 0:
303 data = {
303 data = {
304 'name': '{}@{}'.format(self.name, datetime.now().strftime('%Y-%m-%dT%H-%M-%S')),
304 'name': '{}@{}'.format(self.name, datetime.now().strftime('%Y-%m-%dT%H-%M-%S')),
305 'latitude': self.latitude,
305 'latitude': self.latitude,
306 'longitude': self.longitude,
306 'longitude': self.longitude,
307 'altitude': self.altitude,
307 'altitude': self.altitude,
308 'heading': self.heading
308 'heading': self.heading
309 }
309 }
310
310
311 try:
311 try:
312 data['pedestal'] = self.pedestal.start_device(name_experiment=data['name'])
312 data['pedestal'] = self.pedestal.start_device(name_experiment=data['name'])
313 time.sleep(1.0)
313 time.sleep(1.0)
314 self.generator_start()
314 self.generator_start()
315 time.sleep(1.0)
315 time.sleep(1.0)
316 data['usrp_tx'] = self.transmission_tx.start_device(name_experiment=data['name'])
316 data['usrp_tx'] = self.transmission_tx.start_device(name_experiment=data['name'])
317 time.sleep(1.0)
317 time.sleep(1.0)
318 data['usrp_rx'] = self.reception_rx.start_device(name_experiment=data['name'])
318 data['usrp_rx'] = self.reception_rx.start_device(name_experiment=data['name'])
319 time.sleep(0.1)
319 time.sleep(0.1)
320 proc_url = 'http://'+os.environ['PROC_SITE']+'/start'
320 proc_url = 'http://'+os.environ['PROC_SITE']+'/start'
321 requests.post(proc_url, json=data)
321 requests.post(proc_url, json=data)
322
322
323 except:
323 except:
324 return 0
324 return 0
325 return 2
325 return 2
326 else:
326 else:
327 return 5
327 return 5
328 else:
328 else:
329 return 2
329 return 2
330
330
331
331
332 def stop(self):
332 def stop(self):
333 '''
333 '''
334 Stop experiments's devices
334 Stop experiments's devices
335 PEDESTAL, GENERATOR & USRP's
335 PEDESTAL, GENERATOR & USRP's
336 '''
336 '''
337
337
338 try:
338 try:
339 self.transmission_tx.stop_device()
339 self.transmission_tx.stop_device()
340 time.sleep(1.0)
340 time.sleep(1.0)
341 self.generator_stop()
341 self.generator_stop()
342 time.sleep(0.1)
342 time.sleep(0.1)
343 self.reception_rx.stop_device()
343 self.reception_rx.stop_device()
344 time.sleep(0.1)
344 time.sleep(0.1)
345 self.pedestal.reset_device()
345 self.pedestal.reset_device()
346 time.sleep(14)
346 time.sleep(0.1)
347 self.pedestal.stop_device()
347 self.pedestal.stop_device()
348 time.sleep(0.1)
348 time.sleep(0.1)
349 proc_url = 'http://'+os.environ['PROC_SITE']+'/stop'
349 proc_url = 'http://'+os.environ['PROC_SITE']+'/stop'
350 requests.get(proc_url)
350 requests.get(proc_url)
351 except:
351 except:
352 return 0
352 return 0
353 return 4
353 return 4
354
354
355 def get_status(self):
355 def get_status(self):
356
356
357 if self.status == 3:
357 if self.status == 3:
358 return
358 return
359
359
360 confs = Configuration.objects.filter(experiment=self, type=0)
360 confs = Configuration.objects.filter(experiment=self, type=0)
361
361
362 for conf in confs:
362 for conf in confs:
363 conf.status_device()
363 conf.status_device()
364
364
365 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
365 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
366
366
367 if total==2*confs.count():
367 if total==2*confs.count():
368 status = 1
368 status = 1
369 elif total == 3*confs.count():
369 elif total == 3*confs.count():
370 status = 2
370 status = 2
371 else:
371 else:
372 status = 0
372 status = 0
373
373
374 self.status = status
374 self.status = status
375 self.save()
375 self.save()
376
376
377 def status_color(self):
377 def status_color(self):
378 color = 'muted'
378 color = 'muted'
379 if self.status == 0:
379 if self.status == 0:
380 color = "danger"
380 color = "danger"
381 elif self.status == 1:
381 elif self.status == 1:
382 color = "warning"
382 color = "warning"
383 elif self.status == 2:
383 elif self.status == 2:
384 color = "success"
384 color = "success"
385 elif self.status == 3:
385 elif self.status == 3:
386 color = "info"
386 color = "info"
387
387
388 return color
388 return color
389
389
390 def parms_to_dict(self):
390 def parms_to_dict(self):
391
391
392 params = Params({})
392 params = Params({})
393 params.add(self.jsonify(), 'experiments')
393 params.add(self.jsonify(), 'experiments')
394
394
395 configurations = Configuration.objects.filter(experiment=self, type=0)
395 configurations = Configuration.objects.filter(experiment=self, type=0)
396
396
397 for conf in configurations:
397 for conf in configurations:
398 params.add(conf.jsonify(), 'configurations')
398 params.add(conf.jsonify(), 'configurations')
399
399
400 return params.data
400 return params.data
401
401
402 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
402 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
403
403
404 configurations = Configuration.objects.filter(experiment=self)
404 configurations = Configuration.objects.filter(experiment=self)
405
405
406 if id_exp is not None:
406 if id_exp is not None:
407 exp_parms = parms['experiments']['byId'][id_exp]
407 exp_parms = parms['experiments']['byId'][id_exp]
408 else:
408 else:
409 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
409 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
410
410
411 if configurations:
411 if configurations:
412 for configuration in configurations:
412 for configuration in configurations:
413 configuration.delete()
413 configuration.delete()
414
414
415 for id_conf in exp_parms['configurations']:
415 for id_conf in exp_parms['configurations']:
416 conf_parms = parms['configurations']['byId'][id_conf]
416 conf_parms = parms['configurations']['byId'][id_conf]
417 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
417 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
418 model = CONF_MODELS[conf_parms['device_type']]
418 model = CONF_MODELS[conf_parms['device_type']]
419 conf = model(
419 conf = model(
420 experiment = self,
420 experiment = self,
421 device = device,
421 device = device,
422 )
422 )
423 conf.dict_to_parms(parms, id=id_conf)
423 conf.dict_to_parms(parms, id=id_conf)
424
424
425
425
426 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
426 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
427 self.save()
427 self.save()
428
428
429 return self
429 return self
430
430
431 def get_absolute_url(self):
431 def get_absolute_url(self):
432 return reverse('url_experiment', args=[str(self.id)])
432 return reverse('url_experiment', args=[str(self.id)])
433
433
434 def get_absolute_url_edit(self):
434 def get_absolute_url_edit(self):
435 return reverse('url_edit_experiment', args=[str(self.id)])
435 return reverse('url_edit_experiment', args=[str(self.id)])
436
436
437 def get_absolute_url_delete(self):
437 def get_absolute_url_delete(self):
438 return reverse('url_delete_experiment', args=[str(self.id)])
438 return reverse('url_delete_experiment', args=[str(self.id)])
439
439
440 def get_absolute_url_import(self):
440 def get_absolute_url_import(self):
441 return reverse('url_import_experiment', args=[str(self.id)])
441 return reverse('url_import_experiment', args=[str(self.id)])
442
442
443 def get_absolute_url_export(self):
443 def get_absolute_url_export(self):
444 return reverse('url_export_experiment', args=[str(self.id)])
444 return reverse('url_export_experiment', args=[str(self.id)])
445
445
446 def get_absolute_url_start(self):
446 def get_absolute_url_start(self):
447 return reverse('url_start_experiment', args=[str(self.id)])
447 return reverse('url_start_experiment', args=[str(self.id)])
448
448
449 def get_absolute_url_stop(self):
449 def get_absolute_url_stop(self):
450 return reverse('url_stop_experiment', args=[str(self.id)])
450 return reverse('url_stop_experiment', args=[str(self.id)])
451
451
452
452
453 class Configuration(PolymorphicModel):
453 class Configuration(PolymorphicModel):
454
454
455 id = models.AutoField(primary_key=True)
455 id = models.AutoField(primary_key=True)
456 experiment = models.CharField(default='empty', editable=False, max_length=64, null=True, blank=True)
456 experiment = models.CharField(default='empty', editable=False, max_length=64, null=True, blank=True)
457 experiment_date = models.DateTimeField(default=datetime.now, editable=False)
457 experiment_date = models.DateTimeField(default=datetime.now, editable=False)
458 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
458 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
459 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
459 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
460 created_date = models.DateTimeField(auto_now_add=True)
460 created_date = models.DateTimeField(auto_now_add=True)
461 programmed_date = models.DateTimeField(auto_now=True)
461 programmed_date = models.DateTimeField(auto_now=True)
462 parameters = models.TextField(default='{}')
462 parameters = models.TextField(default='{}')
463 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
463 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
464 hash = models.CharField(default='', max_length=64, null=True, blank=True)
464 hash = models.CharField(default='', max_length=64, null=True, blank=True)
465 message = ""
465 message = ""
466
466
467 class Meta:
467 class Meta:
468 db_table = 'db_configurations'
468 db_table = 'db_configurations'
469 ordering = ('device__device_type__name',)
469 ordering = ('device__device_type__name',)
470
470
471 def __str__(self):
471 def __str__(self):
472
472
473 ret = u'{} '.format(self.device.device_type.name.upper())
473 ret = u'{} '.format(self.device.device_type.name.upper())
474
474
475 if 'mix' in [f.name for f in self._meta.get_fields()]:
475 if 'mix' in [f.name for f in self._meta.get_fields()]:
476 if self.mix:
476 if self.mix:
477 ret = '{} MIX '.format(self.device.device_type.name.upper())
477 ret = '{} MIX '.format(self.device.device_type.name.upper())
478
478
479 if 'label' in [f.name for f in self._meta.get_fields()]:
479 if 'label' in [f.name for f in self._meta.get_fields()]:
480 ret += '{}'.format(self.label)
480 ret += '{}'.format(self.label)
481
481
482 return ret
482 return ret
483
483
484 @property
484 @property
485 def name(self):
485 def name(self):
486
486
487 return str(self)
487 return str(self)
488
488
489 @property
489 @property
490 def label(self):
490 def label(self):
491
491
492 return str(self)
492 return str(self)
493
493
494 def jsonify(self):
494 def jsonify(self):
495
495
496 data = {}
496 data = {}
497
497
498 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
498 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
499 'created_date', 'programmed_date', 'device',
499 'created_date', 'programmed_date', 'device',
500 'experiment', 'author')
500 'experiment', 'author')
501
501
502 for field in self._meta.fields:
502 for field in self._meta.fields:
503 if field.name in ignored:
503 if field.name in ignored:
504 continue
504 continue
505 data[field.name] = field.value_from_object(self)
505 data[field.name] = field.value_from_object(self)
506
506
507 data['device_type'] = self.device.device_type.name
507 data['device_type'] = self.device.device_type.name
508 return data
508 return data
509
509
510 def clone(self, **kwargs):
510 def clone(self, **kwargs):
511 before_id = self.id
511 before_id = self.id
512
512
513 self.pk = None
513 self.pk = None
514 self.id = None
514 self.id = None
515 for attr, value in kwargs.items():
515 for attr, value in kwargs.items():
516 setattr(self, attr, value)
516 setattr(self, attr, value)
517 self.save()
517 self.save()
518
518
519 self.id = before_id
519 self.id = before_id
520 return self
520 return self
521
521
522 def parms_to_dict(self):
522 def parms_to_dict(self):
523
523
524 params = Params({})
524 params = Params({})
525 params.add(self.jsonify(), 'configurations')
525 params.add(self.jsonify(), 'configurations')
526 return params.data
526 return params.data
527
527
528 def parms_to_text(self):
528 def parms_to_text(self):
529
529
530 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
530 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
531
531
532
532
533 def parms_to_binary(self):
533 def parms_to_binary(self):
534
534
535 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
535 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
536
536
537
537
538 def dict_to_parms(self, parameters, id=None):
538 def dict_to_parms(self, parameters, id=None):
539
539
540 params = Params(parameters)
540 params = Params(parameters)
541
541
542 if id:
542 if id:
543 data = params.get_conf(id_conf=id)
543 data = params.get_conf(id_conf=id)
544 else:
544 else:
545 data = params.get_conf(dtype=self.device.device_type.name)
545 data = params.get_conf(dtype=self.device.device_type.name)
546
546
547 for key, value in data.items():
547 for key, value in data.items():
548 if key not in ('id', 'device_type'):
548 if key not in ('id', 'device_type'):
549 setattr(self, key, value)
549 setattr(self, key, value)
550
550
551 self.save()
551 self.save()
552
552
553
553
554 def export_to_file(self, format="json"):
554 def export_to_file(self, format="json"):
555
555
556 content_type = ''
556 content_type = ''
557
557
558 if format == 'racp':
558 if format == 'racp':
559 content_type = 'text/plain'
559 content_type = 'text/plain'
560 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
560 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
561 content = self.parms_to_text(file_format = 'racp')
561 content = self.parms_to_text(file_format = 'racp')
562
562
563 if format == 'text':
563 if format == 'text':
564 content_type = 'text/plain'
564 content_type = 'text/plain'
565 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
565 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
566 content = self.parms_to_text()
566 content = self.parms_to_text()
567
567
568 if format == 'binary':
568 if format == 'binary':
569 content_type = 'application/octet-stream'
569 content_type = 'application/octet-stream'
570 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
570 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
571 content = self.parms_to_binary()
571 content = self.parms_to_binary()
572
572
573 if not content_type:
573 if not content_type:
574 content_type = 'application/json'
574 content_type = 'application/json'
575 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
575 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
576 content = json.dumps(self.parms_to_dict(), indent=2)
576 content = json.dumps(self.parms_to_dict(), indent=2)
577
577
578
578
579 fields = {'content_type':content_type,
579 fields = {'content_type':content_type,
580 'filename':filename,
580 'filename':filename,
581 'content':content
581 'content':content
582 }
582 }
583
583
584 return fields
584 return fields
585
585
586 def import_from_file(self, fp):
586 def import_from_file(self, fp):
587
587
588 parms = {}
588 parms = {}
589
589
590 path, ext = os.path.splitext(fp.name)
590 path, ext = os.path.splitext(fp.name)
591
591
592 if ext == '.json':
592 if ext == '.json':
593 parms = json.load(fp)
593 parms = json.load(fp)
594
594
595 return parms
595 return parms
596
596
597 def status_device(self):
597 def status_device(self):
598
598
599 self.message = 'Function not supported'
599 self.message = 'Function not supported'
600 return False
600 return False
601
601
602
602
603 def stop_device(self):
603 def stop_device(self):
604
604
605 self.message = 'Function not supported'
605 self.message = 'Function not supported'
606 return False
606 return False
607
607
608
608
609 def start_device(self):
609 def start_device(self):
610
610
611 self.message = 'Function not supported'
611 self.message = 'Function not supported'
612 return False
612 return False
613
613
614
614
615 def write_device(self):
615 def write_device(self):
616
616
617 self.message = 'Function not supported'
617 self.message = 'Function not supported'
618 return False
618 return False
619
619
620
620
621 def read_device(self):
621 def read_device(self):
622
622
623 self.message = 'Function not supported'
623 self.message = 'Function not supported'
624 return False
624 return False
625
625
626
626
627 def get_absolute_url(self):
627 def get_absolute_url(self):
628 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
628 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
629
629
630 def get_absolute_url_edit(self):
630 def get_absolute_url_edit(self):
631 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
631 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
632
632
633 def get_absolute_url_delete(self):
633 def get_absolute_url_delete(self):
634 return reverse('url_delete_dev_conf', args=[str(self.id)])
634 return reverse('url_delete_dev_conf', args=[str(self.id)])
635
635
636 def get_absolute_url_import(self):
636 def get_absolute_url_import(self):
637 return reverse('url_import_dev_conf', args=[str(self.id)])
637 return reverse('url_import_dev_conf', args=[str(self.id)])
638
638
639 def get_absolute_url_export(self):
639 def get_absolute_url_export(self):
640 return reverse('url_export_dev_conf', args=[str(self.id)])
640 return reverse('url_export_dev_conf', args=[str(self.id)])
641
641
642 def get_absolute_url_write(self):
642 def get_absolute_url_write(self):
643 return reverse('url_write_dev_conf', args=[str(self.id)])
643 return reverse('url_write_dev_conf', args=[str(self.id)])
644
644
645 def get_absolute_url_read(self):
645 def get_absolute_url_read(self):
646 return reverse('url_read_dev_conf', args=[str(self.id)])
646 return reverse('url_read_dev_conf', args=[str(self.id)])
647
647
648 def get_absolute_url_start(self):
648 def get_absolute_url_start(self):
649 return reverse('url_start_dev_conf', args=[str(self.id)])
649 return reverse('url_start_dev_conf', args=[str(self.id)])
650
650
651 def get_absolute_url_stop(self):
651 def get_absolute_url_stop(self):
652 return reverse('url_stop_dev_conf', args=[str(self.id)])
652 return reverse('url_stop_dev_conf', args=[str(self.id)])
653
653
654 def get_absolute_url_status(self):
654 def get_absolute_url_status(self):
655 return reverse('url_status_dev_conf', args=[str(self.id)])
655 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,1316 +1,1344
1 import ast
1 import ast
2 import json
2 import json
3 import hashlib
3 import hashlib
4 from datetime import datetime, timedelta
4 from datetime import datetime, timedelta
5
5
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.http import HttpResponseRedirect
8 from django.http import HttpResponseRedirect
9 from django.urls import reverse
9 from django.urls import reverse
10 from django.db.models import Q
10 from django.db.models import Q
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 from django.contrib import messages
12 from django.contrib import messages
13 from django.http.request import QueryDict
13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
14 from django.contrib.auth.decorators import login_required, user_passes_test
15
15
16 from django.utils.timezone import is_aware
16 from django.utils.timezone import is_aware
17
17
18 try:
18 try:
19 from urllib.parse import urlencode
19 from urllib.parse import urlencode
20 except ImportError:
20 except ImportError:
21 from urllib import urlencode
21 from urllib import urlencode
22
22
23 from .forms import ExperimentForm, ExperimentEditionForm, DeviceForm, ConfigurationForm, UploadFileForm, DownloadFileForm, NewForm
23 from .forms import ExperimentForm, ExperimentEditionForm, DeviceForm, ConfigurationForm, UploadFileForm, DownloadFileForm, NewForm
24 from .forms import FilterForm, ChangeIpForm
24 from .forms import FilterForm, ChangeIpForm
25
25
26 from apps.pedestal.forms import PedestalConfigurationForm, PedestalEditionForm
26 from apps.pedestal.forms import PedestalConfigurationForm, PedestalEditionForm
27 from apps.generator.forms import GeneratorConfigurationForm
27 from apps.generator.forms import GeneratorConfigurationForm
28 from apps.usrp_rx.forms import USRPRXConfigurationForm, USRPRXEditionForm
28 from apps.usrp_rx.forms import USRPRXConfigurationForm, USRPRXEditionForm
29 from apps.usrp_tx.forms import USRPTXConfigurationForm, USRPTXEditionForm
29 from apps.usrp_tx.forms import USRPTXConfigurationForm, USRPTXEditionForm
30 from .utils import Params
30 from .utils import Params
31
31
32 from .models import Experiment, Device, Configuration, DEV_STATES
32 from .models import Experiment, Device, Configuration, DEV_STATES
33 from apps.pedestal.models import PedestalConfiguration
33 from apps.pedestal.models import PedestalConfiguration
34 from apps.generator.models import GeneratorConfiguration
34 from apps.generator.models import GeneratorConfiguration
35 from apps.usrp_rx.models import USRPRXConfiguration
35 from apps.usrp_rx.models import USRPRXConfiguration
36 from apps.usrp_tx.models import USRPTXConfiguration
36 from apps.usrp_tx.models import USRPTXConfiguration
37 from apps.usrp_tx.validations import validation_usrp_tx_code
37 from apps.usrp_tx.validations import validation_usrp_tx_code
38 from .gps import gps_response
38 from .gps import gps_response
39
39
40
40
41 #comentario test
41 #comentario test
42 CONF_FORMS = {
42 CONF_FORMS = {
43 'pedestal': PedestalConfigurationForm,
43 'pedestal': PedestalConfigurationForm,
44 'generator': GeneratorConfigurationForm,
44 'generator': GeneratorConfigurationForm,
45 'usrp_rx': USRPRXConfigurationForm,
45 'usrp_rx': USRPRXConfigurationForm,
46 'usrp_tx': USRPTXConfigurationForm,
46 'usrp_tx': USRPTXConfigurationForm,
47 }
47 }
48
48
49 CONF_MODELS = {
49 CONF_MODELS = {
50 'pedestal': PedestalConfiguration,
50 'pedestal': PedestalConfiguration,
51 'generator': GeneratorConfiguration,
51 'generator': GeneratorConfiguration,
52 'usrp_rx': USRPRXConfiguration,
52 'usrp_rx': USRPRXConfiguration,
53 'usrp_tx': USRPTXConfiguration,
53 'usrp_tx': USRPTXConfiguration,
54 }
54 }
55
55
56 MIX_MODES = {
56 MIX_MODES = {
57 '0': 'P',
57 '0': 'P',
58 '1': 'S',
58 '1': 'S',
59 }
59 }
60
60
61 MIX_OPERATIONS = {
61 MIX_OPERATIONS = {
62 '0': 'OR',
62 '0': 'OR',
63 '1': 'XOR',
63 '1': 'XOR',
64 '2': 'AND',
64 '2': 'AND',
65 '3': 'NAND',
65 '3': 'NAND',
66 }
66 }
67
67
68
68
69 def is_developer(user):
69 def is_developer(user):
70
71 groups = [str(g.name) for g in user.groups.all()]
70 groups = [str(g.name) for g in user.groups.all()]
72 return 'Developer' in groups or user.is_staff
71 #return 'Developer' in groups or user.is_staff
72 return 'Developer' in groups or user.is_superuser
73
73
74
74
75 def is_operator(user):
75 def is_operator(user):
76
77 groups = [str(g.name) for g in user.groups.all()]
76 groups = [str(g.name) for g in user.groups.all()]
78 return 'Operator' in groups or user.is_staff
77 #return 'Operator' in groups or user.is_staff
78 return 'Operator' in groups or user.is_superuser
79
79
80
80
81 def has_been_modified(model):
81 def has_been_modified(model):
82
82
83 prev_hash = model.hash
83 prev_hash = model.hash
84 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
84 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
85 if prev_hash != new_hash:
85 if prev_hash != new_hash:
86 model.hash = new_hash
86 model.hash = new_hash
87 model.save()
87 model.save()
88 return True
88 return True
89 return False
89 return False
90
90
91
91
92 def index(request):
92 def index(request):
93 kwargs = {'no_sidebar': True}
93 kwargs = {'no_sidebar': True}
94
94
95 return render(request, 'index.html', kwargs)
95 return render(request, 'index.html', kwargs)
96
96
97
97
98 def devices(request):
98 def devices(request):
99
99
100 page = request.GET.get('page')
100 page = request.GET.get('page')
101 order = ('device_type',)
101 order = ('device_type',)
102
102
103 filters = request.GET.copy()
103 filters = request.GET.copy()
104 kwargs = get_paginator(Device, page, order, filters)
104 kwargs = get_paginator(Device, page, order, filters)
105 form = FilterForm(initial=request.GET, extra_fields=['tags'])
105 form = FilterForm(initial=request.GET, extra_fields=['tags'])
106
106
107 kwargs['keys'] = ['device_type',
107 kwargs['keys'] = ['device_type',
108 'ip_address', 'port_address', 'actions']
108 'ip_address', 'port_address', 'actions']
109 kwargs['title'] = 'Device'
109 kwargs['title'] = 'Device'
110 kwargs['suptitle'] = 'List'
110 kwargs['suptitle'] = 'List'
111 kwargs['no_sidebar'] = True
111 kwargs['no_sidebar'] = True
112 kwargs['form'] = form
112 kwargs['form'] = form
113 kwargs['add_url'] = reverse('url_add_device')
113 kwargs['add_url'] = reverse('url_add_device')
114 filters.pop('page', None)
114 filters.pop('page', None)
115 kwargs['q'] = urlencode(filters)
115 kwargs['q'] = urlencode(filters)
116 kwargs['menu_devices'] = 'active'
116 kwargs['menu_devices'] = 'active'
117 return render(request, 'base_list.html', kwargs)
117 return render(request, 'base_list.html', kwargs)
118
118
119
119
120 def device(request, id_dev):
120 def device(request, id_dev):
121
121
122 device = get_object_or_404(Device, pk=id_dev)
122 device = get_object_or_404(Device, pk=id_dev)
123
123
124 kwargs = {}
124 kwargs = {}
125 kwargs['device'] = device
125 kwargs['device'] = device
126 kwargs['device_keys'] = ['device_type',
126 kwargs['device_keys'] = ['device_type',
127 'ip_address', 'port_address', 'description']
127 'ip_address', 'port_address', 'description']
128
128
129 kwargs['title'] = 'Device'
129 kwargs['title'] = 'Device'
130 kwargs['suptitle'] = 'Details'
130 kwargs['suptitle'] = 'Details'
131 kwargs['menu_devices'] = 'active'
131 kwargs['menu_devices'] = 'active'
132
132
133 return render(request, 'device.html', kwargs)
133 return render(request, 'device.html', kwargs)
134
134
135
135
136 @login_required
136 @login_required
137 def device_new(request):
137 def device_new(request):
138
139 if not is_developer(request.user):
140 messages.error(request, 'You must be an developer to create a new experiment')
141 return redirect('url_devices')
138
142
139 if request.method == 'GET':
143 if request.method == 'GET':
140 form = DeviceForm()
144 form = DeviceForm()
141
145
142 if request.method == 'POST':
146 if request.method == 'POST':
143 form = DeviceForm(request.POST)
147 form = DeviceForm(request.POST)
144
148
145 if form.is_valid():
149 if form.is_valid():
146 form.save()
150 form.save()
147 return redirect('url_devices')
151 return redirect('url_devices')
148
152
149 kwargs = {}
153 kwargs = {}
150 kwargs['form'] = form
154 kwargs['form'] = form
151 kwargs['title'] = 'Device'
155 kwargs['title'] = 'Device'
152 kwargs['suptitle'] = 'New'
156 kwargs['suptitle'] = 'New'
153 kwargs['button'] = 'Create'
157 kwargs['button'] = 'Create'
154 kwargs['menu_devices'] = 'active'
158 kwargs['menu_devices'] = 'active'
155
159
156 return render(request, 'base_edit.html', kwargs)
160 return render(request, 'base_edit.html', kwargs)
157
161
158
162
159 @login_required
163 @login_required
160 def device_edit(request, id_dev):
164 def device_edit(request, id_dev):
161
165
162 device = get_object_or_404(Device, pk=id_dev)
166 device = get_object_or_404(Device, pk=id_dev)
167
168 if not is_developer(request.user):
169 messages.error(request, 'You must be an developer to edit this object')
170 return redirect(device.get_absolute_url())
163
171
164 if request.method == 'GET':
172 if request.method == 'GET':
165 form = DeviceForm(instance=device)
173 form = DeviceForm(instance=device)
166
174
167 if request.method == 'POST':
175 if request.method == 'POST':
168 form = DeviceForm(request.POST, instance=device)
176 form = DeviceForm(request.POST, instance=device)
169
177
170 if form.is_valid():
178 if form.is_valid():
171 form.save()
179 form.save()
172 return redirect(device.get_absolute_url())
180 return redirect(device.get_absolute_url())
173
181
174 kwargs = {}
182 kwargs = {}
175 kwargs['form'] = form
183 kwargs['form'] = form
176 kwargs['title'] = 'Device'
184 kwargs['title'] = 'Device'
177 kwargs['suptitle'] = 'Edit'
185 kwargs['suptitle'] = 'Edit'
178 kwargs['button'] = 'Update'
186 kwargs['button'] = 'Update'
179 kwargs['menu_devices'] = 'active'
187 kwargs['menu_devices'] = 'active'
180
188
181 return render(request, 'base_edit.html', kwargs)
189 return render(request, 'base_edit.html', kwargs)
182
190
183
191
184 @login_required
192 @login_required
185 def device_delete(request, id_dev):
193 def device_delete(request, id_dev):
186
194
187 device = get_object_or_404(Device, pk=id_dev)
195 device = get_object_or_404(Device, pk=id_dev)
188
196
189 if request.method == 'POST':
197 if request.method == 'POST':
190
198
191 if is_developer(request.user):
199 if is_developer(request.user):
192 device.delete()
200 device.delete()
193 return redirect('url_devices')
201 return redirect('url_devices')
194
202
195 messages.error(request, 'Not enough permission to delete this object')
203 messages.error(request, 'Not enough permission to delete this object')
196 return redirect(device.get_absolute_url())
204 return redirect(device.get_absolute_url())
197
205
198 kwargs = {
206 kwargs = {
199 'title': 'Delete',
207 'title': 'Delete',
200 'suptitle': 'Device',
208 'suptitle': 'Device',
201 'object': device,
209 'object': device,
202 'delete': True
210 'delete': True
203 }
211 }
204 kwargs['menu_devices'] = 'active'
212 kwargs['menu_devices'] = 'active'
205
213
206 return render(request, 'confirm.html', kwargs)
214 return render(request, 'confirm.html', kwargs)
207
215
208
216
209 @login_required
217 @login_required
210 def device_change_ip(request, id_dev):
218 def device_change_ip(request, id_dev):
211
219
212 device = get_object_or_404(Device, pk=id_dev)
220 device = get_object_or_404(Device, pk=id_dev)
213
221
214 if request.method == 'POST':
222 if request.method == 'POST':
215
223
216 if is_developer(request.user):
224 if is_developer(request.user):
217 device.change_ip(**request.POST.dict())
225 device.change_ip(**request.POST.dict())
218 level, message = device.message.split('|')
226 level, message = device.message.split('|')
219 messages.add_message(request, level, message)
227 messages.add_message(request, level, message)
220 else:
228 else:
221 messages.error(
229 messages.error(
222 request, 'Not enough permission to delete this object')
230 request, 'Not enough permission to delete this object')
223 return redirect(device.get_absolute_url())
231 return redirect(device.get_absolute_url())
224
232
225 kwargs = {
233 kwargs = {
226 'title': 'Device',
234 'title': 'Device',
227 'suptitle': 'Change IP',
235 'suptitle': 'Change IP',
228 'object': device,
236 'object': device,
229 'previous': device.get_absolute_url(),
237 'previous': device.get_absolute_url(),
230 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
238 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
231 'message': ' ',
239 'message': ' ',
232 }
240 }
233 kwargs['menu_devices'] = 'active'
241 kwargs['menu_devices'] = 'active'
234
242
235 return render(request, 'confirm.html', kwargs)
243 return render(request, 'confirm.html', kwargs)
236
244
237
245
238 def experiments(request):
246 def experiments(request):
239
247
240 page = request.GET.get('page')
248 page = request.GET.get('page')
241 order = ('id',)
249 order = ('id',)
242 filters = request.GET.copy()
250 filters = request.GET.copy()
243
251
244 if 'my experiments' in filters:
252 if 'my experiments' in filters:
245 filters.pop('my experiments', None)
253 filters.pop('my experiments', None)
246 filters['mine'] = request.user.id
254 filters['mine'] = request.user.id
247
255
248 kwargs = get_paginator(Experiment, page, order, filters)
256 kwargs = get_paginator(Experiment, page, order, filters)
249
257
250 fields = ['tags']
258 fields = ['tags']
251 if request.user.is_authenticated:
259 if request.user.is_authenticated:
252 fields.append('my experiments')
260 fields.append('my experiments')
253
261
254 form = FilterForm(initial=request.GET, extra_fields=fields)
262 form = FilterForm(initial=request.GET, extra_fields=fields)
255
263
256 kwargs['keys'] = ['name', 'pedestal', 'reception_rx', 'transmission_tx', 'actions']
264 kwargs['keys'] = ['name', 'pedestal', 'reception_rx', 'transmission_tx', 'actions']
257 kwargs['title'] = 'Experiment'
265 kwargs['title'] = 'Experiment'
258 kwargs['suptitle'] = 'List'
266 kwargs['suptitle'] = 'List'
259 kwargs['no_sidebar'] = True
267 kwargs['no_sidebar'] = True
260 kwargs['form'] = form
268 kwargs['form'] = form
261 kwargs['add_url'] = reverse('url_add_experiment')
269 kwargs['add_url'] = reverse('url_add_experiment')
262 filters = request.GET.copy()
270 filters = request.GET.copy()
263 filters.pop('page', None)
271 filters.pop('page', None)
264 kwargs['q'] = urlencode(filters)
272 kwargs['q'] = urlencode(filters)
265 kwargs['menu_experiments'] = 'active'
273 kwargs['menu_experiments'] = 'active'
266
274
267 return render(request, 'base_list.html', kwargs)
275 return render(request, 'base_list.html', kwargs)
268
276
269
277
270 def experiment(request, id_exp):
278 def experiment(request, id_exp):
271
279
272 experiment = get_object_or_404(Experiment, pk=id_exp)
280 experiment = get_object_or_404(Experiment, pk=id_exp)
273 id_p = experiment.pedestal_id
281 id_p = experiment.pedestal_id
274 id_rx = experiment.reception_rx_id
282 id_rx = experiment.reception_rx_id
275 id_tx = experiment.transmission_tx_id
283 id_tx = experiment.transmission_tx_id
276 conf_pedestal = PedestalConfiguration.objects.get(id = id_p)
284 conf_pedestal = PedestalConfiguration.objects.get(id = id_p)
277 conf_rx = USRPRXConfiguration.objects.get(id = id_rx)
285 conf_rx = USRPRXConfiguration.objects.get(id = id_rx)
278 conf_tx = USRPTXConfiguration.objects.get(id = id_tx)
286 conf_tx = USRPTXConfiguration.objects.get(id = id_tx)
279
287
280 gps_data = gps_response(experiment.generator.ip_address)
288 gps_data = gps_response(experiment.generator.ip_address)
281 experiment.latitude = gps_data["statusRpt"]["lat"]
289 experiment.latitude = gps_data["statusRpt"]["lat"]
282 experiment.longitude = gps_data["statusRpt"]["lng"]
290 experiment.longitude = gps_data["statusRpt"]["lng"]
283 experiment.altitude = gps_data["statusRpt"]["alt"]
291 experiment.altitude = gps_data["statusRpt"]["alt"]
284 experiment.save()
292 experiment.save()
285
293
286 kwargs = {}
294 kwargs = {}
287 kwargs['experiment_keys'] = ['name', 'latitude', 'longitude', 'altitude', 'heading']
295 kwargs['experiment_keys'] = ['name', 'latitude', 'longitude', 'altitude', 'heading']
288 kwargs['experiment'] = experiment
296 kwargs['experiment'] = experiment
289
297
290 if conf_pedestal.mode == 'position':
298 if conf_pedestal.mode == 'position':
291 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'angle']
299 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'angle']
292 elif conf_pedestal.mode == 'speed':
300 elif conf_pedestal.mode == 'speed':
293 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'speed']
301 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'speed']
294 else:
302 else:
295 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'speed', 'angle', 'min_value', 'max_value']
303 kwargs['experiment_pedestal_keys'] = ['mode', 'axis', 'speed', 'angle', 'min_value', 'max_value']
296 kwargs['experiment_pedestal'] = conf_pedestal
304 kwargs['experiment_pedestal'] = conf_pedestal
297
305
298 kwargs['experiment_rx_keys'] = ['ip_address_rx', 'daughterboard_rx', 'antenna_rx', 'samplerate_rx', 'frequency_rx', 'datadir', 'clocksource', 'timesource', 'clockrate']
306 kwargs['experiment_rx_keys'] = ['ip_address_rx', 'daughterboard_rx', 'antenna_rx', 'samplerate_rx', 'frequency_rx', 'datadir', 'clocksource', 'timesource', 'clockrate']
299 kwargs['experiment_rx'] = conf_rx
307 kwargs['experiment_rx'] = conf_rx
300
308
301 if not conf_tx.enable_2:
309 if not conf_tx.enable_2:
302 kwargs['experiment_tx_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1', 'code_type_1', 'code_1', 'repetitions_1']
310 kwargs['experiment_tx_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1', 'code_type_1', 'code_1', 'repetitions_1']
303 else:
311 else:
304 kwargs['experiment_tx_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1', 'code_type_1', 'code_1', 'repetitions_1',
312 kwargs['experiment_tx_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1', 'code_type_1', 'code_1', 'repetitions_1',
305 'pulse_2', 'code_type_2', 'code_2', 'repetitions_2']
313 'pulse_2', 'code_type_2', 'code_2', 'repetitions_2']
306 kwargs['experiment_tx'] = conf_tx
314 kwargs['experiment_tx'] = conf_tx
307
315
308 kwargs['title'] = 'Experiment'
316 kwargs['title'] = 'Experiment'
309 kwargs['suptitle'] = 'Details'
317 kwargs['suptitle'] = 'Details'
310 kwargs['button'] = 'Add Configuration'
318 kwargs['button'] = 'Add Configuration'
311 kwargs['menu_experiments'] = 'active'
319 kwargs['menu_experiments'] = 'active'
312
320
313 ###### SIDEBAR ######
321 ###### SIDEBAR ######
314 kwargs.update(sidebar(confs=[conf_pedestal, conf_rx, conf_tx]))
322 kwargs.update(sidebar(confs=[conf_pedestal, conf_rx, conf_tx]))
315
323
316 return render(request, 'experiment.html', kwargs)
324 return render(request, 'experiment.html', kwargs)
317
325
318
326
319 @login_required
327 @login_required
320 def experiment_new(request, id_camp=None):
328 def experiment_new(request, id_camp=None):
321
329
322 if not is_developer(request.user):
330 if not is_developer(request.user):
323 messages.error(
331 messages.error(request, 'You must be an developer to create a new experiment')
324 request, 'Developer required, to create new Experiments')
332 return redirect('url_experiments')
325 return redirect('index')
333
326 kwargs = {}
334 kwargs = {}
327
335
328 if request.method == 'GET':
336 if request.method == 'GET':
329 kwargs['button'] = 'Create'
337 kwargs['button'] = 'Create'
330 form = ExperimentForm()
338 form = ExperimentForm()
331
339
332 if request.method == 'POST':
340 if request.method == 'POST':
333 form = ExperimentForm(request.POST)
341 form = ExperimentForm(request.POST)
334 if form.is_valid():
342 if form.is_valid():
335 experiment = form.save(commit=False)
343 experiment = form.save(commit=False)
336 experiment.author = request.user
344 experiment.author = request.user
337 experiment.save()
345 experiment.save()
338 messages.success(request, 'Experiment configuration successfully created')
346 messages.success(request, 'Experiment configuration successfully created')
339 return redirect('url_experiment', id_exp=experiment.id)
347 return redirect('url_experiment', id_exp=experiment.id)
340
348
341 kwargs['form'] = form
349 kwargs['form'] = form
342 kwargs['title'] = 'Experiment'
350 kwargs['title'] = 'Experiment'
343 kwargs['suptitle'] = 'New'
351 kwargs['suptitle'] = 'New'
344 kwargs['menu_experiments'] = 'active'
352 kwargs['menu_experiments'] = 'active'
345
353
346 return render(request, 'experiment_edit.html', kwargs)
354 return render(request, 'experiment_edit.html', kwargs)
347
355
348
356
349 @login_required
357 @login_required
350 def experiment_edit(request, id_exp):
358 def experiment_edit(request, id_exp):
351
352 experiment = get_object_or_404(Experiment, pk=id_exp)
359 experiment = get_object_or_404(Experiment, pk=id_exp)
360
361 if not is_developer(request.user):
362 messages.error(request, 'You must be an developer to edit this experiment')
363 return redirect(experiment.get_absolute_url())
364
353 id_p = experiment.pedestal_id
365 id_p = experiment.pedestal_id
354 id_rx = experiment.reception_rx_id
366 id_rx = experiment.reception_rx_id
355 id_tx = experiment.transmission_tx_id
367 id_tx = experiment.transmission_tx_id
356 conf_pedestal = PedestalConfiguration.objects.get(id = id_p)
368 conf_pedestal = PedestalConfiguration.objects.get(id = id_p)
357 conf_rx = USRPRXConfiguration.objects.get(id = id_rx)
369 conf_rx = USRPRXConfiguration.objects.get(id = id_rx)
358 conf_tx = USRPTXConfiguration.objects.get(id = id_tx)
370 conf_tx = USRPTXConfiguration.objects.get(id = id_tx)
359
371
360 if request.method == 'GET':
372 if request.method == 'GET':
361 form = ExperimentEditionForm(instance=experiment)
373 form = ExperimentEditionForm(instance=experiment)
362 form_pedestal = PedestalEditionForm(instance=conf_pedestal)
374 form_pedestal = PedestalEditionForm(instance=conf_pedestal)
363 form_rx = USRPRXEditionForm(instance=conf_rx)
375 form_rx = USRPRXEditionForm(instance=conf_rx)
364 form_tx = USRPTXEditionForm(instance=conf_tx)
376 form_tx = USRPTXEditionForm(instance=conf_tx)
365
377
366 if request.method == 'POST':
378 if request.method == 'POST':
367 form = ExperimentEditionForm(request.POST, instance=experiment)
379 form = ExperimentEditionForm(request.POST, instance=experiment)
368 form_pedestal = PedestalEditionForm(request.POST, instance=conf_pedestal)
380 form_pedestal = PedestalEditionForm(request.POST, instance=conf_pedestal)
369 form_rx = USRPRXEditionForm(request.POST, instance=conf_rx)
381 form_rx = USRPRXEditionForm(request.POST, instance=conf_rx)
370 form_tx = USRPTXEditionForm(request.POST, instance=conf_tx)
382 form_tx = USRPTXEditionForm(request.POST, instance=conf_tx)
371
383
372 if form.is_valid() and form_pedestal.is_valid() and form_rx.is_valid() and form_tx.is_valid():
384 if form.is_valid() and form_pedestal.is_valid() and form_rx.is_valid() and form_tx.is_valid():
373 experiment = form.save(commit=False)
385 experiment = form.save(commit=False)
374 pedestal = form_pedestal.save(commit=False)
386 pedestal = form_pedestal.save(commit=False)
375 rx = form_rx.save(commit=False)
387 rx = form_rx.save(commit=False)
376 tx = form_tx.save(commit=False)
388 tx = form_tx.save(commit=False)
377
389
378 pedestal.save()
390 pedestal.save()
379 rx.save()
391 rx.save()
380 validation_usrp_tx_code(request, tx)
392 validation_usrp_tx_code(request, tx)
381 tx.save()
393 tx.save()
382 messages.success(request, 'Experiment configuration successfully updated')
394 messages.success(request, 'Experiment configuration successfully updated')
383 return redirect('url_experiment', id_exp=experiment.id)
395 return redirect('url_experiment', id_exp=experiment.id)
384
396
385 kwargs = {}
397 kwargs = {}
386 kwargs['form'] = form
398 kwargs['form'] = form
387 kwargs['form_pedestal'] = form_pedestal
399 kwargs['form_pedestal'] = form_pedestal
388 kwargs['form_rx'] = form_rx
400 kwargs['form_rx'] = form_rx
389 kwargs['form_tx'] = form_tx
401 kwargs['form_tx'] = form_tx
390 kwargs['title'] = 'Experiment'
402 kwargs['title'] = 'Experiment'
391 kwargs['suptitle'] = 'Edit'
403 kwargs['suptitle'] = 'Edit'
392 kwargs['button'] = 'Update'
404 kwargs['button'] = 'Update'
393 kwargs['menu_experiments'] = 'active'
405 kwargs['menu_experiments'] = 'active'
394
406
395 return render(request, 'experiment_edit.html', kwargs)
407 return render(request, 'experiment_edit.html', kwargs)
396
408
397
409
398 @login_required
410 @login_required
399 def experiment_delete(request, id_exp):
411 def experiment_delete(request, id_exp):
400
412
401 experiment = get_object_or_404(Experiment, pk=id_exp)
413 experiment = get_object_or_404(Experiment, pk=id_exp)
402
414
403 if request.method == 'POST':
415 if request.method == 'POST':
404 if is_developer(request.user):
416 if is_developer(request.user):
405 #for conf in Configuration.objects.filter(experiment=experiment):
417 #for conf in Configuration.objects.filter(experiment=experiment):
406 #conf.delete()
418 #conf.delete()
407 experiment.delete()
419 experiment.delete()
408 return redirect('url_experiments')
420 return redirect('url_experiments')
409
421
410 messages.error(request, 'Not enough permission to delete this object')
422 messages.error(request, 'Not enough permission to delete this experiment')
411 return redirect(experiment.get_absolute_url())
423 return redirect(experiment.get_absolute_url())
412
424
413 kwargs = {
425 kwargs = {
414 'title': 'Delete',
426 'title': 'Delete',
415 'suptitle': 'Experiment',
427 'suptitle': 'Experiment',
416 'object': experiment,
428 'object': experiment,
417 'delete': True
429 'delete': True
418 }
430 }
419
431
420 return render(request, 'confirm.html', kwargs)
432 return render(request, 'confirm.html', kwargs)
421
433
422
434
423 @login_required
435 @login_required
424 def experiment_export(request, id_exp):
436 def experiment_export(request, id_exp):
425
437
426 experiment = get_object_or_404(Experiment, pk=id_exp)
438 experiment = get_object_or_404(Experiment, pk=id_exp)
427 content = experiment.parms_to_dict()
439 content = experiment.parms_to_dict()
428 content_type = 'application/json'
440 content_type = 'application/json'
429 filename = '%s_%s.json' % (experiment.name, experiment.id)
441 filename = '%s_%s.json' % (experiment.name, experiment.id)
430
442
431 response = HttpResponse(content_type=content_type)
443 response = HttpResponse(content_type=content_type)
432 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
444 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
433 response.write(json.dumps(content, indent=2))
445 response.write(json.dumps(content, indent=2))
434
446
435 return response
447 return response
436
448
437
449
438 @login_required
450 @login_required
439 def experiment_import(request, id_exp):
451 def experiment_import(request, id_exp):
440
452
441 experiment = get_object_or_404(Experiment, pk=id_exp)
453 experiment = get_object_or_404(Experiment, pk=id_exp)
442 configurations = Configuration.objects.filter(experiment=experiment)
454 configurations = Configuration.objects.filter(experiment=experiment)
443
455
444 if request.method == 'GET':
456 if request.method == 'GET':
445 file_form = UploadFileForm()
457 file_form = UploadFileForm()
446
458
447 if request.method == 'POST':
459 if request.method == 'POST':
448 file_form = UploadFileForm(request.POST, request.FILES)
460 file_form = UploadFileForm(request.POST, request.FILES)
449
461
450 if file_form.is_valid():
462 if file_form.is_valid():
451 new_exp = experiment.dict_to_parms(
463 new_exp = experiment.dict_to_parms(
452 json.load(request.FILES['file']), CONF_MODELS)
464 json.load(request.FILES['file']), CONF_MODELS)
453 messages.success(
465 messages.success(
454 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
466 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
455 return redirect(new_exp.get_absolute_url_edit())
467 return redirect(new_exp.get_absolute_url_edit())
456
468
457 messages.error(request, "Could not import parameters from file")
469 messages.error(request, "Could not import parameters from file")
458
470
459 kwargs = {}
471 kwargs = {}
460 kwargs['title'] = 'Experiment'
472 kwargs['title'] = 'Experiment'
461 kwargs['form'] = file_form
473 kwargs['form'] = file_form
462 kwargs['suptitle'] = 'Importing file'
474 kwargs['suptitle'] = 'Importing file'
463 kwargs['button'] = 'Import'
475 kwargs['button'] = 'Import'
464 kwargs['menu_experiments'] = 'active'
476 kwargs['menu_experiments'] = 'active'
465
477
466 kwargs.update(sidebar(experiment=experiment))
478 kwargs.update(sidebar(experiment=experiment))
467
479
468 return render(request, 'experiment_import.html', kwargs)
480 return render(request, 'experiment_import.html', kwargs)
469
481
470
482
471 @login_required
483 @login_required
472 def experiment_start(request, id_exp):
484 def experiment_start(request, id_exp):
473 exp = get_object_or_404(Experiment, pk=id_exp)
485 exp = get_object_or_404(Experiment, pk=id_exp)
474
486
487 if not is_developer(request.user) and not is_operator(request.user):
488 messages.error(request, 'You must be an developer or operator to start this experiment')
489 return redirect(exp.get_absolute_url())
490
475 if exp.status == 2:
491 if exp.status == 2:
476 messages.warning(request, 'Experiment {} already runnnig'.format(exp.name))
492 messages.warning(request, 'Experiment {} already runnnig'.format(exp.name))
477 else:
493 else:
478 exp.status = exp.start()
494 exp.status = exp.start()
479 if exp.status == 5:
495 if exp.status == 5:
480 messages.warning(request, 'Experiment {} already runnnig'.format(Experiment.objects.filter(status=2)[0]))
496 messages.warning(request, 'Experiment {} already runnnig'.format(Experiment.objects.filter(status=2)[0]))
481 if exp.status == 0:
497 if exp.status == 0:
482 messages.error(request, 'Experiment {} not start'.format(exp))
498 messages.error(request, 'Experiment {} not start'.format(exp))
483 if exp.status == 2:
499 if exp.status == 2:
484 messages.success(request, 'Experiment {} started'.format(exp))
500 messages.success(request, 'Experiment {} started'.format(exp))
485
501
486 exp.save()
502 exp.save()
487
503
488 return redirect(exp.get_absolute_url())
504 return redirect(exp.get_absolute_url())
489
505
490
506
491 @login_required
507 @login_required
492 def experiment_stop(request, id_exp):
508 def experiment_stop(request, id_exp):
493 all_status = Experiment.objects.filter(status=2)
509 all_status = Experiment.objects.filter(status=2)
494 exp = get_object_or_404(Experiment, pk=id_exp)
510 exp = get_object_or_404(Experiment, pk=id_exp)
495
511
512 if not is_developer(request.user) and not is_operator(request.user):
513 messages.error(request, 'You must be an developer or operator to stop this experiment')
514 return redirect(exp.get_absolute_url())
515
496 if exp.status == 2 or exp.status == 4 or exp.status == 5:
516 if exp.status == 2 or exp.status == 4 or exp.status == 5:
497 for one_exp in all_status:
517 for one_exp in all_status:
498 if one_exp != exp:
518 if one_exp != exp:
499 one_exp.status = 4
519 one_exp.status = 4
500 one_exp.mode_stop = 'web'
520 one_exp.mode_stop = 'web'
501 one_exp.save()
521 one_exp.save()
502
522
503 exp.status = exp.stop()
523 exp.status = exp.stop()
504 exp.mode_stop = 'web'
524 exp.mode_stop = 'web'
505 exp.save()
525 exp.save()
506 messages.success(request, 'Experiment {} stopped'.format(exp))
526 messages.success(request, 'Experiment {} stopped'.format(exp))
507 else:
527 else:
508 messages.error(request, 'Experiment {} not running'.format(exp))
528 messages.error(request, 'Experiment {} not running'.format(exp))
509
529
510 return redirect(exp.get_absolute_url())
530 return redirect(exp.get_absolute_url())
511
531
512
532
513 def experiment_status(request, id_exp):
533 def experiment_status(request, id_exp):
514
534
515 exp = get_object_or_404(Experiment, pk=id_exp)
535 exp = get_object_or_404(Experiment, pk=id_exp)
516
536
517 exp.get_status()
537 exp.get_status()
518
538
519 return redirect(exp.get_absolute_url())
539 return redirect(exp.get_absolute_url())
520
540
521
541
522 def experiment_summary(request, id_exp):
542 def experiment_summary(request, id_exp):
523
543
524 experiment = get_object_or_404(Experiment, pk=id_exp)
544 experiment = get_object_or_404(Experiment, pk=id_exp)
525 configurations = Configuration.objects.filter(
545 configurations = Configuration.objects.filter(
526 experiment=experiment, type=0)
546 experiment=experiment, type=0)
527
547
528 kwargs = {}
548 kwargs = {}
529 kwargs['experiment_keys'] = ['radar_system',
549 kwargs['experiment_keys'] = ['radar_system',
530 'name', 'freq', 'start_time', 'end_time']
550 'name', 'freq', 'start_time', 'end_time']
531 kwargs['experiment'] = experiment
551 kwargs['experiment'] = experiment
532 kwargs['configurations'] = []
552 kwargs['configurations'] = []
533 kwargs['title'] = 'Experiment Summary'
553 kwargs['title'] = 'Experiment Summary'
534 kwargs['suptitle'] = 'Details'
554 kwargs['suptitle'] = 'Details'
535 kwargs['button'] = 'Verify Parameters'
555 kwargs['button'] = 'Verify Parameters'
536
556
537 c_vel = 3.0*(10**8) # m/s
557 c_vel = 3.0*(10**8) # m/s
538 ope_freq = experiment.freq*(10**6) # 1/s
558 ope_freq = experiment.freq*(10**6) # 1/s
539 radar_lambda = c_vel/ope_freq # m
559 radar_lambda = c_vel/ope_freq # m
540 kwargs['radar_lambda'] = radar_lambda
560 kwargs['radar_lambda'] = radar_lambda
541
561
542 ipp = None
562 ipp = None
543 nsa = 1
563 nsa = 1
544 code_id = 0
564 code_id = 0
545 tx_line = {}
565 tx_line = {}
546
566
547 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
567 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
548
568
549 if configuration.mix:
569 if configuration.mix:
550 continue
570 continue
551 conf = {'conf': configuration}
571 conf = {'conf': configuration}
552 conf['keys'] = []
572 conf['keys'] = []
553 conf['NTxs'] = configuration.ntx
573 conf['NTxs'] = configuration.ntx
554 conf['keys'].append('NTxs')
574 conf['keys'].append('NTxs')
555 ipp = configuration.ipp
575 ipp = configuration.ipp
556 conf['IPP'] = ipp
576 conf['IPP'] = ipp
557 conf['keys'].append('IPP')
577 conf['keys'].append('IPP')
558 lines = configuration.get_lines(line_type__name='tx')
578 lines = configuration.get_lines(line_type__name='tx')
559
579
560 for tx_line in lines:
580 for tx_line in lines:
561 tx_params = json.loads(tx_line.params)
581 tx_params = json.loads(tx_line.params)
562 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
582 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
563 conf['keys'].append(tx_line.get_name())
583 conf['keys'].append(tx_line.get_name())
564 delays = tx_params['delays']
584 delays = tx_params['delays']
565 if delays not in ('', '0'):
585 if delays not in ('', '0'):
566 n = len(delays.split(','))
586 n = len(delays.split(','))
567 taus = '{} Taus: {}'.format(n, delays)
587 taus = '{} Taus: {}'.format(n, delays)
568 else:
588 else:
569 taus = '-'
589 taus = '-'
570 conf['Taus ({})'.format(tx_line.get_name())] = taus
590 conf['Taus ({})'.format(tx_line.get_name())] = taus
571 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
591 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
572 for code_line in configuration.get_lines(line_type__name='codes'):
592 for code_line in configuration.get_lines(line_type__name='codes'):
573 code_params = json.loads(code_line.params)
593 code_params = json.loads(code_line.params)
574 code_id = code_params['code']
594 code_id = code_params['code']
575 if tx_line.pk == int(code_params['TX_ref']):
595 if tx_line.pk == int(code_params['TX_ref']):
576 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
596 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
577 '-'.join(code_params['codes']))
597 '-'.join(code_params['codes']))
578 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
598 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
579
599
580 for windows_line in configuration.get_lines(line_type__name='windows'):
600 for windows_line in configuration.get_lines(line_type__name='windows'):
581 win_params = json.loads(windows_line.params)
601 win_params = json.loads(windows_line.params)
582 if tx_line.pk == int(win_params['TX_ref']):
602 if tx_line.pk == int(win_params['TX_ref']):
583 windows = ''
603 windows = ''
584 nsa = win_params['params'][0]['number_of_samples']
604 nsa = win_params['params'][0]['number_of_samples']
585 for i, params in enumerate(win_params['params']):
605 for i, params in enumerate(win_params['params']):
586 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
606 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
587 i, **params)
607 i, **params)
588 conf['Window'] = mark_safe(windows)
608 conf['Window'] = mark_safe(windows)
589 conf['keys'].append('Window')
609 conf['keys'].append('Window')
590
610
591 kwargs['configurations'].append(conf)
611 kwargs['configurations'].append(conf)
592
612
593 for configuration in configurations.filter(device__device_type__name = 'jars'):
613 for configuration in configurations.filter(device__device_type__name = 'jars'):
594
614
595 conf = {'conf': configuration}
615 conf = {'conf': configuration}
596 conf['keys'] = []
616 conf['keys'] = []
597 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
617 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
598 conf['keys'].append('Type of Data')
618 conf['keys'].append('Type of Data')
599 channels_number = configuration.channels_number
619 channels_number = configuration.channels_number
600 exp_type = configuration.exp_type
620 exp_type = configuration.exp_type
601 fftpoints = configuration.fftpoints
621 fftpoints = configuration.fftpoints
602 filter_parms = json.loads(configuration.filter_parms)
622 filter_parms = json.loads(configuration.filter_parms)
603 spectral_number = configuration.spectral_number
623 spectral_number = configuration.spectral_number
604 acq_profiles = configuration.acq_profiles
624 acq_profiles = configuration.acq_profiles
605 cohe_integr = configuration.cohe_integr
625 cohe_integr = configuration.cohe_integr
606 profiles_block = configuration.profiles_block
626 profiles_block = configuration.profiles_block
607
627
608 conf['Num of Profiles'] = acq_profiles
628 conf['Num of Profiles'] = acq_profiles
609 conf['keys'].append('Num of Profiles')
629 conf['keys'].append('Num of Profiles')
610
630
611 conf['Prof per Block'] = profiles_block
631 conf['Prof per Block'] = profiles_block
612 conf['keys'].append('Prof per Block')
632 conf['keys'].append('Prof per Block')
613
633
614 conf['Blocks per File'] = configuration.raw_data_blocks
634 conf['Blocks per File'] = configuration.raw_data_blocks
615 conf['keys'].append('Blocks per File')
635 conf['keys'].append('Blocks per File')
616
636
617 if exp_type == 0: # Short
637 if exp_type == 0: # Short
618 bytes_ = 2
638 bytes_ = 2
619 b = nsa*2*bytes_*channels_number
639 b = nsa*2*bytes_*channels_number
620 else: # Float
640 else: # Float
621 bytes_ = 4
641 bytes_ = 4
622 channels = channels_number + spectral_number
642 channels = channels_number + spectral_number
623 b = nsa*2*bytes_*fftpoints*channels
643 b = nsa*2*bytes_*fftpoints*channels
624
644
625 codes_num = 7
645 codes_num = 7
626 if code_id == 2:
646 if code_id == 2:
627 codes_num = 7
647 codes_num = 7
628 elif code_id == 12:
648 elif code_id == 12:
629 codes_num = 15
649 codes_num = 15
630
650
631 #Jars filter values:
651 #Jars filter values:
632
652
633 clock = float(filter_parms['clock'])
653 clock = float(filter_parms['clock'])
634 filter_2 = int(filter_parms['cic_2'])
654 filter_2 = int(filter_parms['cic_2'])
635 filter_5 = int(filter_parms['cic_5'])
655 filter_5 = int(filter_parms['cic_5'])
636 filter_fir = int(filter_parms['fir'])
656 filter_fir = int(filter_parms['fir'])
637 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
657 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
638
658
639 #Jars values:
659 #Jars values:
640 if ipp is not None:
660 if ipp is not None:
641 IPP_units = ipp/0.15*Fs_MHz
661 IPP_units = ipp/0.15*Fs_MHz
642 IPP_us = IPP_units / Fs_MHz
662 IPP_us = IPP_units / Fs_MHz
643 IPP_s = IPP_units / (Fs_MHz * (10**6))
663 IPP_s = IPP_units / (Fs_MHz * (10**6))
644 Ts = 1/(Fs_MHz*(10**6))
664 Ts = 1/(Fs_MHz*(10**6))
645
665
646 Va = radar_lambda/(4*Ts*cohe_integr)
666 Va = radar_lambda/(4*Ts*cohe_integr)
647 rate_bh = ((nsa-codes_num)*channels_number*2 *
667 rate_bh = ((nsa-codes_num)*channels_number*2 *
648 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
668 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
649 rate_gh = rate_bh/(1024*1024*1024)
669 rate_gh = rate_bh/(1024*1024*1024)
650
670
651 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
671 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
652 conf['keys'].append('Time per Block')
672 conf['keys'].append('Time per Block')
653 conf['Acq time'] = IPP_s * acq_profiles
673 conf['Acq time'] = IPP_s * acq_profiles
654 conf['keys'].append('Acq time')
674 conf['keys'].append('Acq time')
655 conf['Data rate'] = str(rate_gh)+" (GB/h)"
675 conf['Data rate'] = str(rate_gh)+" (GB/h)"
656 conf['keys'].append('Data rate')
676 conf['keys'].append('Data rate')
657 conf['Va (m/s)'] = Va
677 conf['Va (m/s)'] = Va
658 conf['keys'].append('Va (m/s)')
678 conf['keys'].append('Va (m/s)')
659 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
679 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
660 conf['keys'].append('Vrange (m/s)')
680 conf['keys'].append('Vrange (m/s)')
661
681
662 kwargs['configurations'].append(conf)
682 kwargs['configurations'].append(conf)
663 kwargs['menu_experiments'] = 'active'
683 kwargs['menu_experiments'] = 'active'
664
684
665 ###### SIDEBAR ######
685 ###### SIDEBAR ######
666 kwargs.update(sidebar(experiment=experiment))
686 kwargs.update(sidebar(experiment=experiment))
667
687
668 return render(request, 'experiment_summary.html', kwargs)
688 return render(request, 'experiment_summary.html', kwargs)
669
689
670
690
671 @login_required
691 @login_required
672 def experiment_verify(request, id_exp):
692 def experiment_verify(request, id_exp):
673
693
674 experiment = get_object_or_404(Experiment, pk=id_exp)
694 experiment = get_object_or_404(Experiment, pk=id_exp)
675 experiment_data = experiment.parms_to_dict()
695 experiment_data = experiment.parms_to_dict()
676 configurations = Configuration.objects.filter(
696 configurations = Configuration.objects.filter(
677 experiment=experiment, type=0)
697 experiment=experiment, type=0)
678
698
679 kwargs = {}
699 kwargs = {}
680
700
681 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
701 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
682 kwargs['experiment'] = experiment
702 kwargs['experiment'] = experiment
683
703
684 kwargs['configuration_keys'] = ['name', 'device__ip_address',
704 kwargs['configuration_keys'] = ['name', 'device__ip_address',
685 'device__port_address', 'device__status']
705 'device__port_address', 'device__status']
686 kwargs['configurations'] = configurations
706 kwargs['configurations'] = configurations
687 kwargs['experiment_data'] = experiment_data
707 kwargs['experiment_data'] = experiment_data
688
708
689 kwargs['title'] = 'Verify Experiment'
709 kwargs['title'] = 'Verify Experiment'
690 kwargs['suptitle'] = 'Parameters'
710 kwargs['suptitle'] = 'Parameters'
691
711
692 kwargs['button'] = 'Update'
712 kwargs['button'] = 'Update'
693
713
694 jars_conf = False
714 jars_conf = False
695 rc_conf = False
715 rc_conf = False
696 dds_conf = False
716 dds_conf = False
697
717
698 for configuration in configurations:
718 for configuration in configurations:
699 #-------------------- JARS -----------------------:
719 #-------------------- JARS -----------------------:
700 if configuration.device.device_type.name == 'jars':
720 if configuration.device.device_type.name == 'jars':
701 jars_conf = True
721 jars_conf = True
702 jars = configuration
722 jars = configuration
703 kwargs['jars_conf'] = jars_conf
723 kwargs['jars_conf'] = jars_conf
704 filter_parms = json.loads(jars.filter_parms)
724 filter_parms = json.loads(jars.filter_parms)
705 kwargs['filter_parms'] = filter_parms
725 kwargs['filter_parms'] = filter_parms
706 #--Sampling Frequency
726 #--Sampling Frequency
707 clock = filter_parms['clock']
727 clock = filter_parms['clock']
708 filter_2 = filter_parms['cic_2']
728 filter_2 = filter_parms['cic_2']
709 filter_5 = filter_parms['cic_5']
729 filter_5 = filter_parms['cic_5']
710 filter_fir = filter_parms['fir']
730 filter_fir = filter_parms['fir']
711 samp_freq_jars = clock/filter_2/filter_5/filter_fir
731 samp_freq_jars = clock/filter_2/filter_5/filter_fir
712
732
713 kwargs['samp_freq_jars'] = samp_freq_jars
733 kwargs['samp_freq_jars'] = samp_freq_jars
714 kwargs['jars'] = configuration
734 kwargs['jars'] = configuration
715
735
716 #--------------------- RC ----------------------:
736 #--------------------- RC ----------------------:
717 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
737 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
718 rc_conf = True
738 rc_conf = True
719 rc = configuration
739 rc = configuration
720
740
721 rc_parms = configuration.parms_to_dict()
741 rc_parms = configuration.parms_to_dict()
722
742
723 win_lines = rc.get_lines(line_type__name='windows')
743 win_lines = rc.get_lines(line_type__name='windows')
724 if win_lines:
744 if win_lines:
725 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
745 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
726 #--Sampling Frequency
746 #--Sampling Frequency
727 samp_freq_rc = 0.15/dh
747 samp_freq_rc = 0.15/dh
728 kwargs['samp_freq_rc'] = samp_freq_rc
748 kwargs['samp_freq_rc'] = samp_freq_rc
729
749
730 kwargs['rc_conf'] = rc_conf
750 kwargs['rc_conf'] = rc_conf
731 kwargs['rc'] = configuration
751 kwargs['rc'] = configuration
732
752
733 #-------------------- DDS ----------------------:
753 #-------------------- DDS ----------------------:
734 if configuration.device.device_type.name == 'dds':
754 if configuration.device.device_type.name == 'dds':
735 dds_conf = True
755 dds_conf = True
736 dds = configuration
756 dds = configuration
737 dds_parms = configuration.parms_to_dict()
757 dds_parms = configuration.parms_to_dict()
738
758
739 kwargs['dds_conf'] = dds_conf
759 kwargs['dds_conf'] = dds_conf
740 kwargs['dds'] = configuration
760 kwargs['dds'] = configuration
741
761
742 #------------Validation------------:
762 #------------Validation------------:
743 #Clock
763 #Clock
744 if dds_conf and rc_conf and jars_conf:
764 if dds_conf and rc_conf and jars_conf:
745 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']):
765 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']):
746 messages.warning(request, "Devices don't have the same clock.")
766 messages.warning(request, "Devices don't have the same clock.")
747 elif rc_conf and jars_conf:
767 elif rc_conf and jars_conf:
748 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
768 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
749 messages.warning(request, "Devices don't have the same clock.")
769 messages.warning(request, "Devices don't have the same clock.")
750 elif rc_conf and dds_conf:
770 elif rc_conf and dds_conf:
751 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
771 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
752 messages.warning(request, "Devices don't have the same clock.")
772 messages.warning(request, "Devices don't have the same clock.")
753 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
773 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
754 messages.warning(
774 messages.warning(
755 request, "Devices don't have the same Frequency A.")
775 request, "Devices don't have the same Frequency A.")
756
776
757 #------------POST METHOD------------:
777 #------------POST METHOD------------:
758 if request.method == 'POST':
778 if request.method == 'POST':
759 if request.POST['suggest_clock']:
779 if request.POST['suggest_clock']:
760 try:
780 try:
761 suggest_clock = float(request.POST['suggest_clock'])
781 suggest_clock = float(request.POST['suggest_clock'])
762 except:
782 except:
763 messages.warning(request, "Invalid value in CLOCK IN.")
783 messages.warning(request, "Invalid value in CLOCK IN.")
764 return redirect('url_verify_experiment', id_exp=experiment.id)
784 return redirect('url_verify_experiment', id_exp=experiment.id)
765 else:
785 else:
766 suggest_clock = ""
786 suggest_clock = ""
767 if suggest_clock:
787 if suggest_clock:
768 if rc_conf:
788 if rc_conf:
769 rc.clock_in = suggest_clock
789 rc.clock_in = suggest_clock
770 rc.save()
790 rc.save()
771 if jars_conf:
791 if jars_conf:
772 filter_parms = jars.filter_parms
792 filter_parms = jars.filter_parms
773 filter_parms = ast.literal_eval(filter_parms)
793 filter_parms = ast.literal_eval(filter_parms)
774 filter_parms['clock'] = suggest_clock
794 filter_parms['clock'] = suggest_clock
775 jars.filter_parms = json.dumps(filter_parms)
795 jars.filter_parms = json.dumps(filter_parms)
776 jars.save()
796 jars.save()
777 kwargs['filter_parms'] = filter_parms
797 kwargs['filter_parms'] = filter_parms
778 if dds_conf:
798 if dds_conf:
779 dds.clock = suggest_clock
799 dds.clock = suggest_clock
780 dds.save()
800 dds.save()
781
801
782 if request.POST['suggest_frequencyA']:
802 if request.POST['suggest_frequencyA']:
783 try:
803 try:
784 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
804 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
785 except:
805 except:
786 messages.warning(request, "Invalid value in FREQUENCY A.")
806 messages.warning(request, "Invalid value in FREQUENCY A.")
787 return redirect('url_verify_experiment', id_exp=experiment.id)
807 return redirect('url_verify_experiment', id_exp=experiment.id)
788 else:
808 else:
789 suggest_frequencyA = ""
809 suggest_frequencyA = ""
790 if suggest_frequencyA:
810 if suggest_frequencyA:
791 if jars_conf:
811 if jars_conf:
792 filter_parms = jars.filter_parms
812 filter_parms = jars.filter_parms
793 filter_parms = ast.literal_eval(filter_parms)
813 filter_parms = ast.literal_eval(filter_parms)
794 filter_parms['fch'] = suggest_frequencyA
814 filter_parms['fch'] = suggest_frequencyA
795 jars.filter_parms = json.dumps(filter_parms)
815 jars.filter_parms = json.dumps(filter_parms)
796 jars.save()
816 jars.save()
797 kwargs['filter_parms'] = filter_parms
817 kwargs['filter_parms'] = filter_parms
798 if dds_conf:
818 if dds_conf:
799 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
819 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
800 dds.save()
820 dds.save()
801
821
802 kwargs['menu_experiments'] = 'active'
822 kwargs['menu_experiments'] = 'active'
803 kwargs.update(sidebar(experiment=experiment))
823 kwargs.update(sidebar(experiment=experiment))
804 return render(request, 'experiment_verify.html', kwargs)
824 return render(request, 'experiment_verify.html', kwargs)
805
825
806
826
807 def dev_confs(request):
827 def dev_confs(request):
808
828
809 page = request.GET.get('page')
829 page = request.GET.get('page')
810 order = ('-programmed_date', )
830 order = ('-programmed_date', )
811 filters = request.GET.copy()
831 filters = request.GET.copy()
812 if 'my configurations' in filters:
832 if 'my configurations' in filters:
813 filters.pop('my configurations', None)
833 filters.pop('my configurations', None)
814 filters['mine'] = request.user.id
834 filters['mine'] = request.user.id
815 kwargs = get_paginator(Configuration, page, order, filters)
835 kwargs = get_paginator(Configuration, page, order, filters)
816 fields = ['tags', 'historical']
836 fields = ['tags', 'historical']
817 if request.user.is_authenticated:
837 if request.user.is_authenticated:
818 fields.append('my configurations')
838 fields.append('my configurations')
819 form = FilterForm(initial=request.GET, extra_fields=fields)
839 form = FilterForm(initial=request.GET, extra_fields=fields)
820 kwargs['keys'] = ['name', 'device', 'type', 'actions']
840 kwargs['keys'] = ['name', 'device', 'type', 'actions']
821 if request.GET.get('historical') == 'on':
841 if request.GET.get('historical') == 'on':
822 kwargs['keys'].insert(3, 'experiment')
842 kwargs['keys'].insert(3, 'experiment')
823 kwargs['keys'].insert(4, 'experiment_date')
843 kwargs['keys'].insert(4, 'experiment_date')
824 else:
844 else:
825 kwargs['keys'].insert(3, 'programmed_date')
845 kwargs['keys'].insert(3, 'programmed_date')
826
846
827 kwargs['title'] = 'Configuration'
847 kwargs['title'] = 'Configuration'
828 kwargs['suptitle'] = 'List'
848 kwargs['suptitle'] = 'List'
829 kwargs['no_sidebar'] = True
849 kwargs['no_sidebar'] = True
830 kwargs['form'] = form
850 kwargs['form'] = form
831 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
851 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
832 filters = request.GET.copy()
852 filters = request.GET.copy()
833 filters.pop('page', None)
853 filters.pop('page', None)
834 kwargs['q'] = urlencode(filters)
854 kwargs['q'] = urlencode(filters)
835 kwargs['menu_configurations'] = 'active'
855 kwargs['menu_configurations'] = 'active'
836
856
837 return render(request, 'base_list.html', kwargs)
857 return render(request, 'base_list.html', kwargs)
838
858
839
859
840 def dev_conf(request, id_conf):
860 def dev_conf(request, id_conf):
841
861
842 conf = get_object_or_404(Configuration, pk=id_conf)
862 conf = get_object_or_404(Configuration, pk=id_conf)
843
863
844 return redirect(conf.get_absolute_url())
864 return redirect(conf.get_absolute_url())
845
865
846
866
847 @login_required
867 @login_required
848 def dev_conf_new(request, id_exp=0, id_dev=0):
868 def dev_conf_new(request, id_exp=0, id_dev=0):
849
869
850 if not is_developer(request.user):
870 if not is_developer(request.user):
851 messages.error(
871 messages.error(
852 request, 'Developer required, to create new configurations')
872 request, 'Developer required, to create new configurations')
853 return redirect('index')
873 return redirect('url_dev_confs')
854
874
855 initial = {}
875 initial = {}
856 kwargs = {}
876 kwargs = {}
857
877
858 if id_exp != 0:
878 if id_exp != 0:
859 initial['experiment'] = id_exp
879 initial['experiment'] = id_exp
860
880
861 if id_dev != 0:
881 if id_dev != 0:
862 initial['device'] = id_dev
882 initial['device'] = id_dev
863
883
864 if request.method == 'GET':
884 if request.method == 'GET':
865
885
866 if id_dev:
886 if id_dev:
867 kwargs['button'] = 'Create'
887 kwargs['button'] = 'Create'
868 device = Device.objects.get(pk=id_dev)
888 device = Device.objects.get(pk=id_dev)
869 DevConfForm = CONF_FORMS[device.device_type.name]
889 DevConfForm = CONF_FORMS[device.device_type.name]
870 initial['name'] = request.GET['name']
890 initial['name'] = request.GET['name']
871 form = DevConfForm(initial=initial)
891 form = DevConfForm(initial=initial)
872 else:
892 else:
873 kwargs['button'] = 'Create'
893 kwargs['button'] = 'Create'
874 form = ConfigurationForm(initial=initial)
894 form = ConfigurationForm(initial=initial)
875
895
876 if request.method == 'POST':
896 if request.method == 'POST':
877
897
878 device = Device.objects.get(pk=request.POST['device'])
898 device = Device.objects.get(pk=request.POST['device'])
879 DevConfForm = CONF_FORMS[device.device_type.name]
899 DevConfForm = CONF_FORMS[device.device_type.name]
880
900
881 form = DevConfForm(request.POST)
901 form = DevConfForm(request.POST)
882 kwargs['button'] = 'Create'
902 kwargs['button'] = 'Create'
883 if form.is_valid():
903 if form.is_valid():
884 conf = form.save(commit=False)
904 conf = form.save(commit=False)
885
905
886 if device.device_type.name == 'usrp_tx':
906 if device.device_type.name == 'usrp_tx':
887 validation_usrp_tx_code(request, conf)
907 validation_usrp_tx_code(request, conf)
888
908
889 conf.save()
909 conf.save()
890 conf.author = request.user
910 conf.author = request.user
891
911
892 messages.success(request, device.device_type.name + ' configuration successfully created')
912 messages.success(request, device.device_type.name + ' configuration successfully created')
893 return redirect('url_dev_conf', id_conf=conf.pk)
913 return redirect('url_dev_conf', id_conf=conf.pk)
894
914
895 kwargs['id_exp'] = id_exp
915 kwargs['id_exp'] = id_exp
896 kwargs['form'] = form
916 kwargs['form'] = form
897 kwargs['title'] = 'Configuration'
917 kwargs['title'] = 'Configuration'
898 kwargs['suptitle'] = 'New'
918 kwargs['suptitle'] = 'New'
899 kwargs['menu_configurations'] = 'active'
919 kwargs['menu_configurations'] = 'active'
900
920
901 if id_dev != 0:
921 if id_dev != 0:
902 device = Device.objects.get(pk=id_dev)
922 device = Device.objects.get(pk=id_dev)
903 kwargs['device'] = device.device_type.name
923 kwargs['device'] = device.device_type.name
904 return render(request, 'dev_conf_edit.html', kwargs)
924 return render(request, 'dev_conf_edit.html', kwargs)
905
925
906
926
907 @login_required
927 @login_required
908 def dev_conf_edit(request, id_conf):
928 def dev_conf_edit(request, id_conf):
909
929
910 conf = get_object_or_404(Configuration, pk=id_conf)
930 conf = get_object_or_404(Configuration, pk=id_conf)
911
931
912 DevConfForm = CONF_FORMS[conf.device.device_type.name]
932 DevConfForm = CONF_FORMS[conf.device.device_type.name]
913
933
914 if request.method == 'GET':
934 if request.method == 'GET':
915 form = DevConfForm(instance=conf)
935 form = DevConfForm(instance=conf)
916
936
917 if request.method == 'POST':
937 if request.method == 'POST':
918 form = DevConfForm(request.POST, instance=conf)
938 form = DevConfForm(request.POST, instance=conf)
919
939
920 if form.is_valid():
940 if form.is_valid():
921 form.save()
941 form.save()
922 return redirect('url_dev_conf', id_conf=id_conf)
942 return redirect('url_dev_conf', id_conf=id_conf)
923
943
924 kwargs = {}
944 kwargs = {}
925 kwargs['form'] = form
945 kwargs['form'] = form
926 kwargs['title'] = 'Device Configuration'
946 kwargs['title'] = 'Device Configuration'
927 kwargs['suptitle'] = 'Edit'
947 kwargs['suptitle'] = 'Edit'
928 kwargs['button'] = 'Update'
948 kwargs['button'] = 'Update'
929 kwargs['menu_configurations'] = 'active'
949 kwargs['menu_configurations'] = 'active'
930
950
931 ###### SIDEBAR ######
951 ###### SIDEBAR ######
932 kwargs.update(sidebar(conf=conf))
952 kwargs.update(sidebar(conf=conf))
933
953
934 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
954 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
935
955
936
956
937 @login_required
957 @login_required
938 def dev_conf_start(request, id_conf):
958 def dev_conf_start(request, id_conf):
939
959
940 conf = get_object_or_404(Configuration, pk=id_conf)
960 conf = get_object_or_404(Configuration, pk=id_conf)
941
961
962 if not is_developer(request.user) and not is_operator(request.user):
963 messages.error(request, 'You must be an developer or operator to start this configuration')
964 return redirect(conf.get_absolute_url())
965
942 if conf.start_device():
966 if conf.start_device():
943 messages.success(request, conf.message)
967 messages.success(request, conf.message)
944 else:
968 else:
945 messages.error(request, conf.message)
969 messages.error(request, conf.message)
946
970
947 #conf.status_device()
971 #conf.status_device()
948
972
949 return redirect(conf.get_absolute_url())
973 return redirect(conf.get_absolute_url())
950
974
951
975
952 @login_required
976 @login_required
953 def dev_conf_stop(request, id_conf):
977 def dev_conf_stop(request, id_conf):
954
978
955 conf = get_object_or_404(Configuration, pk=id_conf)
979 conf = get_object_or_404(Configuration, pk=id_conf)
956
980
981 if not is_developer(request.user) and not is_operator(request.user):
982 messages.error(request, 'You must be an developer or operator to stop this configuration')
983 return redirect(conf.get_absolute_url())
984
957 if conf.stop_device():
985 if conf.stop_device():
958 messages.success(request, conf.message)
986 messages.success(request, conf.message)
959 else:
987 else:
960 messages.error(request, conf.message)
988 messages.error(request, conf.message)
961
989
962 #conf.status_device()
990 #conf.status_device()
963
991
964 return redirect(conf.get_absolute_url())
992 return redirect(conf.get_absolute_url())
965
993
966
994
967 @login_required
995 @login_required
968 def dev_conf_status(request, id_conf):
996 def dev_conf_status(request, id_conf):
969
997
970 conf = get_object_or_404(Configuration, pk=id_conf)
998 conf = get_object_or_404(Configuration, pk=id_conf)
971
999
972 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1000 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
973 if conf_active!=conf:
1001 if conf_active!=conf:
974 url = '#' if conf_active is None else conf_active.get_absolute_url()
1002 url = '#' if conf_active is None else conf_active.get_absolute_url()
975 label = 'None' if conf_active is None else conf_active.label
1003 label = 'None' if conf_active is None else conf_active.label
976 messages.warning(
1004 messages.warning(
977 request,
1005 request,
978 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1006 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
979 url,
1007 url,
980 label
1008 label
981 ))
1009 ))
982 )
1010 )
983
1011
984 return redirect(conf.get_absolute_url())
1012 return redirect(conf.get_absolute_url())
985
1013
986 if conf.status_device():
1014 if conf.status_device():
987 messages.success(request, conf.message)
1015 messages.success(request, conf.message)
988 else:
1016 else:
989 messages.error(request, conf.message)
1017 messages.error(request, conf.message)
990
1018
991 return redirect(conf.get_absolute_url())
1019 return redirect(conf.get_absolute_url())
992
1020
993
1021
994 @login_required
1022 @login_required
995 def dev_conf_reset(request, id_conf):
1023 def dev_conf_reset(request, id_conf):
996
1024
997 conf = get_object_or_404(Configuration, pk=id_conf)
1025 conf = get_object_or_404(Configuration, pk=id_conf)
998
1026
999 if conf.reset_device():
1027 if conf.reset_device():
1000 messages.success(request, conf.message)
1028 messages.success(request, conf.message)
1001 else:
1029 else:
1002 messages.error(request, conf.message)
1030 messages.error(request, conf.message)
1003
1031
1004 return redirect(conf.get_absolute_url())
1032 return redirect(conf.get_absolute_url())
1005
1033
1006
1034
1007 @login_required
1035 @login_required
1008 def dev_conf_write(request, id_conf):
1036 def dev_conf_write(request, id_conf):
1009
1037
1010 conf = get_object_or_404(Configuration, pk=id_conf)
1038 conf = get_object_or_404(Configuration, pk=id_conf)
1011
1039
1012 if request.method == 'POST':
1040 if request.method == 'POST':
1013 if conf.write_device():
1041 if conf.write_device():
1014 conf.device.conf_active = conf.pk
1042 conf.device.conf_active = conf.pk
1015 conf.device.save()
1043 conf.device.save()
1016 messages.success(request, conf.message)
1044 messages.success(request, conf.message)
1017 if has_been_modified(conf):
1045 if has_been_modified(conf):
1018 conf.clone(type=1)
1046 conf.clone(type=1)
1019 else:
1047 else:
1020 messages.error(request, conf.message)
1048 messages.error(request, conf.message)
1021
1049
1022 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1050 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1023
1051
1024 kwargs = {
1052 kwargs = {
1025 'title': 'Write Configuration',
1053 'title': 'Write Configuration',
1026 'suptitle': conf.label,
1054 'suptitle': conf.label,
1027 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1055 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1028 'delete': False
1056 'delete': False
1029 }
1057 }
1030 kwargs['menu_configurations'] = 'active'
1058 kwargs['menu_configurations'] = 'active'
1031
1059
1032 return render(request, 'confirm.html', kwargs)
1060 return render(request, 'confirm.html', kwargs)
1033
1061
1034
1062
1035 @login_required
1063 @login_required
1036 def dev_conf_read(request, id_conf):
1064 def dev_conf_read(request, id_conf):
1037
1065
1038 conf = get_object_or_404(Configuration, pk=id_conf)
1066 conf = get_object_or_404(Configuration, pk=id_conf)
1039
1067
1040 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1068 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1041
1069
1042 if request.method == 'GET':
1070 if request.method == 'GET':
1043 parms = conf.read_device()
1071 parms = conf.read_device()
1044 #conf.status_device()
1072 #conf.status_device()
1045
1073
1046 if not parms:
1074 if not parms:
1047 messages.error(request, conf.message)
1075 messages.error(request, conf.message)
1048 return redirect(conf.get_absolute_url())
1076 return redirect(conf.get_absolute_url())
1049
1077
1050 form = DevConfForm(initial=parms, instance=conf)
1078 form = DevConfForm(initial=parms, instance=conf)
1051
1079
1052 if request.method == 'POST':
1080 if request.method == 'POST':
1053 form = DevConfForm(request.POST, instance=conf)
1081 form = DevConfForm(request.POST, instance=conf)
1054
1082
1055 if form.is_valid():
1083 if form.is_valid():
1056 form.save()
1084 form.save()
1057 return redirect(conf.get_absolute_url())
1085 return redirect(conf.get_absolute_url())
1058
1086
1059 messages.error(request, "Parameters could not be saved")
1087 messages.error(request, "Parameters could not be saved")
1060
1088
1061 kwargs = {}
1089 kwargs = {}
1062 kwargs['id_dev'] = conf.id
1090 kwargs['id_dev'] = conf.id
1063 kwargs['form'] = form
1091 kwargs['form'] = form
1064 kwargs['title'] = 'Device Configuration'
1092 kwargs['title'] = 'Device Configuration'
1065 kwargs['suptitle'] = 'Parameters read from device'
1093 kwargs['suptitle'] = 'Parameters read from device'
1066 kwargs['button'] = 'Save'
1094 kwargs['button'] = 'Save'
1067
1095
1068 ###### SIDEBAR ######
1096 ###### SIDEBAR ######
1069 kwargs.update(sidebar(conf=conf))
1097 kwargs.update(sidebar(conf=conf))
1070
1098
1071 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1099 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1072
1100
1073
1101
1074 @login_required
1102 @login_required
1075 def dev_conf_import(request, id_conf):
1103 def dev_conf_import(request, id_conf):
1076
1104
1077 conf = get_object_or_404(Configuration, pk=id_conf)
1105 conf = get_object_or_404(Configuration, pk=id_conf)
1078 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1106 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1079
1107
1080 if request.method == 'GET':
1108 if request.method == 'GET':
1081 file_form = UploadFileForm()
1109 file_form = UploadFileForm()
1082
1110
1083 if request.method == 'POST':
1111 if request.method == 'POST':
1084 file_form = UploadFileForm(request.POST, request.FILES)
1112 file_form = UploadFileForm(request.POST, request.FILES)
1085
1113
1086 if file_form.is_valid():
1114 if file_form.is_valid():
1087
1115
1088 data = conf.import_from_file(request.FILES['file'])
1116 data = conf.import_from_file(request.FILES['file'])
1089 parms = Params(data=data).get_conf(
1117 parms = Params(data=data).get_conf(
1090 dtype=conf.device.device_type.name)
1118 dtype=conf.device.device_type.name)
1091
1119
1092 if parms:
1120 if parms:
1093
1121
1094 form = DevConfForm(initial=parms, instance=conf)
1122 form = DevConfForm(initial=parms, instance=conf)
1095
1123
1096 kwargs = {}
1124 kwargs = {}
1097 kwargs['id_dev'] = conf.id
1125 kwargs['id_dev'] = conf.id
1098 kwargs['form'] = form
1126 kwargs['form'] = form
1099 kwargs['title'] = 'Device Configuration'
1127 kwargs['title'] = 'Device Configuration'
1100 kwargs['suptitle'] = 'Parameters imported'
1128 kwargs['suptitle'] = 'Parameters imported'
1101 kwargs['button'] = 'Save'
1129 kwargs['button'] = 'Save'
1102 kwargs['action'] = conf.get_absolute_url_edit()
1130 kwargs['action'] = conf.get_absolute_url_edit()
1103 kwargs['previous'] = conf.get_absolute_url()
1131 kwargs['previous'] = conf.get_absolute_url()
1104
1132
1105 ###### SIDEBAR ######
1133 ###### SIDEBAR ######
1106 kwargs.update(sidebar(conf=conf))
1134 kwargs.update(sidebar(conf=conf))
1107
1135
1108 messages.success(
1136 messages.success(
1109 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1137 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1110
1138
1111 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1139 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1112
1140
1113 messages.error(request, "Could not import parameters from file")
1141 messages.error(request, "Could not import parameters from file")
1114
1142
1115 kwargs = {}
1143 kwargs = {}
1116 kwargs['id_dev'] = conf.id
1144 kwargs['id_dev'] = conf.id
1117 kwargs['title'] = 'Device Configuration'
1145 kwargs['title'] = 'Device Configuration'
1118 kwargs['form'] = file_form
1146 kwargs['form'] = file_form
1119 kwargs['suptitle'] = 'Importing file'
1147 kwargs['suptitle'] = 'Importing file'
1120 kwargs['button'] = 'Import'
1148 kwargs['button'] = 'Import'
1121 kwargs['menu_configurations'] = 'active'
1149 kwargs['menu_configurations'] = 'active'
1122
1150
1123 kwargs.update(sidebar(conf=conf))
1151 kwargs.update(sidebar(conf=conf))
1124
1152
1125 return render(request, 'dev_conf_import.html', kwargs)
1153 return render(request, 'dev_conf_import.html', kwargs)
1126
1154
1127
1155
1128 @login_required
1156 @login_required
1129 def dev_conf_export(request, id_conf):
1157 def dev_conf_export(request, id_conf):
1130
1158
1131 conf = get_object_or_404(Configuration, pk=id_conf)
1159 conf = get_object_or_404(Configuration, pk=id_conf)
1132
1160
1133 if request.method == 'GET':
1161 if request.method == 'GET':
1134 file_form = DownloadFileForm(conf.device.device_type.name)
1162 file_form = DownloadFileForm(conf.device.device_type.name)
1135
1163
1136 if request.method == 'POST':
1164 if request.method == 'POST':
1137 file_form = DownloadFileForm(
1165 file_form = DownloadFileForm(
1138 conf.device.device_type.name, request.POST)
1166 conf.device.device_type.name, request.POST)
1139
1167
1140 if file_form.is_valid():
1168 if file_form.is_valid():
1141 fields = conf.export_to_file(
1169 fields = conf.export_to_file(
1142 format=file_form.cleaned_data['format'])
1170 format=file_form.cleaned_data['format'])
1143
1171
1144 if not fields['content']:
1172 if not fields['content']:
1145 messages.error(request, conf.message)
1173 messages.error(request, conf.message)
1146 return redirect(conf.get_absolute_url_export())
1174 return redirect(conf.get_absolute_url_export())
1147 response = HttpResponse(content_type=fields['content_type'])
1175 response = HttpResponse(content_type=fields['content_type'])
1148 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1176 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1149 response.write(fields['content'])
1177 response.write(fields['content'])
1150
1178
1151 return response
1179 return response
1152
1180
1153 messages.error(request, "Could not export parameters")
1181 messages.error(request, "Could not export parameters")
1154
1182
1155 kwargs = {}
1183 kwargs = {}
1156 kwargs['id_dev'] = conf.id
1184 kwargs['id_dev'] = conf.id
1157 kwargs['title'] = 'Device Configuration'
1185 kwargs['title'] = 'Device Configuration'
1158 kwargs['form'] = file_form
1186 kwargs['form'] = file_form
1159 kwargs['suptitle'] = 'Exporting file'
1187 kwargs['suptitle'] = 'Exporting file'
1160 kwargs['button'] = 'Export'
1188 kwargs['button'] = 'Export'
1161 kwargs['menu_configurations'] = 'active'
1189 kwargs['menu_configurations'] = 'active'
1162
1190
1163 return render(request, 'dev_conf_export.html', kwargs)
1191 return render(request, 'dev_conf_export.html', kwargs)
1164
1192
1165
1193
1166 @login_required
1194 @login_required
1167 def dev_conf_delete(request, id_conf):
1195 def dev_conf_delete(request, id_conf):
1168
1196
1169 conf = get_object_or_404(Configuration, pk=id_conf)
1197 conf = get_object_or_404(Configuration, pk=id_conf)
1170
1198
1171 if request.method == 'POST':
1199 if request.method == 'POST':
1172 if is_developer(request.user):
1200 if is_developer(request.user):
1173 try:
1201 try:
1174 conf.delete()
1202 conf.delete()
1175 except Exception as e:
1203 except Exception as e:
1176 messages.error(request, "The device configuration is protected")
1204 messages.error(request, "The device configuration is protected")
1177 return redirect('url_dev_confs')
1205 return redirect('url_dev_confs')
1178
1206
1179 messages.error(request, 'Not enough permission to delete this object')
1207 messages.error(request, 'Not enough permission to delete this object')
1180 return redirect(conf.get_absolute_url())
1208 return redirect(conf.get_absolute_url())
1181
1209
1182 kwargs = {
1210 kwargs = {
1183 'title': 'Delete',
1211 'title': 'Delete',
1184 'suptitle': 'Configuration',
1212 'suptitle': 'Configuration',
1185 'object': conf,
1213 'object': conf,
1186 'delete': True
1214 'delete': True
1187 }
1215 }
1188 kwargs['menu_configurations'] = 'active'
1216 kwargs['menu_configurations'] = 'active'
1189
1217
1190 return render(request, 'confirm.html', kwargs)
1218 return render(request, 'confirm.html', kwargs)
1191
1219
1192
1220
1193 def sidebar(**kwargs):
1221 def sidebar(**kwargs):
1194
1222
1195 side_data = {}
1223 side_data = {}
1196
1224
1197 conf = kwargs.get('conf', None)
1225 conf = kwargs.get('conf', None)
1198 confs = kwargs.get('confs', None)
1226 confs = kwargs.get('confs', None)
1199 experiment = kwargs.get('experiment', None)
1227 experiment = kwargs.get('experiment', None)
1200
1228
1201 if confs:
1229 if confs:
1202 side_data['side_configurations'] = confs
1230 side_data['side_configurations'] = confs
1203
1231
1204 if experiment:
1232 if experiment:
1205 side_data['experiment'] = experiment
1233 side_data['experiment'] = experiment
1206 experiments = [experiment]
1234 experiments = [experiment]
1207 #configurations = experiment.configuration_set.filter(type=0)
1235 #configurations = experiment.configuration_set.filter(type=0)
1208 side_data['side_experiments'] = experiments
1236 side_data['side_experiments'] = experiments
1209 #side_data['side_configurations'] = configurations.order_by('device__device_type__name')
1237 #side_data['side_configurations'] = configurations.order_by('device__device_type__name')
1210
1238
1211 return side_data
1239 return side_data
1212
1240
1213
1241
1214 def get_paginator(model, page, order, filters={}, n=8):
1242 def get_paginator(model, page, order, filters={}, n=8):
1215
1243
1216 kwargs = {}
1244 kwargs = {}
1217 query = Q()
1245 query = Q()
1218 if isinstance(filters, QueryDict):
1246 if isinstance(filters, QueryDict):
1219 filters = filters.dict()
1247 filters = filters.dict()
1220 [filters.pop(key) for key in list(filters) if filters[key] in ('', ' ')]
1248 [filters.pop(key) for key in list(filters) if filters[key] in ('', ' ')]
1221 filters.pop('page', None)
1249 filters.pop('page', None)
1222
1250
1223 fields = [f.name for f in model._meta.get_fields()]
1251 fields = [f.name for f in model._meta.get_fields()]
1224
1252
1225 if 'historical' in filters:
1253 if 'historical' in filters:
1226 filters.pop('historical')
1254 filters.pop('historical')
1227 filters['type'] = 1
1255 filters['type'] = 1
1228 elif 'type' in fields:
1256 elif 'type' in fields:
1229 filters['type'] = 0
1257 filters['type'] = 0
1230 if 'start_date' in filters:
1258 if 'start_date' in filters:
1231 filters['start_date__gte'] = filters.pop('start_date')
1259 filters['start_date__gte'] = filters.pop('start_date')
1232 if 'end_date' in filters:
1260 if 'end_date' in filters:
1233 filters['start_date__lte'] = filters.pop('end_date')
1261 filters['start_date__lte'] = filters.pop('end_date')
1234 if 'tags' in filters:
1262 if 'tags' in filters:
1235 tags = filters.pop('tags')
1263 tags = filters.pop('tags')
1236 if 'tags' in fields:
1264 if 'tags' in fields:
1237 query = query | Q(tags__icontains=tags)
1265 query = query | Q(tags__icontains=tags)
1238 if 'label' in fields:
1266 if 'label' in fields:
1239 query = query | Q(label__icontains=tags)
1267 query = query | Q(label__icontains=tags)
1240 if 'device' in fields:
1268 if 'device' in fields:
1241 query = query | Q(device__device_type__name__icontains=tags)
1269 query = query | Q(device__device_type__name__icontains=tags)
1242 if 'device_type' in fields:
1270 if 'device_type' in fields:
1243 query = query | Q(device_type__name__icontains=tags)
1271 query = query | Q(device_type__name__icontains=tags)
1244
1272
1245 if 'mine' in filters:
1273 if 'mine' in filters:
1246 filters['author_id'] = filters['mine']
1274 filters['author_id'] = filters['mine']
1247 filters.pop('mine')
1275 filters.pop('mine')
1248 object_list = model.objects.filter(query, **filters).order_by(*order)
1276 object_list = model.objects.filter(query, **filters).order_by(*order)
1249 paginator = Paginator(object_list, n)
1277 paginator = Paginator(object_list, n)
1250
1278
1251 try:
1279 try:
1252 objects = paginator.page(page)
1280 objects = paginator.page(page)
1253 except PageNotAnInteger:
1281 except PageNotAnInteger:
1254 objects = paginator.page(1)
1282 objects = paginator.page(1)
1255 except EmptyPage:
1283 except EmptyPage:
1256 objects = paginator.page(paginator.num_pages)
1284 objects = paginator.page(paginator.num_pages)
1257
1285
1258 kwargs['objects'] = objects
1286 kwargs['objects'] = objects
1259 kwargs['offset'] = (int(page)-1)*n if page else 0
1287 kwargs['offset'] = (int(page)-1)*n if page else 0
1260
1288
1261 return kwargs
1289 return kwargs
1262
1290
1263 @login_required
1291 @login_required
1264 def revoke_tasks(request, id_camp):
1292 def revoke_tasks(request, id_camp):
1265
1293
1266 i = app.control.inspect()
1294 i = app.control.inspect()
1267 scheduled = list(i.scheduled().values())[0]
1295 scheduled = list(i.scheduled().values())[0]
1268 revoked = list(i.revoked().values())[0]
1296 revoked = list(i.revoked().values())[0]
1269
1297
1270 for t in scheduled:
1298 for t in scheduled:
1271 if t['request']['id'] in revoked:
1299 if t['request']['id'] in revoked:
1272 continue
1300 continue
1273 app.control.revoke(t['request']['id'])
1301 app.control.revoke(t['request']['id'])
1274 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1302 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1275 eta = t['eta']
1303 eta = t['eta']
1276 task = t['request']['name'].split('.')[-1]
1304 task = t['request']['name'].split('.')[-1]
1277 messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1305 messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1278
1306
1279 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1307 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1280
1308
1281 @login_required
1309 @login_required
1282 def show_tasks(request, id_camp):
1310 def show_tasks(request, id_camp):
1283
1311
1284 i = app.control.inspect()
1312 i = app.control.inspect()
1285 scheduled = list(i.scheduled().values())[0]
1313 scheduled = list(i.scheduled().values())[0]
1286 revoked = list(i.revoked().values())[0]
1314 revoked = list(i.revoked().values())[0]
1287
1315
1288 for t in scheduled:
1316 for t in scheduled:
1289 if t['request']['id'] in revoked:
1317 if t['request']['id'] in revoked:
1290 continue
1318 continue
1291 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1319 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1292 eta = t['eta']
1320 eta = t['eta']
1293 task = t['request']['name'].split('.')[-1]
1321 task = t['request']['name'].split('.')[-1]
1294 messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
1322 messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
1295
1323
1296 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1324 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1297
1325
1298 def real_time(request):
1326 def real_time(request):
1299
1327
1300 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1328 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1301
1329
1302 kwargs = {}
1330 kwargs = {}
1303 kwargs['title'] = 'CLAIRE'
1331 kwargs['title'] = 'CLAIRE'
1304 kwargs['suptitle'] = 'Real Time'
1332 kwargs['suptitle'] = 'Real Time'
1305 kwargs['no_sidebar'] = True
1333 kwargs['no_sidebar'] = True
1306 kwargs['graphic_path'] = graphic_path
1334 kwargs['graphic_path'] = graphic_path
1307 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1335 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1308
1336
1309 return render(request, 'real_time.html', kwargs)
1337 return render(request, 'real_time.html', kwargs)
1310
1338
1311 def theme(request, theme):
1339 def theme(request, theme):
1312
1340
1313 user = request.user
1341 user = request.user
1314 user.profile.theme = theme
1342 user.profile.theme = theme
1315 user.save()
1343 user.save()
1316 return redirect('index')
1344 return redirect('index')
@@ -1,132 +1,150
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import PedestalConfiguration
12 from .models import PedestalConfiguration
13 from .forms import PedestalConfigurationForm, PedestalImportForm
13 from .forms import PedestalConfigurationForm, PedestalImportForm
14
14
15 def is_developer(user):
16 groups = [str(g.name) for g in user.groups.all()]
17 #return 'Developer' in groups or user.is_staff
18 return 'Developer' in groups or user.is_superuser
19
20
21 def is_operator(user):
22 groups = [str(g.name) for g in user.groups.all()]
23 #return 'Operator' in groups or user.is_staff
24 return 'Operator' in groups or user.is_superuser
25
15
26
16 def conf(request, conf_id):
27 def conf(request, conf_id):
17
28
18 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
29 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
19
30
20 kwargs = {}
31 kwargs = {}
21 kwargs['dev_conf'] = conf
32 kwargs['dev_conf'] = conf
22
33
23 if conf.mode == 'position':
34 if conf.mode == 'position':
24 kwargs['dev_conf_keys'] = ['mode', 'axis', 'angle']
35 kwargs['dev_conf_keys'] = ['mode', 'axis', 'angle']
25 elif conf.mode == 'speed':
36 elif conf.mode == 'speed':
26 kwargs['dev_conf_keys'] = ['mode', 'axis', 'speed']
37 kwargs['dev_conf_keys'] = ['mode', 'axis', 'speed']
27 else:
38 else:
28 kwargs['dev_conf_keys'] = ['mode', 'axis', 'speed', 'angle', 'min_value', 'max_value']
39 kwargs['dev_conf_keys'] = ['mode', 'axis', 'speed', 'angle', 'min_value', 'max_value']
29
40
30
41
31 kwargs['title'] = 'Configuration'
42 kwargs['title'] = 'Configuration'
32 kwargs['suptitle'] = 'Detail'
43 kwargs['suptitle'] = 'Detail'
33
44
34 kwargs['button'] = 'Edit Configuration'
45 kwargs['button'] = 'Edit Configuration'
35
46
36 conf.status_device()
47 conf.status_device()
37
48
38 ###### SIDEBAR ######
49 ###### SIDEBAR ######
39 kwargs.update(sidebar(conf=conf))
50 kwargs.update(sidebar(conf=conf))
40
51
41 return render(request, 'pedestal_conf.html', kwargs)
52 return render(request, 'pedestal_conf.html', kwargs)
42
53
43 @login_required
54 @login_required
44 def conf_edit(request, conf_id):
55 def conf_edit(request, conf_id):
45
56
46 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
57 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
47
58
59 if not is_developer(request.user):
60 messages.error(request, 'You must be an developer to edit this configuration')
61 return redirect(conf.get_absolute_url())
48
62
49 if request.method=='GET':
63 if request.method=='GET':
50
64
51 form = PedestalConfigurationForm(instance=conf)
65 form = PedestalConfigurationForm(instance=conf)
52 if conf.mode == 'position':
66 if conf.mode == 'position':
53 form.fields['speed'].disabled = True
67 form.fields['speed'].disabled = True
54 form.fields['max_value'].disabled = True
68 form.fields['max_value'].disabled = True
55 form.fields['min_value'].disabled = True
69 form.fields['min_value'].disabled = True
56 elif conf.mode == 'speed':
70 elif conf.mode == 'speed':
57 form.fields['angle'].disabled = True
71 form.fields['angle'].disabled = True
58 form.fields['max_value'].disabled = True
72 form.fields['max_value'].disabled = True
59 form.fields['min_value'].disabled = True
73 form.fields['min_value'].disabled = True
60
74
61 elif request.method=='POST':
75 elif request.method=='POST':
62
76
63 line_data = {}
77 line_data = {}
64 conf_data = {}
78 conf_data = {}
65 clock_data = {}
79 clock_data = {}
66 extras = []
80 extras = []
67
81
68 #classified post fields
82 #classified post fields
69
83
70 form = PedestalConfigurationForm(request.POST, instance=conf)
84 form = PedestalConfigurationForm(request.POST, instance=conf)
71
85
72 if form.is_valid():
86 if form.is_valid():
73 form.save()
87 form.save()
74
88
75 messages.success(request, 'Pedestal configuration successfully updated')
89 messages.success(request, 'Pedestal configuration successfully updated')
76
90
77 return redirect(conf.get_absolute_url())
91 return redirect(conf.get_absolute_url())
78
92
79 kwargs = {}
93 kwargs = {}
80 kwargs['dev_conf'] = conf
94 kwargs['dev_conf'] = conf
81 kwargs['form'] = form
95 kwargs['form'] = form
82 kwargs['edit'] = True
96 kwargs['edit'] = True
83
97
84 kwargs['title'] = 'Pedestal Configuration'
98 kwargs['title'] = 'Pedestal Configuration'
85 kwargs['suptitle'] = 'Edit'
99 kwargs['suptitle'] = 'Edit'
86 kwargs['button'] = 'Update'
100 kwargs['button'] = 'Update'
87
101
88 return render(request, 'pedestal_conf_edit.html', kwargs)
102 return render(request, 'pedestal_conf_edit.html', kwargs)
89
103
90 def import_file(request, conf_id):
104 def import_file(request, conf_id):
91
105
92 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
106 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
93 if request.method=='POST':
107 if request.method=='POST':
94 form = PedestalImportForm(request.POST, request.FILES)
108 form = PedestalImportForm(request.POST, request.FILES)
95 if form.is_valid():
109 if form.is_valid():
96 try:
110 try:
97 data = conf.import_from_file(request.FILES['file_name'])
111 data = conf.import_from_file(request.FILES['file_name'])
98 conf.dict_to_parms(data)
112 conf.dict_to_parms(data)
99 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
113 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
100 return redirect(conf.get_absolute_url_edit())
114 return redirect(conf.get_absolute_url_edit())
101
115
102 except Exception as e:
116 except Exception as e:
103 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
117 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
104 else:
118 else:
105 messages.warning(request, 'Your current configuration will be replaced')
119 messages.warning(request, 'Your current configuration will be replaced')
106 form = PedestalImportForm()
120 form = PedestalImportForm()
107
121
108 kwargs = {}
122 kwargs = {}
109 kwargs['form'] = form
123 kwargs['form'] = form
110 kwargs['title'] = 'Pedestal Configuration'
124 kwargs['title'] = 'Pedestal Configuration'
111 kwargs['suptitle'] = 'Import file'
125 kwargs['suptitle'] = 'Import file'
112 kwargs['button'] = 'Upload'
126 kwargs['button'] = 'Upload'
113 kwargs['previous'] = conf.get_absolute_url()
127 kwargs['previous'] = conf.get_absolute_url()
114
128
115 return render(request, 'pedestal_import.html', kwargs)
129 return render(request, 'pedestal_import.html', kwargs)
116
130
117 @login_required
131 @login_required
118 def conf_reset(request, conf_id):
132 def conf_reset(request, conf_id):
119
133
120 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
134 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
121
135
136 if not is_developer(request.user) and not is_operator(request.user):
137 messages.error(request, 'You must be an developer or operator to reset this pedestal')
138 return redirect(conf.get_absolute_url())
139
122 if conf.reset_device():
140 if conf.reset_device():
123 messages.success(request, conf.message)
141 messages.success(request, conf.message)
124 else:
142 else:
125 messages.error(request, conf.message)
143 messages.error(request, conf.message)
126
144
127 return redirect(conf.get_absolute_url())
145 return redirect(conf.get_absolute_url())
128
146
129 def conf_raw(request, conf_id):
147 def conf_raw(request, conf_id):
130 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
148 conf = get_object_or_404(PedestalConfiguration, pk=conf_id)
131 raw = conf.write_device(raw=True)
149 raw = conf.write_device(raw=True)
132 return HttpResponse(raw, content_type='application/json') No newline at end of file
150 return HttpResponse(raw, content_type='application/json')
@@ -1,129 +1,141
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import USRPRXConfiguration
12 from .models import USRPRXConfiguration
13 from .forms import USRPRXConfigurationForm, USRPRXImportForm
13 from .forms import USRPRXConfigurationForm, USRPRXImportForm
14
14
15 def is_developer(user):
16 groups = [str(g.name) for g in user.groups.all()]
17 #return 'Developer' in groups or user.is_staff
18 return 'Developer' in groups or user.is_superuser
19
20
21 def is_operator(user):
22 groups = [str(g.name) for g in user.groups.all()]
23 #return 'Operator' in groups or user.is_staff
24 return 'Operator' in groups or user.is_superuser
15
25
16 def conf(request, conf_id):
26 def conf(request, conf_id):
17
27
18 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
28 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
19
29
20 kwargs = {}
30 kwargs = {}
21 kwargs['dev_conf'] = conf
31 kwargs['dev_conf'] = conf
22 kwargs['dev_conf_keys'] = ['ip_address_rx', 'daughterboard_rx', 'antenna_rx', 'samplerate_rx', 'frequency_rx', 'datadir', 'clocksource', 'timesource', 'clockrate']
32 kwargs['dev_conf_keys'] = ['ip_address_rx', 'daughterboard_rx', 'antenna_rx', 'samplerate_rx', 'frequency_rx', 'datadir', 'clocksource', 'timesource', 'clockrate']
23
33
24 kwargs['title'] = 'Configuration'
34 kwargs['title'] = 'Configuration'
25 kwargs['suptitle'] = 'Detail'
35 kwargs['suptitle'] = 'Detail'
26
36
27 kwargs['button'] = 'Edit Configuration'
37 kwargs['button'] = 'Edit Configuration'
28
38
29 conf.status_device()
39 conf.status_device()
30
40
31 ###### SIDEBAR ######
41 ###### SIDEBAR ######
32 kwargs.update(sidebar(conf=conf))
42 kwargs.update(sidebar(conf=conf))
33
43
34 return render(request, 'usrp_rx_conf.html', kwargs)
44 return render(request, 'usrp_rx_conf.html', kwargs)
35
45
36 @login_required
46 @login_required
37 def conf_edit(request, conf_id):
47 def conf_edit(request, conf_id):
38
48
39 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
49 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
40
50
51 if not is_developer(request.user):
52 messages.error(request, 'You must be an developer to edit this configuration')
53 return redirect(conf.get_absolute_url())
54
41 if request.method=='GET':
55 if request.method=='GET':
42
43 form = USRPRXConfigurationForm(instance=conf)
56 form = USRPRXConfigurationForm(instance=conf)
44
57
45 elif request.method=='POST':
58 elif request.method=='POST':
46
47 line_data = {}
59 line_data = {}
48 conf_data = {}
60 conf_data = {}
49 clock_data = {}
61 clock_data = {}
50 extras = []
62 extras = []
51
63
52 #classified post fields
64 #classified post fields
53 for label,value in request.POST.items():
65 for label,value in request.POST.items():
54 if label=='csrfmiddlewaretoken':
66 if label=='csrfmiddlewaretoken':
55 continue
67 continue
56
68
57 if label.count('|')==0:
69 if label.count('|')==0:
58 if label in ('mode', 'multiplier', 'divisor', 'reference'):
70 if label in ('mode', 'multiplier', 'divisor', 'reference'):
59 clock_data[label] = value
71 clock_data[label] = value
60 else:
72 else:
61 conf_data[label] = value
73 conf_data[label] = value
62 continue
74 continue
63
75
64 elif label.split('|')[0]!='-1':
76 elif label.split('|')[0]!='-1':
65 extras.append(label)
77 extras.append(label)
66 continue
78 continue
67
79
68 x, pk, name = label.split('|')
80 x, pk, name = label.split('|')
69
81
70 if name=='codes':
82 if name=='codes':
71 value = [s for s in value.split('\r\n') if s]
83 value = [s for s in value.split('\r\n') if s]
72
84
73 if pk in line_data:
85 if pk in line_data:
74 line_data[pk][name] = value
86 line_data[pk][name] = value
75 else:
87 else:
76 line_data[pk] = {name:value}
88 line_data[pk] = {name:value}
77
89
78 form = USRPRXConfigurationForm(conf_data, instance=conf)
90 form = USRPRXConfigurationForm(conf_data, instance=conf)
79
91
80 if form.is_valid():
92 if form.is_valid():
81 form.save()
93 form.save()
82
94
83 messages.success(request, 'USRP Rx configuration successfully updated')
95 messages.success(request, 'USRP Rx configuration successfully updated')
84
96
85 return redirect(conf.get_absolute_url())
97 return redirect(conf.get_absolute_url())
86
98
87 kwargs = {}
99 kwargs = {}
88 kwargs['dev_conf'] = conf
100 kwargs['dev_conf'] = conf
89 kwargs['form'] = form
101 kwargs['form'] = form
90 kwargs['edit'] = True
102 kwargs['edit'] = True
91
103
92 kwargs['title'] = 'USRP Rx Configuration'
104 kwargs['title'] = 'USRP Rx Configuration'
93 kwargs['suptitle'] = 'Edit'
105 kwargs['suptitle'] = 'Edit'
94 kwargs['button'] = 'Update'
106 kwargs['button'] = 'Update'
95
107
96 return render(request, 'usrp_rx_conf_edit.html', kwargs)
108 return render(request, 'usrp_rx_conf_edit.html', kwargs)
97
109
98 def import_file(request, conf_id):
110 def import_file(request, conf_id):
99
111
100 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
112 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
101 if request.method=='POST':
113 if request.method=='POST':
102 form = USRPRXImportForm(request.POST, request.FILES)
114 form = USRPRXImportForm(request.POST, request.FILES)
103 if form.is_valid():
115 if form.is_valid():
104 try:
116 try:
105 data = conf.import_from_file(request.FILES['file_name'])
117 data = conf.import_from_file(request.FILES['file_name'])
106 conf.dict_to_parms(data)
118 conf.dict_to_parms(data)
107 conf.update_pulses()
119 conf.update_pulses()
108 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
120 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
109 return redirect(conf.get_absolute_url_edit())
121 return redirect(conf.get_absolute_url_edit())
110
122
111 except Exception as e:
123 except Exception as e:
112 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
124 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
113 else:
125 else:
114 messages.warning(request, 'Your current configuration will be replaced')
126 messages.warning(request, 'Your current configuration will be replaced')
115 form = USRPRXImportForm()
127 form = USRPRXImportForm()
116
128
117 kwargs = {}
129 kwargs = {}
118 kwargs['form'] = form
130 kwargs['form'] = form
119 kwargs['title'] = 'USRP Rx Configuration'
131 kwargs['title'] = 'USRP Rx Configuration'
120 kwargs['suptitle'] = 'Import file'
132 kwargs['suptitle'] = 'Import file'
121 kwargs['button'] = 'Upload'
133 kwargs['button'] = 'Upload'
122 kwargs['previous'] = conf.get_absolute_url()
134 kwargs['previous'] = conf.get_absolute_url()
123
135
124 return render(request, 'usrp_rx_import.html', kwargs)
136 return render(request, 'usrp_rx_import.html', kwargs)
125
137
126 def conf_raw(request, conf_id):
138 def conf_raw(request, conf_id):
127 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
139 conf = get_object_or_404(USRPRXConfiguration, pk=conf_id)
128 raw = conf.write_device(raw=True)
140 raw = conf.write_device(raw=True)
129 return HttpResponse(raw, content_type='application/json') No newline at end of file
141 return HttpResponse(raw, content_type='application/json')
@@ -1,106 +1,121
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import USRPTXConfiguration, TXCode
12 from .models import USRPTXConfiguration, TXCode
13 from .forms import USRPTXConfigurationForm, USRPTXImportForm
13 from .forms import USRPTXConfigurationForm, USRPTXImportForm
14 from .validations import validation_usrp_tx_code
14 from .validations import validation_usrp_tx_code
15
15
16 def is_developer(user):
17 groups = [str(g.name) for g in user.groups.all()]
18 #return 'Developer' in groups or user.is_staff
19 return 'Developer' in groups or user.is_superuser
20
21
22 def is_operator(user):
23 groups = [str(g.name) for g in user.groups.all()]
24 #return 'Operator' in groups or user.is_staff
25 return 'Operator' in groups or user.is_superuser
26
16
27
17 def conf(request, conf_id):
28 def conf(request, conf_id):
18
29
19 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
30 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
20
31
21 kwargs = {}
32 kwargs = {}
22 kwargs['dev_conf'] = conf
33 kwargs['dev_conf'] = conf
23 if not conf.enable_2:
34 if not conf.enable_2:
24 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1',
35 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1',
25 'code_type_1', 'code_1', 'repetitions_1']
36 'code_type_1', 'code_1', 'repetitions_1']
26 else:
37 else:
27 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1',
38 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'delay', 'pulse_1',
28 'code_type_1', 'code_1', 'repetitions_1', 'pulse_2', 'code_type_2', 'code_2', 'repetitions_2']
39 'code_type_1', 'code_1', 'repetitions_1', 'pulse_2', 'code_type_2', 'code_2', 'repetitions_2']
29
40
30 kwargs['title'] = 'Configuration'
41 kwargs['title'] = 'Configuration'
31 kwargs['suptitle'] = 'Detail'
42 kwargs['suptitle'] = 'Detail'
32
43
33 kwargs['button'] = 'Edit Configuration'
44 kwargs['button'] = 'Edit Configuration'
34
45
35 conf.status_device()
46 conf.status_device()
36
47
37 ###### SIDEBAR ######
48 ###### SIDEBAR ######
38 kwargs.update(sidebar(conf=conf))
49 kwargs.update(sidebar(conf=conf))
39
50
40 return render(request, 'usrp_tx_conf.html', kwargs)
51 return render(request, 'usrp_tx_conf.html', kwargs)
41
52
42 @login_required
53 @login_required
43 def conf_edit(request, conf_id):
54 def conf_edit(request, conf_id):
44
55
45 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
56 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
46
57
58 if not is_developer(request.user):
59 messages.error(request, 'You must be an developer to edit this configuration')
60 return redirect(conf.get_absolute_url())
61
47 if request.method=='GET':
62 if request.method=='GET':
48
63
49 form = USRPTXConfigurationForm(instance=conf)
64 form = USRPTXConfigurationForm(instance=conf)
50
65
51
66
52 elif request.method=='POST':
67 elif request.method=='POST':
53
68
54 form = USRPTXConfigurationForm(request.POST, instance=conf)
69 form = USRPTXConfigurationForm(request.POST, instance=conf)
55
70
56 if form.is_valid():
71 if form.is_valid():
57
72
58 tx = form.save(commit=False)
73 tx = form.save(commit=False)
59 validation_usrp_tx_code(request, tx)
74 validation_usrp_tx_code(request, tx)
60 tx.save()
75 tx.save()
61 messages.success(request, 'USRP Tx configuration successfully updated')
76 messages.success(request, 'USRP Tx configuration successfully updated')
62 return redirect(conf.get_absolute_url())
77 return redirect(conf.get_absolute_url())
63
78
64 kwargs = {}
79 kwargs = {}
65 kwargs['dev_conf'] = conf
80 kwargs['dev_conf'] = conf
66 kwargs['form'] = form
81 kwargs['form'] = form
67 kwargs['edit'] = True
82 kwargs['edit'] = True
68
83
69 kwargs['title'] = 'USRP Tx Configuration'
84 kwargs['title'] = 'USRP Tx Configuration'
70 kwargs['suptitle'] = 'Edit'
85 kwargs['suptitle'] = 'Edit'
71 kwargs['button'] = 'Update'
86 kwargs['button'] = 'Update'
72
87
73 return render(request, 'usrp_tx_conf_edit.html', kwargs)
88 return render(request, 'usrp_tx_conf_edit.html', kwargs)
74
89
75 def import_file(request, conf_id):
90 def import_file(request, conf_id):
76
91
77 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
92 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
78 if request.method=='POST':
93 if request.method=='POST':
79 form = USRPTXImportForm(request.POST, request.FILES)
94 form = USRPTXImportForm(request.POST, request.FILES)
80 if form.is_valid():
95 if form.is_valid():
81 try:
96 try:
82 data = conf.import_from_file(request.FILES['file_name'])
97 data = conf.import_from_file(request.FILES['file_name'])
83 conf.dict_to_parms(data)
98 conf.dict_to_parms(data)
84 #conf.update_pulses()
99 #conf.update_pulses()
85 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
100 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
86 return redirect(conf.get_absolute_url_edit())
101 return redirect(conf.get_absolute_url_edit())
87
102
88 except Exception as e:
103 except Exception as e:
89 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
104 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
90 else:
105 else:
91 messages.warning(request, 'Your current configuration will be replaced')
106 messages.warning(request, 'Your current configuration will be replaced')
92 form = USRPTXImportForm()
107 form = USRPTXImportForm()
93
108
94 kwargs = {}
109 kwargs = {}
95 kwargs['form'] = form
110 kwargs['form'] = form
96 kwargs['title'] = 'USRP Tx Configuration'
111 kwargs['title'] = 'USRP Tx Configuration'
97 kwargs['suptitle'] = 'Import file'
112 kwargs['suptitle'] = 'Import file'
98 kwargs['button'] = 'Upload'
113 kwargs['button'] = 'Upload'
99 kwargs['previous'] = conf.get_absolute_url()
114 kwargs['previous'] = conf.get_absolute_url()
100
115
101 return render(request, 'usrp_tx_import.html', kwargs)
116 return render(request, 'usrp_tx_import.html', kwargs)
102
117
103 def conf_raw(request, conf_id):
118 def conf_raw(request, conf_id):
104 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
119 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
105 raw = conf.write_device(raw=True)
120 raw = conf.write_device(raw=True)
106 return HttpResponse(raw, content_type='application/json') No newline at end of file
121 return HttpResponse(raw, content_type='application/json')
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now