##// END OF EJS Templates
Se añadió y corrigió la aplicación de colores por change beam
Renato Huallpa -
r394:63661266e9fd
parent child
Show More
@@ -0,0 +1,414
1 {% extends "dev_conf.html" %} {% load static %} {% load django_bootstrap5 %} {% load main_tags %}
2 {% block extra-head %}
3 <style>
4 .abs {
5 width: auto;
6 display: inline-block;
7 text-align: center;
8 }
9
10 .abs td {
11 padding: 4px;
12 }
13
14 .module td {
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
17 border: 1px solid
18 }
19
20 .legend {
21 margin-left: 15px;
22 display: inline-block;
23 border: 2px solid;
24 vertical-align: top;
25 }
26
27 .legend th {
28 border-bottom: 1px dashed;
29 font-weight: bold;
30 vertical-align: center;
31 text-align: center;
32 }
33
34 .legend td {
35 padding: 2px;
36 text-align: center;
37 font-weight: bold;
38 }
39
40 </style>
41 {% endblock %}
42
43
44 {% block extra-menu-actions %}
45 <li>
46 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
47 <span class="far fa-image" aria-hidden="true"></span> View Patterns </a>
48 </li>
49 {% endblock %}
50
51
52 {% block extra-content %}
53 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
54 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js">
55 </script>
56
57
58 {% if beams %}
59 <h4>Beams:</h4>
60 <div class="container">
61 <ul class="nav nav-pills">
62 {% for beam in beams %}
63 <li class="nav-item">
64 <a {%if beam.pk == active_beam %} class="nav-link active" {% else %} class="nav-link" {% endif %} data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
65 </li>
66 {% endfor %}
67 </ul>
68
69 <div class="tab-content">
70 {% for beam in beams %}
71 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}in active show{% endif %}">
72 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
73 <table id="abs_pattern{{forloop.counter}}" class="abs">
74 <tr>
75 <td>
76 <b>North Quarter</b>
77 <table class="module">
78 <tr>
79 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="1" {%else%} {{color_status.1}} {%endif%}{%endif%}> {{beam.get_upvalues.0}}</span></td>
80 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="2" {%else%} {{color_status.2}} {%endif%}{%endif%}> {{beam.get_upvalues.1}}</span></td>
81 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="3" {%else%} {{color_status.3}} {%endif%}{%endif%}> {{beam.get_upvalues.2}}</span></td>
82 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="4" {%else%} {{color_status.4}} {%endif%}{%endif%}> {{beam.get_upvalues.3}}</span></td>
83 </tr>
84 <tr>
85 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="101" {%else%} {{color_status.1}} {%endif%}{%endif%}> {{beam.get_downvalues.0}}</span></td>
86 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="102" {%else%} {{color_status.2}} {%endif%}{%endif%}> {{beam.get_downvalues.1}}</span></td>
87 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="103" {%else%} {{color_status.3}} {%endif%}{%endif%}> {{beam.get_downvalues.2}}</span></td>
88 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="104" {%else%} {{color_status.4}} {%endif%}{%endif%}> {{beam.get_downvalues.3}}</span></td>
89 </tr>
90 <tr>
91 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="9" {%else%} {{color_status.9}} {%endif%}{%endif%}> {{beam.get_upvalues.8}}</span></td>
92 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="10" {%else%} {{color_status.10}} {%endif%} {%endif%}>{{beam.get_upvalues.9}}</span></td>
93 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="11" {%else%} {{color_status.11}} {%endif%} {%endif%}>{{beam.get_upvalues.10}}</span></td>
94 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="12" {%else%} {{color_status.12}} {%endif%} {%endif%}>{{beam.get_upvalues.11}}</span></td>
95 </tr>
96 <tr>
97 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="109" {%else%} {{color_status.9}} {%endif%}{%endif%}> {{beam.get_downvalues.8}}</span></td>
98 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="110" {%else%} {{color_status.10}} {%endif%} {%endif%}>{{beam.get_downvalues.9}}</span></td>
99 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="111" {%else%} {{color_status.11}} {%endif%} {%endif%}>{{beam.get_downvalues.10}}</span></td>
100 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="112" {%else%} {{color_status.12}} {%endif%} {%endif%}>{{beam.get_downvalues.11}}</span></td>
101 </tr>
102 <tr>
103 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="17" {%else%} {{color_status.17}} {%endif%} {%endif%}>{{beam.get_upvalues.16}}</span></td>
104 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="18" {%else%} {{color_status.18}} {%endif%} {%endif%}>{{beam.get_upvalues.17}}</span></td>
105 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="19" {%else%} {{color_status.19}} {%endif%} {%endif%}>{{beam.get_upvalues.18}}</span></td>
106 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="20" {%else%} {{color_status.20}} {%endif%} {%endif%}>{{beam.get_upvalues.19}}</span></td>
107 </tr>
108 <tr>
109 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="117" {%else%} {{color_status.17}} {%endif%} {%endif%}>{{beam.get_downvalues.16}}</span></td>
110 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="118" {%else%} {{color_status.18}} {%endif%} {%endif%}>{{beam.get_downvalues.17}}</span></td>
111 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="119" {%else%} {{color_status.19}} {%endif%} {%endif%}>{{beam.get_downvalues.18}}</span></td>
112 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="120" {%else%} {{color_status.20}} {%endif%} {%endif%}>{{beam.get_downvalues.19}}</span></td>
113 </tr>
114 <tr>
115 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="25" {%else%} {{color_status.25}} {%endif%} {%endif%}>{{beam.get_upvalues.24}}</span></td>
116 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="26" {%else%} {{color_status.26}} {%endif%} {%endif%}>{{beam.get_upvalues.25}}</span></td>
117 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="27" {%else%} {{color_status.27}} {%endif%} {%endif%}>{{beam.get_upvalues.26}}</span></td>
118 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="28" {%else%} {{color_status.28}} {%endif%} {%endif%}>{{beam.get_upvalues.27}}</span></td>
119 </tr>
120 <tr>
121 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="125" {%else%} {{color_status.25}} {%endif%} {%endif%}>{{beam.get_downvalues.24}}</span></td>
122 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="126" {%else%} {{color_status.26}} {%endif%} {%endif%}>{{beam.get_downvalues.25}}</span></td>
123 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="127" {%else%} {{color_status.27}} {%endif%} {%endif%}>{{beam.get_downvalues.26}}</span></td>
124 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="128" {%else%} {{color_status.28}} {%endif%} {%endif%}>{{beam.get_downvalues.27}}</span></td>
125 </tr>
126 </table>
127 </td>
128 <td>
129 <b>East Quarter</b>
130 <table class="module">
131 <tr>
132 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="5" {%else%} {{color_status.5}} {%endif%}{%endif%}> {{beam.get_upvalues.4}}</span></td>
133 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="6" {%else%} {{color_status.6}} {%endif%}{%endif%}> {{beam.get_upvalues.5}}</span></td>
134 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="7" {%else%} {{color_status.7}} {%endif%}{%endif%}> {{beam.get_upvalues.6}}</span></td>
135 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="8" {%else%} {{color_status.8}} {%endif%}{%endif%}> {{beam.get_upvalues.7}}</span></td>
136 </tr>
137 <tr>
138 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="105" {%else%} {{color_status.5}} {%endif%}{%endif%}> {{beam.get_downvalues.4}}</span></td>
139 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="106" {%else%} {{color_status.6}} {%endif%}{%endif%}> {{beam.get_downvalues.5}}</span></td>
140 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="107" {%else%} {{color_status.7}} {%endif%}{%endif%}> {{beam.get_downvalues.6}}</span></td>
141 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="108" {%else%} {{color_status.8}} {%endif%}{%endif%}> {{beam.get_downvalues.7}}</span></td>
142 </tr>
143 <tr>
144 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="13" {%else%} {{color_status.13}} {%endif%} {%endif%}>{{beam.get_upvalues.12}}</span></td>
145 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="14" {%else%} {{color_status.14}} {%endif%} {%endif%}>{{beam.get_upvalues.13}}</span></td>
146 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="15" {%else%} {{color_status.15}} {%endif%} {%endif%}>{{beam.get_upvalues.14}}</span></td>
147 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="16" {%else%} {{color_status.16}} {%endif%} {%endif%}>{{beam.get_upvalues.15}}</span></td>
148 </tr>
149 <tr>
150 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="113" {%else%} {{color_status.13}} {%endif%} {%endif%}>{{beam.get_downvalues.12}}</span></td>
151 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="114" {%else%} {{color_status.14}} {%endif%} {%endif%}>{{beam.get_downvalues.13}}</span></td>
152 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="115" {%else%} {{color_status.15}} {%endif%} {%endif%}>{{beam.get_downvalues.14}}</span></td>
153 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="116" {%else%} {{color_status.16}} {%endif%} {%endif%}>{{beam.get_downvalues.15}}</span></td>
154 </tr>
155 <tr>
156 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="21" {%else%} {{color_status.21}} {%endif%} {%endif%}>{{beam.get_upvalues.20}}</span></td>
157 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="22" {%else%} {{color_status.22}} {%endif%} {%endif%}>{{beam.get_upvalues.21}}</span></td>
158 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="23" {%else%} {{color_status.23}} {%endif%} {%endif%}>{{beam.get_upvalues.22}}</span></td>
159 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="24" {%else%} {{color_status.24}} {%endif%} {%endif%}>{{beam.get_upvalues.23}}</span></td>
160 </tr>
161 <tr>
162 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="121" {%else%} {{color_status.21}} {%endif%} {%endif%}>{{beam.get_downvalues.20}}</span></td>
163 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="122" {%else%} {{color_status.22}} {%endif%} {%endif%}>{{beam.get_downvalues.21}}</span></td>
164 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="123" {%else%} {{color_status.23}} {%endif%} {%endif%}>{{beam.get_downvalues.22}}</span></td>
165 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="124" {%else%} {{color_status.24}} {%endif%} {%endif%}>{{beam.get_downvalues.23}}</span></td>
166 </tr>
167 <tr>
168 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="29" {%else%} {{color_status.29}} {%endif%} {%endif%}>{{beam.get_upvalues.28}}</span></td>
169 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="30" {%else%} {{color_status.30}} {%endif%} {%endif%}>{{beam.get_upvalues.29}}</span></td>
170 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="31" {%else%} {{color_status.31}} {%endif%} {%endif%}>{{beam.get_upvalues.30}}</span></td>
171 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="32" {%else%} {{color_status.32}} {%endif%} {%endif%}>{{beam.get_upvalues.31}}</span></td>
172 </tr>
173 <tr>
174 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="129" {%else%} {{color_status.29}} {%endif%} {%endif%}>{{beam.get_downvalues.28}}</span></td>
175 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="130" {%else%} {{color_status.30}} {%endif%} {%endif%}>{{beam.get_downvalues.29}}</span></td>
176 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="131" {%else%} {{color_status.31}} {%endif%} {%endif%}>{{beam.get_downvalues.30}}</span></td>
177 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="132" {%else%} {{color_status.32}} {%endif%} {%endif%}>{{beam.get_downvalues.31}}</span></td>
178 </tr>
179 </table>
180 </td>
181 </tr>
182 <tr>
183 <td>
184 <b>West Quarter</b>
185 <table class="module">
186 <tr>
187 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="33" {%else%} {{color_status.33}} {%endif%} {%endif%}>{{beam.get_upvalues.32}}</span></td>
188 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="34" {%else%} {{color_status.34}} {%endif%} {%endif%}>{{beam.get_upvalues.33}}</span></td>
189 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="35" {%else%} {{color_status.35}} {%endif%} {%endif%}>{{beam.get_upvalues.34}}</span></td>
190 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="36" {%else%} {{color_status.36}} {%endif%} {%endif%}>{{beam.get_upvalues.35}}</span></td>
191 </tr>
192 <tr>
193 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="133" {%else%} {{color_status.33}} {%endif%} {%endif%}>{{beam.get_downvalues.32}}</span></td>
194 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="134" {%else%} {{color_status.34}} {%endif%} {%endif%}>{{beam.get_downvalues.33}}</span></td>
195 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="135" {%else%} {{color_status.35}} {%endif%} {%endif%}>{{beam.get_downvalues.34}}</span></td>
196 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="136" {%else%} {{color_status.36}} {%endif%} {%endif%}>{{beam.get_downvalues.35}}</span></td>
197 </tr>
198 <tr>
199 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="41" {%else%} {{color_status.41}} {%endif%} {%endif%}>{{beam.get_upvalues.40}}</span></td>
200 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="42" {%else%} {{color_status.42}} {%endif%} {%endif%}>{{beam.get_upvalues.41}}</span></td>
201 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="43" {%else%} {{color_status.43}} {%endif%} {%endif%}>{{beam.get_upvalues.42}}</span></td>
202 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="44" {%else%} {{color_status.44}} {%endif%} {%endif%}>{{beam.get_upvalues.43}}</span></td>
203 </tr>
204 <tr>
205 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="141" {%else%} {{color_status.41}} {%endif%} {%endif%}>{{beam.get_downvalues.40}}</span></td>
206 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="142" {%else%} {{color_status.42}} {%endif%} {%endif%}>{{beam.get_downvalues.41}}</span></td>
207 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="143" {%else%} {{color_status.43}} {%endif%} {%endif%}>{{beam.get_downvalues.42}}</span></td>
208 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="144" {%else%} {{color_status.44}} {%endif%} {%endif%}>{{beam.get_downvalues.43}}</span></td>
209 </tr>
210 <tr>
211 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="49" {%else%} {{color_status.49}} {%endif%} {%endif%}>{{beam.get_upvalues.48}}</span></td>
212 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="50" {%else%} {{color_status.50}} {%endif%} {%endif%}>{{beam.get_upvalues.49}}</span></td>
213 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="51" {%else%} {{color_status.51}} {%endif%} {%endif%}>{{beam.get_upvalues.50}}</span></td>
214 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="52" {%else%} {{color_status.52}} {%endif%} {%endif%}>{{beam.get_upvalues.51}}</span></td>
215 </tr>
216 <tr>
217 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="149" {%else%} {{color_status.49}} {%endif%} {%endif%}>{{beam.get_downvalues.48}}</span></td>
218 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="150" {%else%} {{color_status.50}} {%endif%} {%endif%}>{{beam.get_downvalues.49}}</span></td>
219 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="151" {%else%} {{color_status.51}} {%endif%} {%endif%}>{{beam.get_downvalues.50}}</span></td>
220 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="152" {%else%} {{color_status.52}} {%endif%} {%endif%}>{{beam.get_downvalues.51}}</span></td>
221 </tr>
222 <tr>
223 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="57" {%else%} {{color_status.57}} {%endif%} {%endif%}>{{beam.get_upvalues.56}}</span></td>
224 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="58" {%else%} {{color_status.58}} {%endif%} {%endif%}>{{beam.get_upvalues.57}}</span></td>
225 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="59" {%else%} {{color_status.59}} {%endif%} {%endif%}>{{beam.get_upvalues.58}}</span></td>
226 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="60" {%else%} {{color_status.60}} {%endif%} {%endif%}>{{beam.get_upvalues.59}}</span></td>
227 </tr>
228 <tr>
229 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="157" {%else%} {{color_status.57}} {%endif%} {%endif%}>{{beam.get_downvalues.56}}</span></td>
230 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="158" {%else%} {{color_status.58}} {%endif%} {%endif%}>{{beam.get_downvalues.57}}</span></td>
231 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="159" {%else%} {{color_status.59}} {%endif%} {%endif%}>{{beam.get_downvalues.58}}</span></td>
232 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="160" {%else%} {{color_status.60}} {%endif%} {%endif%}>{{beam.get_downvalues.59}}</span></td>
233 </tr>
234 </table>
235 </td>
236 <td>
237 <b>South Quarter</b>
238 <table class="module">
239 <tr>
240 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="37" {%else%} {{color_status.37}} {%endif%} {%endif%}>{{beam.get_upvalues.36}}</span></td>
241 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="38" {%else%} {{color_status.38}} {%endif%} {%endif%}>{{beam.get_upvalues.37}}</span></td>
242 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="39" {%else%} {{color_status.39}} {%endif%} {%endif%}>{{beam.get_upvalues.38}}</span></td>
243 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="40" {%else%} {{color_status.40}} {%endif%} {%endif%}>{{beam.get_upvalues.39}}</span></td>
244 </tr>
245 <tr>
246 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="137" {%else%} {{color_status.37}} {%endif%} {%endif%}>{{beam.get_downvalues.36}}</span></td>
247 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="138" {%else%} {{color_status.38}} {%endif%} {%endif%}>{{beam.get_downvalues.37}}</span></td>
248 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="139" {%else%} {{color_status.39}} {%endif%} {%endif%}>{{beam.get_downvalues.38}}</span></td>
249 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="140" {%else%} {{color_status.40}} {%endif%} {%endif%}>{{beam.get_downvalues.39}}</span></td>
250 </tr>
251 <tr>
252 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="45" {%else%} {{color_status.45}} {%endif%} {%endif%}>{{beam.get_upvalues.44}}</span></td>
253 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="46" {%else%} {{color_status.46}} {%endif%} {%endif%}>{{beam.get_upvalues.45}}</span></td>
254 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="47" {%else%} {{color_status.47}} {%endif%} {%endif%}>{{beam.get_upvalues.46}}</span></td>
255 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="48" {%else%} {{color_status.48}} {%endif%} {%endif%}>{{beam.get_upvalues.47}}</span></td>
256 </tr>
257 <tr>
258 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="145" {%else%} {{color_status.45}} {%endif%} {%endif%}>{{beam.get_downvalues.44}}</span></td>
259 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="146" {%else%} {{color_status.46}} {%endif%} {%endif%}>{{beam.get_downvalues.45}}</span></td>
260 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="147" {%else%} {{color_status.47}} {%endif%} {%endif%}>{{beam.get_downvalues.46}}</span></td>
261 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="148" {%else%} {{color_status.48}} {%endif%} {%endif%}>{{beam.get_downvalues.47}}</span></td>
262 </tr>
263 <tr>
264 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="53" {%else%} {{color_status.53}} {%endif%} {%endif%}>{{beam.get_upvalues.52}}</span></td>
265 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="54" {%else%} {{color_status.54}} {%endif%} {%endif%}>{{beam.get_upvalues.53}}</span></td>
266 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="55" {%else%} {{color_status.55}} {%endif%} {%endif%}>{{beam.get_upvalues.54}}</span></td>
267 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="56" {%else%} {{color_status.56}} {%endif%} {%endif%}>{{beam.get_upvalues.55}}</span></td>
268 </tr>
269 <tr>
270 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="153" {%else%} {{color_status.53}} {%endif%} {%endif%}>{{beam.get_downvalues.52}}</span></td>
271 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="154" {%else%} {{color_status.54}} {%endif%} {%endif%}>{{beam.get_downvalues.53}}</span></td>
272 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="155" {%else%} {{color_status.55}} {%endif%} {%endif%}>{{beam.get_downvalues.54}}</span></td>
273 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="156" {%else%} {{color_status.56}} {%endif%} {%endif%}>{{beam.get_downvalues.55}}</span></td>
274 </tr>
275 <tr>
276 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="61" {%else%} {{color_status.61}} {%endif%} {%endif%}>{{beam.get_upvalues.60}}</span></td>
277 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="62" {%else%} {{color_status.62}} {%endif%} {%endif%}>{{beam.get_upvalues.61}}</span></td>
278 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="63" {%else%} {{color_status.63}} {%endif%} {%endif%}>{{beam.get_upvalues.62}}</span></td>
279 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="64" {%else%} {{color_status.64}} {%endif%} {%endif%}>{{beam.get_upvalues.63}}</span></td>
280 </tr>
281 <tr>
282 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="161" {%else%} {{color_status.61}} {%endif%} {%endif%}>{{beam.get_downvalues.60}}</span></td>
283 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="162" {%else%} {{color_status.62}} {%endif%} {%endif%}>{{beam.get_downvalues.61}}</span></td>
284 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="163" {%else%} {{color_status.63}} {%endif%} {%endif%}>{{beam.get_downvalues.62}}</span></td>
285 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="164" {%else%} {{color_status.64}} {%endif%} {%endif%}>{{beam.get_downvalues.63}}</span></td>
286 </tr>
287 </table>
288 </td>
289 </tr>
290 </table>
291
292 <!-- <meta id="configuraciones_down" data-playlist="{{ beam.get_downvalues }}">
293 <meta id="configuraciones_up" data-playlist="{{ beam.get_upvalues }}">
294 <meta id="sda" data-toggle="" -->
295
296 {% if beam.id == active_beam %}
297 <table class="legend">
298 <tr>
299 <th>Legend</th>
300 </tr>
301 <tr>
302 <td class="text-warning">Connected</td>
303 </tr>
304 <tr>
305 <td class="text-success">Running</td>
306 </tr>
307 <tr>
308 <td class="text-info">Mismath</td>
309 </tr>
310 <tr>
311 <td class="text-danger">Disconnected</td>
312 </tr>
313 </table>
314 {% else %}
315 <div style="vertical-align: top; display:inline-block;">
316 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
317 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
318 Change Beam</button>
319 <br><br><br>
320 <button id="change_beam_mqtt{{forloop.counter}}" type="button" class="btn btn-default">
321 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
322 Change Beam MQTT</button>
323 </div>
324 {% endif %}
325 </div>
326 {% endfor %}
327 </div>
328 </div>
329
330
331 {% else %}
332 <p style="color:#b4bcc2; margin-left: 5%;">
333 <i>No Beams...</i>
334 </p>
335 {% endif %}
336 {% endblock extra-content %}
337
338 {% block extra-js%}
339 <script>
340 $(document).ready(function () {
341
342 var socket = io.connect('http://' + document.domain + ':' + location.port);
343
344 socket.on('connect', function(data) {
345 console.log('Connecting... OK');
346 })
347
348 socket.on('abs_ws', function(data) {
349 console.log('ingresamos');
350 console.log(data.msg);
351 var text = data['msg'];
352 // $('#chatLog').val(text);
353
354 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
355 })
356
357 socket.on('beams_ack', function(data) {
358 // console.log('beams_ack');
359 var text = data['msg'];
360
361 for (let i=1; i<=64;i++){
362
363 var elemento = document.getElementById(text[i-1]);
364 var elemento2 = document.getElementById(text[i-1]+100);
365 if (text[i-1]<=64){
366 // console.log("1")
367 // elemento=document.getElementById(text[i-1]);
368 elemento.style.color="green";
369 elemento.style.fontWeight = "bold";
370 elemento2.style.color="green";
371 elemento2.style.fontWeight = "bold";}
372 else if (text[i-1]>64){
373 elemento=document.getElementById(text[i-1]-64);
374 elemento2=document.getElementById(text[i-1]-64+100);
375 elemento.style.color="blue";
376 elemento.style.fontWeight = "bold";
377 elemento2.style.color="blue";
378 elemento2.style.fontWeight = "bold"}
379 else {
380 elemento.style.color="red";
381 elemento.style.fontWeight = "bold";
382 elemento2.style.color="red";
383 elemento2.style.fontWeight = "bold"}
384 }
385 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
386 })
387
388
389 {% for beam in beams %}
390
391 {% if dev_conf.operation_mode == 1 %}
392 $("#send_beam{{forloop.counter}}").prop('disabled', true)
393 $("#change_beam_mqtt{{forloop.counter}}").prop('disabled', true)
394 {% else %}
395 $("#send_beam{{forloop.counter}}").click(function () {
396 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
397 });
398
399 change_beam_mqtt_btn=$("#change_beam_mqtt{{forloop.counter}}")
400 change_beam_mqtt_btn.click(function () {
401 document.location = "{% url 'url_change_beam_mqtt' dev_conf.id beam.id %}";
402 });
403
404 {% endif %}
405
406 {% endfor %}
407
408
409 });
410
411 </script>
412
413
414 {% endblock %}
@@ -1,1190 +1,1190
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration , User
2 from apps.main.models import Configuration , User
3 from django.urls import reverse
3 from django.urls import reverse
4 from celery.execute import send_task
4 from celery.execute import send_task
5 from datetime import datetime
5 from datetime import datetime
6 import ast
6 import ast
7 import socket
7 import socket
8 import json
8 import json
9 import requests
9 import requests
10 import struct
10 import struct
11 import os, sys, time
11 import os, sys, time
12
12
13 from .mqtt import client as mqtt_client
13 from .mqtt import client as mqtt_client
14 from radarsys.socketconfig import sio as sio
14 from radarsys.socketconfig import sio as sio
15 import json
15 import json
16
16
17 antenna_default = json.dumps({
17 antenna_default = json.dumps({
18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 ]
26 ]
27 ,
27 ,
28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 })
36 })
37
37
38
38
39 tx_default = json.dumps({
39 tx_default = json.dumps({
40 "up": [[1,1,1,1,0,0,0,0],
40 "up": [[1,1,1,1,0,0,0,0],
41 [1,1,1,1,0,0,0,0],
41 [1,1,1,1,0,0,0,0],
42 [1,1,1,1,0,0,0,0],
42 [1,1,1,1,0,0,0,0],
43 [1,1,1,1,0,0,0,0],
43 [1,1,1,1,0,0,0,0],
44 [0,0,0,0,1,1,1,1],
44 [0,0,0,0,1,1,1,1],
45 [0,0,0,0,1,1,1,1],
45 [0,0,0,0,1,1,1,1],
46 [0,0,0,0,1,1,1,1],
46 [0,0,0,0,1,1,1,1],
47 [0,0,0,0,1,1,1,1]],
47 [0,0,0,0,1,1,1,1]],
48
48
49 "down": [[1,1,1,1,0,0,0,0],
49 "down": [[1,1,1,1,0,0,0,0],
50 [1,1,1,1,0,0,0,0],
50 [1,1,1,1,0,0,0,0],
51 [1,1,1,1,0,0,0,0],
51 [1,1,1,1,0,0,0,0],
52 [1,1,1,1,0,0,0,0],
52 [1,1,1,1,0,0,0,0],
53 [0,0,0,0,1,1,1,1],
53 [0,0,0,0,1,1,1,1],
54 [0,0,0,0,1,1,1,1],
54 [0,0,0,0,1,1,1,1],
55 [0,0,0,0,1,1,1,1],
55 [0,0,0,0,1,1,1,1],
56 [0,0,0,0,1,1,1,1]],
56 [0,0,0,0,1,1,1,1]],
57 })
57 })
58
58
59 rx_default = json.dumps({
59 rx_default = json.dumps({
60 "up": [[1,1,1,1,0,0,0,0],
60 "up": [[1,1,1,1,0,0,0,0],
61 [1,1,1,1,0,0,0,0],
61 [1,1,1,1,0,0,0,0],
62 [1,1,1,1,0,0,0,0],
62 [1,1,1,1,0,0,0,0],
63 [1,1,1,1,0,0,0,0],
63 [1,1,1,1,0,0,0,0],
64 [0,0,0,0,1,1,1,1],
64 [0,0,0,0,1,1,1,1],
65 [0,0,0,0,1,1,1,1],
65 [0,0,0,0,1,1,1,1],
66 [0,0,0,0,1,1,1,1],
66 [0,0,0,0,1,1,1,1],
67 [0,0,0,0,1,1,1,1]],
67 [0,0,0,0,1,1,1,1]],
68
68
69 "down": [[1,1,1,1,0,0,0,0],
69 "down": [[1,1,1,1,0,0,0,0],
70 [1,1,1,1,0,0,0,0],
70 [1,1,1,1,0,0,0,0],
71 [1,1,1,1,0,0,0,0],
71 [1,1,1,1,0,0,0,0],
72 [1,1,1,1,0,0,0,0],
72 [1,1,1,1,0,0,0,0],
73 [0,0,0,0,1,1,1,1],
73 [0,0,0,0,1,1,1,1],
74 [0,0,0,0,1,1,1,1],
74 [0,0,0,0,1,1,1,1],
75 [0,0,0,0,1,1,1,1],
75 [0,0,0,0,1,1,1,1],
76 [0,0,0,0,1,1,1,1]],
76 [0,0,0,0,1,1,1,1]],
77 })
77 })
78
78
79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 default_messages = {}
80 default_messages = {}
81
81
82 for i in range(1,65):
82 for i in range(1,65):
83 default_messages[str(i)] = "Module "+str(i)
83 default_messages[str(i)] = "Module "+str(i)
84
84
85
85
86 ues_default = json.dumps({
86 ues_default = json.dumps({
87 "up": [0.533333,0.00000,1.06667,0.00000],
87 "up": [0.533333,0.00000,1.06667,0.00000],
88 "down": [0.533333,0.00000,1.06667,0.00000]
88 "down": [0.533333,0.00000,1.06667,0.00000]
89 })
89 })
90
90
91 onlyrx_default = json.dumps({
91 onlyrx_default = json.dumps({
92 "up": False,
92 "up": False,
93 "down": False
93 "down": False
94 })
94 })
95
95
96 def up_convertion(cadena):
96 def up_convertion(cadena):
97 valores = []
97 valores = []
98 for c in cadena:
98 for c in cadena:
99 if c == 1.0: valores=valores+['000']
99 if c == 1.0: valores=valores+['000']
100 if c == 2.0: valores=valores+['001']
100 if c == 2.0: valores=valores+['001']
101 if c == 3.0: valores=valores+['010']
101 if c == 3.0: valores=valores+['010']
102 if c == 0.0: valores=valores+['011']
102 if c == 0.0: valores=valores+['011']
103 if c == 0.5: valores=valores+['100']
103 if c == 0.5: valores=valores+['100']
104 if c == 1.5: valores=valores+['101']
104 if c == 1.5: valores=valores+['101']
105 if c == 2.5: valores=valores+['110']
105 if c == 2.5: valores=valores+['110']
106 if c == 3.5: valores=valores+['111']
106 if c == 3.5: valores=valores+['111']
107
107
108 return valores
108 return valores
109
109
110 def up_conv_bits(value):
110 def up_conv_bits(value):
111
111
112 if value == 1.0: bits="000"
112 if value == 1.0: bits="000"
113 if value == 2.0: bits="001"
113 if value == 2.0: bits="001"
114 if value == 3.0: bits="010"
114 if value == 3.0: bits="010"
115 if value == 0.0: bits="011"
115 if value == 0.0: bits="011"
116 if value == 0.5: bits="100"
116 if value == 0.5: bits="100"
117 if value == 1.5: bits="101"
117 if value == 1.5: bits="101"
118 if value == 2.5: bits="110"
118 if value == 2.5: bits="110"
119 if value == 3.5: bits="111"
119 if value == 3.5: bits="111"
120
120
121 return bits
121 return bits
122
122
123 def down_convertion(cadena):
123 def down_convertion(cadena):
124 valores = []
124 valores = []
125 for c in cadena:
125 for c in cadena:
126 if c == 1.0: valores=valores+['000']
126 if c == 1.0: valores=valores+['000']
127 if c == 2.0: valores=valores+['001']
127 if c == 2.0: valores=valores+['001']
128 if c == 3.0: valores=valores+['010']
128 if c == 3.0: valores=valores+['010']
129 if c == 0.0: valores=valores+['011']
129 if c == 0.0: valores=valores+['011']
130 if c == 0.5: valores=valores+['100']
130 if c == 0.5: valores=valores+['100']
131 if c == 1.5: valores=valores+['101']
131 if c == 1.5: valores=valores+['101']
132 if c == 2.5: valores=valores+['110']
132 if c == 2.5: valores=valores+['110']
133 if c == 3.5: valores=valores+['111']
133 if c == 3.5: valores=valores+['111']
134
134
135 return valores
135 return valores
136
136
137 def down_conv_bits(value):
137 def down_conv_bits(value):
138
138
139 if value == 1.0: bits="000"
139 if value == 1.0: bits="000"
140 if value == 2.0: bits="001"
140 if value == 2.0: bits="001"
141 if value == 3.0: bits="010"
141 if value == 3.0: bits="010"
142 if value == 0.0: bits="011"
142 if value == 0.0: bits="011"
143 if value == 0.5: bits="100"
143 if value == 0.5: bits="100"
144 if value == 1.5: bits="101"
144 if value == 1.5: bits="101"
145 if value == 2.5: bits="110"
145 if value == 2.5: bits="110"
146 if value == 3.5: bits="111"
146 if value == 3.5: bits="111"
147
147
148 return bits
148 return bits
149
149
150 def up_conv_value(bits):
150 def up_conv_value(bits):
151
151
152 if bits == "000": value=1.0
152 if bits == "000": value=1.0
153 if bits == "001": value=2.0
153 if bits == "001": value=2.0
154 if bits == "010": value=3.0
154 if bits == "010": value=3.0
155 if bits == "011": value=0.0
155 if bits == "011": value=0.0
156 if bits == "100": value=0.5
156 if bits == "100": value=0.5
157 if bits == "101": value=1.5
157 if bits == "101": value=1.5
158 if bits == "110": value=2.5
158 if bits == "110": value=2.5
159 if bits == "111": value=3.5
159 if bits == "111": value=3.5
160
160
161 return value
161 return value
162
162
163 def down_conv_value(bits):
163 def down_conv_value(bits):
164
164
165 if bits == "000": value=1.0
165 if bits == "000": value=1.0
166 if bits == "001": value=2.0
166 if bits == "001": value=2.0
167 if bits == "010": value=3.0
167 if bits == "010": value=3.0
168 if bits == "011": value=0.0
168 if bits == "011": value=0.0
169 if bits == "100": value=0.5
169 if bits == "100": value=0.5
170 if bits == "101": value=1.5
170 if bits == "101": value=1.5
171 if bits == "110": value=2.5
171 if bits == "110": value=2.5
172 if bits == "111": value=3.5
172 if bits == "111": value=3.5
173
173
174 return value
174 return value
175
175
176 def ip2position(module_number):
176 def ip2position(module_number):
177 j=0
177 j=0
178 i=0
178 i=0
179 for x in range(0,module_number-1):
179 for x in range(0,module_number-1):
180 j=j+1
180 j=j+1
181 if j==8:
181 if j==8:
182 i=i+1
182 i=i+1
183 j=0
183 j=0
184
184
185 pos = [i,j]
185 pos = [i,j]
186 return pos
186 return pos
187
187
188
188
189 def fromBinary2Char(binary_string):
189 def fromBinary2Char(binary_string):
190 number = int(binary_string, 2)
190 number = int(binary_string, 2)
191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 number = number + 33
192 number = number + 33
193 char = chr(number)
193 char = chr(number)
194 return char
194 return char
195
195
196 def fromChar2Binary(char):
196 def fromChar2Binary(char):
197 number = ord(char) - 33
197 number = ord(char) - 33
198 #Minus 33 to get the real value
198 #Minus 33 to get the real value
199 bits = bin(number)[2:]
199 bits = bin(number)[2:]
200 #To ensure we have a string with 6bits
200 #To ensure we have a string with 6bits
201 if len(bits) < 6:
201 if len(bits) < 6:
202 bits = bits.zfill(6)
202 bits = bits.zfill(6)
203 return bits
203 return bits
204
204
205 OPERATION_MODES = (
205 OPERATION_MODES = (
206 (0, 'Manual'),
206 (0, 'Manual'),
207 (1, 'Automatic'),
207 (1, 'Automatic'),
208 )
208 )
209
209
210 class ABSConfiguration(Configuration):
210 class ABSConfiguration(Configuration):
211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
216
216
217 class Meta:
217 class Meta:
218 db_table = 'abs_configurations'
218 db_table = 'abs_configurations'
219
219
220 def get_absolute_url_plot(self):
220 def get_absolute_url_plot(self):
221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
222
222
223
223
224 def parms_to_dict(self):
224 def parms_to_dict(self):
225
225
226 parameters = {}
226 parameters = {}
227
227
228 parameters['device_id'] = self.device.id
228 parameters['device_id'] = self.device.id
229 parameters['label'] = self.label
229 parameters['label'] = self.label
230 parameters['device_type'] = self.device.device_type.name
230 parameters['device_type'] = self.device.device_type.name
231 parameters['beams'] = {}
231 parameters['beams'] = {}
232
232
233 beams = ABSBeam.objects.filter(abs_conf=self)
233 beams = ABSBeam.objects.filter(abs_conf=self)
234 b=1
234 b=1
235 for beam in beams:
235 for beam in beams:
236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
238 b+=1
238 b+=1
239
239
240 return parameters
240 return parameters
241
241
242
242
243 def dict_to_parms(self, parameters):
243 def dict_to_parms(self, parameters):
244
244
245 self.label = parameters['label']
245 self.label = parameters['label']
246
246
247 absbeams = ABSBeam.objects.filter(abs_conf=self)
247 absbeams = ABSBeam.objects.filter(abs_conf=self)
248 beams = parameters['beams']
248 beams = parameters['beams']
249
249
250 if absbeams:
250 if absbeams:
251 beams_number = len(beams)
251 beams_number = len(beams)
252 absbeams_number = len(absbeams)
252 absbeams_number = len(absbeams)
253 if beams_number==absbeams_number:
253 if beams_number==absbeams_number:
254 i = 1
254 i = 1
255 for absbeam in absbeams:
255 for absbeam in absbeams:
256 absbeam.dict_to_parms(beams['beam'+str(i)])
256 absbeam.dict_to_parms(beams['beam'+str(i)])
257 i = i+1
257 i = i+1
258 elif beams_number > absbeams_number:
258 elif beams_number > absbeams_number:
259 i = 1
259 i = 1
260 for absbeam in absbeams:
260 for absbeam in absbeams:
261 absbeam.dict_to_parms(beams['beam'+str(i)])
261 absbeam.dict_to_parms(beams['beam'+str(i)])
262 i=i+1
262 i=i+1
263 for x in range(i,beams_number+1):
263 for x in range(i,beams_number+1):
264 new_beam = ABSBeam(
264 new_beam = ABSBeam(
265 name =beams['beam'+str(i)]['name'],
265 name =beams['beam'+str(i)]['name'],
266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
267 abs_conf = self,
267 abs_conf = self,
268 tx =json.dumps(beams['beam'+str(i)]['tx']),
268 tx =json.dumps(beams['beam'+str(i)]['tx']),
269 rx =json.dumps(beams['beam'+str(i)]['rx']),
269 rx =json.dumps(beams['beam'+str(i)]['rx']),
270 ues =json.dumps(beams['beam'+str(i)]['ues']),
270 ues =json.dumps(beams['beam'+str(i)]['ues']),
271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
272 )
272 )
273 new_beam.save()
273 new_beam.save()
274 i=i+1
274 i=i+1
275 else: #beams_number < absbeams_number:
275 else: #beams_number < absbeams_number:
276 i = 1
276 i = 1
277 for absbeam in absbeams:
277 for absbeam in absbeams:
278 if i <= beams_number:
278 if i <= beams_number:
279 absbeam.dict_to_parms(beams['beam'+str(i)])
279 absbeam.dict_to_parms(beams['beam'+str(i)])
280 i=i+1
280 i=i+1
281 else:
281 else:
282 absbeam.delete()
282 absbeam.delete()
283 else:
283 else:
284 for beam in beams:
284 for beam in beams:
285 new_beam = ABSBeam(
285 new_beam = ABSBeam(
286 name =beams[beam]['name'],
286 name =beams[beam]['name'],
287 antenna =json.dumps(beams[beam]['antenna']),
287 antenna =json.dumps(beams[beam]['antenna']),
288 abs_conf = self,
288 abs_conf = self,
289 tx =json.dumps(beams[beam]['tx']),
289 tx =json.dumps(beams[beam]['tx']),
290 rx =json.dumps(beams[beam]['rx']),
290 rx =json.dumps(beams[beam]['rx']),
291 ues =json.dumps(beams[beam]['ues']),
291 ues =json.dumps(beams[beam]['ues']),
292 only_rx =json.dumps(beams[beam]['only_rx'])
292 only_rx =json.dumps(beams[beam]['only_rx'])
293 )
293 )
294 new_beam.save()
294 new_beam.save()
295
295
296
296
297
297
298 def update_from_file(self, parameters):
298 def update_from_file(self, parameters):
299
299
300 self.dict_to_parms(parameters)
300 self.dict_to_parms(parameters)
301 self.save()
301 self.save()
302
302
303
303
304 def get_beams(self, **kwargs):
304 def get_beams(self, **kwargs):
305 '''
305 '''
306 This function returns ABS Configuration beams
306 This function returns ABS Configuration beams
307 '''
307 '''
308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
309
309
310 def clone(self, **kwargs):
310 def clone(self, **kwargs):
311
311
312 beams = self.get_beams()
312 beams = self.get_beams()
313 self.pk = None
313 self.pk = None
314 self.id = None
314 self.id = None
315 for attr, value in kwargs.items():
315 for attr, value in kwargs.items():
316 setattr(self, attr, value)
316 setattr(self, attr, value)
317 self.save()
317 self.save()
318
318
319 for beam in beams:
319 for beam in beams:
320 beam.clone(abs_conf=self)
320 beam.clone(abs_conf=self)
321
321
322 #-----For Active Beam-----
322 #-----For Active Beam-----
323 new_beams = ABSBeam.objects.filter(abs_conf=self)
323 new_beams = ABSBeam.objects.filter(abs_conf=self)
324 self.active_beam = new_beams[0].id
324 self.active_beam = new_beams[0].id
325 self.save()
325 self.save()
326 #-----For Active Beam-----
326 #-----For Active Beam-----
327 #-----For Device Status---
327 #-----For Device Status---
328 self.device.status = 3
328 self.device.status = 3
329 self.device.save()
329 self.device.save()
330 #-----For Device Status---
330 #-----For Device Status---
331
331
332 return self
332 return self
333
333
334
334
335 def start_device(self):
335 def start_device(self):
336
336
337 if self.device.status == 3:
337 if self.device.status == 3:
338
338
339 try:
339 try:
340 #self.write_device()
340 #self.write_device()
341 send_task('task_change_beam', [self.id],)
341 send_task('task_change_beam', [self.id],)
342 # print("*************************RUNNING ABS**************************",flush=True)
342 # print("*************************RUNNING ABS**************************",flush=True)
343 self.message = 'ABS running'
343 self.message = 'ABS running'
344
344
345 except Exception as e:
345 except Exception as e:
346 self.message = str(e)
346 self.message = str(e)
347 return False
347 return False
348
348
349 return True
349 return True
350
350
351 else:
351 else:
352 self.message = 'Please, select Write ABS Device first.'
352 self.message = 'Please, select Write ABS Device first.'
353 return False
353 return False
354
354
355
355
356 def stop_device(self):
356 def stop_device(self):
357 self.device.status = 2
357 self.device.status = 2
358 self.active_beam = 0
358 self.active_beam = 0
359 self.device.save()
359 self.device.save()
360 self.message = 'ABS has been stopped.'
360 self.message = 'ABS has been stopped.'
361 self.save()
361 self.save()
362
362
363 return True
363 return True
364
364
365 def stop_device_mqtt(self):
365 def stop_device_mqtt(self):
366
366
367 self.device.status = 2
367 self.device.status = 2
368 self.active_beam = 0
368 self.active_beam = 0
369 # conf_active = None
369 # conf_active = None
370 # conf_active.save()
370 # conf_active.save()
371 self.device.save()
371 self.device.save()
372 self.message = 'ABS has been stopped.'
372 self.message = 'ABS has been stopped.'
373 self.save()
373 self.save()
374
374
375 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
375 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
376
376
377 return True
377 return True
378
378
379 def write_device(self):
379 def write_device(self):
380
380
381 """
381 """
382 This function sends the beams list to every abs module.
382 This function sends the beams list to every abs module.
383 It needs 'module_conf' function
383 It needs 'module_conf' function
384 """
384 """
385
385
386 beams = ABSBeam.objects.filter(abs_conf=self)
386 beams = ABSBeam.objects.filter(abs_conf=self)
387 nbeams = len(beams)
387 nbeams = len(beams)
388
388
389 # Se manda a cero RC para poder realizar cambio de beam
389 # Se manda a cero RC para poder realizar cambio de beam
390 if self.experiment is None:
390 if self.experiment is None:
391 confs = []
391 confs = []
392 else:
392 else:
393 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
393 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
394 confdds = ''
394 confdds = ''
395 confjars = ''
395 confjars = ''
396 confrc = ''
396 confrc = ''
397 #TO STOP DEVICES: DDS-JARS-RC
397 #TO STOP DEVICES: DDS-JARS-RC
398 for i in range(0,len(confs)):
398 for i in range(0,len(confs)):
399 if i==0:
399 if i==0:
400 for conf in confs:
400 for conf in confs:
401 if conf.device.device_type.name == 'dds':
401 if conf.device.device_type.name == 'dds':
402 confdds = conf
402 confdds = conf
403 confdds.stop_device()
403 confdds.stop_device()
404 break
404 break
405 if i==1:
405 if i==1:
406 for conf in confs:
406 for conf in confs:
407 if conf.device.device_type.name == 'jars':
407 if conf.device.device_type.name == 'jars':
408 confjars = conf
408 confjars = conf
409 confjars.stop_device()
409 confjars.stop_device()
410 break
410 break
411 if i==2:
411 if i==2:
412 for conf in confs:
412 for conf in confs:
413 if conf.device.device_type.name == 'rc':
413 if conf.device.device_type.name == 'rc':
414 confrc = conf
414 confrc = conf
415 confrc.stop_device()
415 confrc.stop_device()
416 break
416 break
417
417
418 '''
418 '''
419 if self.connected_modules() == 0 :
419 if self.connected_modules() == 0 :
420 print("No encuentra modulos")
420 print("No encuentra modulos")
421 self.message = "No ABS Module detected."
421 self.message = "No ABS Module detected."
422 return False
422 return False
423 '''
423 '''
424 #-------------Write each abs module-----------
424 #-------------Write each abs module-----------
425
425
426 if beams:
426 if beams:
427 block_id = 0
427 block_id = 0
428 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
428 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
429 for i, status in enumerate(self.module_status):
429 for i, status in enumerate(self.module_status):
430 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
430 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
431 status = ['0'] * 64
431 status = ['0'] * 64
432 n = 0
432 n = 0
433 print("Estoy en write_device normal",flush=True)
433 print("Estoy en write_device normal",flush=True)
434 sock = self.send_multicast(message)
434 sock = self.send_multicast(message)
435
435
436 while True:
436 while True:
437 #for i in range(32):
437 #for i in range(32):
438 try:
438 try:
439 data, address = sock.recvfrom(1024)
439 data, address = sock.recvfrom(1024)
440 print (address, data)
440 print (address, data)
441 data = data.decode("utf-8")
441 data = data.decode("utf-8")
442 if data == '1':
442 if data == '1':
443 status[int(address[0][10:])-1] = '3'
443 status[int(address[0][10:])-1] = '3'
444 #print (int(address[0][10:])-1)
444 #print (int(address[0][10:])-1)
445 elif data == '0':
445 elif data == '0':
446 status[int(address[0][10:])-1] = '1'
446 status[int(address[0][10:])-1] = '1'
447 except socket.timeout:
447 except socket.timeout:
448 print('Timeout')
448 print('Timeout')
449 break
449 break
450 except Exception as e:
450 except Exception as e:
451 print ('Error {}'.format(e))
451 print ('Error {}'.format(e))
452 n += 1
452 n += 1
453 sock.close()
453 sock.close()
454 else:
454 else:
455 self.message = "ABS Configuration does not have beams"
455 self.message = "ABS Configuration does not have beams"
456 # print('No beams')
456 # print('No beams')
457 #Start DDS-RC-JARS
457 #Start DDS-RC-JARS
458 if confdds:
458 if confdds:
459 confdds.start_device()
459 confdds.start_device()
460 if confrc:
460 if confrc:
461 #print confrc
461 #print confrc
462 confrc.start_device()
462 confrc.start_device()
463 if confjars:
463 if confjars:
464 confjars.start_device()
464 confjars.start_device()
465 return False
465 return False
466
466
467 if n == 64:
467 if n == 64:
468 self.message = "Could not write ABS Modules"
468 self.message = "Could not write ABS Modules"
469 self.device.status = 0
469 self.device.status = 0
470 self.module_status = ''.join(status)
470 self.module_status = ''.join(status)
471 self.save()
471 self.save()
472 # print('Could not write ABS')
472 # print('Could not write ABS')
473 #Start DDS-RC-JARS
473 #Start DDS-RC-JARS
474 if confdds:
474 if confdds:
475 confdds.start_device()
475 confdds.start_device()
476 if confrc:
476 if confrc:
477 #print confrc
477 #print confrc
478 confrc.start_device()
478 confrc.start_device()
479 if confjars:
479 if confjars:
480 confjars.start_device()
480 confjars.start_device()
481 return False
481 return False
482 else:
482 else:
483 self.message = "ABS Beams List have been sent to ABS Modules"
483 self.message = "ABS Beams List have been sent to ABS Modules"
484 print('ABS beams list sent')
484 print('ABS beams list sent')
485 self.active_beam = beams[0].pk
485 self.active_beam = beams[0].pk
486
486
487 #Start DDS-RC-JARS
487 #Start DDS-RC-JARS
488 if confdds:
488 if confdds:
489 confdds.start_device()
489 confdds.start_device()
490 if confrc:
490 if confrc:
491 #print confrc
491 #print confrc
492 confrc.start_device()
492 confrc.start_device()
493 if confjars:
493 if confjars:
494 confjars.start_device()
494 confjars.start_device()
495
495
496 # print('Inicia intento de salvar device.status')
496 # print('Inicia intento de salvar device.status')
497 self.device.status = 3
497 self.device.status = 3
498 self.module_status = ''.join(status)
498 self.module_status = ''.join(status)
499 #print(status)
499 #print(status)
500 self.save()
500 self.save()
501 # print('Estatus salvado')
501 # print('Estatus salvado')
502 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
502 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
503 conf_active.conf = self
503 conf_active.conf = self
504 conf_active.save()
504 conf_active.save()
505 return True
505 return True
506
506
507
507
508 # DEV_STATES = (
508 # DEV_STATES = (
509 # (0, 'No connected'),
509 # (0, 'No connected'),
510 # (1, 'Connected'),
510 # (1, 'Connected'),
511 # (2, 'Configured'),
511 # (2, 'Configured'),
512 # (3, 'Running'),
512 # (3, 'Running'),
513 # (4, 'Unknown'),
513 # (4, 'Unknown'),
514 # (5, 'Busy')
514 # (5, 'Busy')
515 # )
515 # )
516
516
517 def write_device_mqtt(self):
517 def write_device_mqtt(self):
518
518
519 if self.experiment is None:
519 if self.experiment is None:
520 confs = []
520 confs = []
521 else:
521 else:
522 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
522 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
523 confdds = ''
523 confdds = ''
524 confjars = ''
524 confjars = ''
525 confrc = ''
525 confrc = ''
526 #TO STOP DEVICES: DDS-JARS-RC
526 #TO STOP DEVICES: DDS-JARS-RC
527 for i in range(0,len(confs)):
527 for i in range(0,len(confs)):
528 if i==0:
528 if i==0:
529 for conf in confs:
529 for conf in confs:
530 if conf.device.device_type.name == 'dds':
530 if conf.device.device_type.name == 'dds':
531 confdds = conf
531 confdds = conf
532 confdds.stop_device()
532 confdds.stop_device()
533 break
533 break
534 if i==1:
534 if i==1:
535 for conf in confs:
535 for conf in confs:
536 if conf.device.device_type.name == 'jars':
536 if conf.device.device_type.name == 'jars':
537 confjars = conf
537 confjars = conf
538 confjars.stop_device()
538 confjars.stop_device()
539 break
539 break
540 if i==2:
540 if i==2:
541 for conf in confs:
541 for conf in confs:
542 if conf.device.device_type.name == 'rc':
542 if conf.device.device_type.name == 'rc':
543 confrc = conf
543 confrc = conf
544 confrc.stop_device()
544 confrc.stop_device()
545 break
545 break
546
546
547 apuntes_up_down=''
547 apuntes_up_down=''
548 beams = ABSBeam.objects.filter(abs_conf=self)
548 beams = ABSBeam.objects.filter(abs_conf=self)
549
549
550 inicializacion="{\"beams\":["
550 inicializacion="{\"beams\":["
551 finalizacion="]}"
551 finalizacion="]}"
552
552
553 for beam in beams:
553 for beam in beams:
554 beam.antenna=beam.antenna[1:]
554 beam.antenna=beam.antenna[1:]
555 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
555 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
556 apuntes_up_down=apuntes_up_down+info
556 apuntes_up_down=apuntes_up_down+info
557
557
558 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
558 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
559 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
559 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
560 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
560 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
561
561
562 self.active_beam = beams[0].pk
562 self.active_beam = beams[0].pk
563
563
564 #Start DDS-RC-JARS
564 #Start DDS-RC-JARS
565 if confdds:
565 if confdds:
566 confdds.start_device()
566 confdds.start_device()
567 if confrc:
567 if confrc:
568 #print confrc
568 #print confrc
569 confrc.start_device()
569 confrc.start_device()
570 if confjars:
570 if confjars:
571 confjars.start_device()
571 confjars.start_device()
572
572
573 self.device.status = 3
573 self.device.status = 3
574 self.save()
574 self.save()
575
575
576 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
576 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
577 conf_active.conf = self
577 conf_active.conf = self
578 conf_active.save()
578 conf_active.save()
579 return True
579 return True
580
580
581 def read_module(self, module):
581 def read_module(self, module):
582
582
583 """
583 """
584 Read out-bits (up-down) of 1 abs module NOT for Configuration
584 Read out-bits (up-down) of 1 abs module NOT for Configuration
585 """
585 """
586
586
587 ip_address = self.device.ip_address
587 ip_address = self.device.ip_address
588 ip_address = ip_address.split('.')
588 ip_address = ip_address.split('.')
589 module_seq = (ip_address[0],ip_address[1],ip_address[2])
589 module_seq = (ip_address[0],ip_address[1],ip_address[2])
590 dot = '.'
590 dot = '.'
591 module_ip = dot.join(module_seq)+'.'+str(module)
591 module_ip = dot.join(module_seq)+'.'+str(module)
592 module_port = self.device.port_address
592 module_port = self.device.port_address
593 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
593 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
594
594
595 module_status = json.loads(self.module_status)
595 module_status = json.loads(self.module_status)
596 print(read_route)
596 print(read_route)
597
597
598 module_bits = ''
598 module_bits = ''
599
599
600 try:
600 try:
601 r_read = requests.get(read_route, timeout=0.5)
601 r_read = requests.get(read_route, timeout=0.5)
602 answer = r_read.json()
602 answer = r_read.json()
603 module_bits = answer['allbits']
603 module_bits = answer['allbits']
604 except:
604 except:
605 return {}
605 return {}
606
606
607 return module_bits
607 return module_bits
608
608
609 def read_device(self):
609 def read_device(self):
610
610
611 parms = {}
611 parms = {}
612 # Reads active modules.
612 # Reads active modules.
613 module_status = json.loads(self.module_status)
613 module_status = json.loads(self.module_status)
614 total = 0
614 total = 0
615 for status in module_status:
615 for status in module_status:
616 if module_status[status] != 0:
616 if module_status[status] != 0:
617 module_bits = self.read_module(int(status))
617 module_bits = self.read_module(int(status))
618 bits={}
618 bits={}
619 if module_bits:
619 if module_bits:
620 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
620 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
621 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
621 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
622 parms[str(status)] = bits
622 parms[str(status)] = bits
623
623
624 total +=1
624 total +=1
625
625
626 if total==0:
626 if total==0:
627 self.message = "No ABS Module detected. Please select 'Status'."
627 self.message = "No ABS Module detected. Please select 'Status'."
628 return False
628 return False
629
629
630
630
631
631
632 self.message = "ABS Modules have been read"
632 self.message = "ABS Modules have been read"
633 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
633 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
634 return parms
634 return parms
635
635
636
636
637 def connected_modules(self):
637 def connected_modules(self):
638 """
638 """
639 This function returns the number of connected abs-modules without updating.
639 This function returns the number of connected abs-modules without updating.
640 """
640 """
641 num = 0
641 num = 0
642 print(self.module_status)
642 print(self.module_status)
643 for i, status in enumerate(self.module_status):
643 for i, status in enumerate(self.module_status):
644 if status != '0':
644 if status != '0':
645 num += 1
645 num += 1
646 #print('status {}:{}'.format(i+1, status))
646 #print('status {}:{}'.format(i+1, status))
647 return num
647 return num
648
648
649 def send_multicast(self, message):
649 def send_multicast(self, message):
650 #print("Send multicast")
650 #print("Send multicast")
651 multicast_group = ('224.3.29.71', 10000)
651 multicast_group = ('224.3.29.71', 10000)
652 # Create the datagram socket
652 # Create the datagram socket
653 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
653 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
654 sock.settimeout(1)
654 sock.settimeout(1)
655 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
655 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
656 local_ip = '0.0.0.0'
656 local_ip = '0.0.0.0'
657 print("He llegado a IP local")
657 print("He llegado a IP local")
658
658
659 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
659 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
660 sock.sendto(message.encode(), multicast_group)
660 sock.sendto(message.encode(), multicast_group)
661 print('Sending ' + message)
661 print('Sending ' + message)
662 return sock
662 return sock
663
663
664 def status_device(self):
664 def status_device(self):
665 """
665 """
666 This function returns the status of all abs-modules as one.
666 This function returns the status of all abs-modules as one.
667 If at least one module is connected, its answer is "1"
667 If at least one module is connected, its answer is "1"
668 """
668 """
669 print ('Status device')
669 print ('Status device')
670 print (self.active_beam)
670 print (self.active_beam)
671 beams = ABSBeam.objects.filter(abs_conf=self)
671 beams = ABSBeam.objects.filter(abs_conf=self)
672 #print beams[self.active_beam-1].module_6bits(0)
672 #print beams[self.active_beam-1].module_6bits(0)
673 active = ABSActive.objects.get(pk=1)
673 active = ABSActive.objects.get(pk=1)
674 if active.conf != self:
674 if active.conf != self:
675 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
675 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
676 self.message += "\n"
676 self.message += "\n"
677 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
677 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
678
678
679 return False
679 return False
680
680
681 sock = self.send_multicast('MNTR')
681 sock = self.send_multicast('MNTR')
682 print("Estoy en status_deice",flush=True)
682 print("Estoy en status_deice",flush=True)
683
683
684 n = 0
684 n = 0
685 status = ['0'] * 64
685 status = ['0'] * 64
686
686
687 while True:
687 while True:
688 #for i in range(32):
688 #for i in range(32):
689 #if True:
689 #if True:
690 try:
690 try:
691 print("Recibiendo")
691 print("Recibiendo")
692 address = None
692 address = None
693 data, address = sock.recvfrom(2)
693 data, address = sock.recvfrom(2)
694 print (address, data)
694 print (address, data)
695 print("!!!!")
695 print("!!!!")
696 data = data.decode()
696 data = data.decode()
697 aux_mon = "1"
697 aux_mon = "1"
698 aux_expected = aux_mon
698 aux_expected = aux_mon
699 if(len(data)==2):
699 if(len(data)==2):
700 print ("data[1]: ")
700 print ("data[1]: ")
701 print (data[1])
701 print (data[1])
702 aux_mon = fromChar2Binary(data[1])
702 aux_mon = fromChar2Binary(data[1])
703 print (aux_mon)
703 print (aux_mon)
704 aux_i = (str(address[0]).split('.'))[3]
704 aux_i = (str(address[0]).split('.'))[3]
705 print (aux_i)
705 print (aux_i)
706 print ('Active beam')
706 print ('Active beam')
707 beam_active = ABSBeam.objects.get(pk=self.active_beam)
707 beam_active = ABSBeam.objects.get(pk=self.active_beam)
708 print (beam_active)
708 print (beam_active)
709 aux_expected = beam_active.module_6bits(int(aux_i)-1)
709 aux_expected = beam_active.module_6bits(int(aux_i)-1)
710 print (aux_expected)
710 print (aux_expected)
711
711
712 print ("data[0]: ")
712 print ("data[0]: ")
713 print (data[0])
713 print (data[0])
714
714
715 if data[0] == '1':
715 if data[0] == '1':
716 status[int(address[0][10:])-1] = '3'
716 status[int(address[0][10:])-1] = '3'
717 if aux_mon == aux_expected:
717 if aux_mon == aux_expected:
718 print ('Es igual')
718 print ('Es igual')
719 else:
719 else:
720 print ('Es diferente')
720 print ('Es diferente')
721 status[int(address[0][10:])-1] = '2'
721 status[int(address[0][10:])-1] = '2'
722
722
723 elif data[0] == '0':
723 elif data[0] == '0':
724 status[int(address[0][10:])-1] = '1'
724 status[int(address[0][10:])-1] = '1'
725 n += 1
725 n += 1
726 print('Module: {} connected'.format(address))
726 print('Module: {} connected'.format(address))
727 except socket.timeout:
727 except socket.timeout:
728 print('Timeout')
728 print('Timeout')
729 break
729 break
730 except:
730 except:
731 print('Module: {} error'.format(address))
731 print('Module: {} error'.format(address))
732 pass
732 pass
733
733
734 sock.close()
734 sock.close()
735
735
736 if n > 0:
736 if n > 0:
737 self.message = 'ABS modules Status have been updated.'
737 self.message = 'ABS modules Status have been updated.'
738 self.device.status = 1
738 self.device.status = 1
739 else:
739 else:
740 self.device.status = 0
740 self.device.status = 0
741 self.message = 'No ABS module is connected.'
741 self.message = 'No ABS module is connected.'
742 self.module_status = ''.join(status)
742 self.module_status = ''.join(status)
743 self.save()
743 self.save()
744
744
745 return self.device.status
745 return self.device.status
746
746
747
747
748 def send_beam(self, beam_pos):
748 def send_beam(self, beam_pos):
749 """
749 """
750 This function connects to a multicast group and sends the beam number
750 This function connects to a multicast group and sends the beam number
751 to all abs modules.
751 to all abs modules.
752 """
752 """
753 print ('Send beam')
753 print ('Send beam')
754 print (self.active_beam)
754 print (self.active_beam)
755 beams = ABSBeam.objects.filter(abs_conf=self)
755 beams = ABSBeam.objects.filter(abs_conf=self)
756 #print beams[self.active_beam-1].module_6bits(0)
756 #print beams[self.active_beam-1].module_6bits(0)
757 active = ABSActive.objects.get(pk=1)
757 active = ABSActive.objects.get(pk=1)
758 if active.conf != self:
758 if active.conf != self:
759 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
759 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
760 self.message += "\n"
760 self.message += "\n"
761 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
761 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
762
762
763 return False
763 return False
764
764
765 # Se manda a cero RC para poder realizar cambio de beam
765 # Se manda a cero RC para poder realizar cambio de beam
766 if self.experiment is None:
766 if self.experiment is None:
767 confs = []
767 confs = []
768 else:
768 else:
769 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
769 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
770 confdds = ''
770 confdds = ''
771 confjars = ''
771 confjars = ''
772 confrc = ''
772 confrc = ''
773 #TO STOP DEVICES: DDS-JARS-RC
773 #TO STOP DEVICES: DDS-JARS-RC
774 for i in range(0,len(confs)):
774 for i in range(0,len(confs)):
775 if i==0:
775 if i==0:
776 for conf in confs:
776 for conf in confs:
777 if conf.device.device_type.name == 'dds':
777 if conf.device.device_type.name == 'dds':
778 confdds = conf
778 confdds = conf
779 confdds.stop_device()
779 confdds.stop_device()
780 break
780 break
781 if i==1:
781 if i==1:
782 for conf in confs:
782 for conf in confs:
783 if conf.device.device_type.name == 'jars':
783 if conf.device.device_type.name == 'jars':
784 confjars = conf
784 confjars = conf
785 confjars.stop_device()
785 confjars.stop_device()
786 break
786 break
787 if i==2:
787 if i==2:
788 for conf in confs:
788 for conf in confs:
789 if conf.device.device_type.name == 'rc':
789 if conf.device.device_type.name == 'rc':
790 confrc = conf
790 confrc = conf
791 confrc.stop_device()
791 confrc.stop_device()
792 break
792 break
793 if beam_pos > 0:
793 if beam_pos > 0:
794 beam_pos = beam_pos - 1
794 beam_pos = beam_pos - 1
795 else:
795 else:
796 beam_pos = 0
796 beam_pos = 0
797
797
798 #El indice del apunte debe ser menor que el numero total de apuntes
798 #El indice del apunte debe ser menor que el numero total de apuntes
799 #El servidor tcp en el embebido comienza a contar desde 0
799 #El servidor tcp en el embebido comienza a contar desde 0
800 status = ['0'] * 64
800 status = ['0'] * 64
801 message = 'CHGB{}'.format(beam_pos)
801 message = 'CHGB{}'.format(beam_pos)
802 sock = self.send_multicast(message)
802 sock = self.send_multicast(message)
803 print("Estoy en send_beam ",flush=True)
803 print("Estoy en send_beam ",flush=True)
804 while True:
804 while True:
805 #for i in range(32):
805 #for i in range(32):
806 try:
806 try:
807 data, address = sock.recvfrom(1024)
807 data, address = sock.recvfrom(1024)
808 print (address, data)
808 print (address, data)
809 data = data.decode()
809 data = data.decode()
810 if data == '1':
810 if data == '1':
811 status[int(address[0][10:])-1] = '3'
811 status[int(address[0][10:])-1] = '3'
812 elif data == '0':
812 elif data == '0':
813 status[int(address[0][10:])-1] = '1'
813 status[int(address[0][10:])-1] = '1'
814 except socket.timeout:
814 except socket.timeout:
815 print('Timeout')
815 print('Timeout')
816 break
816 break
817 except Exception as e:
817 except Exception as e:
818 print ('Error {}'.format(e))
818 print ('Error {}'.format(e))
819 pass
819 pass
820
820
821 sock.close()
821 sock.close()
822
822
823 #Start DDS-RC-JARS
823 #Start DDS-RC-JARS
824 if confdds:
824 if confdds:
825 confdds.start_device()
825 confdds.start_device()
826 if confrc:
826 if confrc:
827 #print confrc
827 #print confrc
828 confrc.start_device()
828 confrc.start_device()
829 if confjars:
829 if confjars:
830 confjars.start_device()
830 confjars.start_device()
831
831
832 self.message = "ABS Beam has been changed"
832 self.message = "ABS Beam has been changed"
833 self.module_status = ''.join(status)
833 self.module_status = ''.join(status)
834 self.save()
834 self.save()
835 return True
835 return True
836
836
837 def change_beam_mqtt(self, beam_pos):
837 def change_beam_mqtt(self, beam_pos):
838 """
838 """
839 This function connects to a multicast group and sends the beam number
839 This function connects send through mqtt the order of change_beam (id of beam).
840 to all abs modules.
841 """
840 """
842 print ('Send beam')
841 print ('Change beam MQTT')
843 print (self.active_beam)
842 print (self.active_beam)
844 beams = ABSBeam.objects.filter(abs_conf=self)
843 beams = ABSBeam.objects.filter(abs_conf=self)
845 #print beams[self.active_beam-1].module_6bits(0)
844 #print beams[self.active_beam-1].module_6bits(0)
846 active = ABSActive.objects.get(pk=1)
845 active = ABSActive.objects.get(pk=1)
847 if active.conf != self:
846 if active.conf != self:
848 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
847 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_mqtt_url()
849 self.message += "\n"
848 self.message += "\n"
850 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
849 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
851
850
852 return False
851 return False
853
852
854 # Se manda a cero RC para poder realizar cambio de beam
853 # Se manda a cero RC para poder realizar cambio de beam
855 if self.experiment is None:
854 if self.experiment is None:
856 confs = []
855 confs = []
857 else:
856 else:
858 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
857 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
859 confdds = ''
858 confdds = ''
860 confjars = ''
859 confjars = ''
861 confrc = ''
860 confrc = ''
862 #TO STOP DEVICES: DDS-JARS-RC
861 #TO STOP DEVICES: DDS-JARS-RC
863 for i in range(0,len(confs)):
862 for i in range(0,len(confs)):
864 if i==0:
863 if i==0:
865 for conf in confs:
864 for conf in confs:
866 if conf.device.device_type.name == 'dds':
865 if conf.device.device_type.name == 'dds':
867 confdds = conf
866 confdds = conf
868 confdds.stop_device()
867 confdds.stop_device()
869 break
868 break
870 if i==1:
869 if i==1:
871 for conf in confs:
870 for conf in confs:
872 if conf.device.device_type.name == 'jars':
871 if conf.device.device_type.name == 'jars':
873 confjars = conf
872 confjars = conf
874 confjars.stop_device()
873 confjars.stop_device()
875 break
874 break
876 if i==2:
875 if i==2:
877 for conf in confs:
876 for conf in confs:
878 if conf.device.device_type.name == 'rc':
877 if conf.device.device_type.name == 'rc':
879 confrc = conf
878 confrc = conf
880 confrc.stop_device()
879 confrc.stop_device()
881 break
880 break
882 if beam_pos > 0:
881 if beam_pos > 0:
883 beam_pos = beam_pos - 1
882 beam_pos = beam_pos - 1
884 else:
883 else:
885 beam_pos = 0
884 beam_pos = 0
886
885
887 #El indice del apunte debe ser menor que el numero total de apuntes
886 #El indice del apunte debe ser menor que el numero total de apuntes
888 #El servidor tcp en el embebido comienza a contar desde 0
887 #El servidor tcp en el embebido comienza a contar desde 0
889 # status = ['0'] * 64
888 # status = ['0'] * 64
890 # message = 'CHGB{}'.format(beam_pos)
889 # message = 'CHGB{}'.format(beam_pos)
891 # sock = self.send_multicast(message)
890 # sock = self.send_multicast(message)
892 # while True:
891 # while True:
893 # #for i in range(32):
892 # #for i in range(32):
894 # try:
893 # try:
895 # data, address = sock.recvfrom(1024)
894 # data, address = sock.recvfrom(1024)
896 # print (address, data)
895 # print (address, data)
897 # data = data.decode()
896 # data = data.decode()
898 # if data == '1':
897 # if data == '1':
899 # status[int(address[0][10:])-1] = '3'
898 # status[int(address[0][10:])-1] = '3'
900 # elif data == '0':
899 # elif data == '0':
901 # status[int(address[0][10:])-1] = '1'
900 # status[int(address[0][10:])-1] = '1'
902 # except socket.timeout:
901 # except socket.timeout:
903 # print('Timeout')
902 # print('Timeout')
904 # break
903 # break
905 # except Exception as e:
904 # except Exception as e:
906 # print ('Error {}'.format(e))
905 # print ('Error {}'.format(e))
907 # pass
906 # pass
908
907
909 # sock.close()
908 # sock.close()
909 mqtt_client.publish('abs/change_beam',str(beam_pos))
910
910
911
911 #Start DDS-RC-JARS
912 #Start DDS-RC-JARS
912 if confdds:
913 if confdds:
913 confdds.start_device()
914 confdds.start_device()
914 if confrc:
915 if confrc:
915 #print confrc
916 #print confrc
916 confrc.start_device()
917 confrc.start_device()
917 if confjars:
918 if confjars:
918 confjars.start_device()
919 confjars.start_device()
919
920
920 self.message = "ABS Beam has been changed"
921 self.message = "ABS Beam has been changed"
921 self.module_status = ''.join(status)
922 self.save()
922 self.save()
923 return True
923 return True
924
924
925 def get_absolute_url_import(self):
925 def get_absolute_url_import(self):
926 return reverse('url_import_abs_conf', args=[str(self.id)])
926 return reverse('url_import_abs_conf', args=[str(self.id)])
927
927
928 class ABSActive(models.Model):
928 class ABSActive(models.Model):
929 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
929 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
930
930
931 class Meta:
931 class Meta:
932 db_table = 'abs_absactive'
932 db_table = 'abs_absactive'
933
933
934 class ABSBeam(models.Model):
934 class ABSBeam(models.Model):
935
935
936 name = models.CharField(max_length=60, default='Beam')
936 name = models.CharField(max_length=60, default='Beam')
937 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
937 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
938 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
938 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
939 verbose_name='ABS Configuration', on_delete=models.CASCADE)
939 verbose_name='ABS Configuration', on_delete=models.CASCADE)
940 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
940 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
941 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
941 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
942 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
942 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
943 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
943 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
944 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
944 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
945 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
945 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
946
946
947 class Meta:
947 class Meta:
948 db_table = 'abs_beams'
948 db_table = 'abs_beams'
949
949
950 def __unicode__(self):
950 def __unicode__(self):
951 return u'%s' % (self.name)
951 return u'%s' % (self.name)
952
952
953 def parms_to_dict(self):
953 def parms_to_dict(self):
954
954
955 parameters = {}
955 parameters = {}
956 parameters['name'] = self.name
956 parameters['name'] = self.name
957 parameters['antenna'] = ast.literal_eval(self.antenna)
957 parameters['antenna'] = ast.literal_eval(self.antenna)
958 parameters['abs_conf'] = self.abs_conf.name
958 parameters['abs_conf'] = self.abs_conf.name
959 parameters['tx'] = ast.literal_eval(self.tx)
959 parameters['tx'] = ast.literal_eval(self.tx)
960 parameters['rx'] = ast.literal_eval(self.rx)
960 parameters['rx'] = ast.literal_eval(self.rx)
961 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
961 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
962 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
962 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
963 parameters['ues'] = ast.literal_eval(self.ues)
963 parameters['ues'] = ast.literal_eval(self.ues)
964 parameters['only_rx'] = json.loads(self.only_rx)
964 parameters['only_rx'] = json.loads(self.only_rx)
965
965
966 return parameters
966 return parameters
967
967
968 def dict_to_parms(self, parameters):
968 def dict_to_parms(self, parameters):
969
969
970 self.name = parameters['name']
970 self.name = parameters['name']
971 self.antenna = json.dumps(parameters['antenna'])
971 self.antenna = json.dumps(parameters['antenna'])
972 #self.abs_conf = parameters['abs_conf']
972 #self.abs_conf = parameters['abs_conf']
973 self.tx = json.dumps(parameters['tx'])
973 self.tx = json.dumps(parameters['tx'])
974 self.rx = json.dumps(parameters['rx'])
974 self.rx = json.dumps(parameters['rx'])
975 #self.s_time = parameters['s_time']
975 #self.s_time = parameters['s_time']
976 #self.e_time = parameters['e_time']
976 #self.e_time = parameters['e_time']
977 self.ues = json.dumps(parameters['ues'])
977 self.ues = json.dumps(parameters['ues'])
978 self.only_rx = json.dumps(parameters['only_rx'])
978 self.only_rx = json.dumps(parameters['only_rx'])
979 self.save()
979 self.save()
980
980
981
981
982 def clone(self, **kwargs):
982 def clone(self, **kwargs):
983
983
984 self.pk = None
984 self.pk = None
985 self.id = None
985 self.id = None
986 for attr, value in kwargs.items():
986 for attr, value in kwargs.items():
987 setattr(self, attr, value)
987 setattr(self, attr, value)
988
988
989 self.save()
989 self.save()
990
990
991 return self
991 return self
992
992
993
993
994 def module_6bits(self, module):
994 def module_6bits(self, module):
995 """
995 """
996 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
996 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
997 """
997 """
998 module += 1
998 module += 1
999 if module > 64:
999 if module > 64:
1000 beam_bits = ""
1000 beam_bits = ""
1001 return beam_bits
1001 return beam_bits
1002
1002
1003 data = ast.literal_eval(self.antenna)
1003 data = ast.literal_eval(self.antenna)
1004 up_data = data['antenna_up']
1004 up_data = data['antenna_up']
1005 down_data = data['antenna_down']
1005 down_data = data['antenna_down']
1006
1006
1007 pos = ip2position(module)
1007 pos = ip2position(module)
1008 up_value = up_data[pos[0]][pos[1]]
1008 up_value = up_data[pos[0]][pos[1]]
1009 down_value = down_data[pos[0]][pos[1]]
1009 down_value = down_data[pos[0]][pos[1]]
1010
1010
1011 up_bits = up_conv_bits(up_value)
1011 up_bits = up_conv_bits(up_value)
1012 down_bits = down_conv_bits(down_value)
1012 down_bits = down_conv_bits(down_value)
1013 beam_bits = up_bits+down_bits
1013 beam_bits = up_bits+down_bits
1014
1014
1015 return beam_bits
1015 return beam_bits
1016
1016
1017
1017
1018 @property
1018 @property
1019 def get_upvalues(self):
1019 def get_upvalues(self):
1020 """
1020 """
1021 This function reads antenna pattern and show the up-value of one abs module
1021 This function reads antenna pattern and show the up-value of one abs module
1022 """
1022 """
1023
1023
1024 data = ast.literal_eval(self.antenna)
1024 data = ast.literal_eval(self.antenna)
1025 up_data = data['antenna_up']
1025 up_data = data['antenna_up']
1026
1026
1027 up_values = []
1027 up_values = []
1028 for data in up_data:
1028 for data in up_data:
1029 for i in range(0,8):
1029 for i in range(0,8):
1030 up_values.append(data[i])
1030 up_values.append(data[i])
1031
1031
1032 return up_values
1032 return up_values
1033
1033
1034 @property
1034 @property
1035 def antenna_upvalues(self):
1035 def antenna_upvalues(self):
1036 """
1036 """
1037 This function reads antenna pattern and show the up - values of one abs beam
1037 This function reads antenna pattern and show the up - values of one abs beam
1038 in a particular order
1038 in a particular order
1039 """
1039 """
1040 data = ast.literal_eval(self.antenna)
1040 data = ast.literal_eval(self.antenna)
1041 up_data = data['antenna_up']
1041 up_data = data['antenna_up']
1042
1042
1043 return up_data
1043 return up_data
1044
1044
1045 @property
1045 @property
1046 def antenna_downvalues(self):
1046 def antenna_downvalues(self):
1047 """
1047 """
1048 This function reads antenna pattern and show the down - values of one abs beam
1048 This function reads antenna pattern and show the down - values of one abs beam
1049 in a particular order
1049 in a particular order
1050 """
1050 """
1051 data = ast.literal_eval(self.antenna)
1051 data = ast.literal_eval(self.antenna)
1052 down_data = data['antenna_down']
1052 down_data = data['antenna_down']
1053
1053
1054 return down_data
1054 return down_data
1055
1055
1056 @property
1056 @property
1057 def get_downvalues(self):
1057 def get_downvalues(self):
1058 """
1058 """
1059 This function reads antenna pattern and show the down-value of one abs module
1059 This function reads antenna pattern and show the down-value of one abs module
1060 """
1060 """
1061
1061
1062 data = ast.literal_eval(self.antenna)
1062 data = ast.literal_eval(self.antenna)
1063 down_data = data['antenna_down']
1063 down_data = data['antenna_down']
1064
1064
1065 down_values = []
1065 down_values = []
1066 for data in down_data:
1066 for data in down_data:
1067 for i in range(0,8):
1067 for i in range(0,8):
1068 down_values.append(data[i])
1068 down_values.append(data[i])
1069
1069
1070 return down_values
1070 return down_values
1071
1071
1072 @property
1072 @property
1073 def get_up_ues(self):
1073 def get_up_ues(self):
1074 """
1074 """
1075 This function shows the up-ues-value of one beam
1075 This function shows the up-ues-value of one beam
1076 """
1076 """
1077 data = ast.literal_eval(self.ues)
1077 data = ast.literal_eval(self.ues)
1078 up_ues = data['up']
1078 up_ues = data['up']
1079
1079
1080 return up_ues
1080 return up_ues
1081
1081
1082 @property
1082 @property
1083 def get_down_ues(self):
1083 def get_down_ues(self):
1084 """
1084 """
1085 This function shows the down-ues-value of one beam
1085 This function shows the down-ues-value of one beam
1086 """
1086 """
1087 data = ast.literal_eval(self.ues)
1087 data = ast.literal_eval(self.ues)
1088 down_ues = data['down']
1088 down_ues = data['down']
1089
1089
1090 return down_ues
1090 return down_ues
1091
1091
1092 @property
1092 @property
1093 def get_up_onlyrx(self):
1093 def get_up_onlyrx(self):
1094 """
1094 """
1095 This function shows the up-onlyrx-value of one beam
1095 This function shows the up-onlyrx-value of one beam
1096 """
1096 """
1097 data = json.loads(self.only_rx)
1097 data = json.loads(self.only_rx)
1098 up_onlyrx = data['up']
1098 up_onlyrx = data['up']
1099
1099
1100 return up_onlyrx
1100 return up_onlyrx
1101
1101
1102 @property
1102 @property
1103 def get_down_onlyrx(self):
1103 def get_down_onlyrx(self):
1104 """
1104 """
1105 This function shows the down-onlyrx-value of one beam
1105 This function shows the down-onlyrx-value of one beam
1106 """
1106 """
1107 data = json.loads(self.only_rx)
1107 data = json.loads(self.only_rx)
1108 down_onlyrx = data['down']
1108 down_onlyrx = data['down']
1109
1109
1110 return down_onlyrx
1110 return down_onlyrx
1111
1111
1112 @property
1112 @property
1113 def get_tx(self):
1113 def get_tx(self):
1114 """
1114 """
1115 This function shows the tx-values of one beam
1115 This function shows the tx-values of one beam
1116 """
1116 """
1117 data = json.loads(self.tx)
1117 data = json.loads(self.tx)
1118
1118
1119 return data
1119 return data
1120
1120
1121 @property
1121 @property
1122 def get_uptx(self):
1122 def get_uptx(self):
1123 """
1123 """
1124 This function shows the up-tx-values of one beam
1124 This function shows the up-tx-values of one beam
1125 """
1125 """
1126 data = json.loads(self.tx)
1126 data = json.loads(self.tx)
1127 up_data = data['up']
1127 up_data = data['up']
1128
1128
1129 up_values = []
1129 up_values = []
1130 for data in up_data:
1130 for data in up_data:
1131 for i in range(0,8):
1131 for i in range(0,8):
1132 up_values.append(data[i])
1132 up_values.append(data[i])
1133
1133
1134 return up_values
1134 return up_values
1135
1135
1136 @property
1136 @property
1137 def get_downtx(self):
1137 def get_downtx(self):
1138 """
1138 """
1139 This function shows the down-tx-values of one beam
1139 This function shows the down-tx-values of one beam
1140 """
1140 """
1141 data = json.loads(self.tx)
1141 data = json.loads(self.tx)
1142 down_data = data['down']
1142 down_data = data['down']
1143
1143
1144 down_values = []
1144 down_values = []
1145 for data in down_data:
1145 for data in down_data:
1146 for i in range(0,8):
1146 for i in range(0,8):
1147 down_values.append(data[i])
1147 down_values.append(data[i])
1148
1148
1149 return down_values
1149 return down_values
1150
1150
1151
1151
1152
1152
1153 @property
1153 @property
1154 def get_rx(self):
1154 def get_rx(self):
1155 """
1155 """
1156 This function shows the rx-values of one beam
1156 This function shows the rx-values of one beam
1157 """
1157 """
1158 data = json.loads(self.rx)
1158 data = json.loads(self.rx)
1159
1159
1160 return data
1160 return data
1161
1161
1162 @property
1162 @property
1163 def get_uprx(self):
1163 def get_uprx(self):
1164 """
1164 """
1165 This function shows the up-rx-values of one beam
1165 This function shows the up-rx-values of one beam
1166 """
1166 """
1167 data = json.loads(self.rx)
1167 data = json.loads(self.rx)
1168 up_data = data['up']
1168 up_data = data['up']
1169
1169
1170 up_values = []
1170 up_values = []
1171 for data in up_data:
1171 for data in up_data:
1172 for i in range(0,8):
1172 for i in range(0,8):
1173 up_values.append(data[i])
1173 up_values.append(data[i])
1174
1174
1175 return up_values
1175 return up_values
1176
1176
1177 @property
1177 @property
1178 def get_downrx(self):
1178 def get_downrx(self):
1179 """
1179 """
1180 This function shows the down-rx-values of one beam
1180 This function shows the down-rx-values of one beam
1181 """
1181 """
1182 data = json.loads(self.rx)
1182 data = json.loads(self.rx)
1183 down_data = data['down']
1183 down_data = data['down']
1184
1184
1185 down_values = []
1185 down_values = []
1186 for data in down_data:
1186 for data in down_data:
1187 for i in range(0,8):
1187 for i in range(0,8):
1188 down_values.append(data[i])
1188 down_values.append(data[i])
1189
1189
1190 return down_values
1190 return down_values
@@ -1,426 +1,425
1 {% extends "dev_conf.html" %} {% load static %} {% load django_bootstrap5 %} {% load main_tags %}
1 {% extends "dev_conf.html" %} {% load static %} {% load django_bootstrap5 %} {% load main_tags %}
2 {% block extra-head %}
2 {% block extra-head %}
3 <style>
3 <style>
4 .abs {
4 .abs {
5 width: auto;
5 width: auto;
6 display: inline-block;
6 display: inline-block;
7 text-align: center;
7 text-align: center;
8 }
8 }
9
9
10 .abs td {
10 .abs td {
11 padding: 4px;
11 padding: 4px;
12 }
12 }
13
13
14 .module td {
14 .module td {
15 padding: 4px 15px 4px 15px;
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
16 font-weight: bold;
17 border: 1px solid
17 border: 1px solid
18 }
18 }
19
19
20 .legend {
20 .legend {
21 margin-left: 15px;
21 margin-left: 15px;
22 display: inline-block;
22 display: inline-block;
23 border: 2px solid;
23 border: 2px solid;
24 vertical-align: top;
24 vertical-align: top;
25 }
25 }
26
26
27 .legend th {
27 .legend th {
28 border-bottom: 1px dashed;
28 border-bottom: 1px dashed;
29 font-weight: bold;
29 font-weight: bold;
30 vertical-align: center;
30 vertical-align: center;
31 text-align: center;
31 text-align: center;
32 }
32 }
33
33
34 .legend td {
34 .legend td {
35 padding: 2px;
35 padding: 2px;
36 text-align: center;
36 text-align: center;
37 font-weight: bold;
37 font-weight: bold;
38 }
38 }
39
39
40 </style>
40 </style>
41 {% endblock %}
41 {% endblock %}
42
42
43
43
44 {% block extra-menu-actions %}
44 {% block extra-menu-actions %}
45 <li>
45 <li>
46 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
46 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
47 <span class="far fa-image" aria-hidden="true"></span> View Patterns </a>
47 <span class="far fa-image" aria-hidden="true"></span> View Patterns </a>
48 </li>
48 </li>
49 {% endblock %}
49 {% endblock %}
50
50
51
51
52 {% block extra-content %}
52 {% block extra-content %}
53 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
53 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
54 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js">
54 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js">
55 </script>
55 </script>
56
56
57
57
58 {% if beams %}
58 {% if beams %}
59 <h4>Beams:</h4>
59 <h4>Beams MQTT:</h4>
60 <div class="container">
60 <div class="container">
61 <ul class="nav nav-pills">
61 <ul class="nav nav-pills">
62 {% for beam in beams %}
62 {% for beam in beams %}
63 <li class="nav-item">
63 <li class="nav-item">
64 <a {%if beam.pk == active_beam %} class="nav-link active" {% else %} class="nav-link" {% endif %} data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
64 <a {%if beam.pk == active_beam %} class="nav-link active" {% else %} class="nav-link" {% endif %} data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
65 </li>
65 </li>
66 {% endfor %}
66 {% endfor %}
67 </ul>
67 </ul>
68
68
69 <div class="tab-content">
69 <div class="tab-content">
70 {% for beam in beams %}
70 {% for beam in beams %}
71 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}in active show{% endif %}">
71 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}in active show{% endif %}">
72 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
72 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
73 <table id="abs_pattern{{forloop.counter}}" class="abs">
73 <table id="abs_pattern{{forloop.counter}}" class="abs">
74 <tr>
74 <tr>
75 <td>
75 <td>
76 <b>North Quarter</b>
76 <b>North Quarter</b>
77 <table class="module">
77 <table class="module">
78 <tr>
78 <tr>
79 <td title='{{module_messages.1}}'><span id="1" {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_upvalues.0}}</span></td>
79 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} id="1" {%endif%}>{{beam.get_upvalues.0}}</span></td>
80 <td title='{{module_messages.2}}'><span id="2" {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_upvalues.1}}</span></td>
80 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} id="2" {%endif%}>{{beam.get_upvalues.1}}</span></td>
81 <td title='{{module_messages.3}}'><span id="3" {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_upvalues.2}}</span></td>
81 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} id="3" {%endif%}>{{beam.get_upvalues.2}}</span></td>
82 <td title='{{module_messages.4}}'><span id="4" {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_upvalues.3}}</span></td>
82 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} id="4" {%endif%}>{{beam.get_upvalues.3}}</span></td>
83 </tr>
83 </tr>
84 <tr>
84 <tr>
85 <td title='{{module_messages.1}}'><span id="101" {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_downvalues.0}}</span></td>
85 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} id="101" {%endif%}>{{beam.get_downvalues.0}}</span></td>
86 <td title='{{module_messages.2}}'><span id="102" {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_downvalues.1}}</span></td>
86 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} id="102" {%endif%}>{{beam.get_downvalues.1}}</span></td>
87 <td title='{{module_messages.3}}'> <span id="103" {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_downvalues.2}}</span></td>
87 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} id="103" {%endif%}>{{beam.get_downvalues.2}}</span></td>
88 <td title='{{module_messages.4}}'> <span id="104" {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_downvalues.3}}</span></td>
88 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} id="104" {%endif%}>{{beam.get_downvalues.3}}</span></td>
89 </tr>
89 </tr>
90 <tr>
90 <tr>
91 <td title='{{module_messages.9}}'> <span id="9" {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_upvalues.8}}</span></td>
91 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} id="9" {%endif%}>{{beam.get_upvalues.8}}</span></td>
92 <td title='{{module_messages.10}}'><span id="10" {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_upvalues.9}}</span></td>
92 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} id="10" {%endif%}>{{beam.get_upvalues.9}}</span></td>
93 <td title='{{module_messages.11}}'><span id="11" {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_upvalues.10}}</span></td>
93 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} id="11" {%endif%}>{{beam.get_upvalues.10}}</span></td>
94 <td title='{{module_messages.12}}'><span id="12" {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_upvalues.11}}</span></td>
94 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} id="12" {%endif%}>{{beam.get_upvalues.11}}</span></td>
95 </tr>
95 </tr>
96 <tr>
96 <tr>
97 <td title='{{module_messages.9}}'> <span id="109" {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_downvalues.8}}</span></td>
97 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} id="109" {%endif%}>{{beam.get_downvalues.8}}</span></td>
98 <td title='{{module_messages.10}}'><span id="110" {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_downvalues.9}}</span></td>
98 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} id="110" {%endif%}>{{beam.get_downvalues.9}}</span></td>
99 <td title='{{module_messages.11}}'><span id="111" {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_downvalues.10}}</span></td>
99 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} id="111" {%endif%}>{{beam.get_downvalues.10}}</span></td>
100 <td title='{{module_messages.12}}'><span id="112" {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_downvalues.11}}</span></td>
100 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} id="112" {%endif%}>{{beam.get_downvalues.11}}</span></td>
101 </tr>
101 </tr>
102 <tr>
102 <tr>
103 <td title='{{module_messages.17}}'><span id="17" {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_upvalues.16}}</span></td>
103 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} id="17" {%endif%}>{{beam.get_upvalues.16}}</span></td>
104 <td title='{{module_messages.18}}'><span id="18" {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_upvalues.17}}</span></td>
104 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} id="18" {%endif%}>{{beam.get_upvalues.17}}</span></td>
105 <td title='{{module_messages.19}}'><span id="19" {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_upvalues.18}}</span></td>
105 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} id="19" {%endif%}>{{beam.get_upvalues.18}}</span></td>
106 <td title='{{module_messages.20}}'><span id="20" {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_upvalues.19}}</span></td>
106 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} id="20" {%endif%}>{{beam.get_upvalues.19}}</span></td>
107 </tr>
107 </tr>
108 <tr>
108 <tr>
109 <td title='{{module_messages.17}}'><span id="117" {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_downvalues.16}}</span></td>
109 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} id="117" {%endif%}>{{beam.get_downvalues.16}}</span></td>
110 <td title='{{module_messages.18}}'><span id="118" {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_downvalues.17}}</span></td>
110 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} id="118" {%endif%}>{{beam.get_downvalues.17}}</span></td>
111 <td title='{{module_messages.19}}'><span id="119" {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_downvalues.18}}</span></td>
111 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} id="119" {%endif%}>{{beam.get_downvalues.18}}</span></td>
112 <td title='{{module_messages.20}}'><span id="120" {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_downvalues.19}}</span></td>
112 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} id="120" {%endif%}>{{beam.get_downvalues.19}}</span></td>
113 </tr>
113 </tr>
114 <tr>
114 <tr>
115 <td title='{{module_messages.25}}'><span id="25" {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_upvalues.24}}</span></td>
115 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} id="25" {%endif%}>{{beam.get_upvalues.24}}</span></td>
116 <td title='{{module_messages.26}}'><span id="26" {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_upvalues.25}}</span></td>
116 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} id="26" {%endif%}>{{beam.get_upvalues.25}}</span></td>
117 <td title='{{module_messages.27}}'><span id="27" {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_upvalues.26}}</span></td>
117 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} id="27" {%endif%}>{{beam.get_upvalues.26}}</span></td>
118 <td title='{{module_messages.28}}'><span id="28" {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_upvalues.27}}</span></td>
118 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} id="28" {%endif%}>{{beam.get_upvalues.27}}</span></td>
119 </tr>
119 </tr>
120 <tr>
120 <tr>
121 <td title='{{module_messages.25}}'><span id="125" {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_downvalues.24}}</span></td>
121 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} id="125" {%endif%}>{{beam.get_downvalues.24}}</span></td>
122 <td title='{{module_messages.26}}'><span id="126" {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_downvalues.25}}</span></td>
122 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} id="126" {%endif%}>{{beam.get_downvalues.25}}</span></td>
123 <td title='{{module_messages.27}}'><span id="127" {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_downvalues.26}}</span></td>
123 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} id="127" {%endif%}>{{beam.get_downvalues.26}}</span></td>
124 <td title='{{module_messages.28}}'><span id="128" {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_downvalues.27}}</span></td>
124 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} id="128" {%endif%}>{{beam.get_downvalues.27}}</span></td>
125 </tr>
125 </tr>
126 </table>
126 </table>
127 </td>
127 </td>
128 <td>
128 <td>
129 <b>East Quarter</b>
129 <b>East Quarter</b>
130 <table class="module">
130 <table class="module">
131 <tr>
131 <tr>
132 <td title='{{module_messages.5}}'> <span id="5" {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_upvalues.4}}</span></td>
132 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} id="5" {%endif%}>{{beam.get_upvalues.4}}</span></td>
133 <td title='{{module_messages.6}}'> <span id="6" {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_upvalues.5}}</span></td>
133 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} id="6" {%endif%}>{{beam.get_upvalues.5}}</span></td>
134 <td title='{{module_messages.7}}'> <span id="7" {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_upvalues.6}}</span></td>
134 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} id="7" {%endif%}>{{beam.get_upvalues.6}}</span></td>
135 <td title='{{module_messages.8}}'> <span id="8" {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_upvalues.7}}</span></td>
135 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} id="8" {%endif%}>{{beam.get_upvalues.7}}</span></td>
136 </tr>
136 </tr>
137 <tr>
137 <tr>
138 <td title='{{module_messages.5}}'> <span id="105" {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_downvalues.4}}</span></td>
138 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} id="105" {%endif%}>{{beam.get_downvalues.4}}</span></td>
139 <td title='{{module_messages.6}}'> <span id="106" {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_downvalues.5}}</span></td>
139 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} id="106" {%endif%}>{{beam.get_downvalues.5}}</span></td>
140 <td title='{{module_messages.7}}'> <span id="107" {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_downvalues.6}}</span></td>
140 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} id="107" {%endif%}>{{beam.get_downvalues.6}}</span></td>
141 <td title='{{module_messages.8}}'> <span id="108" {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_downvalues.7}}</span></td>
141 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} id="108" {%endif%}>{{beam.get_downvalues.7}}</span></td>
142 </tr>
142 </tr>
143 <tr>
143 <tr>
144 <td title='{{module_messages.13}}'><span id="13" {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_upvalues.12}}</span></td>
144 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} id="13" {%endif%}>{{beam.get_upvalues.12}}</span></td>
145 <td title='{{module_messages.14}}'><span id="14" {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_upvalues.13}}</span></td>
145 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} id="14" {%endif%}>{{beam.get_upvalues.13}}</span></td>
146 <td title='{{module_messages.15}}'><span id="15" {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_upvalues.14}}</span></td>
146 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} id="15" {%endif%}>{{beam.get_upvalues.14}}</span></td>
147 <td title='{{module_messages.16}}'><span id="16" {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_upvalues.15}}</span></td>
147 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} id="16" {%endif%}>{{beam.get_upvalues.15}}</span></td>
148 </tr>
148 </tr>
149 <tr>
149 <tr>
150 <td title='{{module_messages.13}}'><span id="113" {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_downvalues.12}}</span></td>
150 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} id="113" {%endif%}>{{beam.get_downvalues.12}}</span></td>
151 <td title='{{module_messages.14}}'><span id="114" {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_downvalues.13}}</span></td>
151 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} id="114" {%endif%}>{{beam.get_downvalues.13}}</span></td>
152 <td title='{{module_messages.15}}'><span id="115" {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_downvalues.14}}</span></td>
152 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} id="115" {%endif%}>{{beam.get_downvalues.14}}</span></td>
153 <td title='{{module_messages.16}}'><span id="116" {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_downvalues.15}}</span></td>
153 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} id="116" {%endif%}>{{beam.get_downvalues.15}}</span></td>
154 </tr>
154 </tr>
155 <tr>
155 <tr>
156 <td title='{{module_messages.21}}'><span id="21" {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_upvalues.20}}</span></td>
156 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} id="21" {%endif%}>{{beam.get_upvalues.20}}</span></td>
157 <td title='{{module_messages.22}}'><span id="22" {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_upvalues.21}}</span></td>
157 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} id="22" {%endif%}>{{beam.get_upvalues.21}}</span></td>
158 <td title='{{module_messages.23}}'><span id="23" {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_upvalues.22}}</span></td>
158 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} id="23" {%endif%}>{{beam.get_upvalues.22}}</span></td>
159 <td title='{{module_messages.24}}'><span id="24" {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_upvalues.23}}</span></td>
159 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} id="24" {%endif%}>{{beam.get_upvalues.23}}</span></td>
160 </tr>
160 </tr>
161 <tr>
161 <tr>
162 <td title='{{module_messages.21}}'><span id="121" {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_downvalues.20}}</span></td>
162 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} id="121" {%endif%}>{{beam.get_downvalues.20}}</span></td>
163 <td title='{{module_messages.22}}'><span id="122" {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_downvalues.21}}</span></td>
163 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} id="122" {%endif%}>{{beam.get_downvalues.21}}</span></td>
164 <td title='{{module_messages.23}}'><span id="123" {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_downvalues.22}}</span></td>
164 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} id="123" {%endif%}>{{beam.get_downvalues.22}}</span></td>
165 <td title='{{module_messages.24}}'><span id="124" {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_downvalues.23}}</span></td>
165 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} id="124" {%endif%}>{{beam.get_downvalues.23}}</span></td>
166 </tr>
166 </tr>
167 <tr>
167 <tr>
168 <td title='{{module_messages.29}}'><span id="29" {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_upvalues.28}}</span></td>
168 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} id="29" {%endif%}>{{beam.get_upvalues.28}}</span></td>
169 <td title='{{module_messages.30}}'><span id="30" {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_upvalues.29}}</span></td>
169 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} id="30" {%endif%}>{{beam.get_upvalues.29}}</span></td>
170 <td title='{{module_messages.31}}'><span id="31" {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_upvalues.30}}</span></td>
170 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} id="31" {%endif%}>{{beam.get_upvalues.30}}</span></td>
171 <td title='{{module_messages.32}}'><span id="32" {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_upvalues.31}}</span></td>
171 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} id="32" {%endif%}>{{beam.get_upvalues.31}}</span></td>
172 </tr>
172 </tr>
173 <tr>
173 <tr>
174 <td title='{{module_messages.29}}'><span id="129" {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_downvalues.28}}</span></td>
174 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} id="129" {%endif%}>{{beam.get_downvalues.28}}</span></td>
175 <td title='{{module_messages.30}}'><span id="130" {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_downvalues.29}}</span></td>
175 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} id="130" {%endif%}>{{beam.get_downvalues.29}}</span></td>
176 <td title='{{module_messages.31}}'><span id="131" {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_downvalues.30}}</span></td>
176 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} id="131" {%endif%}>{{beam.get_downvalues.30}}</span></td>
177 <td title='{{module_messages.32}}'><span id="132" {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_downvalues.31}}</span></td>
177 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} id="132" {%endif%}>{{beam.get_downvalues.31}}</span></td>
178 </tr>
178 </tr>
179 </table>
179 </table>
180 </td>
180 </td>
181 </tr>
181 </tr>
182 <tr>
182 <tr>
183 <td>
183 <td>
184 <b>West Quarter</b>
184 <b>West Quarter</b>
185 <table class="module">
185 <table class="module">
186 <tr>
186 <tr>
187 <td title='{{module_messages.33}}'><span id="33" {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_upvalues.32}}</span></td>
187 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} id="33" {%endif%}>{{beam.get_upvalues.32}}</span></td>
188 <td title='{{module_messages.34}}'><span id="34" {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_upvalues.33}}</span></td>
188 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} id="34" {%endif%}>{{beam.get_upvalues.33}}</span></td>
189 <td title='{{module_messages.35}}'><span id="35" {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_upvalues.34}}</span></td>
189 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} id="35" {%endif%}>{{beam.get_upvalues.34}}</span></td>
190 <td title='{{module_messages.36}}'><span id="36" {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_upvalues.35}}</span></td>
190 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} id="36" {%endif%}>{{beam.get_upvalues.35}}</span></td>
191 </tr>
191 </tr>
192 <tr>
192 <tr>
193 <td title='{{module_messages.33}}'><span id="133" {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_downvalues.32}}</span></td>
193 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} id="133" {%endif%}>{{beam.get_downvalues.32}}</span></td>
194 <td title='{{module_messages.34}}'><span id="134" {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_downvalues.33}}</span></td>
194 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} id="134" {%endif%}>{{beam.get_downvalues.33}}</span></td>
195 <td title='{{module_messages.35}}'><span id="135" {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_downvalues.34}}</span></td>
195 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} id="135" {%endif%}>{{beam.get_downvalues.34}}</span></td>
196 <td title='{{module_messages.36}}'><span id="136" {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_downvalues.35}}</span></td>
196 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} id="136" {%endif%}>{{beam.get_downvalues.35}}</span></td>
197 </tr>
197 </tr>
198 <tr>
198 <tr>
199 <td title='{{module_messages.41}}'><span id="41" {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_upvalues.40}}</span></td>
199 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} id="41" {%endif%}>{{beam.get_upvalues.40}}</span></td>
200 <td title='{{module_messages.42}}'><span id="42" {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_upvalues.41}}</span></td>
200 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} id="42" {%endif%}>{{beam.get_upvalues.41}}</span></td>
201 <td title='{{module_messages.43}}'><span id="43" {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_upvalues.42}}</span></td>
201 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} id="43" {%endif%}>{{beam.get_upvalues.42}}</span></td>
202 <td title='{{module_messages.44}}'><span id="44" {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_upvalues.43}}</span></td>
202 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} id="44" {%endif%}>{{beam.get_upvalues.43}}</span></td>
203 </tr>
203 </tr>
204 <tr>
204 <tr>
205 <td title='{{module_messages.41}}'><span id="141" {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_downvalues.40}}</span></td>
205 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} id="141" {%endif%}>{{beam.get_downvalues.40}}</span></td>
206 <td title='{{module_messages.42}}'><span id="142" {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_downvalues.41}}</span></td>
206 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} id="142" {%endif%}>{{beam.get_downvalues.41}}</span></td>
207 <td title='{{module_messages.43}}'><span id="143" {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_downvalues.42}}</span></td>
207 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} id="143" {%endif%}>{{beam.get_downvalues.42}}</span></td>
208 <td title='{{module_messages.44}}'><span id="144" {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_downvalues.43}}</span></td>
208 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} id="144" {%endif%}>{{beam.get_downvalues.43}}</span></td>
209 </tr>
209 </tr>
210 <tr>
210 <tr>
211 <td title='{{module_messages.49}}'><span id="49" {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_upvalues.48}}</span></td>
211 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} id="49" {%endif%}>{{beam.get_upvalues.48}}</span></td>
212 <td title='{{module_messages.51}}'><span id="50" {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_upvalues.49}}</span></td>
212 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} id="50" {%endif%}>{{beam.get_upvalues.49}}</span></td>
213 <td title='{{module_messages.52}}'><span id="51" {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_upvalues.50}}</span></td>
213 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} id="51" {%endif%}>{{beam.get_upvalues.50}}</span></td>
214 <td title='{{module_messages.53}}'><span id="52" {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_upvalues.51}}</span></td>
214 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="52" {%endif%}>{{beam.get_upvalues.51}}</span></td>
215 </tr>
215 </tr>
216 <tr>
216 <tr>
217 <td title='{{module_messages.49}}'><span id="149" {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_downvalues.48}}</span></td>
217 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} id="149" {%endif%}>{{beam.get_downvalues.48}}</span></td>
218 <td title='{{module_messages.50}}'><span id="150" {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_downvalues.49}}</span></td>
218 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} id="150" {%endif%}>{{beam.get_downvalues.49}}</span></td>
219 <td title='{{module_messages.51}}'><span id="151" {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_downvalues.50}}</span></td>
219 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} id="151" {%endif%}>{{beam.get_downvalues.50}}</span></td>
220 <td title='{{module_messages.52}}'><span id="152" {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_downvalues.51}}</span></td>
220 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} id="152" {%endif%}>{{beam.get_downvalues.51}}</span></td>
221 </tr>
221 </tr>
222 <tr>
222 <tr>
223 <td title='{{module_messages.57}}'><span id="57" {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_upvalues.56}}</span></td>
223 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} id="57" {%endif%}>{{beam.get_upvalues.56}}</span></td>
224 <td title='{{module_messages.58}}'><span id="58" {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_upvalues.57}}</span></td>
224 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} id="58" {%endif%}>{{beam.get_upvalues.57}}</span></td>
225 <td title='{{module_messages.59}}'><span id="59" {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_upvalues.58}}</span></td>
225 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} id="59" {%endif%}>{{beam.get_upvalues.58}}</span></td>
226 <td title='{{module_messages.60}}'><span id="60" {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_upvalues.59}}</span></td>
226 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} id="60" {%endif%}>{{beam.get_upvalues.59}}</span></td>
227 </tr>
227 </tr>
228 <tr>
228 <tr>
229 <td title='{{module_messages.57}}'><span id="157" {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_downvalues.56}}</span></td>
229 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} id="157" {%endif%}>{{beam.get_downvalues.56}}</span></td>
230 <td title='{{module_messages.58}}'><span id="158" {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_downvalues.57}}</span></td>
230 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} id="158" {%endif%}>{{beam.get_downvalues.57}}</span></td>
231 <td title='{{module_messages.59}}'><span id="159" {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_downvalues.58}}</span></td>
231 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} id="159" {%endif%}>{{beam.get_downvalues.58}}</span></td>
232 <td title='{{module_messages.60}}'><span id="160" {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_downvalues.59}}</span></td>
232 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} id="160" {%endif%}>{{beam.get_downvalues.59}}</span></td>
233 </tr>
233 </tr>
234 </table>
234 </table>
235 </td>
235 </td>
236 <td>
236 <td>
237 <b>South Quarter</b>
237 <b>South Quarter</b>
238 <table class="module">
238 <table class="module">
239 <tr>
239 <tr>
240 <td title='{{module_messages.37}}'><span id="37" {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_upvalues.36}}</span></td>
240 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} id="37" {%endif%}>{{beam.get_upvalues.36}}</span></td>
241 <td title='{{module_messages.38}}'><span id="38" {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_upvalues.37}}</span></td>
241 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} id="38" {%endif%}>{{beam.get_upvalues.37}}</span></td>
242 <td title='{{module_messages.39}}'><span id="39" {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_upvalues.38}}</span></td>
242 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} id="39" {%endif%}>{{beam.get_upvalues.38}}</span></td>
243 <td title='{{module_messages.40}}'><span id="40" {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_upvalues.39}}</span></td>
243 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} id="40" {%endif%}>{{beam.get_upvalues.39}}</span></td>
244 </tr>
244 </tr>
245 <tr>
245 <tr>
246 <td title='{{module_messages.37}}'><span id="137" {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_downvalues.36}}</span></td>
246 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} id="137" {%endif%}>{{beam.get_downvalues.36}}</span></td>
247 <td title='{{module_messages.38}}'><span id="138" {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_downvalues.37}}</span></td>
247 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} id="138" {%endif%}>{{beam.get_downvalues.37}}</span></td>
248 <td title='{{module_messages.39}}'><span id="139" {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_downvalues.38}}</span></td>
248 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} id="139" {%endif%}>{{beam.get_downvalues.38}}</span></td>
249 <td title='{{module_messages.40}}'><span id="140" {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_downvalues.39}}</span></td>
249 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} id="140" {%endif%}>{{beam.get_downvalues.39}}</span></td>
250 </tr>
250 </tr>
251 <tr>
251 <tr>
252 <td title='{{module_messages.45}}'><span id="45" {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_upvalues.44}}</span></td>
252 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} id="45" {%endif%}>{{beam.get_upvalues.44}}</span></td>
253 <td title='{{module_messages.46}}'><span id="46" {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_upvalues.45}}</span></td>
253 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} id="46" {%endif%}>{{beam.get_upvalues.45}}</span></td>
254 <td title='{{module_messages.47}}'><span id="47" {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_upvalues.46}}</span></td>
254 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} id="47" {%endif%}>{{beam.get_upvalues.46}}</span></td>
255 <td title='{{module_messages.48}}'><span id="48" {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_upvalues.47}}</span></td>
255 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} id="48" {%endif%}>{{beam.get_upvalues.47}}</span></td>
256 </tr>
256 </tr>
257 <tr>
257 <tr>
258 <td title='{{module_messages.45}}'><span id="145" {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_downvalues.44}}</span></td>
258 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} id="145" {%endif%}>{{beam.get_downvalues.44}}</span></td>
259 <td title='{{module_messages.46}}'><span id="146" {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_downvalues.45}}</span></td>
259 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} id="146" {%endif%}>{{beam.get_downvalues.45}}</span></td>
260 <td title='{{module_messages.47}}'><span id="147" {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_downvalues.46}}</span></td>
260 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} id="147" {%endif%}>{{beam.get_downvalues.46}}</span></td>
261 <td title='{{module_messages.48}}'><span id="148" {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_downvalues.47}}</span></td>
261 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} id="148" {%endif%}>{{beam.get_downvalues.47}}</span></td>
262 </tr>
262 </tr>
263 <tr>
263 <tr>
264 <td title='{{module_messages.53}}'><span id="53" {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_upvalues.52}}</span></td>
264 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="53" {%endif%}>{{beam.get_upvalues.52}}</span></td>
265 <td title='{{module_messages.54}}'><span id="54" {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_upvalues.53}}</span></td>
265 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} id="54" {%endif%}>{{beam.get_upvalues.53}}</span></td>
266 <td title='{{module_messages.55}}'><span id="55" {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_upvalues.54}}</span></td>
266 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} id="55" {%endif%}>{{beam.get_upvalues.54}}</span></td>
267 <td title='{{module_messages.56}}'><span id="56" {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_upvalues.55}}</span></td>
267 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} id="56" {%endif%}>{{beam.get_upvalues.55}}</span></td>
268 </tr>
268 </tr>
269 <tr>
269 <tr>
270 <td title='{{module_messages.53}}'><span id="153" {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_downvalues.52}}</span></td>
270 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="153" {%endif%}>{{beam.get_downvalues.52}}</span></td>
271 <td title='{{module_messages.54}}'><span id="154" {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_downvalues.53}}</span></td>
271 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} id="154" {%endif%}>{{beam.get_downvalues.53}}</span></td>
272 <td title='{{module_messages.55}}'><span id="155" {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_downvalues.54}}</span></td>
272 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} id="155" {%endif%}>{{beam.get_downvalues.54}}</span></td>
273 <td title='{{module_messages.56}}'><span id="156" {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_downvalues.55}}</span></td>
273 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} id="156" {%endif%}>{{beam.get_downvalues.55}}</span></td>
274 </tr>
274 </tr>
275 <tr>
275 <tr>
276 <td title='{{module_messages.61}}'><span id="61" {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_upvalues.60}}</span></td>
276 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} id="61" {%endif%}>{{beam.get_upvalues.60}}</span></td>
277 <td title='{{module_messages.62}}'><span id="62" {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_upvalues.61}}</span></td>
277 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} id="62" {%endif%}>{{beam.get_upvalues.61}}</span></td>
278 <td title='{{module_messages.63}}'><span id="63" {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_upvalues.62}}</span></td>
278 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} id="63" {%endif%}>{{beam.get_upvalues.62}}</span></td>
279 <td title='{{module_messages.64}}'><span id="64" {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_upvalues.63}}</span></td>
279 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} id="64" {%endif%}>{{beam.get_upvalues.63}}</span></td>
280 </tr>
280 </tr>
281 <tr>
281 <tr>
282 <td title='{{module_messages.61}}'><span id="161" {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_downvalues.60}}</span></td>
282 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} id="161" {%endif%}>{{beam.get_downvalues.60}}</span></td>
283 <td title='{{module_messages.62}}'><span id="162" {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_downvalues.61}}</span></td>
283 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} id="162" {%endif%}>{{beam.get_downvalues.61}}</span></td>
284 <td title='{{module_messages.63}}'><span id="163" {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_downvalues.62}}</span></td>
284 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} id="163" {%endif%}>{{beam.get_downvalues.62}}</span></td>
285 <td title='{{module_messages.64}}'><span id="164" {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_downvalues.63}}</span></td>
285 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} id="164" {%endif%}>{{beam.get_downvalues.63}}</span></td>
286 </tr>
286 </tr>
287 </table>
287 </table>
288 </td>
288 </td>
289 </tr>
289 </tr>
290 </table>
290 </table>
291
291
292 <!-- <meta id="configuraciones_down" data-playlist="{{ beam.get_downvalues }}">
292 <!-- <meta id="configuraciones_down" data-playlist="{{ beam.get_downvalues }}">
293 <meta id="configuraciones_up" data-playlist="{{ beam.get_upvalues }}">
293 <meta id="configuraciones_up" data-playlist="{{ beam.get_upvalues }}">
294 <meta id="sda" data-toggle="" -->
294 <meta id="sda" data-toggle="" -->
295
295
296 {% if beam.id == active_beam %}
296 {% if beam.id == active_beam %}
297 <table class="legend">
297 <table class="legend">
298 <tr>
298 <tr>
299 <th>Legend</th>
299 <th>Legend</th>
300 </tr>
300 </tr>
301 <tr>
301 <tr>
302 <td class="text-warning">Connected</td>
302 <td class="text-success">Running and Match</td>
303 </tr>
303 </tr>
304 <tr>
304 <tr>
305 <td class="text-success">Running</td>
305 <td class="text-info">Mismatch</td>
306 </tr>
307 <tr>
308 <td class="text-info">Mismath</td>
309 </tr>
306 </tr>
310 <tr>
307 <tr>
311 <td class="text-danger">Disconnected</td>
308 <td class="text-danger">Disconnected</td>
312 </tr>
309 </tr>
313 </table>
310 </table>
314 {% else %}
311 {% else %}
315 <div style="vertical-align: top; display:inline-block;">
312 <div style="vertical-align: top; display:inline-block;">
316 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
313 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
317 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
314 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
318 Change Beam</button>
315 Change Beam</button>
319 <br><br><br>
316 <br><br><br>
320 <button id="change_beam_mqtt{{forloop.counter}}" type="button" class="btn btn-default">
317 <button id="change_beam_mqtt{{forloop.counter}}" type="button" class="btn btn-default">
321 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
318 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
322 Change Beam MQTT</button>
319 Change Beam MQTT</button>
323 </div>
320 </div>
324 {% endif %}
321 {% endif %}
325 </div>
322 </div>
326 {% endfor %}
323 {% endfor %}
327 </div>
324 </div>
328 </div>
325 </div>
329
326
330
327
331 {% else %}
328 {% else %}
332 <p style="color:#b4bcc2; margin-left: 5%;">
329 <p style="color:#b4bcc2; margin-left: 5%;">
333 <i>No Beams...</i>
330 <i>No Beams...</i>
334 </p>
331 </p>
335 {% endif %}
332 {% endif %}
336 {% endblock extra-content %}
333 {% endblock extra-content %}
337
334
338 {% block extra-js%}
335 {% block extra-js%}
339 <script>
336 <script>
340 $(document).ready(function () {
337 $(document).ready(function () {
341
338
342 // var elemento = document.getElementById("4");
339 // var elemento = document.getElementById("4");
340 // console.log(beam.pk);
341 // console.log(active_beam);
343
342
344 var socket = io.connect('http://' + document.domain + ':' + location.port);
343 var socket = io.connect('http://' + document.domain + ':' + location.port);
345
344
346 socket.on('connect', function(data) {
345 socket.on('connect', function(data) {
347 console.log('Connecting... OK');
346 console.log('Connecting... OK');
348 })
347 })
349
348
350 socket.on('abs_ws', function(data) {
349 socket.on('abs_ws', function(data) {
351 console.log('ingresamos');
350 console.log('ingresamos');
352 console.log(data.msg);
351 console.log(data.msg);
353 var text = data['msg'];
352 var text = data['msg'];
354 // $('#chatLog').val(text);
353 // $('#chatLog').val(text);
355
354
356 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
355 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
357 })
356 })
358
357
359 socket.on('beams_ack', function(data) {
358 socket.on('beams_ack', function(data) {
360 console.log('beams_ack');
359 // console.log('beams_ack');
361 var text = data['msg'];
360 var text = data['msg'];
362
361
363 for (let i=1; i<=64;i++){
362 for (let i=1; i<=64;i++){
364
363
365 var elemento = document.getElementById(text[i-1]);
364 var elemento = document.getElementById(text[i-1]);
366 var elemento2 = document.getElementById(text[i-1]+100);
365 var elemento2 = document.getElementById(text[i-1]+100);
367 if (text[i-1]<=64){
366 if (text[i-1]<=64){
368 console.log("1")
367 // console.log("1")
369 // elemento=document.getElementById(text[i-1]);
368 // elemento=document.getElementById(text[i-1]);
370 elemento.style.color="green";
369 elemento.style.color="green";
371 elemento.style.fontWeight = "bold";
370 elemento.style.fontWeight = "bold";
372 elemento2.style.color="green";
371 elemento2.style.color="green";
373 elemento2.style.fontWeight = "bold";}
372 elemento2.style.fontWeight = "bold";}
374 else if (text[i-1]>64){
373 else if (text[i-1]>64){
375 elemento=document.getElementById(text[i-1]-64);
374 elemento=document.getElementById(text[i-1]-64);
376 elemento2=document.getElementById(text[i-1]-64+100);
375 elemento2=document.getElementById(text[i-1]-64+100);
377 elemento.style.color="yellow";
376 elemento.style.color="blue";
378 elemento.style.fontWeight = "bold";
377 elemento.style.fontWeight = "bold";
379 elemento2.style.color="yellow";
378 elemento2.style.color="blue";
380 elemento2.style.fontWeight = "bold"}
379 elemento2.style.fontWeight = "bold"}
381 else {
380 else {
382 elemento.style.color="red";
381 elemento.style.color="red";
383 elemento.style.fontWeight = "bold";
382 elemento.style.fontWeight = "bold";
384 elemento2.style.color="red";
383 elemento2.style.color="red";
385 elemento2.style.fontWeight = "bold"}
384 elemento2.style.fontWeight = "bold"}
386 }
385 }
387
386
388
387
389
388
390 console.log(text[0])
389 // console.log(text[0])
391
390
392
391
393 // $('#chatLog').val(text);
392 // $('#chatLog').val(text);
394
393
395 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
394 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
396 })
395 })
397
396
398
397
399 {% for beam in beams %}
398 {% for beam in beams %}
400
399
401 {% if dev_conf.operation_mode == 1 %}
400 {% if dev_conf.operation_mode == 1 %}
402 $("#send_beam{{forloop.counter}}").prop('disabled', true)
401 $("#send_beam{{forloop.counter}}").prop('disabled', true)
403 $("#change_beam_mqtt{{forloop.counter}}").prop('disabled', true)
402 $("#change_beam_mqtt{{forloop.counter}}").prop('disabled', true)
404 {% else %}
403 {% else %}
405 $("#send_beam{{forloop.counter}}").click(function () {
404 $("#send_beam{{forloop.counter}}").click(function () {
406 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
405 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
407 });
406 });
408
407
409 change_beam_mqtt_btn=$("#change_beam_mqtt{{forloop.counter}}")
408 change_beam_mqtt_btn=$("#change_beam_mqtt{{forloop.counter}}")
410 change_beam_mqtt_btn.click(function () {
409 change_beam_mqtt_btn.click(function () {
411 info="change_beam_mqtt{{forloop.counter}}"
410 // info="change_beam_mqtt{{forloop.counter}}"
412 socket.emit('change_beam',{data:info});
411 // socket.emit('change_beam',{data:info});
413 document.location = "{% url 'url_send_beam_mqtt' dev_conf.id beam.id %}";
412 document.location = "{% url 'url_change_beam_mqtt' dev_conf.id beam.id %}";
414 });
413 });
415
414
416 {% endif %}
415 {% endif %}
417
416
418 {% endfor %}
417 {% endfor %}
419
418
420
419
421 });
420 });
422
421
423 </script>
422 </script>
424
423
425
424
426 {% endblock %}
425 {% endblock %}
@@ -1,19 +1,20
1 from django.urls import path
1 from django.urls import path
2
2
3 from apps.abs import views
3 from apps.abs import views
4
4
5 urlpatterns = (
5 urlpatterns = (
6 path('<int:id_conf>/', views.abs_conf, name='url_abs_conf'),
6 path('<int:id_conf>/', views.abs_conf, name='url_abs_conf'),
7 path('<int:id_conf>/mqtt', views.abs_conf_mqtt, name='url_abs_conf_mqtt'),
7 path('<int:id_conf>/edit/', views.abs_conf_edit, name='url_edit_abs_conf'),
8 path('<int:id_conf>/edit/', views.abs_conf_edit, name='url_edit_abs_conf'),
8 path('alert/', views.abs_conf_alert, name='url_alert_abs_conf'),
9 path('alert/', views.abs_conf_alert, name='url_alert_abs_conf'),
9 path('<int:id_conf>/import/', views.import_file, name='url_import_abs_conf'),
10 path('<int:id_conf>/import/', views.import_file, name='url_import_abs_conf'),
10 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
11 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
11 path('<int:id_conf>/change_beam/<int:id_beam>/', views.send_beam, name='url_send_beam'),
12 path('<int:id_conf>/change_beam/<int:id_beam>/', views.send_beam, name='url_send_beam'),
12 path('<int:id_conf>/change_beam/<int:id_beam>/', views.change_beam_mqtt, name='url_send_beam_mqtt'),
13 path('<int:id_conf>/change_beam_mqtt/<int:id_beam>/', views.change_beam_mqtt, name='url_change_beam_mqtt'),
13 path('<int:id_conf>/plot/', views.plot_patterns, name='url_plot_abs_patterns'),
14 path('<int:id_conf>/plot/', views.plot_patterns, name='url_plot_abs_patterns'),
14 path('<int:id_conf>/plot/<int:id_beam>/', views.plot_patterns, name='url_plot_abs_patterns2'),
15 path('<int:id_conf>/plot/<int:id_beam>/', views.plot_patterns, name='url_plot_abs_patterns2'),
15 path('<int:id_conf>/plot/<int:id_beam>/<slug:antenna>/pattern.png/', views.plot_pattern, name='url_plot_beam'),
16 path('<int:id_conf>/plot/<int:id_beam>/<slug:antenna>/pattern.png/', views.plot_pattern, name='url_plot_beam'),
16 path('<int:id_conf>/add_beam/', views.add_beam, name='url_add_abs_beam'),
17 path('<int:id_conf>/add_beam/', views.add_beam, name='url_add_abs_beam'),
17 path('<int:id_conf>/beam/<int:id_beam>/delete/', views.remove_beam, name='url_remove_abs_beam'),
18 path('<int:id_conf>/beam/<int:id_beam>/delete/', views.remove_beam, name='url_remove_abs_beam'),
18 path('<int:id_conf>/beam/<int:id_beam>/edit/', views.edit_beam, name='url_edit_abs_beam'),
19 path('<int:id_conf>/beam/<int:id_beam>/edit/', views.edit_beam, name='url_edit_abs_beam'),
19 )
20 )
@@ -1,560 +1,574
1 from django.shortcuts import render
1 from django.shortcuts import render
2 from django.template import RequestContext
2 from django.template import RequestContext
3 from django.shortcuts import redirect, render, get_object_or_404
3 from django.shortcuts import redirect, render, get_object_or_404
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.conf import settings
5 from django.conf import settings
6 from django.http import HttpResponse
6 from django.http import HttpResponse
7 from django.urls import reverse
7 from django.urls import reverse
8 from django.views.decorators.csrf import csrf_exempt
8 from django.views.decorators.csrf import csrf_exempt
9 from django.utils.safestring import mark_safe
9 from django.utils.safestring import mark_safe
10
10
11 from datetime import datetime
11 from datetime import datetime
12 from time import sleep
12 from time import sleep
13 import os
13 import os
14 import io
14 import io
15
15
16 from apps.main.models import Device, Configuration, Experiment
16 from apps.main.models import Device, Configuration, Experiment
17 from apps.main.views import sidebar
17 from apps.main.views import sidebar
18
18
19 from .models import ABSConfiguration, ABSBeam
19 from .models import ABSConfiguration, ABSBeam
20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
21
21
22 from .utils.overJroShow import overJroShow
22 from .utils.overJroShow import overJroShow
23 #from .utils.OverJRO import OverJRO
23 #from .utils.OverJRO import OverJRO
24 #Create your views here.
24 #Create your views here.
25 import json, ast
25 import json, ast
26
26
27 from .mqtt import client as mqtt_client
27 from .mqtt import client as mqtt_client
28 from radarsys.socketconfig import sio as sio
28 from radarsys.socketconfig import sio as sio
29
29
30 def get_values_from_form(form_data):
30 def get_values_from_form(form_data):
31
31
32 sublistup = []
32 sublistup = []
33 sublistdown = []
33 sublistdown = []
34 subtxlistup = []
34 subtxlistup = []
35 subtxlistdown = []
35 subtxlistdown = []
36 subrxlistup = []
36 subrxlistup = []
37 subrxlistdown = []
37 subrxlistdown = []
38
38
39 up_values_list = []
39 up_values_list = []
40 down_values_list = []
40 down_values_list = []
41 up_txvalues_list = []
41 up_txvalues_list = []
42 down_txvalues_list = []
42 down_txvalues_list = []
43 up_rxvalues_list = []
43 up_rxvalues_list = []
44 down_rxvalues_list = []
44 down_rxvalues_list = []
45
45
46 values_list = {}
46 values_list = {}
47 cont = 1
47 cont = 1
48
48
49 for i in range(1,65):
49 for i in range(1,65):
50 x = float(form_data['abs_up'+str(i)])
50 x = float(form_data['abs_up'+str(i)])
51 y = float(form_data['abs_down'+str(i)])
51 y = float(form_data['abs_down'+str(i)])
52 sublistup.append(x)
52 sublistup.append(x)
53 sublistdown.append(y)
53 sublistdown.append(y)
54
54
55 if str(i) in form_data.getlist('uptx_checks'):
55 if str(i) in form_data.getlist('uptx_checks'):
56 subtxlistup.append(1)
56 subtxlistup.append(1)
57 else:
57 else:
58 subtxlistup.append(0)
58 subtxlistup.append(0)
59 if str(i) in form_data.getlist('downtx_checks'):
59 if str(i) in form_data.getlist('downtx_checks'):
60 subtxlistdown.append(1)
60 subtxlistdown.append(1)
61 else:
61 else:
62 subtxlistdown.append(0)
62 subtxlistdown.append(0)
63
63
64 if str(i) in form_data.getlist('uprx_checks'):
64 if str(i) in form_data.getlist('uprx_checks'):
65 subrxlistup.append(1)
65 subrxlistup.append(1)
66 else:
66 else:
67 subrxlistup.append(0)
67 subrxlistup.append(0)
68 if str(i) in form_data.getlist('downrx_checks'):
68 if str(i) in form_data.getlist('downrx_checks'):
69 subrxlistdown.append(1)
69 subrxlistdown.append(1)
70 else:
70 else:
71 subrxlistdown.append(0)
71 subrxlistdown.append(0)
72
72
73 cont = cont+1
73 cont = cont+1
74
74
75 if cont == 9:
75 if cont == 9:
76 up_values_list.append(sublistup)
76 up_values_list.append(sublistup)
77 down_values_list.append(sublistdown)
77 down_values_list.append(sublistdown)
78 sublistup = []
78 sublistup = []
79 sublistdown = []
79 sublistdown = []
80
80
81 up_txvalues_list.append(subtxlistup)
81 up_txvalues_list.append(subtxlistup)
82 down_txvalues_list.append(subtxlistdown)
82 down_txvalues_list.append(subtxlistdown)
83 subtxlistup = []
83 subtxlistup = []
84 subtxlistdown = []
84 subtxlistdown = []
85 up_rxvalues_list.append(subrxlistup)
85 up_rxvalues_list.append(subrxlistup)
86 down_rxvalues_list.append(subrxlistdown)
86 down_rxvalues_list.append(subrxlistdown)
87 subrxlistup = []
87 subrxlistup = []
88 subrxlistdown = []
88 subrxlistdown = []
89 cont = 1
89 cont = 1
90
90
91
91
92 list_uesup = []
92 list_uesup = []
93 list_uesdown = []
93 list_uesdown = []
94 for i in range(1,5):
94 for i in range(1,5):
95 if form_data['ues_up'+str(i)] == '':
95 if form_data['ues_up'+str(i)] == '':
96 list_uesup.append(0.0)
96 list_uesup.append(0.0)
97 else:
97 else:
98 list_uesup.append(float(form_data['ues_up'+str(i)]))
98 list_uesup.append(float(form_data['ues_up'+str(i)]))
99
99
100 if form_data['ues_down'+str(i)] == '':
100 if form_data['ues_down'+str(i)] == '':
101 list_uesdown.append(0.0)
101 list_uesdown.append(0.0)
102 else:
102 else:
103 list_uesdown.append(float(form_data['ues_down'+str(i)]))
103 list_uesdown.append(float(form_data['ues_down'+str(i)]))
104
104
105 onlyrx_list = form_data.getlist('onlyrx')
105 onlyrx_list = form_data.getlist('onlyrx')
106 only_rx = {}
106 only_rx = {}
107 if '1' in onlyrx_list:
107 if '1' in onlyrx_list:
108 only_rx['up'] = True
108 only_rx['up'] = True
109 else:
109 else:
110 only_rx['up'] = False
110 only_rx['up'] = False
111 if '2' in onlyrx_list:
111 if '2' in onlyrx_list:
112 only_rx['down'] = True
112 only_rx['down'] = True
113 else:
113 else:
114 only_rx['down'] = False
114 only_rx['down'] = False
115
115
116 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
116 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
117 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
117 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
118 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
118 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
119 ues = {'up': list_uesup, 'down': list_uesdown}
119 ues = {'up': list_uesup, 'down': list_uesdown}
120 name = str(form_data['beam_name'])
120 name = str(form_data['beam_name'])
121
121
122 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
122 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
123
123
124 return beam_data
124 return beam_data
125
125
126
126
127 def abs_conf(request, id_conf):
127 def abs_conf(request, id_conf):
128
128
129 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
129 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
130 beams = ABSBeam.objects.filter(abs_conf=conf)
130 beams = ABSBeam.objects.filter(abs_conf=conf)
131 #------------Colors for Active Beam:-------------
131 #------------Colors for Active Beam:-------------
132 all_status = {}
132 all_status = {}
133 module_messages = json.loads(conf.module_messages)
133 module_messages = json.loads(conf.module_messages)
134
134
135 color_status = {}
135 color_status = {}
136 for i, status in enumerate(conf.module_status):
136 for i, status in enumerate(conf.module_status):
137 if status == '3': #Running background-color: #00cc00;
137 if status == '3': #Running background-color: #00cc00;
138 all_status['{}'.format(i+1)] = 2
138 all_status['{}'.format(i+1)] = 2
139 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
139 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
140 elif status == '2':
140 elif status == '2':
141 all_status['{}'.format(i+1)] = 1
141 all_status['{}'.format(i+1)] = 1
142 color_status['{}'.format(i+1)] = 'class=text-info'
142 color_status['{}'.format(i+1)] = 'class=text-info'
143 elif status == '1': #Connected background-color: #ee902c;
143 elif status == '1': #Connected background-color: #ee902c;
144 all_status['{}'.format(i+1)] = 1
144 all_status['{}'.format(i+1)] = 1
145 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
145 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
146 else: #Disconnected background-color: #ff0000;
146 else: #Disconnected background-color: #ff0000;
147 all_status['{}'.format(i+1)] = 0
147 all_status['{}'.format(i+1)] = 0
148 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
148 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
149 #------------------------------------------------
149 #------------------------------------------------
150
150
151 kwargs = {}
151 kwargs = {}
152 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
152 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
153 kwargs['dev_conf'] = conf
153 kwargs['dev_conf'] = conf
154
154
155 if conf.operation_mode == 0:
155 if conf.operation_mode == 0:
156 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
156 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
157 else:
157 else:
158 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
158 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
159
159
160 kwargs['title'] = 'ABS Configuration'
160 kwargs['title'] = 'ABS Configuration'
161 kwargs['suptitle'] = 'Details'
161 kwargs['suptitle'] = 'Details'
162 kwargs['button'] = 'Edit Configuration'
162 kwargs['button'] = 'Edit Configuration'
163
163
164 if conf.active_beam != 0:
164 if conf.active_beam != 0:
165 kwargs['active_beam'] = int(conf.active_beam)
165 kwargs['active_beam'] = int(conf.active_beam)
166
166
167 kwargs['beams'] = beams
167 kwargs['beams'] = beams
168 kwargs['modules_status'] = all_status
168 kwargs['modules_status'] = all_status
169 kwargs['color_status'] = color_status
169 kwargs['color_status'] = color_status
170 kwargs['module_messages'] = module_messages
170 kwargs['module_messages'] = module_messages
171 ###### SIDEBAR ######
171 ###### SIDEBAR ######
172 kwargs.update(sidebar(conf=conf))
172 kwargs.update(sidebar(conf=conf))
173
173
174 return render(request, 'abs_conf.html', kwargs)
174 return render(request, 'abs_conf.html', kwargs)
175
175
176 def abs_conf_mqtt(request, id_conf):
177 print("Estoy en abs_conf_mqtt",flush=True)
178 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
179 beams = ABSBeam.objects.filter(abs_conf=conf)
180 #------------Colors for Active Beam:-------------
181 all_status = {}
182 module_messages = json.loads(conf.module_messages)
183
184 kwargs = {}
185 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
186 kwargs['dev_conf'] = conf
187
188 if conf.operation_mode == 0:
189 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
190 else:
191 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
192
193 kwargs['title'] = 'ABS Configuration'
194 kwargs['suptitle'] = 'Details'
195 kwargs['button'] = 'Edit Configuration'
196
197 if conf.active_beam != 0:
198 kwargs['active_beam'] = int(conf.active_beam)
176
199
200 kwargs['mqtt']=True
201 kwargs['beams'] = beams
202 kwargs['modules_status'] = all_status
203 kwargs['module_messages'] = module_messages
204 ###### SIDEBAR ######
205 kwargs.update(sidebar(conf=conf))
206 print("conf.active_beam: {}",format(conf.active_beam))
207
208 # print(conf.beam.pk)
209
210 return render(request, 'abs_conf_mqtt.html', kwargs)
211 # // console.log(beam.pk);
212 # // console.log(active_beam);
177 # def abs_conf_mqtt(request, id_conf):
213 # def abs_conf_mqtt(request, id_conf):
178 # # socket.on('beams_ack',function(data){
214 # # socket.on('beams_ack',function(data){
179 # ack=data;
215 # ack=data;
180 # console.log("ack")
216 # console.log("ack")
181 # console.log(ack)
217 # console.log(ack)
182 # })
218 # })
183
219
184
220
185 def abs_conf_edit(request, id_conf):
221 def abs_conf_edit(request, id_conf):
186
222
187 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
223 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
188
224
189 beams = ABSBeam.objects.filter(abs_conf=conf)
225 beams = ABSBeam.objects.filter(abs_conf=conf)
190
226
191 if request.method=='GET':
227 if request.method=='GET':
192 form = ABSConfigurationForm(instance=conf)
228 form = ABSConfigurationForm(instance=conf)
193
229
194 if request.method=='POST':
230 if request.method=='POST':
195 form = ABSConfigurationForm(request.POST, instance=conf)
231 form = ABSConfigurationForm(request.POST, instance=conf)
196
232
197 if form.is_valid():
233 if form.is_valid():
198 conf = form.save(commit=False)
234 conf = form.save(commit=False)
199 conf.save()
235 conf.save()
200 return redirect('url_abs_conf', id_conf=conf.id)
236 return redirect('url_abs_conf_mqtt', id_conf=conf.id)
201
237
202 ###### SIDEBAR ######
238 ###### SIDEBAR ######
203 kwargs = {}
239 kwargs = {}
204
240
205 kwargs['dev_conf'] = conf
241 kwargs['dev_conf'] = conf
206 #kwargs['id_dev'] = conf.id
242 #kwargs['id_dev'] = conf.id
207 kwargs['id_conf'] = conf.id
243 kwargs['id_conf'] = conf.id
208 kwargs['form'] = form
244 kwargs['form'] = form
209 kwargs['abs_beams'] = beams
245 kwargs['abs_beams'] = beams
210 kwargs['title'] = 'Device Configuration'
246 kwargs['title'] = 'Device Configuration'
211 kwargs['suptitle'] = 'Edit'
247 kwargs['suptitle'] = 'Edit'
212 kwargs['button'] = 'Save'
248 kwargs['button'] = 'Save'
249 kwargs['mqtt']=True
213
250
214 kwargs['edit'] = True
251 kwargs['edit'] = True
215
252
216 return render(request, 'abs_conf_edit.html', kwargs)
253 return render(request, 'abs_conf_edit.html', kwargs)
217
254
218 @csrf_exempt
255 @csrf_exempt
219 def abs_conf_alert(request):
256 def abs_conf_alert(request):
220
257
221 if request.method == 'POST':
258 if request.method == 'POST':
222 print (request.POST)
259 print (request.POST)
223 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
260 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
224 else:
261 else:
225 return redirect('index')
262 return redirect('index')
226
263
227
264
228 def import_file(request, id_conf):
265 def import_file(request, id_conf):
229
266
230 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
267 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
231 if request.method=='POST':
268 if request.method=='POST':
232 form = ABSImportForm(request.POST, request.FILES)
269 form = ABSImportForm(request.POST, request.FILES)
233 if form.is_valid():
270 if form.is_valid():
234 try:
271 try:
235 parms = conf.import_from_file(request.FILES['file_name'])
272 parms = conf.import_from_file(request.FILES['file_name'])
236
273
237 if parms:
274 if parms:
238 conf.update_from_file(parms)
275 conf.update_from_file(parms)
239 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
276 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
240 return redirect(conf.get_absolute_url_edit())
277 return redirect(conf.get_absolute_url_edit())
241
278
242 except Exception as e:
279 except Exception as e:
243 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
280 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
244
281
245 else:
282 else:
246 messages.warning(request, 'Your current configuration will be replaced')
283 messages.warning(request, 'Your current configuration will be replaced')
247 form = ABSImportForm()
284 form = ABSImportForm()
248
285
249 kwargs = {}
286 kwargs = {}
250 kwargs['form'] = form
287 kwargs['form'] = form
251 kwargs['title'] = 'ABS Configuration'
288 kwargs['title'] = 'ABS Configuration'
252 kwargs['suptitle'] = 'Import file'
289 kwargs['suptitle'] = 'Import file'
253 kwargs['button'] = 'Upload'
290 kwargs['button'] = 'Upload'
254 kwargs['previous'] = conf.get_absolute_url()
291 kwargs['previous'] = conf.get_absolute_url()
255
292
256 return render(request, 'abs_import.html', kwargs)
293 return render(request, 'abs_import.html', kwargs)
257
294
258
295
259 def send_beam(request, id_conf, id_beam):
296 def send_beam(request, id_conf, id_beam):
260
297
261 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
298 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
262
299
263 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
300 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
264 if abs!=conf:
301 if abs!=conf:
265 url = '#' if abs is None else abs.get_absolute_url()
302 url = '#' if abs is None else abs.get_absolute_url()
266 label = 'None' if abs is None else abs.label
303 label = 'None' if abs is None else abs.label
267 messages.warning(
304 messages.warning(
268 request,
305 request,
269 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
306 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
270 url,
307 url,
271 label
308 label
272 ))
309 ))
273 )
310 )
274 return redirect(conf.get_absolute_url())
311 return redirect(conf.get_absolute_url())
275
312
276 beam = get_object_or_404(ABSBeam, pk=id_beam)
313 beam = get_object_or_404(ABSBeam, pk=id_beam)
277
314
278 if request.method == 'POST':
315 if request.method == 'POST':
279
316
280 beams_list = ABSBeam.objects.filter(abs_conf=conf)
317 beams_list = ABSBeam.objects.filter(abs_conf=conf)
281 conf.active_beam = id_beam
318 conf.active_beam = id_beam
282
319
283 i = 0
320 i = 0
284 for b in beams_list:
321 for b in beams_list:
285 if b.id == int(id_beam):
322 if b.id == int(id_beam):
286 break
323 break
287 else:
324 else:
288 i += 1
325 i += 1
289 beam_pos = i + 1 #Estandarizar
326 beam_pos = i + 1 #Estandarizar
290 print('{} Position {}'.format(beam.name,str(beam_pos)))
327 print('{} Position {}'.format(beam.name,str(beam_pos)))
291 conf.send_beam(beam_pos)
328 conf.send_beam(beam_pos)
292
329
293 return redirect('url_abs_conf', conf.id)
330 return redirect('url_abs_conf', conf.id)
294
331
295 kwargs = {
332 kwargs = {
296 'title': 'ABS',
333 'title': 'ABS',
297 'suptitle': conf.label,
334 'suptitle': conf.label,
298 'message': 'Are you sure you want to change ABS Beam to: {}?'.format(beam.name),
335 'message': 'Are you sure you want to change ABS Beam through SEND BEAM to: {}?'.format(beam.name),
299 'delete': False
336 'delete': False
300 }
337 }
301 kwargs['menu_configurations'] = 'active'
338 kwargs['menu_configurations'] = 'active'
302
339
303 return render(request, 'confirm.html', kwargs)
340 return render(request, 'confirm.html', kwargs)
304
341
305 def change_beam_mqtt(request, id_conf, id_beam):
342 def change_beam_mqtt(request, id_conf, id_beam):
306
343
307 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
344 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
345 print("conf: {}".format(conf),flush=True)
308
346
309 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
347 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
348 print("abs: {}".format(abs),flush=True)
310 if abs!=conf:
349 if abs!=conf:
311 url = '#' if abs is None else abs.get_absolute_url()
350 url = '#' if abs is None else abs.get_absolute_url()
312 label = 'None' if abs is None else abs.label
351 label = 'None' if abs is None else abs.label
313 messages.warning(
352 messages.warning(
314 request,
353 request,
315 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
354 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
316 url,
355 url,
317 label
356 label
318 ))
357 ))
319 )
358 )
320 return redirect(conf.get_absolute_url())
359 return redirect(conf.get_absolute_mqtt_url())
321
360
322 beams = ABSBeam.objects.filter(abs_conf=conf)
361 beams = ABSBeam.objects.filter(abs_conf=conf)
323 beam = get_object_or_404(ABSBeam, pk=id_beam)
362 beam = get_object_or_404(ABSBeam, pk=id_beam)
324
363
325 if request.method == 'POST':
364 if request.method == 'POST':
326
365
327 beams_list = ABSBeam.objects.filter(abs_conf=conf)
366 beams_list = ABSBeam.objects.filter(abs_conf=conf)
328 conf.active_beam = id_beam
367 conf.active_beam = id_beam
329
368
330 i = 0
369 i = 0
331 for b in beams_list:
370 for b in beams_list:
332 if b.id == int(id_beam):
371 if b.id == int(id_beam):
333 break
372 break
334 else:
373 else:
335 i += 1
374 i += 1
336 beam_pos = i + 1 #Estandarizar
375 beam_pos = i + 1 #Estandarizar
337
376
338 print('{} Position {}'.format(beam.name,str(beam_pos)))
377 print('{} Position {}'.format(beam.name,str(beam_pos)),flush=True)
339 conf.change_beam_mqtt(beam_pos)
378 conf.change_beam_mqtt(beam_pos)
340
341 module_messages = json.loads(conf.module_messages)
342 kwargs = {}
343 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
344 kwargs['dev_conf'] = conf
345
346 if conf.operation_mode == 0:
347 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
348 else:
349 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
350
351 kwargs['title'] = 'ABS Configuration'
352 kwargs['suptitle'] = 'Details'
353 kwargs['button'] = 'Edit Configuration'
354 if conf.active_beam != 0:
355 kwargs['active_beam'] = int(conf.active_beam)
356
357
358 kwargs['beams'] = beams
359 # kwargs['modules_status'] = all_status
360 # kwargs['color_status'] = color_status
361
362
363 kwargs['module_messages'] = module_messages
364
365 ###### SIDEBAR ######
366 kwargs.update(sidebar(conf=conf))
367
379
368 # return redirect('url_abs_conf', conf.id)
380 # return redirect('url_abs_conf', conf.id)
369 return render(request, 'abs_conf_mqtt.html',kwargs)
381 return redirect('url_abs_conf_mqtt', conf.id)
382 # return render(request, 'abs_conf_mqtt.html',kwargs)
370
383
371 kwargs = {
384 kwargs = {
372 'title': 'ABS',
385 'title': 'ABS',
386 'mqtt':True,
373 'suptitle': conf.label,
387 'suptitle': conf.label,
374 'message': 'Are you sure you want to change ABS Beam through MQTT to: {}?'.format(beam.name),
388 'message': 'Are you sure you want to change ABS Beam through MQTT to: {}?'.format(beam.name),
375 'delete': False
389 'delete': False
376 }
390 }
377 kwargs['menu_configurations'] = 'active'
391 kwargs['menu_configurations'] = 'active'
378
392
379 return render(request, 'confirm.html', kwargs)
393 return render(request, 'confirm.html', kwargs)
380
394
381 def add_beam(request, id_conf):
395 def add_beam(request, id_conf):
382
396
383 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
397 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
384 confs = Configuration.objects.all()
398 confs = Configuration.objects.all()
385
399
386 if request.method=='GET':
400 if request.method=='GET':
387 form = ABSBeamAddForm()
401 form = ABSBeamAddForm()
388
402
389 if request.method=='POST':
403 if request.method=='POST':
390 form = ABSBeamAddForm(request.POST)
404 form = ABSBeamAddForm(request.POST)
391
405
392 beam_data = get_values_from_form(request.POST)
406 beam_data = get_values_from_form(request.POST)
393
407
394 new_beam = ABSBeam(
408 new_beam = ABSBeam(
395 name = beam_data['name'],
409 name = beam_data['name'],
396 antenna = json.dumps(beam_data['antenna']),
410 antenna = json.dumps(beam_data['antenna']),
397 abs_conf = conf,
411 abs_conf = conf,
398 tx = json.dumps(beam_data['tx']),
412 tx = json.dumps(beam_data['tx']),
399 rx = json.dumps(beam_data['rx']),
413 rx = json.dumps(beam_data['rx']),
400 ues = json.dumps(beam_data['ues']),
414 ues = json.dumps(beam_data['ues']),
401 only_rx = json.dumps(beam_data['only_rx'])
415 only_rx = json.dumps(beam_data['only_rx'])
402 )
416 )
403 new_beam.save()
417 new_beam.save()
404 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
418 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
405
419
406 return redirect('url_edit_abs_conf', conf.id)
420 return redirect('url_edit_abs_conf', conf.id)
407
421
408 ###### SIDEBAR ######
422 ###### SIDEBAR ######
409 kwargs = {}
423 kwargs = {}
410
424
411 #kwargs['dev_conf'] = conf.device
425 #kwargs['dev_conf'] = conf.device
412 #kwargs['id_dev'] = conf.device
426 #kwargs['id_dev'] = conf.device
413 #kwargs['previous'] = conf.get_absolute_url_edit()
427 #kwargs['previous'] = conf.get_absolute_url_edit()
414 kwargs['id_conf'] = conf.id
428 kwargs['id_conf'] = conf.id
415 kwargs['form'] = form
429 kwargs['form'] = form
416 kwargs['title'] = 'ABS Beams'
430 kwargs['title'] = 'ABS Beams'
417 kwargs['suptitle'] = 'Add Beam'
431 kwargs['suptitle'] = 'Add Beam'
418 kwargs['button'] = 'Add'
432 kwargs['button'] = 'Add'
419 kwargs['no_sidebar'] = True
433 kwargs['no_sidebar'] = True
420 kwargs['edit'] = True
434 kwargs['edit'] = True
421
435
422 return render(request, 'abs_add_beam.html', kwargs)
436 return render(request, 'abs_add_beam.html', kwargs)
423
437
424
438
425 def edit_beam(request, id_conf, id_beam):
439 def edit_beam(request, id_conf, id_beam):
426
440
427 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
441 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
428 beam = get_object_or_404(ABSBeam, pk=id_beam)
442 beam = get_object_or_404(ABSBeam, pk=id_beam)
429
443
430 if request.method=='GET':
444 if request.method=='GET':
431 form = ABSBeamEditForm(initial={'beam': beam})
445 form = ABSBeamEditForm(initial={'beam': beam})
432
446
433 if request.method=='POST':
447 if request.method=='POST':
434 form = ABSBeamEditForm(request.POST)
448 form = ABSBeamEditForm(request.POST)
435
449
436 beam_data = get_values_from_form(request.POST)
450 beam_data = get_values_from_form(request.POST)
437
451
438 beam.dict_to_parms(beam_data)
452 beam.dict_to_parms(beam_data)
439 beam.save()
453 beam.save()
440
454
441 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
455 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
442
456
443 return redirect('url_edit_abs_conf', conf.id)
457 return redirect('url_edit_abs_conf', conf.id)
444
458
445 ###### SIDEBAR ######
459 ###### SIDEBAR ######
446 kwargs = {}
460 kwargs = {}
447
461
448 kwargs['id_conf'] = conf.id
462 kwargs['id_conf'] = conf.id
449 kwargs['form'] = form
463 kwargs['form'] = form
450 kwargs['title'] = 'ABS Beams'
464 kwargs['title'] = 'ABS Beams'
451 kwargs['suptitle'] = 'Edit Beam'
465 kwargs['suptitle'] = 'Edit Beam'
452 kwargs['button'] = 'Save'
466 kwargs['button'] = 'Save'
453 kwargs['no_sidebar'] = True
467 kwargs['no_sidebar'] = True
454
468
455 #kwargs['previous'] = conf.get_absolute_url_edit()
469 #kwargs['previous'] = conf.get_absolute_url_edit()
456 kwargs['edit'] = True
470 kwargs['edit'] = True
457
471
458 return render(request, 'abs_edit_beam.html', kwargs)
472 return render(request, 'abs_edit_beam.html', kwargs)
459
473
460
474
461
475
462 def remove_beam(request, id_conf, id_beam):
476 def remove_beam(request, id_conf, id_beam):
463
477
464 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
478 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
465 beam = get_object_or_404(ABSBeam, pk=id_beam)
479 beam = get_object_or_404(ABSBeam, pk=id_beam)
466
480
467 if request.method=='POST':
481 if request.method=='POST':
468 if beam:
482 if beam:
469 try:
483 try:
470 beam.delete()
484 beam.delete()
471 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
485 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
472 except:
486 except:
473 messages.error(request, 'Unable to delete beam: "%s".' % beam)
487 messages.error(request, 'Unable to delete beam: "%s".' % beam)
474
488
475 return redirect('url_edit_abs_conf', conf.id)
489 return redirect('url_edit_abs_conf', conf.id)
476
490
477 ###### SIDEBAR ######
491 ###### SIDEBAR ######
478 kwargs = {}
492 kwargs = {}
479
493
480 kwargs['object'] = beam
494 kwargs['object'] = beam
481 kwargs['delete'] = True
495 kwargs['delete'] = True
482 kwargs['title'] = 'Delete'
496 kwargs['title'] = 'Delete'
483 kwargs['suptitle'] = 'Beam'
497 kwargs['suptitle'] = 'Beam'
484 kwargs['previous'] = conf.get_absolute_url_edit()
498 kwargs['previous'] = conf.get_absolute_url_edit()
485 return render(request, 'confirm.html', kwargs)
499 return render(request, 'confirm.html', kwargs)
486
500
487
501
488
502
489 def plot_patterns(request, id_conf, id_beam=None):
503 def plot_patterns(request, id_conf, id_beam=None):
490
504
491 kwargs = {}
505 kwargs = {}
492 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
506 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
493 beams = ABSBeam.objects.filter(abs_conf=conf)
507 beams = ABSBeam.objects.filter(abs_conf=conf)
494
508
495 if id_beam:
509 if id_beam:
496 beam = get_object_or_404(ABSBeam, pk=id_beam)
510 beam = get_object_or_404(ABSBeam, pk=id_beam)
497 kwargs['beam'] = beam
511 kwargs['beam'] = beam
498
512
499 ###### SIDEBAR ######
513 ###### SIDEBAR ######
500
514
501 kwargs['dev_conf'] = conf.device
515 kwargs['dev_conf'] = conf.device
502 kwargs['id_dev'] = conf.device
516 kwargs['id_dev'] = conf.device
503 kwargs['id_conf'] = conf.id
517 kwargs['id_conf'] = conf.id
504 kwargs['abs_beams'] = beams
518 kwargs['abs_beams'] = beams
505 kwargs['title'] = 'ABS Patterns'
519 kwargs['title'] = 'ABS Patterns'
506 kwargs['suptitle'] = conf.name
520 kwargs['suptitle'] = conf.name
507 kwargs['no_sidebar'] = True
521 kwargs['no_sidebar'] = True
508
522
509 return render(request, 'abs_patterns.html', kwargs)
523 return render(request, 'abs_patterns.html', kwargs)
510
524
511
525
512 def plot_pattern(request, id_conf, id_beam, antenna):
526 def plot_pattern(request, id_conf, id_beam, antenna):
513
527
514 if antenna=='down':
528 if antenna=='down':
515 sleep(3)
529 sleep(3)
516
530
517 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
531 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
518 beam = get_object_or_404(ABSBeam, pk=id_beam)
532 beam = get_object_or_404(ABSBeam, pk=id_beam)
519 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
533 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
520 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
534 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
521 gain_tx = json.loads(beam.tx)[antenna]
535 gain_tx = json.loads(beam.tx)[antenna]
522 gain_rx = json.loads(beam.rx)[antenna]
536 gain_rx = json.loads(beam.rx)[antenna]
523 ues = json.loads(beam.ues)[antenna]
537 ues = json.loads(beam.ues)[antenna]
524 newOverJro = overJroShow(beam.name)
538 newOverJro = overJroShow(beam.name)
525 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
539 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
526 buf = io.BytesIO()
540 buf = io.BytesIO()
527 fig.savefig(buf, format='png')
541 fig.savefig(buf, format='png')
528 response = HttpResponse(buf.getvalue(), content_type='image/png')
542 response = HttpResponse(buf.getvalue(), content_type='image/png')
529 return response
543 return response
530
544
531 import os
545 import os
532 from django.http import HttpResponse
546 from django.http import HttpResponse
533
547
534 @sio.on('connection-bind')
548 @sio.on('connection-bind')
535 def abs_connection_bind(sid, data):
549 def abs_connection_bind(sid, data):
536 print("sid:",sid,"data",data)
550 print("sid:",sid,"data",data)
537
551
538 @sio.on('disconnect')
552 @sio.on('disconnect')
539 def abs_test_disconnect(sid):
553 def abs_test_disconnect(sid):
540 print("Disconnected")
554 print("Disconnected")
541
555
542 @sio.event
556 @sio.event
543 def abs_send_beam_up(sid, message):
557 def abs_send_beam_up(sid, message):
544 mqtt_client.publish('abs/beams_up', message['data'])
558 mqtt_client.publish('abs/beams_up', message['data'])
545
559
546 @sio.event
560 @sio.event
547 def abs_send_beam_down(sid, message):
561 def abs_send_beam_down(sid, message):
548 mqtt_client.publish('abs/beams_down', message['data'])
562 mqtt_client.publish('abs/beams_down', message['data'])
549
563
550 @sio.event
564 # @sio.event
551 def change_beam(sid,message):
565 # def change_beam(sid,message):
552 data=str(message['data'])
566 # data=str(message['data'])
553 data=data[16]
567 # data=data[16]
554 mqtt_client.publish('abs/change_beam',data)
568 # mqtt_client.publish('abs/change_beam',data)
555
569
556
570
557
571
558
572
559
573
560
574
@@ -1,850 +1,856
1
1
2 import os
2 import os
3 import json
3 import json
4 import requests
4 import requests
5 import time
5 import time
6 from datetime import datetime
6 from datetime import datetime
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.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 from apps.rc.utils import RCFile
23 from apps.rc.utils import RCFile
24 from apps.jars.utils import RacpFile
24 from apps.jars.utils import RacpFile
25 from devices.dds import api as dds_api
25 from devices.dds import api as dds_api
26 from devices.dds import data as dds_data
26 from devices.dds import data as dds_data
27
27
28
28
29 DEV_PORTS = {
29 DEV_PORTS = {
30 'rc' : 2000,
30 'rc' : 2000,
31 'dds' : 2000,
31 'dds' : 2000,
32 'jars' : 2000,
32 'jars' : 2000,
33 'usrp' : 2000,
33 'usrp' : 2000,
34 'cgs' : 8080,
34 'cgs' : 8080,
35 'abs' : 8080,
35 'abs' : 8080,
36 'dds_rest': 80
36 'dds_rest': 80
37 }
37 }
38
38
39 RADAR_STATES = (
39 RADAR_STATES = (
40 (0, 'No connected'),
40 (0, 'No connected'),
41 (1, 'Connected'),
41 (1, 'Connected'),
42 (2, 'Configured'),
42 (2, 'Configured'),
43 (3, 'Running'),
43 (3, 'Running'),
44 (4, 'Scheduled'),
44 (4, 'Scheduled'),
45 )
45 )
46
46
47 EXPERIMENT_TYPE = (
47 EXPERIMENT_TYPE = (
48 (0, 'RAW_DATA'),
48 (0, 'RAW_DATA'),
49 (1, 'PDATA'),
49 (1, 'PDATA'),
50 )
50 )
51
51
52 DECODE_TYPE = (
52 DECODE_TYPE = (
53 (0, 'None'),
53 (0, 'None'),
54 (1, 'TimeDomain'),
54 (1, 'TimeDomain'),
55 (2, 'FreqDomain'),
55 (2, 'FreqDomain'),
56 (3, 'InvFreqDomain'),
56 (3, 'InvFreqDomain'),
57 )
57 )
58
58
59 DEV_STATES = (
59 DEV_STATES = (
60 (0, 'No connected'),
60 (0, 'No connected'),
61 (1, 'Connected'),
61 (1, 'Connected'),
62 (2, 'Configured'),
62 (2, 'Configured'),
63 (3, 'Running'),
63 (3, 'Running'),
64 (4, 'Unknown'),
64 (4, 'Unknown'),
65 (5, 'Busy')
65 (5, 'Busy')
66 )
66 )
67
67
68 DEV_TYPES = (
68 DEV_TYPES = (
69 ('', 'Select a device type'),
69 ('', 'Select a device type'),
70 ('rc', 'Radar Controller'),
70 ('rc', 'Radar Controller'),
71 ('dds', 'Direct Digital Synthesizer'),
71 ('dds', 'Direct Digital Synthesizer'),
72 ('jars', 'Jicamarca Radar Acquisition System'),
72 ('jars', 'Jicamarca Radar Acquisition System'),
73 ('usrp', 'Universal Software Radio Peripheral'),
73 ('usrp', 'Universal Software Radio Peripheral'),
74 ('cgs', 'Clock Generator System'),
74 ('cgs', 'Clock Generator System'),
75 ('abs', 'Automatic Beam Switching'),
75 ('abs', 'Automatic Beam Switching'),
76 ('dds_rest', 'Direct Digital Synthesizer_REST'),
76 ('dds_rest', 'Direct Digital Synthesizer_REST'),
77 ('atrad', 'Transmitter ATRAD'),
77 ('atrad', 'Transmitter ATRAD'),
78 )
78 )
79
79
80 EXP_STATES = (
80 EXP_STATES = (
81 (0,'Error'), #RED
81 (0,'Error'), #RED
82 (1,'Cancelled'), #YELLOW
82 (1,'Cancelled'), #YELLOW
83 (2,'Running'), #GREEN
83 (2,'Running'), #GREEN
84 (3,'Scheduled'), #BLUE
84 (3,'Scheduled'), #BLUE
85 (4,'Unknown'), #WHITE
85 (4,'Unknown'), #WHITE
86 )
86 )
87
87
88 CONF_TYPES = (
88 CONF_TYPES = (
89 (0, 'Active'),
89 (0, 'Active'),
90 (1, 'Historical'),
90 (1, 'Historical'),
91 )
91 )
92
92
93 class Profile(models.Model):
93 class Profile(models.Model):
94 user = models.OneToOneField(User, on_delete=models.CASCADE)
94 user = models.OneToOneField(User, on_delete=models.CASCADE)
95 theme = models.CharField(max_length=30, default='spacelab')
95 theme = models.CharField(max_length=30, default='spacelab')
96
96
97
97
98 @receiver(post_save, sender=User)
98 @receiver(post_save, sender=User)
99 def create_user_profile(sender, instance, created, **kwargs):
99 def create_user_profile(sender, instance, created, **kwargs):
100 if created:
100 if created:
101 Profile.objects.create(user=instance)
101 Profile.objects.create(user=instance)
102
102
103 @receiver(post_save, sender=User)
103 @receiver(post_save, sender=User)
104 def save_user_profile(sender, instance, **kwargs):
104 def save_user_profile(sender, instance, **kwargs):
105 instance.profile.save()
105 instance.profile.save()
106
106
107
107
108 class Location(models.Model):
108 class Location(models.Model):
109
109
110 name = models.CharField(max_length = 30)
110 name = models.CharField(max_length = 30)
111 description = models.TextField(blank=True, null=True)
111 description = models.TextField(blank=True, null=True)
112
112
113 class Meta:
113 class Meta:
114 db_table = 'db_location'
114 db_table = 'db_location'
115
115
116 def __str__(self):
116 def __str__(self):
117 return u'%s' % self.name
117 return u'%s' % self.name
118
118
119 def get_absolute_url(self):
119 def get_absolute_url(self):
120 return reverse('url_location', args=[str(self.id)])
120 return reverse('url_location', args=[str(self.id)])
121
121
122
122
123 class DeviceType(models.Model):
123 class DeviceType(models.Model):
124
124
125 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
125 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
126 sequence = models.PositiveSmallIntegerField(default=55)
126 sequence = models.PositiveSmallIntegerField(default=55)
127 description = models.TextField(blank=True, null=True)
127 description = models.TextField(blank=True, null=True)
128
128
129 class Meta:
129 class Meta:
130 db_table = 'db_device_types'
130 db_table = 'db_device_types'
131
131
132 def __str__(self):
132 def __str__(self):
133 return u'%s' % self.get_name_display()
133 return u'%s' % self.get_name_display()
134
134
135 class Device(models.Model):
135 class Device(models.Model):
136
136
137 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
137 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
138 location = models.ForeignKey('Location', on_delete=models.CASCADE)
138 location = models.ForeignKey('Location', on_delete=models.CASCADE)
139 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
139 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
140 port_address = models.PositiveSmallIntegerField(default=2000)
140 port_address = models.PositiveSmallIntegerField(default=2000)
141 description = models.TextField(blank=True, null=True)
141 description = models.TextField(blank=True, null=True)
142 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
142 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
143 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
143 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
144
144
145 class Meta:
145 class Meta:
146 db_table = 'db_devices'
146 db_table = 'db_devices'
147
147
148 def __str__(self):
148 def __str__(self):
149 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
149 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
150
150
151 return ret
151 return ret
152
152
153 @property
153 @property
154 def name(self):
154 def name(self):
155 return str(self)
155 return str(self)
156
156
157 def get_status(self):
157 def get_status(self):
158 return self.status
158 return self.status
159
159
160 @property
160 @property
161 def status_color(self):
161 def status_color(self):
162 color = 'muted'
162 color = 'muted'
163 if self.status == 0:
163 if self.status == 0:
164 color = "danger"
164 color = "danger"
165 elif self.status == 1:
165 elif self.status == 1:
166 color = "warning"
166 color = "warning"
167 elif self.status == 2:
167 elif self.status == 2:
168 color = "info"
168 color = "info"
169 elif self.status == 3:
169 elif self.status == 3:
170 color = "success"
170 color = "success"
171
171
172 return color
172 return color
173
173
174 def url(self, path=None):
174 def url(self, path=None):
175
175
176 if path:
176 if path:
177 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
177 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
178 else:
178 else:
179 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
179 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
180
180
181 def get_absolute_url(self):
181 def get_absolute_url(self):
182 return reverse('url_device', args=[str(self.id)])
182 return reverse('url_device', args=[str(self.id)])
183
183
184 def get_absolute_url_edit(self):
184 def get_absolute_url_edit(self):
185 return reverse('url_edit_device', args=[str(self.id)])
185 return reverse('url_edit_device', args=[str(self.id)])
186
186
187 def get_absolute_url_delete(self):
187 def get_absolute_url_delete(self):
188 return reverse('url_delete_device', args=[str(self.id)])
188 return reverse('url_delete_device', args=[str(self.id)])
189
189
190 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
190 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
191
191
192 if self.device_type.name=='dds':
192 if self.device_type.name=='dds':
193 try:
193 try:
194 answer = dds_api.change_ip(ip = self.ip_address,
194 answer = dds_api.change_ip(ip = self.ip_address,
195 port = self.port_address,
195 port = self.port_address,
196 new_ip = ip_address,
196 new_ip = ip_address,
197 mask = mask,
197 mask = mask,
198 gateway = gateway)
198 gateway = gateway)
199 if answer[0]=='1':
199 if answer[0]=='1':
200 self.message = '25|DDS - {}'.format(answer)
200 self.message = '25|DDS - {}'.format(answer)
201 self.ip_address = ip_address
201 self.ip_address = ip_address
202 self.save()
202 self.save()
203 else:
203 else:
204 self.message = '30|DDS - {}'.format(answer)
204 self.message = '30|DDS - {}'.format(answer)
205 return False
205 return False
206 except Exception as e:
206 except Exception as e:
207 self.message = '40|{}'.format(str(e))
207 self.message = '40|{}'.format(str(e))
208 return False
208 return False
209
209
210 elif self.device_type.name=='rc':
210 elif self.device_type.name=='rc':
211 headers = {'content-type': "application/json",
211 headers = {'content-type': "application/json",
212 'cache-control': "no-cache"}
212 'cache-control': "no-cache"}
213
213
214 ip = [int(x) for x in ip_address.split('.')]
214 ip = [int(x) for x in ip_address.split('.')]
215 dns = [int(x) for x in dns.split('.')]
215 dns = [int(x) for x in dns.split('.')]
216 gateway = [int(x) for x in gateway.split('.')]
216 gateway = [int(x) for x in gateway.split('.')]
217 subnet = [int(x) for x in mask.split('.')]
217 subnet = [int(x) for x in mask.split('.')]
218
218
219 payload = {
219 payload = {
220 "ip": ip,
220 "ip": ip,
221 "dns": dns,
221 "dns": dns,
222 "gateway": gateway,
222 "gateway": gateway,
223 "subnet": subnet
223 "subnet": subnet
224 }
224 }
225
225
226 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
226 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
227 try:
227 try:
228 answer = req.json()
228 answer = req.json()
229 if answer['changeip']=='ok':
229 if answer['changeip']=='ok':
230 self.message = '25|IP succesfully changed'
230 self.message = '25|IP succesfully changed'
231 self.ip_address = ip_address
231 self.ip_address = ip_address
232 self.save()
232 self.save()
233 else:
233 else:
234 self.message = '30|An error ocuur when changing IP'
234 self.message = '30|An error ocuur when changing IP'
235 except Exception as e:
235 except Exception as e:
236 self.message = '40|{}'.format(str(e))
236 self.message = '40|{}'.format(str(e))
237 else:
237 else:
238 self.message = 'Not implemented'
238 self.message = 'Not implemented'
239 return False
239 return False
240
240
241 return True
241 return True
242
242
243
243
244 class Campaign(models.Model):
244 class Campaign(models.Model):
245
245
246 template = models.BooleanField(default=False)
246 template = models.BooleanField(default=False)
247 name = models.CharField(max_length=60, unique=True)
247 name = models.CharField(max_length=60, unique=True)
248 start_date = models.DateTimeField(blank=True, null=True)
248 start_date = models.DateTimeField(blank=True, null=True)
249 end_date = models.DateTimeField(blank=True, null=True)
249 end_date = models.DateTimeField(blank=True, null=True)
250 tags = models.CharField(max_length=40, blank=True, null=True)
250 tags = models.CharField(max_length=40, blank=True, null=True)
251 description = models.TextField(blank=True, null=True)
251 description = models.TextField(blank=True, null=True)
252 experiments = models.ManyToManyField('Experiment', blank=True)
252 experiments = models.ManyToManyField('Experiment', blank=True)
253 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
253 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
254
254
255 class Meta:
255 class Meta:
256 db_table = 'db_campaigns'
256 db_table = 'db_campaigns'
257 ordering = ('name',)
257 ordering = ('name',)
258
258
259 def __str__(self):
259 def __str__(self):
260 if self.template:
260 if self.template:
261 return u'{} (template)'.format(self.name)
261 return u'{} (template)'.format(self.name)
262 else:
262 else:
263 return u'{}'.format(self.name)
263 return u'{}'.format(self.name)
264
264
265 def jsonify(self):
265 def jsonify(self):
266
266
267 data = {}
267 data = {}
268
268
269 ignored = ('template')
269 ignored = ('template')
270
270
271 for field in self._meta.fields:
271 for field in self._meta.fields:
272 if field.name in ignored:
272 if field.name in ignored:
273 continue
273 continue
274 data[field.name] = field.value_from_object(self)
274 data[field.name] = field.value_from_object(self)
275
275
276 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
276 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
277 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
277 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
278
278
279 return data
279 return data
280
280
281 def parms_to_dict(self):
281 def parms_to_dict(self):
282
282
283 params = Params({})
283 params = Params({})
284 params.add(self.jsonify(), 'campaigns')
284 params.add(self.jsonify(), 'campaigns')
285
285
286 for exp in Experiment.objects.filter(campaign = self):
286 for exp in Experiment.objects.filter(campaign = self):
287 params.add(exp.jsonify(), 'experiments')
287 params.add(exp.jsonify(), 'experiments')
288 configurations = Configuration.objects.filter(experiment=exp, type=0)
288 configurations = Configuration.objects.filter(experiment=exp, type=0)
289
289
290 for conf in configurations:
290 for conf in configurations:
291 params.add(conf.jsonify(), 'configurations')
291 params.add(conf.jsonify(), 'configurations')
292 if conf.device.device_type.name=='rc':
292 if conf.device.device_type.name=='rc':
293 for line in conf.get_lines():
293 for line in conf.get_lines():
294 params.add(line.jsonify(), 'lines')
294 params.add(line.jsonify(), 'lines')
295
295
296 return params.data
296 return params.data
297
297
298 def dict_to_parms(self, parms, CONF_MODELS):
298 def dict_to_parms(self, parms, CONF_MODELS):
299
299
300 experiments = Experiment.objects.filter(campaign = self)
300 experiments = Experiment.objects.filter(campaign = self)
301
301
302 if experiments:
302 if experiments:
303 for experiment in experiments:
303 for experiment in experiments:
304 experiment.delete()
304 experiment.delete()
305
305
306 for id_exp in parms['experiments']['allIds']:
306 for id_exp in parms['experiments']['allIds']:
307 exp_parms = parms['experiments']['byId'][id_exp]
307 exp_parms = parms['experiments']['byId'][id_exp]
308 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
308 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
309 exp = Experiment(name='{}'.format(dum))
309 exp = Experiment(name='{}'.format(dum))
310 exp.save()
310 exp.save()
311 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
311 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
312 self.experiments.add(exp)
312 self.experiments.add(exp)
313
313
314 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
314 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
315
315
316 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
316 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
317 self.start_date = camp_parms['start_date']
317 self.start_date = camp_parms['start_date']
318 self.end_date = camp_parms['end_date']
318 self.end_date = camp_parms['end_date']
319 self.tags = camp_parms['tags']
319 self.tags = camp_parms['tags']
320 self.save()
320 self.save()
321
321
322 return self
322 return self
323
323
324 def get_experiments_by_radar(self, radar=None):
324 def get_experiments_by_radar(self, radar=None):
325
325
326 ret = []
326 ret = []
327 if radar:
327 if radar:
328 locations = Location.objects.filter(pk=radar)
328 locations = Location.objects.filter(pk=radar)
329 else:
329 else:
330 locations = set([e.location for e in self.experiments.all()])
330 locations = set([e.location for e in self.experiments.all()])
331
331
332 for loc in locations:
332 for loc in locations:
333 dum = {}
333 dum = {}
334 dum['name'] = loc.name
334 dum['name'] = loc.name
335 dum['id'] = loc.pk
335 dum['id'] = loc.pk
336 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
336 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
337 ret.append(dum)
337 ret.append(dum)
338 return ret
338 return ret
339
339
340 def get_absolute_url(self):
340 def get_absolute_url(self):
341 return reverse('url_campaign', args=[str(self.id)])
341 return reverse('url_campaign', args=[str(self.id)])
342
342
343 def get_absolute_url_edit(self):
343 def get_absolute_url_edit(self):
344 return reverse('url_edit_campaign', args=[str(self.id)])
344 return reverse('url_edit_campaign', args=[str(self.id)])
345
345
346 def get_absolute_url_delete(self):
346 def get_absolute_url_delete(self):
347 return reverse('url_delete_campaign', args=[str(self.id)])
347 return reverse('url_delete_campaign', args=[str(self.id)])
348
348
349 def get_absolute_url_export(self):
349 def get_absolute_url_export(self):
350 return reverse('url_export_campaign', args=[str(self.id)])
350 return reverse('url_export_campaign', args=[str(self.id)])
351
351
352 def get_absolute_url_import(self):
352 def get_absolute_url_import(self):
353 return reverse('url_import_campaign', args=[str(self.id)])
353 return reverse('url_import_campaign', args=[str(self.id)])
354
354
355
355
356 class RunningExperiment(models.Model):
356 class RunningExperiment(models.Model):
357 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
357 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
358 running_experiment = models.ManyToManyField('Experiment', blank = True)
358 running_experiment = models.ManyToManyField('Experiment', blank = True)
359 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
359 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
360
360
361
361
362 class Experiment(models.Model):
362 class Experiment(models.Model):
363
363
364 template = models.BooleanField(default=False)
364 template = models.BooleanField(default=False)
365 name = models.CharField(max_length=40, default='', unique=True)
365 name = models.CharField(max_length=40, default='', unique=True)
366 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
366 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
367 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
367 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
368 start_time = models.TimeField(default='00:00:00')
368 start_time = models.TimeField(default='00:00:00')
369 end_time = models.TimeField(default='23:59:59')
369 end_time = models.TimeField(default='23:59:59')
370 task = models.CharField(max_length=36, default='', blank=True, null=True)
370 task = models.CharField(max_length=36, default='', blank=True, null=True)
371 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
371 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
372 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
372 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
373 hash = models.CharField(default='', max_length=64, null=True, blank=True)
373 hash = models.CharField(default='', max_length=64, null=True, blank=True)
374
374
375 class Meta:
375 class Meta:
376 db_table = 'db_experiments'
376 db_table = 'db_experiments'
377 ordering = ('template', 'name')
377 ordering = ('template', 'name')
378
378
379 def __str__(self):
379 def __str__(self):
380 if self.template:
380 if self.template:
381 return u'%s (template)' % (self.name)
381 return u'%s (template)' % (self.name)
382 else:
382 else:
383 return u'%s' % (self.name)
383 return u'%s' % (self.name)
384
384
385 def jsonify(self):
385 def jsonify(self):
386
386
387 data = {}
387 data = {}
388
388
389 ignored = ('template')
389 ignored = ('template')
390
390
391 for field in self._meta.fields:
391 for field in self._meta.fields:
392 if field.name in ignored:
392 if field.name in ignored:
393 continue
393 continue
394 data[field.name] = field.value_from_object(self)
394 data[field.name] = field.value_from_object(self)
395
395
396 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
396 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
397 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
397 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
398 data['location'] = self.location.name
398 data['location'] = self.location.name
399 data['configurations'] = ['{}'.format(conf.pk) for
399 data['configurations'] = ['{}'.format(conf.pk) for
400 conf in Configuration.objects.filter(experiment=self, type=0)]
400 conf in Configuration.objects.filter(experiment=self, type=0)]
401
401
402 return data
402 return data
403
403
404 @property
404 @property
405 def radar_system(self):
405 def radar_system(self):
406 return self.location
406 return self.location
407
407
408 def clone(self, **kwargs):
408 def clone(self, **kwargs):
409
409
410 confs = Configuration.objects.filter(experiment=self, type=0)
410 confs = Configuration.objects.filter(experiment=self, type=0)
411 self.pk = None
411 self.pk = None
412 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
412 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
413 for attr, value in kwargs.items():
413 for attr, value in kwargs.items():
414 setattr(self, attr, value)
414 setattr(self, attr, value)
415
415
416 self.save()
416 self.save()
417
417
418 for conf in confs:
418 for conf in confs:
419 conf.clone(experiment=self, template=False)
419 conf.clone(experiment=self, template=False)
420
420
421 return self
421 return self
422
422
423 def start(self):
423 def start(self):
424 '''
424 '''
425 Configure and start experiments's devices
425 Configure and start experiments's devices
426 ABS-CGS-DDS-RC-JARS
426 ABS-CGS-DDS-RC-JARS
427 '''
427 '''
428 self.status=5 #Busy
428 self.status=5 #Busy
429 self.save()
429 self.save()
430 # print("Guardando STATUS: {}".format(self.status))
430 # print("Guardando STATUS: {}".format(self.status))
431
431
432 confs = []
432 confs = []
433 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
433 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
434 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
434 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
435 if rc_mix:
435 if rc_mix:
436 for conf in allconfs:
436 for conf in allconfs:
437 if conf.device.device_type.name == 'rc' and not conf.mix:
437 if conf.device.device_type.name == 'rc' and not conf.mix:
438 continue
438 continue
439 confs.append(conf)
439 confs.append(conf)
440 else:
440 else:
441 confs = allconfs
441 confs = allconfs
442
442
443
443
444 for conf in confs:
444 for conf in confs:
445 print("conf->",conf)
445 print("conf->",conf)
446 print(conf.device)
446 print(conf.device)
447 print(conf.device.status)
447 print(conf.device.status)
448 print("--------------",flush=True)
448 print("--------------",flush=True)
449 print("Stop ",conf.name,flush=True)
449 print("Stop ",conf.name,flush=True)
450 if conf.stop_device() ==False:
450 if conf.stop_device() ==False:
451 print("Falló Stop ",conf.name)
451 print("Falló Stop ",conf.name)
452 print("Cancelando Campaña...",flush=True)
452 print("Cancelando Campaña...",flush=True)
453 return 0
453 return 0
454 print("Write ",conf.name,flush=True)
454 print("Write ",conf.name,flush=True)
455 if conf.write_device() ==False:
455 if conf.write_device() ==False:
456 print("Falló Write ",conf.name)
456 print("Falló Write ",conf.name)
457 print("Cancelando Campaña...",flush=True)
457 print("Cancelando Campaña...",flush=True)
458 return 0
458 return 0
459 print("Save",conf.name,flush=True)
459 print("Save",conf.name,flush=True)
460 conf.device.conf_active = conf.pk
460 conf.device.conf_active = conf.pk
461 conf.device.save()
461 conf.device.save()
462 print("Start",conf.name,flush=True)
462 print("Start",conf.name,flush=True)
463 if conf.start_device()==False:
463 if conf.start_device()==False:
464 print("Falló Start ",conf.name)
464 print("Falló Start ",conf.name)
465 print("Cancelando Campaña...",flush=True)
465 print("Cancelando Campaña...",flush=True)
466 return 0
466 return 0
467 print("--- CONFIGURACIÓN EXITOSA ---",flush=True)
467 print("--- CONFIGURACIÓN EXITOSA ---",flush=True)
468 time.sleep(1)
468 time.sleep(1)
469
469
470 return 2
470 return 2
471
471
472
472
473 def stop(self):
473 def stop(self):
474 '''
474 '''
475 Stop experiments's devices
475 Stop experiments's devices
476 DDS-JARS-RC-CGS-ABS
476 DDS-JARS-RC-CGS-ABS
477 '''
477 '''
478
478
479 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
479 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
480 confs = confs.exclude(device__device_type__name='cgs')
480 confs = confs.exclude(device__device_type__name='cgs')
481 try:
481 try:
482 for conf in confs:
482 for conf in confs:
483 conf.stop_device()
483 conf.stop_device()
484 except:
484 except:
485 return 0
485 return 0
486 return 1
486 return 1
487
487
488 def get_status(self):
488 def get_status(self):
489
489
490 if self.status == 3:
490 if self.status == 3:
491 return
491 return
492
492
493 confs = Configuration.objects.filter(experiment=self, type=0)
493 confs = Configuration.objects.filter(experiment=self, type=0)
494
494
495 for conf in confs:
495 for conf in confs:
496 conf.status_device()
496 conf.status_device()
497
497
498 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
498 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
499
499
500 if total==2*confs.count():
500 if total==2*confs.count():
501 status = 1
501 status = 1
502 elif total == 3*confs.count():
502 elif total == 3*confs.count():
503 status = 2
503 status = 2
504 else:
504 else:
505 status = 0
505 status = 0
506
506
507 self.status = status
507 self.status = status
508 self.save()
508 self.save()
509
509
510 def status_color(self):
510 def status_color(self):
511 color = 'muted'
511 color = 'muted'
512 if self.status == 0:
512 if self.status == 0:
513 color = "danger"
513 color = "danger"
514 elif self.status == 1:
514 elif self.status == 1:
515 color = "warning"
515 color = "warning"
516 elif self.status == 2:
516 elif self.status == 2:
517 color = "success"
517 color = "success"
518 elif self.status == 3:
518 elif self.status == 3:
519 color = "info"
519 color = "info"
520
520
521 return color
521 return color
522
522
523 def parms_to_dict(self):
523 def parms_to_dict(self):
524
524
525 params = Params({})
525 params = Params({})
526 params.add(self.jsonify(), 'experiments')
526 params.add(self.jsonify(), 'experiments')
527
527
528 configurations = Configuration.objects.filter(experiment=self, type=0)
528 configurations = Configuration.objects.filter(experiment=self, type=0)
529
529
530 for conf in configurations:
530 for conf in configurations:
531 params.add(conf.jsonify(), 'configurations')
531 params.add(conf.jsonify(), 'configurations')
532 if conf.device.device_type.name=='rc':
532 if conf.device.device_type.name=='rc':
533 for line in conf.get_lines():
533 for line in conf.get_lines():
534 params.add(line.jsonify(), 'lines')
534 params.add(line.jsonify(), 'lines')
535
535
536 return params.data
536 return params.data
537
537
538 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
538 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
539
539
540 configurations = Configuration.objects.filter(experiment=self)
540 configurations = Configuration.objects.filter(experiment=self)
541
541
542 if id_exp is not None:
542 if id_exp is not None:
543 exp_parms = parms['experiments']['byId'][id_exp]
543 exp_parms = parms['experiments']['byId'][id_exp]
544 else:
544 else:
545 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
545 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
546
546
547 if configurations:
547 if configurations:
548 for configuration in configurations:
548 for configuration in configurations:
549 configuration.delete()
549 configuration.delete()
550
550
551 for id_conf in exp_parms['configurations']:
551 for id_conf in exp_parms['configurations']:
552 conf_parms = parms['configurations']['byId'][id_conf]
552 conf_parms = parms['configurations']['byId'][id_conf]
553 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
553 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
554 model = CONF_MODELS[conf_parms['device_type']]
554 model = CONF_MODELS[conf_parms['device_type']]
555 conf = model(
555 conf = model(
556 experiment = self,
556 experiment = self,
557 device = device,
557 device = device,
558 )
558 )
559 conf.dict_to_parms(parms, id=id_conf)
559 conf.dict_to_parms(parms, id=id_conf)
560
560
561
561
562 location, created = Location.objects.get_or_create(name=exp_parms['location'])
562 location, created = Location.objects.get_or_create(name=exp_parms['location'])
563 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
563 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
564 self.location = location
564 self.location = location
565 self.start_time = exp_parms['start_time']
565 self.start_time = exp_parms['start_time']
566 self.end_time = exp_parms['end_time']
566 self.end_time = exp_parms['end_time']
567 self.save()
567 self.save()
568
568
569 return self
569 return self
570
570
571 def get_absolute_url(self):
571 def get_absolute_url(self):
572 return reverse('url_experiment', args=[str(self.id)])
572 return reverse('url_experiment', args=[str(self.id)])
573
573
574 def get_absolute_url_edit(self):
574 def get_absolute_url_edit(self):
575 return reverse('url_edit_experiment', args=[str(self.id)])
575 return reverse('url_edit_experiment', args=[str(self.id)])
576
576
577 def get_absolute_url_delete(self):
577 def get_absolute_url_delete(self):
578 return reverse('url_delete_experiment', args=[str(self.id)])
578 return reverse('url_delete_experiment', args=[str(self.id)])
579
579
580 def get_absolute_url_import(self):
580 def get_absolute_url_import(self):
581 return reverse('url_import_experiment', args=[str(self.id)])
581 return reverse('url_import_experiment', args=[str(self.id)])
582
582
583 def get_absolute_url_export(self):
583 def get_absolute_url_export(self):
584 return reverse('url_export_experiment', args=[str(self.id)])
584 return reverse('url_export_experiment', args=[str(self.id)])
585
585
586 def get_absolute_url_start(self):
586 def get_absolute_url_start(self):
587 return reverse('url_start_experiment', args=[str(self.id)])
587 return reverse('url_start_experiment', args=[str(self.id)])
588
588
589 def get_absolute_url_stop(self):
589 def get_absolute_url_stop(self):
590 return reverse('url_stop_experiment', args=[str(self.id)])
590 return reverse('url_stop_experiment', args=[str(self.id)])
591
591
592
592
593 class Configuration(PolymorphicModel):
593 class Configuration(PolymorphicModel):
594
594
595 template = models.BooleanField(default=False)
595 template = models.BooleanField(default=False)
596 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
596 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
597 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
597 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
598 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
598 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
599 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
599 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
600 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
600 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
601 created_date = models.DateTimeField(auto_now_add=True)
601 created_date = models.DateTimeField(auto_now_add=True)
602 programmed_date = models.DateTimeField(auto_now=True)
602 programmed_date = models.DateTimeField(auto_now=True)
603 parameters = models.TextField(default='{}')
603 parameters = models.TextField(default='{}')
604 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
604 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
605 hash = models.CharField(default='', max_length=64, null=True, blank=True)
605 hash = models.CharField(default='', max_length=64, null=True, blank=True)
606 message = ""
606 message = ""
607
607
608 class Meta:
608 class Meta:
609 db_table = 'db_configurations'
609 db_table = 'db_configurations'
610 ordering = ('device__device_type__name',)
610 ordering = ('device__device_type__name',)
611
611
612 def __str__(self):
612 def __str__(self):
613
613
614 ret = u'{} '.format(self.device.device_type.name.upper())
614 ret = u'{} '.format(self.device.device_type.name.upper())
615
615
616 if 'mix' in [f.name for f in self._meta.get_fields()]:
616 if 'mix' in [f.name for f in self._meta.get_fields()]:
617 if self.mix:
617 if self.mix:
618 ret = '{} MIX '.format(self.device.device_type.name.upper())
618 ret = '{} MIX '.format(self.device.device_type.name.upper())
619
619
620 if 'label' in [f.name for f in self._meta.get_fields()]:
620 if 'label' in [f.name for f in self._meta.get_fields()]:
621 ret += '{}'.format(self.label)
621 ret += '{}'.format(self.label)
622
622
623 if self.template:
623 if self.template:
624 ret += ' (template)'
624 ret += ' (template)'
625
625
626 return ret
626 return ret
627
627
628 @property
628 @property
629 def name(self):
629 def name(self):
630
630
631 return str(self)
631 return str(self)
632
632
633 def jsonify(self):
633 def jsonify(self):
634
634
635 data = {}
635 data = {}
636
636
637 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
637 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
638 'created_date', 'programmed_date', 'template', 'device',
638 'created_date', 'programmed_date', 'template', 'device',
639 'experiment')
639 'experiment')
640
640
641 for field in self._meta.fields:
641 for field in self._meta.fields:
642 if field.name in ignored:
642 if field.name in ignored:
643 continue
643 continue
644 data[field.name] = field.value_from_object(self)
644 data[field.name] = field.value_from_object(self)
645
645
646 data['device_type'] = self.device.device_type.name
646 data['device_type'] = self.device.device_type.name
647
647
648 if self.device.device_type.name == 'rc':
648 if self.device.device_type.name == 'rc':
649 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
649 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
650 data['delays'] = self.get_delays()
650 data['delays'] = self.get_delays()
651 data['pulses'] = self.get_pulses()
651 data['pulses'] = self.get_pulses()
652
652
653 elif self.device.device_type.name == 'jars':
653 elif self.device.device_type.name == 'jars':
654 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
654 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
655
655
656 elif self.device.device_type.name == 'dds':
656 elif self.device.device_type.name == 'dds':
657 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
657 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
658 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
658 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
659 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
659 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
660 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
660 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
661
661
662 elif self.device.device_type.name == 'dds_rest':
662 elif self.device.device_type.name == 'dds_rest':
663 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
663 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
664 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
664 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
665 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
665 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
666 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
666 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
667 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
667 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
668 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
668 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
669 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
669 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
670 return data
670 return data
671
671
672 def clone(self, **kwargs):
672 def clone(self, **kwargs):
673
673
674 self.pk = None
674 self.pk = None
675 self.id = None
675 self.id = None
676 for attr, value in kwargs.items():
676 for attr, value in kwargs.items():
677 setattr(self, attr, value)
677 setattr(self, attr, value)
678
678
679 self.save()
679 self.save()
680
680
681 return self
681 return self
682
682
683 def parms_to_dict(self):
683 def parms_to_dict(self):
684
684
685 params = Params({})
685 params = Params({})
686 params.add(self.jsonify(), 'configurations')
686 params.add(self.jsonify(), 'configurations')
687
687
688 if self.device.device_type.name=='rc':
688 if self.device.device_type.name=='rc':
689 for line in self.get_lines():
689 for line in self.get_lines():
690 params.add(line.jsonify(), 'lines')
690 params.add(line.jsonify(), 'lines')
691
691
692 return params.data
692 return params.data
693
693
694 def parms_to_text(self):
694 def parms_to_text(self):
695
695
696 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
696 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
697
697
698
698
699 def parms_to_binary(self):
699 def parms_to_binary(self):
700
700
701 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
701 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
702
702
703
703
704 def dict_to_parms(self, parameters, id=None):
704 def dict_to_parms(self, parameters, id=None):
705
705
706 params = Params(parameters)
706 params = Params(parameters)
707
707
708 if id:
708 if id:
709 data = params.get_conf(id_conf=id)
709 data = params.get_conf(id_conf=id)
710 else:
710 else:
711 data = params.get_conf(dtype=self.device.device_type.name)
711 data = params.get_conf(dtype=self.device.device_type.name)
712
712
713 if data['device_type']=='rc':
713 if data['device_type']=='rc':
714 self.clean_lines()
714 self.clean_lines()
715 lines = data.pop('lines', None)
715 lines = data.pop('lines', None)
716 for line_id in lines:
716 for line_id in lines:
717 pass
717 pass
718
718
719 for key, value in data.items():
719 for key, value in data.items():
720 if key not in ('id', 'device_type'):
720 if key not in ('id', 'device_type'):
721 setattr(self, key, value)
721 setattr(self, key, value)
722
722
723 self.save()
723 self.save()
724
724
725
725
726 def export_to_file(self, format="json"):
726 def export_to_file(self, format="json"):
727
727
728 content_type = ''
728 content_type = ''
729
729
730 if format == 'racp':
730 if format == 'racp':
731 content_type = 'text/plain'
731 content_type = 'text/plain'
732 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
732 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
733 content = self.parms_to_text(file_format = 'racp')
733 content = self.parms_to_text(file_format = 'racp')
734
734
735 if format == 'text':
735 if format == 'text':
736 content_type = 'text/plain'
736 content_type = 'text/plain'
737 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
737 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
738 content = self.parms_to_text()
738 content = self.parms_to_text()
739
739
740 if format == 'binary':
740 if format == 'binary':
741 content_type = 'application/octet-stream'
741 content_type = 'application/octet-stream'
742 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
742 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
743 content = self.parms_to_binary()
743 content = self.parms_to_binary()
744
744
745 if not content_type:
745 if not content_type:
746 content_type = 'application/json'
746 content_type = 'application/json'
747 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
747 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
748 content = json.dumps(self.parms_to_dict(), indent=2)
748 content = json.dumps(self.parms_to_dict(), indent=2)
749
749
750 fields = {'content_type':content_type,
750 fields = {'content_type':content_type,
751 'filename':filename,
751 'filename':filename,
752 'content':content
752 'content':content
753 }
753 }
754
754
755 return fields
755 return fields
756
756
757 def import_from_file(self, fp):
757 def import_from_file(self, fp):
758
758
759 parms = {}
759 parms = {}
760
760
761 path, ext = os.path.splitext(fp.name)
761 path, ext = os.path.splitext(fp.name)
762
762
763 if ext == '.json':
763 if ext == '.json':
764 parms = json.load(fp)
764 parms = json.load(fp)
765
765
766 if ext == '.dds':
766 if ext == '.dds':
767 lines = fp.readlines()
767 lines = fp.readlines()
768 parms = dds_data.text_to_dict(lines)
768 parms = dds_data.text_to_dict(lines)
769
769
770 if ext == '.racp':
770 if ext == '.racp':
771 if self.device.device_type.name == 'jars':
771 if self.device.device_type.name == 'jars':
772 parms = RacpFile(fp).to_dict()
772 parms = RacpFile(fp).to_dict()
773 parms['filter_parms'] = json.loads(self.filter_parms)
773 parms['filter_parms'] = json.loads(self.filter_parms)
774 return parms
774 return parms
775 parms = RCFile(fp).to_dict()
775 parms = RCFile(fp).to_dict()
776
776
777 return parms
777 return parms
778
778
779 def status_device(self):
779 def status_device(self):
780
780
781 self.message = 'Function not implemented'
781 self.message = 'Function not implemented'
782 return False
782 return False
783
783
784
784
785 def stop_device(self):
785 def stop_device(self):
786
786
787 self.message = 'Function not implemented'
787 self.message = 'Function not implemented'
788 print("BUENAS SEÑALES??? NO LO CREO2",flush=True)
788 print("BUENAS SEÑALES??? NO LO CREO2",flush=True)
789 return False
789 return False
790
790
791
791
792 def start_device(self):
792 def start_device(self):
793
793
794 self.message = 'Function not implemented'
794 self.message = 'Function not implemented'
795 print("BUENAS SEÑALES??? NO LO CREO",flush=True)
795 print("BUENAS SEÑALES??? NO LO CREO",flush=True)
796 return False
796 return False
797
797
798
798
799 def write_device(self, parms):
799 def write_device(self, parms):
800
800
801 self.message = 'Function not implemented'
801 self.message = 'Function not implemented'
802 print("BUENAS SEÑALES??? NO LO CREO3",flush=True)
802 print("BUENAS SEÑALES??? NO LO CREO3",flush=True)
803 return False
803 return False
804
804
805 def write_device_mqtt(self, parms):
805 def write_device_mqtt(self, parms):
806
806
807 self.message = 'Function not implemented'
807 self.message = 'Function not implemented'
808 return False
808 return False
809
809
810 def read_device(self):
810 def read_device(self):
811
811
812 self.message = 'Function not implemented'
812 self.message = 'Function not implemented'
813 return False
813 return False
814
814
815
815
816 def get_absolute_url(self):
816 def get_absolute_url(self):
817 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
817 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
818
819 def get_absolute_mqtt_url(self):
820 if self.device.device_type.name=='abs':
821 return reverse('url_%s_conf_mqtt' % self.device.device_type.name, args=[str(self.id)])
822 else:
823 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
818
824
819 def get_absolute_url_edit(self):
825 def get_absolute_url_edit(self):
820 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
826 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
821
827
822 def get_absolute_url_delete(self):
828 def get_absolute_url_delete(self):
823 return reverse('url_delete_dev_conf', args=[str(self.id)])
829 return reverse('url_delete_dev_conf', args=[str(self.id)])
824
830
825 def get_absolute_url_import(self):
831 def get_absolute_url_import(self):
826 return reverse('url_import_dev_conf', args=[str(self.id)])
832 return reverse('url_import_dev_conf', args=[str(self.id)])
827
833
828 def get_absolute_url_export(self):
834 def get_absolute_url_export(self):
829 return reverse('url_export_dev_conf', args=[str(self.id)])
835 return reverse('url_export_dev_conf', args=[str(self.id)])
830
836
831 def get_absolute_url_write(self):
837 def get_absolute_url_write(self):
832 return reverse('url_write_dev_conf', args=[str(self.id)])
838 return reverse('url_write_dev_conf', args=[str(self.id)])
833
839
834 def get_absolute_url_write_mqtt(self):
840 def get_absolute_url_write_mqtt(self):
835 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
841 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
836
842
837 def get_absolute_url_read(self):
843 def get_absolute_url_read(self):
838 return reverse('url_read_dev_conf', args=[str(self.id)])
844 return reverse('url_read_dev_conf', args=[str(self.id)])
839
845
840 def get_absolute_url_start(self):
846 def get_absolute_url_start(self):
841 return reverse('url_start_dev_conf', args=[str(self.id)])
847 return reverse('url_start_dev_conf', args=[str(self.id)])
842
848
843 def get_absolute_url_stop(self):
849 def get_absolute_url_stop(self):
844 return reverse('url_stop_dev_conf', args=[str(self.id)])
850 return reverse('url_stop_dev_conf', args=[str(self.id)])
845
851
846 def get_absolute_url_stop_mqtt(self):
852 def get_absolute_url_stop_mqtt(self):
847 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
853 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
848
854
849 def get_absolute_url_status(self):
855 def get_absolute_url_status(self):
850 return reverse('url_status_dev_conf', args=[str(self.id)])
856 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,99 +1,99
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load django_bootstrap5 %}
2 {% load django_bootstrap5 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block extra-head %}
6 {% block extra-head %}
7 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
8 {% endblock %}
8 {% endblock %}
9 {% block content-title %}{{title}}{% endblock %}
9 {% block content-title %}{{title}}{% endblock %}
10 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 {% block content-suptitle %}{{suptitle}}{% endblock %}
11
11
12 {% block content %}
12 {% block content %}
13
13
14 {% block content-filter %}
14 {% block content-filter %}
15 {% if form %}
15 {% if form %}
16 <form class="form" method="get">
16 <form class="form" method="get">
17 {% bootstrap_form form layout='horizontal' size='md' %}
17 {% bootstrap_form form layout='horizontal' size='md' %}
18 <div class="pull-right">
18 <div class="pull-right">
19 <br>
19 <br>
20 <button type="button" class="btn btn-primary btn-sm" onclick="window.location.replace('?');"><span class="fas fa-sync-alt" aria-hidden="true"></span></button>
20 <button type="button" class="btn btn-primary btn-sm" onclick="window.location.replace('?');"><span class="fas fa-sync-alt" aria-hidden="true"></span></button>
21 <button type="submit" class="btn btn-primary btn-sm"><span class="fas fa-search" aria-hidden="true"></span></button>
21 <button type="submit" class="btn btn-primary btn-sm"><span class="fas fa-search" aria-hidden="true"></span></button>
22 {% if add_url %}
22 {% if add_url %}
23 <a class="btn btn-sm btn-info" href="{{add_url}}"><span class="fas fa-plus" aria-hidden="true"></span></a>
23 <a class="btn btn-sm btn-info" href="{{add_url}}"><span class="fas fa-plus" aria-hidden="true"></span></a>
24 {% endif %}
24 {% endif %}
25 </div>
25 </div>
26 </form>
26 </form>
27 {% endif %}
27 {% endif %}
28 {% endblock %}
28 {% endblock %}
29 <div style="clear: both;"></div>
29 <div style="clear: both;"></div>
30 <br>
30 <br>
31 <table class="table table-hover">
31 <table class="table table-hover">
32 <tr>
32 <tr>
33 <th>#</th>
33 <th>#</th>
34 {% for key in keys %}
34 {% for key in keys %}
35 {% if key == 'location'%}
35 {% if key == 'location'%}
36 <th>System</th>
36 <th>System</th>
37 {% else %}
37 {% else %}
38 <th>{{ key|title }}</th>
38 <th>{{ key|title }}</th>
39 {% endif %}
39 {% endif %}
40 {% endfor%}
40 {% endfor%}
41 </tr>
41 </tr>
42 {% for object in objects %}
42 {% for object in objects %}
43 <tr class="clickable-row" data-href="{{object.get_absolute_url}}">
43 <tr class="clickable-row" data-href="{{object.get_absolute_mqtt_url}}">
44 <td>{{ forloop.counter|add:offset }}</td>
44 <td>{{ forloop.counter|add:offset }}</td>
45 {% for key in keys %}
45 {% for key in keys %}
46 {% if key == 'actions' %}
46 {% if key == 'actions' %}
47 <td>
47 <td>
48 <a class="btn btn-sm btn-danger" href="{{object.get_absolute_url_delete}}"><span class="fas fa-times" aria-hidden="true"></span></a>
48 <a class="btn btn-sm btn-danger" href="{{object.get_absolute_url_delete}}"><span class="fas fa-times" aria-hidden="true"></span></a>
49 <a class="btn btn-sm btn-primary" href="{{object.get_absolute_url_edit}}"><span class="fa fa-pencil" aria-hidden="true"></span></a>
49 <a class="btn btn-sm btn-primary" href="{{object.get_absolute_url_edit}}"><span class="fa fa-pencil" aria-hidden="true"></span></a>
50 </td>
50 </td>
51 {% else %}
51 {% else %}
52 <td>{{ object|attr:key }}</td>
52 <td>{{ object|attr:key }}</td>
53 {% endif %}
53 {% endif %}
54 {% endfor %}
54 {% endfor %}
55 </tr>
55 </tr>
56 {% endfor %}
56 {% endfor %}
57 </table>
57 </table>
58
58
59 <div class="pagination">
59 <div class="pagination">
60 <span class="step-links">
60 <span class="step-links">
61 {% if objects.has_previous %}
61 {% if objects.has_previous %}
62 <a href="?page={{ objects.previous_page_number }}&{{q}}"><span class="fas fa-chevron-left" aria-hidden="true"></span></a>
62 <a href="?page={{ objects.previous_page_number }}&{{q}}"><span class="fas fa-chevron-left" aria-hidden="true"></span></a>
63 {% endif %}
63 {% endif %}
64 <span class="current">
64 <span class="current">
65 Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
65 Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
66 </span>
66 </span>
67 {% if objects.has_next %}
67 {% if objects.has_next %}
68 <a href="?page={{ objects.next_page_number }}&{{q}}"><span class="fas fa-chevron-right" aria-hidden="true"></span></a>
68 <a href="?page={{ objects.next_page_number }}&{{q}}"><span class="fas fa-chevron-right" aria-hidden="true"></span></a>
69 {% endif %}
69 {% endif %}
70 </span>
70 </span>
71 </div>
71 </div>
72
72
73 {% endblock %}
73 {% endblock %}
74
74
75 {% block extra-js%}
75 {% block extra-js%}
76 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
76 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
77 <script type="text/javascript">
77 <script type="text/javascript">
78
78
79 $('.input-group.date').datetimepicker({
79 $('.input-group.date').datetimepicker({
80 format: "YYYY-MM-DD",
80 format: "YYYY-MM-DD",
81 icons: {
81 icons: {
82 time: 'far fa-clock',
82 time: 'far fa-clock',
83 date: 'far fa-calendar-alt',
83 date: 'far fa-calendar-alt',
84 up: 'fas fa-arrow-up',
84 up: 'fas fa-arrow-up',
85 down: 'fas fa-arrow-down',
85 down: 'fas fa-arrow-down',
86 previous: 'fas fa-chevron-left',
86 previous: 'fas fa-chevron-left',
87 next: 'fas fa-chevron-right',
87 next: 'fas fa-chevron-right',
88 today: 'far fa-calendar-check',
88 today: 'far fa-calendar-check',
89 clear: 'far fa-trash-alt',
89 clear: 'far fa-trash-alt',
90 close: 'fas fa-times'
90 close: 'fas fa-times'
91 }
91 }
92 });
92 });
93
93
94 $(".clickable-row").click(function() {
94 $(".clickable-row").click(function() {
95 document.location = $(this).data("href");
95 document.location = $(this).data("href");
96 });
96 });
97
97
98 </script>
98 </script>
99 {% endblock %}
99 {% endblock %}
@@ -1,2111 +1,2109
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 CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25
25
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
32 from apps.dds_rest.forms import DDSRestConfigurationForm
32 from apps.dds_rest.forms import DDSRestConfigurationForm
33 from apps.atrad.forms import ATRADConfigurationForm
33 from apps.atrad.forms import ATRADConfigurationForm
34 from .utils import Params
34 from .utils import Params
35
35
36 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
36 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
37 from apps.cgs.models import CGSConfiguration
37 from apps.cgs.models import CGSConfiguration
38 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
38 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
39 from apps.usrp.models import USRPConfiguration
39 from apps.usrp.models import USRPConfiguration
40 from apps.abs.models import ABSConfiguration, ABSBeam
40 from apps.abs.models import ABSConfiguration, ABSBeam
41 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
41 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
42 from apps.dds.models import DDSConfiguration
42 from apps.dds.models import DDSConfiguration
43 from apps.dds_rest.models import DDSRestConfiguration
43 from apps.dds_rest.models import DDSRestConfiguration
44 from apps.atrad.models import ATRADConfiguration
44 from apps.atrad.models import ATRADConfiguration
45
45
46 #from .tasks import task_start
46 #from .tasks import task_start
47 from radarsys.celery import app
47 from radarsys.celery import app
48
48
49
49
50 from .mqtt import client as mqtt_client
50 from .mqtt import client as mqtt_client
51 from radarsys.socketconfig import sio as sio
51 from radarsys.socketconfig import sio as sio
52
52
53 #comentario test
53 #comentario test
54 CONF_FORMS = {
54 CONF_FORMS = {
55 'rc': RCConfigurationForm,
55 'rc': RCConfigurationForm,
56 'dds': DDSConfigurationForm,
56 'dds': DDSConfigurationForm,
57 'dds_rest': DDSRestConfigurationForm,
57 'dds_rest': DDSRestConfigurationForm,
58 'jars': JARSConfigurationForm,
58 'jars': JARSConfigurationForm,
59 'cgs': CGSConfigurationForm,
59 'cgs': CGSConfigurationForm,
60 'abs': ABSConfigurationForm,
60 'abs': ABSConfigurationForm,
61 'usrp': USRPConfigurationForm,
61 'usrp': USRPConfigurationForm,
62 'atrad': ATRADConfigurationForm,
62 'atrad': ATRADConfigurationForm,
63 }
63 }
64
64
65 CONF_MODELS = {
65 CONF_MODELS = {
66 'rc': RCConfiguration,
66 'rc': RCConfiguration,
67 'dds': DDSConfiguration,
67 'dds': DDSConfiguration,
68 'dds_rest': DDSRestConfiguration,
68 'dds_rest': DDSRestConfiguration,
69 'jars': JARSConfiguration,
69 'jars': JARSConfiguration,
70 'cgs': CGSConfiguration,
70 'cgs': CGSConfiguration,
71 'abs': ABSConfiguration,
71 'abs': ABSConfiguration,
72 'usrp': USRPConfiguration,
72 'usrp': USRPConfiguration,
73 'atrad': ATRADConfiguration,
73 'atrad': ATRADConfiguration,
74 }
74 }
75
75
76 MIX_MODES = {
76 MIX_MODES = {
77 '0': 'P',
77 '0': 'P',
78 '1': 'S',
78 '1': 'S',
79 }
79 }
80
80
81 MIX_OPERATIONS = {
81 MIX_OPERATIONS = {
82 '0': 'OR',
82 '0': 'OR',
83 '1': 'XOR',
83 '1': 'XOR',
84 '2': 'AND',
84 '2': 'AND',
85 '3': 'NAND',
85 '3': 'NAND',
86 }
86 }
87
87
88
88
89 def is_developer(user):
89 def is_developer(user):
90
90
91 groups = [str(g.name) for g in user.groups.all()]
91 groups = [str(g.name) for g in user.groups.all()]
92 return 'Developer' in groups or user.is_staff
92 return 'Developer' in groups or user.is_staff
93
93
94
94
95 def is_operator(user):
95 def is_operator(user):
96
96
97 groups = [str(g.name) for g in user.groups.all()]
97 groups = [str(g.name) for g in user.groups.all()]
98 return 'Operator' in groups or user.is_staff
98 return 'Operator' in groups or user.is_staff
99
99
100
100
101 def has_been_modified(model):
101 def has_been_modified(model):
102
102
103 prev_hash = model.hash
103 prev_hash = model.hash
104 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
104 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
105 if prev_hash != new_hash:
105 if prev_hash != new_hash:
106 model.hash = new_hash
106 model.hash = new_hash
107 model.save()
107 model.save()
108 return True
108 return True
109 return False
109 return False
110
110
111
111
112 def index(request):
112 def index(request):
113 kwargs = {'no_sidebar': True}
113 kwargs = {'no_sidebar': True}
114
114
115 return render(request, 'index.html', kwargs)
115 return render(request, 'index.html', kwargs)
116
116
117
117
118 def locations(request):
118 def locations(request):
119
119
120 page = request.GET.get('page')
120 page = request.GET.get('page')
121 order = ('name',)
121 order = ('name',)
122
122
123 kwargs = get_paginator(Location, page, order)
123 kwargs = get_paginator(Location, page, order)
124
124
125 kwargs['keys'] = ['name', 'description']
125 kwargs['keys'] = ['name', 'description']
126 kwargs['title'] = 'Radar System'
126 kwargs['title'] = 'Radar System'
127 kwargs['suptitle'] = 'List'
127 kwargs['suptitle'] = 'List'
128 kwargs['no_sidebar'] = True
128 kwargs['no_sidebar'] = True
129
129
130 return render(request, 'base_list.html', kwargs)
130 return render(request, 'base_list.html', kwargs)
131
131
132
132
133 def location(request, id_loc):
133 def location(request, id_loc):
134
134
135 location = get_object_or_404(Location, pk=id_loc)
135 location = get_object_or_404(Location, pk=id_loc)
136
136
137 kwargs = {}
137 kwargs = {}
138 kwargs['location'] = location
138 kwargs['location'] = location
139 kwargs['location_keys'] = ['name', 'description']
139 kwargs['location_keys'] = ['name', 'description']
140
140
141 kwargs['title'] = 'Location'
141 kwargs['title'] = 'Location'
142 kwargs['suptitle'] = 'Details'
142 kwargs['suptitle'] = 'Details'
143
143
144 return render(request, 'location.html', kwargs)
144 return render(request, 'location.html', kwargs)
145
145
146
146
147 @login_required
147 @login_required
148 def location_new(request):
148 def location_new(request):
149
149
150 if request.method == 'GET':
150 if request.method == 'GET':
151 form = LocationForm()
151 form = LocationForm()
152
152
153 if request.method == 'POST':
153 if request.method == 'POST':
154 form = LocationForm(request.POST)
154 form = LocationForm(request.POST)
155
155
156 if form.is_valid():
156 if form.is_valid():
157 form.save()
157 form.save()
158 return redirect('url_locations')
158 return redirect('url_locations')
159
159
160 kwargs = {}
160 kwargs = {}
161 kwargs['form'] = form
161 kwargs['form'] = form
162 kwargs['title'] = 'Radar System'
162 kwargs['title'] = 'Radar System'
163 kwargs['suptitle'] = 'New'
163 kwargs['suptitle'] = 'New'
164 kwargs['button'] = 'Create'
164 kwargs['button'] = 'Create'
165
165
166 return render(request, 'base_edit.html', kwargs)
166 return render(request, 'base_edit.html', kwargs)
167
167
168
168
169 @login_required
169 @login_required
170 def location_edit(request, id_loc):
170 def location_edit(request, id_loc):
171
171
172 location = get_object_or_404(Location, pk=id_loc)
172 location = get_object_or_404(Location, pk=id_loc)
173
173
174 if request.method == 'GET':
174 if request.method == 'GET':
175 form = LocationForm(instance=location)
175 form = LocationForm(instance=location)
176
176
177 if request.method == 'POST':
177 if request.method == 'POST':
178 form = LocationForm(request.POST, instance=location)
178 form = LocationForm(request.POST, instance=location)
179
179
180 if form.is_valid():
180 if form.is_valid():
181 form.save()
181 form.save()
182 return redirect('url_locations')
182 return redirect('url_locations')
183
183
184 kwargs = {}
184 kwargs = {}
185 kwargs['form'] = form
185 kwargs['form'] = form
186 kwargs['title'] = 'Location'
186 kwargs['title'] = 'Location'
187 kwargs['suptitle'] = 'Edit'
187 kwargs['suptitle'] = 'Edit'
188 kwargs['button'] = 'Update'
188 kwargs['button'] = 'Update'
189
189
190 return render(request, 'base_edit.html', kwargs)
190 return render(request, 'base_edit.html', kwargs)
191
191
192
192
193 @login_required
193 @login_required
194 def location_delete(request, id_loc):
194 def location_delete(request, id_loc):
195
195
196 location = get_object_or_404(Location, pk=id_loc)
196 location = get_object_or_404(Location, pk=id_loc)
197
197
198 if request.method == 'POST':
198 if request.method == 'POST':
199
199
200 if is_developer(request.user):
200 if is_developer(request.user):
201 location.delete()
201 location.delete()
202 return redirect('url_locations')
202 return redirect('url_locations')
203
203
204 messages.error(request, 'Not enough permission to delete this object')
204 messages.error(request, 'Not enough permission to delete this object')
205 return redirect(location.get_absolute_url())
205 return redirect(location.get_absolute_url())
206
206
207 kwargs = {
207 kwargs = {
208 'title': 'Delete',
208 'title': 'Delete',
209 'suptitle': 'Location',
209 'suptitle': 'Location',
210 'object': location,
210 'object': location,
211 'delete': True
211 'delete': True
212 }
212 }
213
213
214 return render(request, 'confirm.html', kwargs)
214 return render(request, 'confirm.html', kwargs)
215
215
216
216
217 def devices(request):
217 def devices(request):
218
218
219 page = request.GET.get('page')
219 page = request.GET.get('page')
220 order = ('location', 'device_type')
220 order = ('location', 'device_type')
221
221
222 filters = request.GET.copy()
222 filters = request.GET.copy()
223 kwargs = get_paginator(Device, page, order, filters)
223 kwargs = get_paginator(Device, page, order, filters)
224 form = FilterForm(initial=request.GET, extra_fields=['tags'])
224 form = FilterForm(initial=request.GET, extra_fields=['tags'])
225
225
226 kwargs['keys'] = ['device_type', 'location',
226 kwargs['keys'] = ['device_type', 'location',
227 'ip_address', 'port_address', 'actions']
227 'ip_address', 'port_address', 'actions']
228 kwargs['title'] = 'Device'
228 kwargs['title'] = 'Device'
229 kwargs['suptitle'] = 'List'
229 kwargs['suptitle'] = 'List'
230 kwargs['no_sidebar'] = True
230 kwargs['no_sidebar'] = True
231 kwargs['form'] = form
231 kwargs['form'] = form
232 kwargs['add_url'] = reverse('url_add_device')
232 kwargs['add_url'] = reverse('url_add_device')
233 filters.pop('page', None)
233 filters.pop('page', None)
234 kwargs['q'] = urlencode(filters)
234 kwargs['q'] = urlencode(filters)
235 kwargs['menu_devices'] = 'active'
235 kwargs['menu_devices'] = 'active'
236 return render(request, 'base_list.html', kwargs)
236 return render(request, 'base_list.html', kwargs)
237
237
238
238
239 def device(request, id_dev):
239 def device(request, id_dev):
240
240
241 device = get_object_or_404(Device, pk=id_dev)
241 device = get_object_or_404(Device, pk=id_dev)
242
242
243 kwargs = {}
243 kwargs = {}
244 kwargs['device'] = device
244 kwargs['device'] = device
245 kwargs['device_keys'] = ['device_type',
245 kwargs['device_keys'] = ['device_type',
246 'ip_address', 'port_address', 'description']
246 'ip_address', 'port_address', 'description']
247
247
248 kwargs['title'] = 'Device'
248 kwargs['title'] = 'Device'
249 kwargs['suptitle'] = 'Details'
249 kwargs['suptitle'] = 'Details'
250 kwargs['menu_devices'] = 'active'
250 kwargs['menu_devices'] = 'active'
251
251
252 return render(request, 'device.html', kwargs)
252 return render(request, 'device.html', kwargs)
253
253
254
254
255 @login_required
255 @login_required
256 def device_new(request):
256 def device_new(request):
257
257
258 if request.method == 'GET':
258 if request.method == 'GET':
259 form = DeviceForm()
259 form = DeviceForm()
260
260
261 if request.method == 'POST':
261 if request.method == 'POST':
262 form = DeviceForm(request.POST)
262 form = DeviceForm(request.POST)
263
263
264 if form.is_valid():
264 if form.is_valid():
265 form.save()
265 form.save()
266 return redirect('url_devices')
266 return redirect('url_devices')
267
267
268 kwargs = {}
268 kwargs = {}
269 kwargs['form'] = form
269 kwargs['form'] = form
270 kwargs['title'] = 'Device'
270 kwargs['title'] = 'Device'
271 kwargs['suptitle'] = 'New_2'
271 kwargs['suptitle'] = 'New_2'
272 kwargs['button'] = 'Create'
272 kwargs['button'] = 'Create'
273 kwargs['menu_devices'] = 'active'
273 kwargs['menu_devices'] = 'active'
274
274
275 return render(request, 'base_edit.html', kwargs)
275 return render(request, 'base_edit.html', kwargs)
276
276
277
277
278 @login_required
278 @login_required
279 def device_edit(request, id_dev):
279 def device_edit(request, id_dev):
280
280
281 device = get_object_or_404(Device, pk=id_dev)
281 device = get_object_or_404(Device, pk=id_dev)
282
282
283 if request.method == 'GET':
283 if request.method == 'GET':
284 form = DeviceForm(instance=device)
284 form = DeviceForm(instance=device)
285
285
286 if request.method == 'POST':
286 if request.method == 'POST':
287 form = DeviceForm(request.POST, instance=device)
287 form = DeviceForm(request.POST, instance=device)
288
288
289 if form.is_valid():
289 if form.is_valid():
290 form.save()
290 form.save()
291 return redirect(device.get_absolute_url())
291 return redirect(device.get_absolute_url())
292
292
293 kwargs = {}
293 kwargs = {}
294 kwargs['form'] = form
294 kwargs['form'] = form
295 kwargs['title'] = 'Device'
295 kwargs['title'] = 'Device'
296 kwargs['suptitle'] = 'Edit'
296 kwargs['suptitle'] = 'Edit'
297 kwargs['button'] = 'Update'
297 kwargs['button'] = 'Update'
298 kwargs['menu_devices'] = 'active'
298 kwargs['menu_devices'] = 'active'
299
299
300 return render(request, 'base_edit.html', kwargs)
300 return render(request, 'base_edit.html', kwargs)
301
301
302
302
303 @login_required
303 @login_required
304 def device_delete(request, id_dev):
304 def device_delete(request, id_dev):
305
305
306 device = get_object_or_404(Device, pk=id_dev)
306 device = get_object_or_404(Device, pk=id_dev)
307
307
308 if request.method == 'POST':
308 if request.method == 'POST':
309
309
310 if is_developer(request.user):
310 if is_developer(request.user):
311 device.delete()
311 device.delete()
312 return redirect('url_devices')
312 return redirect('url_devices')
313
313
314 messages.error(request, 'Not enough permission to delete this object')
314 messages.error(request, 'Not enough permission to delete this object')
315 return redirect(device.get_absolute_url())
315 return redirect(device.get_absolute_url())
316
316
317 kwargs = {
317 kwargs = {
318 'title': 'Delete',
318 'title': 'Delete',
319 'suptitle': 'Device',
319 'suptitle': 'Device',
320 'object': device,
320 'object': device,
321 'delete': True
321 'delete': True
322 }
322 }
323 kwargs['menu_devices'] = 'active'
323 kwargs['menu_devices'] = 'active'
324
324
325 return render(request, 'confirm.html', kwargs)
325 return render(request, 'confirm.html', kwargs)
326
326
327
327
328 @login_required
328 @login_required
329 def device_change_ip(request, id_dev):
329 def device_change_ip(request, id_dev):
330
330
331 device = get_object_or_404(Device, pk=id_dev)
331 device = get_object_or_404(Device, pk=id_dev)
332
332
333 if request.method == 'POST':
333 if request.method == 'POST':
334
334
335 if is_developer(request.user):
335 if is_developer(request.user):
336 device.change_ip(**request.POST.dict())
336 device.change_ip(**request.POST.dict())
337
337
338 print(device.ip_address, device.message)
338 print(device.ip_address, device.message)
339
339
340 level, message = device.message.split('|')
340 level, message = device.message.split('|')
341 messages.add_message(request, level, message)
341 messages.add_message(request, level, message)
342 else:
342 else:
343 messages.error(
343 messages.error(
344 request, 'Not enough permission to delete this object')
344 request, 'Not enough permission to delete this object')
345 return redirect(device.get_absolute_url())
345 return redirect(device.get_absolute_url())
346
346
347 kwargs = {
347 kwargs = {
348 'title': 'Device',
348 'title': 'Device',
349 'suptitle': 'Change IP',
349 'suptitle': 'Change IP',
350 'object': device,
350 'object': device,
351 'previous': device.get_absolute_url(),
351 'previous': device.get_absolute_url(),
352 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
352 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
353 'message': ' ',
353 'message': ' ',
354 }
354 }
355 kwargs['menu_devices'] = 'active'
355 kwargs['menu_devices'] = 'active'
356
356
357 return render(request, 'confirm.html', kwargs)
357 return render(request, 'confirm.html', kwargs)
358
358
359
359
360 def campaigns(request):
360 def campaigns(request):
361
361
362 page = request.GET.get('page')
362 page = request.GET.get('page')
363 order = ('-start_date',)
363 order = ('-start_date',)
364 filters = request.GET.copy()
364 filters = request.GET.copy()
365
365
366 kwargs = get_paginator(Campaign, page, order, filters)
366 kwargs = get_paginator(Campaign, page, order, filters)
367
367
368 form = FilterForm(initial=request.GET, extra_fields=[
368 form = FilterForm(initial=request.GET, extra_fields=[
369 'range_date', 'tags', 'template'])
369 'range_date', 'tags', 'template'])
370 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
370 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
371 kwargs['title'] = 'Campaign'
371 kwargs['title'] = 'Campaign'
372 kwargs['suptitle'] = 'List'
372 kwargs['suptitle'] = 'List'
373 kwargs['no_sidebar'] = True
373 kwargs['no_sidebar'] = True
374 kwargs['form'] = form
374 kwargs['form'] = form
375 kwargs['add_url'] = reverse('url_add_campaign')
375 kwargs['add_url'] = reverse('url_add_campaign')
376 filters.pop('page', None)
376 filters.pop('page', None)
377 kwargs['q'] = urlencode(filters)
377 kwargs['q'] = urlencode(filters)
378 kwargs['menu_campaigns'] = 'active'
378 kwargs['menu_campaigns'] = 'active'
379
379
380 return render(request, 'base_list.html', kwargs)
380 return render(request, 'base_list.html', kwargs)
381
381
382
382
383 def campaign(request, id_camp):
383 def campaign(request, id_camp):
384
384
385 campaign = get_object_or_404(Campaign, pk=id_camp)
385 campaign = get_object_or_404(Campaign, pk=id_camp)
386 experiments = Experiment.objects.filter(campaign=campaign)
386 experiments = Experiment.objects.filter(campaign=campaign)
387
387
388 form = CampaignForm(instance=campaign)
388 form = CampaignForm(instance=campaign)
389
389
390 kwargs = {}
390 kwargs = {}
391 kwargs['campaign'] = campaign
391 kwargs['campaign'] = campaign
392 kwargs['campaign_keys'] = ['template', 'name',
392 kwargs['campaign_keys'] = ['template', 'name',
393 'start_date', 'end_date', 'tags', 'description']
393 'start_date', 'end_date', 'tags', 'description']
394
394
395 kwargs['experiments'] = experiments
395 kwargs['experiments'] = experiments
396 kwargs['experiment_keys'] = [
396 kwargs['experiment_keys'] = [
397 'name', 'radar_system', 'start_time', 'end_time']
397 'name', 'radar_system', 'start_time', 'end_time']
398
398
399 kwargs['title'] = 'Campaign'
399 kwargs['title'] = 'Campaign'
400 kwargs['suptitle'] = 'Details'
400 kwargs['suptitle'] = 'Details'
401
401
402 kwargs['form'] = form
402 kwargs['form'] = form
403 kwargs['button'] = 'Add Experiment'
403 kwargs['button'] = 'Add Experiment'
404 kwargs['menu_campaigns'] = 'active'
404 kwargs['menu_campaigns'] = 'active'
405
405
406 return render(request, 'campaign.html', kwargs)
406 return render(request, 'campaign.html', kwargs)
407
407
408
408
409 @login_required
409 @login_required
410 def campaign_new(request):
410 def campaign_new(request):
411
411
412 kwargs = {}
412 kwargs = {}
413
413
414 if request.method == 'GET':
414 if request.method == 'GET':
415
415
416 if 'template' in request.GET:
416 if 'template' in request.GET:
417 if request.GET['template'] == '0':
417 if request.GET['template'] == '0':
418 form = NewForm(initial={'create_from': 2},
418 form = NewForm(initial={'create_from': 2},
419 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
419 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
420 else:
420 else:
421 kwargs['button'] = 'Create'
421 kwargs['button'] = 'Create'
422 kwargs['experiments'] = Configuration.objects.filter(
422 kwargs['experiments'] = Configuration.objects.filter(
423 experiment=request.GET['template'])
423 experiment=request.GET['template'])
424 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
424 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
425 camp = Campaign.objects.get(pk=request.GET['template'])
425 camp = Campaign.objects.get(pk=request.GET['template'])
426 form = CampaignForm(instance=camp,
426 form = CampaignForm(instance=camp,
427 initial={'name': '{}_{:%Y%m%d%H%M%S}'.format(camp.name, datetime.now()),
427 initial={'name': '{}_{:%Y%m%d%H%M%S}'.format(camp.name, datetime.now()),
428 'template': False})
428 'template': False})
429 elif 'blank' in request.GET:
429 elif 'blank' in request.GET:
430 kwargs['button'] = 'Create'
430 kwargs['button'] = 'Create'
431 form = CampaignForm()
431 form = CampaignForm()
432 else:
432 else:
433 form = NewForm()
433 form = NewForm()
434
434
435 if request.method == 'POST':
435 if request.method == 'POST':
436 kwargs['button'] = 'Create'
436 kwargs['button'] = 'Create'
437 post = request.POST.copy()
437 post = request.POST.copy()
438 experiments = []
438 experiments = []
439
439
440 for id_exp in post.getlist('experiments'):
440 for id_exp in post.getlist('experiments'):
441 exp = Experiment.objects.get(pk=id_exp)
441 exp = Experiment.objects.get(pk=id_exp)
442 new_exp = exp.clone(template=False)
442 new_exp = exp.clone(template=False)
443 experiments.append(new_exp)
443 experiments.append(new_exp)
444
444
445 post.setlist('experiments', [])
445 post.setlist('experiments', [])
446
446
447 form = CampaignForm(post)
447 form = CampaignForm(post)
448
448
449 if form.is_valid():
449 if form.is_valid():
450 campaign = form.save(commit=False)
450 campaign = form.save(commit=False)
451 campaign.author = request.user
451 campaign.author = request.user
452 campaign.save()
452 campaign.save()
453 for exp in experiments:
453 for exp in experiments:
454 campaign.experiments.add(exp)
454 campaign.experiments.add(exp)
455
455
456 return redirect('url_campaign', id_camp=campaign.id)
456 return redirect('url_campaign', id_camp=campaign.id)
457
457
458 kwargs['form'] = form
458 kwargs['form'] = form
459 kwargs['title'] = 'Campaign'
459 kwargs['title'] = 'Campaign'
460 kwargs['suptitle'] = 'New'
460 kwargs['suptitle'] = 'New'
461 kwargs['menu_campaigns'] = 'active'
461 kwargs['menu_campaigns'] = 'active'
462
462
463 return render(request, 'campaign_edit.html', kwargs)
463 return render(request, 'campaign_edit.html', kwargs)
464
464
465
465
466 @login_required
466 @login_required
467 def campaign_edit(request, id_camp):
467 def campaign_edit(request, id_camp):
468
468
469 campaign = get_object_or_404(Campaign, pk=id_camp)
469 campaign = get_object_or_404(Campaign, pk=id_camp)
470
470
471 if request.method == 'GET':
471 if request.method == 'GET':
472 form = CampaignForm(instance=campaign)
472 form = CampaignForm(instance=campaign)
473
473
474 if request.method == 'POST':
474 if request.method == 'POST':
475 exps = campaign.experiments.all().values_list('pk', flat=True)
475 exps = campaign.experiments.all().values_list('pk', flat=True)
476 post = request.POST.copy()
476 post = request.POST.copy()
477 new_exps = post.getlist('experiments')
477 new_exps = post.getlist('experiments')
478 post.setlist('experiments', [])
478 post.setlist('experiments', [])
479 form = CampaignForm(post, instance=campaign)
479 form = CampaignForm(post, instance=campaign)
480
480
481 if form.is_valid():
481 if form.is_valid():
482 camp = form.save()
482 camp = form.save()
483 for id_exp in new_exps:
483 for id_exp in new_exps:
484 if int(id_exp) in exps:
484 if int(id_exp) in exps:
485 exps.pop(id_exp)
485 exps.pop(id_exp)
486 else:
486 else:
487 exp = Experiment.objects.get(pk=id_exp)
487 exp = Experiment.objects.get(pk=id_exp)
488 if exp.template:
488 if exp.template:
489 camp.experiments.add(exp.clone(template=False))
489 camp.experiments.add(exp.clone(template=False))
490 else:
490 else:
491 camp.experiments.add(exp)
491 camp.experiments.add(exp)
492
492
493 for id_exp in exps:
493 for id_exp in exps:
494 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
494 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
495
495
496 return redirect('url_campaign', id_camp=id_camp)
496 return redirect('url_campaign', id_camp=id_camp)
497
497
498 kwargs = {}
498 kwargs = {}
499 kwargs['form'] = form
499 kwargs['form'] = form
500 kwargs['title'] = 'Campaign'
500 kwargs['title'] = 'Campaign'
501 kwargs['suptitle'] = 'Edit'
501 kwargs['suptitle'] = 'Edit'
502 kwargs['button'] = 'Update'
502 kwargs['button'] = 'Update'
503 kwargs['menu_campaigns'] = 'active'
503 kwargs['menu_campaigns'] = 'active'
504
504
505 return render(request, 'campaign_edit.html', kwargs)
505 return render(request, 'campaign_edit.html', kwargs)
506
506
507
507
508 @login_required
508 @login_required
509 def campaign_delete(request, id_camp):
509 def campaign_delete(request, id_camp):
510
510
511 campaign = get_object_or_404(Campaign, pk=id_camp)
511 campaign = get_object_or_404(Campaign, pk=id_camp)
512
512
513 if request.method == 'POST':
513 if request.method == 'POST':
514 if is_developer(request.user):
514 if is_developer(request.user):
515
515
516 for exp in campaign.experiments.all():
516 for exp in campaign.experiments.all():
517 for conf in Configuration.objects.filter(experiment=exp):
517 for conf in Configuration.objects.filter(experiment=exp):
518 conf.delete()
518 conf.delete()
519 exp.delete()
519 exp.delete()
520 campaign.delete()
520 campaign.delete()
521
521
522 return redirect('url_campaigns')
522 return redirect('url_campaigns')
523
523
524 messages.error(request, 'Not enough permission to delete this object')
524 messages.error(request, 'Not enough permission to delete this object')
525 return redirect(campaign.get_absolute_url())
525 return redirect(campaign.get_absolute_url())
526
526
527 kwargs = {
527 kwargs = {
528 'title': 'Delete',
528 'title': 'Delete',
529 'suptitle': 'Campaign',
529 'suptitle': 'Campaign',
530 'object': campaign,
530 'object': campaign,
531 'delete': True
531 'delete': True
532 }
532 }
533 kwargs['menu_campaigns'] = 'active'
533 kwargs['menu_campaigns'] = 'active'
534
534
535 return render(request, 'confirm.html', kwargs)
535 return render(request, 'confirm.html', kwargs)
536
536
537
537
538 @login_required
538 @login_required
539 def campaign_export(request, id_camp):
539 def campaign_export(request, id_camp):
540
540
541 campaign = get_object_or_404(Campaign, pk=id_camp)
541 campaign = get_object_or_404(Campaign, pk=id_camp)
542 content = campaign.parms_to_dict()
542 content = campaign.parms_to_dict()
543 content_type = 'application/json'
543 content_type = 'application/json'
544 filename = '%s_%s.json' % (campaign.name, campaign.id)
544 filename = '%s_%s.json' % (campaign.name, campaign.id)
545
545
546 response = HttpResponse(content_type=content_type)
546 response = HttpResponse(content_type=content_type)
547 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
547 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
548 response.write(json.dumps(content, indent=2))
548 response.write(json.dumps(content, indent=2))
549
549
550 return response
550 return response
551
551
552
552
553 @login_required
553 @login_required
554 def campaign_import(request, id_camp):
554 def campaign_import(request, id_camp):
555
555
556 campaign = get_object_or_404(Campaign, pk=id_camp)
556 campaign = get_object_or_404(Campaign, pk=id_camp)
557
557
558 if request.method == 'GET':
558 if request.method == 'GET':
559 file_form = UploadFileForm()
559 file_form = UploadFileForm()
560
560
561 if request.method == 'POST':
561 if request.method == 'POST':
562 file_form = UploadFileForm(request.POST, request.FILES)
562 file_form = UploadFileForm(request.POST, request.FILES)
563
563
564 if file_form.is_valid():
564 if file_form.is_valid():
565 new_camp = campaign.dict_to_parms(
565 new_camp = campaign.dict_to_parms(
566 json.load(request.FILES['file']), CONF_MODELS)
566 json.load(request.FILES['file']), CONF_MODELS)
567 messages.success(
567 messages.success(
568 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
568 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
569 return redirect(new_camp.get_absolute_url_edit())
569 return redirect(new_camp.get_absolute_url_edit())
570
570
571 messages.error(request, "Could not import parameters from file")
571 messages.error(request, "Could not import parameters from file")
572
572
573 kwargs = {}
573 kwargs = {}
574 kwargs['title'] = 'Campaign'
574 kwargs['title'] = 'Campaign'
575 kwargs['form'] = file_form
575 kwargs['form'] = file_form
576 kwargs['suptitle'] = 'Importing file'
576 kwargs['suptitle'] = 'Importing file'
577 kwargs['button'] = 'Import'
577 kwargs['button'] = 'Import'
578 kwargs['menu_campaigns'] = 'active'
578 kwargs['menu_campaigns'] = 'active'
579
579
580 return render(request, 'campaign_import.html', kwargs)
580 return render(request, 'campaign_import.html', kwargs)
581
581
582
582
583 def experiments(request):
583 def experiments(request):
584
584
585 page = request.GET.get('page')
585 page = request.GET.get('page')
586 order = ('location',)
586 order = ('location',)
587 filters = request.GET.copy()
587 filters = request.GET.copy()
588
588
589 if 'my experiments' in filters:
589 if 'my experiments' in filters:
590 filters.pop('my experiments', None)
590 filters.pop('my experiments', None)
591 filters['mine'] = request.user.id
591 filters['mine'] = request.user.id
592
592
593 kwargs = get_paginator(Experiment, page, order, filters)
593 kwargs = get_paginator(Experiment, page, order, filters)
594
594
595 fields = ['tags', 'template']
595 fields = ['tags', 'template']
596 if request.user.is_authenticated:
596 if request.user.is_authenticated:
597 fields.append('my experiments')
597 fields.append('my experiments')
598
598
599 form = FilterForm(initial=request.GET, extra_fields=fields)
599 form = FilterForm(initial=request.GET, extra_fields=fields)
600
600
601 kwargs['keys'] = ['name', 'radar_system',
601 kwargs['keys'] = ['name', 'radar_system',
602 'start_time', 'end_time', 'actions']
602 'start_time', 'end_time', 'actions']
603 kwargs['title'] = 'Experiment'
603 kwargs['title'] = 'Experiment'
604 kwargs['suptitle'] = 'List'
604 kwargs['suptitle'] = 'List'
605 kwargs['no_sidebar'] = True
605 kwargs['no_sidebar'] = True
606 kwargs['form'] = form
606 kwargs['form'] = form
607 kwargs['add_url'] = reverse('url_add_experiment')
607 kwargs['add_url'] = reverse('url_add_experiment')
608 filters = request.GET.copy()
608 filters = request.GET.copy()
609 filters.pop('page', None)
609 filters.pop('page', None)
610 kwargs['q'] = urlencode(filters)
610 kwargs['q'] = urlencode(filters)
611 kwargs['menu_experiments'] = 'active'
611 kwargs['menu_experiments'] = 'active'
612
612
613 return render(request, 'base_list.html', kwargs)
613 return render(request, 'base_list.html', kwargs)
614
614
615
615
616 def experiment(request, id_exp):
616 def experiment(request, id_exp):
617
617
618 experiment = get_object_or_404(Experiment, pk=id_exp)
618 experiment = get_object_or_404(Experiment, pk=id_exp)
619
619
620 configurations = Configuration.objects.filter(
620 configurations = Configuration.objects.filter(
621 experiment=experiment, type=0)
621 experiment=experiment, type=0)
622
622
623 kwargs = {}
623 kwargs = {}
624
624
625 kwargs['experiment_keys'] = ['template', 'radar_system',
625 kwargs['experiment_keys'] = ['template', 'radar_system',
626 'name', 'freq', 'start_time', 'end_time']
626 'name', 'freq', 'start_time', 'end_time']
627 kwargs['experiment'] = experiment
627 kwargs['experiment'] = experiment
628 kwargs['configuration_keys'] = ['name', 'device__ip_address',
628 kwargs['configuration_keys'] = ['name', 'device__ip_address',
629 'device__port_address', 'device__status']
629 'device__port_address', 'device__status']
630 kwargs['configurations'] = configurations
630 kwargs['configurations'] = configurations
631 kwargs['title'] = 'Experiment'
631 kwargs['title'] = 'Experiment'
632 kwargs['suptitle'] = 'Details'
632 kwargs['suptitle'] = 'Details'
633 kwargs['button'] = 'Add Configuration'
633 kwargs['button'] = 'Add Configuration'
634 kwargs['menu_experiments'] = 'active'
634 kwargs['menu_experiments'] = 'active'
635
635
636 ###### SIDEBAR ######
636 ###### SIDEBAR ######
637 kwargs.update(sidebar(experiment=experiment))
637 kwargs.update(sidebar(experiment=experiment))
638
638
639 return render(request, 'experiment.html', kwargs)
639 return render(request, 'experiment.html', kwargs)
640
640
641
641
642 @login_required
642 @login_required
643 def experiment_new(request, id_camp=None):
643 def experiment_new(request, id_camp=None):
644
644
645 if not is_developer(request.user):
645 if not is_developer(request.user):
646 messages.error(
646 messages.error(
647 request, 'Developer required, to create new Experiments')
647 request, 'Developer required, to create new Experiments')
648 return redirect('index')
648 return redirect('index')
649 kwargs = {}
649 kwargs = {}
650
650
651 if request.method == 'GET':
651 if request.method == 'GET':
652 if 'template' in request.GET:
652 if 'template' in request.GET:
653 if request.GET['template'] == '0':
653 if request.GET['template'] == '0':
654 form = NewForm(initial={'create_from': 2},
654 form = NewForm(initial={'create_from': 2},
655 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
655 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
656 else:
656 else:
657 kwargs['button'] = 'Create'
657 kwargs['button'] = 'Create'
658 kwargs['configurations'] = Configuration.objects.filter(
658 kwargs['configurations'] = Configuration.objects.filter(
659 experiment=request.GET['template'])
659 experiment=request.GET['template'])
660 kwargs['configuration_keys'] = ['name', 'device__name',
660 kwargs['configuration_keys'] = ['name', 'device__name',
661 'device__ip_address', 'device__port_address']
661 'device__ip_address', 'device__port_address']
662 exp = Experiment.objects.get(pk=request.GET['template'])
662 exp = Experiment.objects.get(pk=request.GET['template'])
663 form = ExperimentForm(instance=exp,
663 form = ExperimentForm(instance=exp,
664 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
664 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
665 'template': False})
665 'template': False})
666 elif 'blank' in request.GET:
666 elif 'blank' in request.GET:
667 kwargs['button'] = 'Create'
667 kwargs['button'] = 'Create'
668 form = ExperimentForm()
668 form = ExperimentForm()
669 else:
669 else:
670 form = NewForm()
670 form = NewForm()
671
671
672 if request.method == 'POST':
672 if request.method == 'POST':
673 form = ExperimentForm(request.POST)
673 form = ExperimentForm(request.POST)
674 if form.is_valid():
674 if form.is_valid():
675 experiment = form.save(commit=False)
675 experiment = form.save(commit=False)
676 experiment.author = request.user
676 experiment.author = request.user
677 experiment.save()
677 experiment.save()
678
678
679 if 'template' in request.GET:
679 if 'template' in request.GET:
680 configurations = Configuration.objects.filter(
680 configurations = Configuration.objects.filter(
681 experiment=request.GET['template'], type=0)
681 experiment=request.GET['template'], type=0)
682 for conf in configurations:
682 for conf in configurations:
683 conf.clone(experiment=experiment, template=False)
683 conf.clone(experiment=experiment, template=False)
684
684
685 return redirect('url_experiment', id_exp=experiment.id)
685 return redirect('url_experiment', id_exp=experiment.id)
686
686
687 kwargs['form'] = form
687 kwargs['form'] = form
688 kwargs['title'] = 'Experiment'
688 kwargs['title'] = 'Experiment'
689 kwargs['suptitle'] = 'New'
689 kwargs['suptitle'] = 'New'
690 kwargs['menu_experiments'] = 'active'
690 kwargs['menu_experiments'] = 'active'
691
691
692 return render(request, 'experiment_edit.html', kwargs)
692 return render(request, 'experiment_edit.html', kwargs)
693
693
694
694
695 @login_required
695 @login_required
696 def experiment_edit(request, id_exp):
696 def experiment_edit(request, id_exp):
697
697
698 experiment = get_object_or_404(Experiment, pk=id_exp)
698 experiment = get_object_or_404(Experiment, pk=id_exp)
699
699
700 if request.method == 'GET':
700 if request.method == 'GET':
701 form = ExperimentForm(instance=experiment)
701 form = ExperimentForm(instance=experiment)
702
702
703 if request.method == 'POST':
703 if request.method == 'POST':
704 form = ExperimentForm(request.POST, instance=experiment)
704 form = ExperimentForm(request.POST, instance=experiment)
705
705
706 if form.is_valid():
706 if form.is_valid():
707 experiment = form.save()
707 experiment = form.save()
708 return redirect('url_experiment', id_exp=experiment.id)
708 return redirect('url_experiment', id_exp=experiment.id)
709
709
710 kwargs = {}
710 kwargs = {}
711 kwargs['form'] = form
711 kwargs['form'] = form
712 kwargs['title'] = 'Experiment'
712 kwargs['title'] = 'Experiment'
713 kwargs['suptitle'] = 'Edit'
713 kwargs['suptitle'] = 'Edit'
714 kwargs['button'] = 'Update'
714 kwargs['button'] = 'Update'
715 kwargs['menu_experiments'] = 'active'
715 kwargs['menu_experiments'] = 'active'
716
716
717 return render(request, 'experiment_edit.html', kwargs)
717 return render(request, 'experiment_edit.html', kwargs)
718
718
719
719
720 @login_required
720 @login_required
721 def experiment_delete(request, id_exp):
721 def experiment_delete(request, id_exp):
722
722
723 experiment = get_object_or_404(Experiment, pk=id_exp)
723 experiment = get_object_or_404(Experiment, pk=id_exp)
724
724
725 if request.method == 'POST':
725 if request.method == 'POST':
726 if is_developer(request.user):
726 if is_developer(request.user):
727 for conf in Configuration.objects.filter(experiment=experiment):
727 for conf in Configuration.objects.filter(experiment=experiment):
728 conf.delete()
728 conf.delete()
729 experiment.delete()
729 experiment.delete()
730 return redirect('url_experiments')
730 return redirect('url_experiments')
731
731
732 messages.error(request, 'Not enough permission to delete this object')
732 messages.error(request, 'Not enough permission to delete this object')
733 return redirect(experiment.get_absolute_url())
733 return redirect(experiment.get_absolute_url())
734
734
735 kwargs = {
735 kwargs = {
736 'title': 'Delete',
736 'title': 'Delete',
737 'suptitle': 'Experiment',
737 'suptitle': 'Experiment',
738 'object': experiment,
738 'object': experiment,
739 'delete': True
739 'delete': True
740 }
740 }
741
741
742 return render(request, 'confirm.html', kwargs)
742 return render(request, 'confirm.html', kwargs)
743
743
744
744
745 @login_required
745 @login_required
746 def experiment_export(request, id_exp):
746 def experiment_export(request, id_exp):
747
747
748 experiment = get_object_or_404(Experiment, pk=id_exp)
748 experiment = get_object_or_404(Experiment, pk=id_exp)
749 content = experiment.parms_to_dict()
749 content = experiment.parms_to_dict()
750 content_type = 'application/json'
750 content_type = 'application/json'
751 filename = '%s_%s.json' % (experiment.name, experiment.id)
751 filename = '%s_%s.json' % (experiment.name, experiment.id)
752
752
753 response = HttpResponse(content_type=content_type)
753 response = HttpResponse(content_type=content_type)
754 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
754 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
755 response.write(json.dumps(content, indent=2))
755 response.write(json.dumps(content, indent=2))
756
756
757 return response
757 return response
758
758
759
759
760 @login_required
760 @login_required
761 def experiment_import(request, id_exp):
761 def experiment_import(request, id_exp):
762
762
763 experiment = get_object_or_404(Experiment, pk=id_exp)
763 experiment = get_object_or_404(Experiment, pk=id_exp)
764 configurations = Configuration.objects.filter(experiment=experiment)
764 configurations = Configuration.objects.filter(experiment=experiment)
765
765
766 if request.method == 'GET':
766 if request.method == 'GET':
767 file_form = UploadFileForm()
767 file_form = UploadFileForm()
768
768
769 if request.method == 'POST':
769 if request.method == 'POST':
770 file_form = UploadFileForm(request.POST, request.FILES)
770 file_form = UploadFileForm(request.POST, request.FILES)
771
771
772 if file_form.is_valid():
772 if file_form.is_valid():
773 new_exp = experiment.dict_to_parms(
773 new_exp = experiment.dict_to_parms(
774 json.load(request.FILES['file']), CONF_MODELS)
774 json.load(request.FILES['file']), CONF_MODELS)
775 messages.success(
775 messages.success(
776 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
776 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
777 return redirect(new_exp.get_absolute_url_edit())
777 return redirect(new_exp.get_absolute_url_edit())
778
778
779 messages.error(request, "Could not import parameters from file")
779 messages.error(request, "Could not import parameters from file")
780
780
781 kwargs = {}
781 kwargs = {}
782 kwargs['title'] = 'Experiment'
782 kwargs['title'] = 'Experiment'
783 kwargs['form'] = file_form
783 kwargs['form'] = file_form
784 kwargs['suptitle'] = 'Importing file'
784 kwargs['suptitle'] = 'Importing file'
785 kwargs['button'] = 'Import'
785 kwargs['button'] = 'Import'
786 kwargs['menu_experiments'] = 'active'
786 kwargs['menu_experiments'] = 'active'
787
787
788 kwargs.update(sidebar(experiment=experiment))
788 kwargs.update(sidebar(experiment=experiment))
789
789
790 return render(request, 'experiment_import.html', kwargs)
790 return render(request, 'experiment_import.html', kwargs)
791
791
792
792
793 @login_required
793 @login_required
794 def experiment_start(request, id_exp):
794 def experiment_start(request, id_exp):
795
795
796 exp = get_object_or_404(Experiment, pk=id_exp)
796 exp = get_object_or_404(Experiment, pk=id_exp)
797
797
798 if exp.status == 2:
798 if exp.status == 2:
799 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
799 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
800 else:
800 else:
801 exp.status = exp.start()
801 exp.status = exp.start()
802 if exp.status == 0:
802 if exp.status == 0:
803 messages.error(request, 'Experiment {} not start'.format(exp))
803 messages.error(request, 'Experiment {} not start'.format(exp))
804 if exp.status == 2:
804 if exp.status == 2:
805 messages.success(request, 'Experiment {} started'.format(exp))
805 messages.success(request, 'Experiment {} started'.format(exp))
806
806
807 exp.save()
807 exp.save()
808
808
809 return redirect(exp.get_absolute_url())
809 return redirect(exp.get_absolute_url())
810
810
811
811
812 @login_required
812 @login_required
813 def experiment_stop(request, id_exp):
813 def experiment_stop(request, id_exp):
814
814
815 exp = get_object_or_404(Experiment, pk=id_exp)
815 exp = get_object_or_404(Experiment, pk=id_exp)
816
816
817 if exp.status == 2:
817 if exp.status == 2:
818 exp.status = exp.stop()
818 exp.status = exp.stop()
819 exp.save()
819 exp.save()
820 messages.success(request, 'Experiment {} stopped'.format(exp))
820 messages.success(request, 'Experiment {} stopped'.format(exp))
821 else:
821 else:
822 messages.error(request, 'Experiment {} not running'.format(exp))
822 messages.error(request, 'Experiment {} not running'.format(exp))
823
823
824 return redirect(exp.get_absolute_url())
824 return redirect(exp.get_absolute_url())
825
825
826
826
827 def experiment_status(request, id_exp):
827 def experiment_status(request, id_exp):
828
828
829 exp = get_object_or_404(Experiment, pk=id_exp)
829 exp = get_object_or_404(Experiment, pk=id_exp)
830
830
831 exp.get_status()
831 exp.get_status()
832
832
833 return redirect(exp.get_absolute_url())
833 return redirect(exp.get_absolute_url())
834
834
835
835
836 @login_required
836 @login_required
837 def experiment_mix(request, id_exp):
837 def experiment_mix(request, id_exp):
838
838
839 experiment = get_object_or_404(Experiment, pk=id_exp)
839 experiment = get_object_or_404(Experiment, pk=id_exp)
840 rc_confs = [conf for conf in RCConfiguration.objects.filter(
840 rc_confs = [conf for conf in RCConfiguration.objects.filter(
841 experiment=id_exp,
841 experiment=id_exp,
842 type=0,
842 type=0,
843 mix=False)]
843 mix=False)]
844
844
845 if len(rc_confs) < 2:
845 if len(rc_confs) < 2:
846 messages.warning(
846 messages.warning(
847 request, 'You need at least two RC Configurations to make a mix')
847 request, 'You need at least two RC Configurations to make a mix')
848 return redirect(experiment.get_absolute_url())
848 return redirect(experiment.get_absolute_url())
849
849
850 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
850 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
851
851
852 if mix_confs:
852 if mix_confs:
853 mix = mix_confs[0]
853 mix = mix_confs[0]
854 else:
854 else:
855 mix = RCConfiguration(experiment=experiment,
855 mix = RCConfiguration(experiment=experiment,
856 device=rc_confs[0].device,
856 device=rc_confs[0].device,
857 ipp=rc_confs[0].ipp,
857 ipp=rc_confs[0].ipp,
858 clock_in=rc_confs[0].clock_in,
858 clock_in=rc_confs[0].clock_in,
859 clock_divider=rc_confs[0].clock_divider,
859 clock_divider=rc_confs[0].clock_divider,
860 mix=True,
860 mix=True,
861 parameters='')
861 parameters='')
862 mix.save()
862 mix.save()
863
863
864 line_type = RCLineType.objects.get(name='mix')
864 line_type = RCLineType.objects.get(name='mix')
865 print("VIew obteniendo len getlines")
865 print("VIew obteniendo len getlines")
866 print(len(rc_confs[0].get_lines()))
866 print(len(rc_confs[0].get_lines()))
867 for i in range(len(rc_confs[0].get_lines())):
867 for i in range(len(rc_confs[0].get_lines())):
868 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
868 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
869 line.save()
869 line.save()
870
870
871 initial = {'name': mix.name,
871 initial = {'name': mix.name,
872 'result': parse_mix_result(mix.parameters),
872 'result': parse_mix_result(mix.parameters),
873 'delay': 0,
873 'delay': 0,
874 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
874 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
875 }
875 }
876
876
877 if request.method == 'GET':
877 if request.method == 'GET':
878 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
878 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
879
879
880 if request.method == 'POST':
880 if request.method == 'POST':
881 result = mix.parameters
881 result = mix.parameters
882
882
883 if '{}|'.format(request.POST['experiment']) in result:
883 if '{}|'.format(request.POST['experiment']) in result:
884 messages.error(request, 'Configuration already added')
884 messages.error(request, 'Configuration already added')
885 else:
885 else:
886 if 'operation' in request.POST:
886 if 'operation' in request.POST:
887 operation = MIX_OPERATIONS[request.POST['operation']]
887 operation = MIX_OPERATIONS[request.POST['operation']]
888 else:
888 else:
889 operation = ' '
889 operation = ' '
890
890
891 mode = MIX_MODES[request.POST['mode']]
891 mode = MIX_MODES[request.POST['mode']]
892
892
893 if result:
893 if result:
894 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
894 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
895 request.POST['experiment'],
895 request.POST['experiment'],
896 mode,
896 mode,
897 operation,
897 operation,
898 float(
898 float(
899 request.POST['delay']),
899 request.POST['delay']),
900 parse_mask(
900 parse_mask(
901 request.POST.getlist('mask'))
901 request.POST.getlist('mask'))
902 )
902 )
903 else:
903 else:
904 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
904 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
905 mode,
905 mode,
906 operation,
906 operation,
907 float(request.POST['delay']),
907 float(request.POST['delay']),
908 parse_mask(
908 parse_mask(
909 request.POST.getlist('mask'))
909 request.POST.getlist('mask'))
910 )
910 )
911
911
912 mix.parameters = result
912 mix.parameters = result
913 mix.save()
913 mix.save()
914 mix.update_pulses()
914 mix.update_pulses()
915
915
916 initial['result'] = parse_mix_result(result)
916 initial['result'] = parse_mix_result(result)
917 initial['name'] = mix.name
917 initial['name'] = mix.name
918
918
919 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
919 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
920
920
921 kwargs = {
921 kwargs = {
922 'title': 'Experiment',
922 'title': 'Experiment',
923 'suptitle': 'Mix Configurations',
923 'suptitle': 'Mix Configurations',
924 'form': form,
924 'form': form,
925 'extra_button': 'Delete',
925 'extra_button': 'Delete',
926 'button': 'Add',
926 'button': 'Add',
927 'cancel': 'Back',
927 'cancel': 'Back',
928 'previous': experiment.get_absolute_url(),
928 'previous': experiment.get_absolute_url(),
929 'id_exp': id_exp,
929 'id_exp': id_exp,
930
930
931 }
931 }
932 kwargs['menu_experiments'] = 'active'
932 kwargs['menu_experiments'] = 'active'
933
933
934 return render(request, 'experiment_mix.html', kwargs)
934 return render(request, 'experiment_mix.html', kwargs)
935
935
936
936
937 @login_required
937 @login_required
938 def experiment_mix_delete(request, id_exp):
938 def experiment_mix_delete(request, id_exp):
939
939
940 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
940 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
941 values = conf.parameters.split('-')
941 values = conf.parameters.split('-')
942 conf.parameters = '-'.join(values[:-1])
942 conf.parameters = '-'.join(values[:-1])
943 conf.save()
943 conf.save()
944
944
945 return redirect('url_mix_experiment', id_exp=id_exp)
945 return redirect('url_mix_experiment', id_exp=id_exp)
946
946
947
947
948 def experiment_summary(request, id_exp):
948 def experiment_summary(request, id_exp):
949
949
950 experiment = get_object_or_404(Experiment, pk=id_exp)
950 experiment = get_object_or_404(Experiment, pk=id_exp)
951 configurations = Configuration.objects.filter(
951 configurations = Configuration.objects.filter(
952 experiment=experiment, type=0)
952 experiment=experiment, type=0)
953
953
954 kwargs = {}
954 kwargs = {}
955 kwargs['experiment_keys'] = ['radar_system',
955 kwargs['experiment_keys'] = ['radar_system',
956 'name', 'freq', 'start_time', 'end_time']
956 'name', 'freq', 'start_time', 'end_time']
957 kwargs['experiment'] = experiment
957 kwargs['experiment'] = experiment
958 kwargs['configurations'] = []
958 kwargs['configurations'] = []
959 kwargs['title'] = 'Experiment Summary'
959 kwargs['title'] = 'Experiment Summary'
960 kwargs['suptitle'] = 'Details'
960 kwargs['suptitle'] = 'Details'
961 kwargs['button'] = 'Verify Parameters'
961 kwargs['button'] = 'Verify Parameters'
962
962
963 c_vel = 3.0*(10**8) # m/s
963 c_vel = 3.0*(10**8) # m/s
964 ope_freq = experiment.freq*(10**6) # 1/s
964 ope_freq = experiment.freq*(10**6) # 1/s
965 radar_lambda = c_vel/ope_freq # m
965 radar_lambda = c_vel/ope_freq # m
966 kwargs['radar_lambda'] = radar_lambda
966 kwargs['radar_lambda'] = radar_lambda
967
967
968 ipp = None
968 ipp = None
969 nsa = 1
969 nsa = 1
970 code_id = 0
970 code_id = 0
971 tx_line = {}
971 tx_line = {}
972
972
973 for configuration in configurations.filter(device__device_type__name = 'rc'):
973 for configuration in configurations.filter(device__device_type__name = 'rc'):
974
974
975 if configuration.mix:
975 if configuration.mix:
976 continue
976 continue
977 conf = {'conf': configuration}
977 conf = {'conf': configuration}
978 conf['keys'] = []
978 conf['keys'] = []
979 conf['NTxs'] = configuration.ntx
979 conf['NTxs'] = configuration.ntx
980 conf['keys'].append('NTxs')
980 conf['keys'].append('NTxs')
981 ipp = configuration.ipp
981 ipp = configuration.ipp
982 conf['IPP'] = ipp
982 conf['IPP'] = ipp
983 conf['keys'].append('IPP')
983 conf['keys'].append('IPP')
984 lines = configuration.get_lines(line_type__name='tx')
984 lines = configuration.get_lines(line_type__name='tx')
985
985
986 for tx_line in lines:
986 for tx_line in lines:
987 tx_params = json.loads(tx_line.params)
987 tx_params = json.loads(tx_line.params)
988 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
988 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
989 conf['keys'].append(tx_line.get_name())
989 conf['keys'].append(tx_line.get_name())
990 delays = tx_params['delays']
990 delays = tx_params['delays']
991 if delays not in ('', '0'):
991 if delays not in ('', '0'):
992 n = len(delays.split(','))
992 n = len(delays.split(','))
993 taus = '{} Taus: {}'.format(n, delays)
993 taus = '{} Taus: {}'.format(n, delays)
994 else:
994 else:
995 taus = '-'
995 taus = '-'
996 conf['Taus ({})'.format(tx_line.get_name())] = taus
996 conf['Taus ({})'.format(tx_line.get_name())] = taus
997 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
997 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
998 for code_line in configuration.get_lines(line_type__name='codes'):
998 for code_line in configuration.get_lines(line_type__name='codes'):
999 code_params = json.loads(code_line.params)
999 code_params = json.loads(code_line.params)
1000 code_id = code_params['code']
1000 code_id = code_params['code']
1001 if tx_line.pk == int(code_params['TX_ref']):
1001 if tx_line.pk == int(code_params['TX_ref']):
1002 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
1002 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
1003 '-'.join(code_params['codes']))
1003 '-'.join(code_params['codes']))
1004 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
1004 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
1005
1005
1006 for windows_line in configuration.get_lines(line_type__name='windows'):
1006 for windows_line in configuration.get_lines(line_type__name='windows'):
1007 win_params = json.loads(windows_line.params)
1007 win_params = json.loads(windows_line.params)
1008 if tx_line.pk == int(win_params['TX_ref']):
1008 if tx_line.pk == int(win_params['TX_ref']):
1009 windows = ''
1009 windows = ''
1010 nsa = win_params['params'][0]['number_of_samples']
1010 nsa = win_params['params'][0]['number_of_samples']
1011 for i, params in enumerate(win_params['params']):
1011 for i, params in enumerate(win_params['params']):
1012 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1012 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1013 i, **params)
1013 i, **params)
1014 conf['Window'] = mark_safe(windows)
1014 conf['Window'] = mark_safe(windows)
1015 conf['keys'].append('Window')
1015 conf['keys'].append('Window')
1016
1016
1017 kwargs['configurations'].append(conf)
1017 kwargs['configurations'].append(conf)
1018
1018
1019 for configuration in configurations.filter(device__device_type__name = 'jars'):
1019 for configuration in configurations.filter(device__device_type__name = 'jars'):
1020
1020
1021 conf = {'conf': configuration}
1021 conf = {'conf': configuration}
1022 conf['keys'] = []
1022 conf['keys'] = []
1023 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1023 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1024 conf['keys'].append('Type of Data')
1024 conf['keys'].append('Type of Data')
1025 channels_number = configuration.channels_number
1025 channels_number = configuration.channels_number
1026 exp_type = configuration.exp_type
1026 exp_type = configuration.exp_type
1027 fftpoints = configuration.fftpoints
1027 fftpoints = configuration.fftpoints
1028 filter_parms = json.loads(configuration.filter_parms)
1028 filter_parms = json.loads(configuration.filter_parms)
1029 spectral_number = configuration.spectral_number
1029 spectral_number = configuration.spectral_number
1030 acq_profiles = configuration.acq_profiles
1030 acq_profiles = configuration.acq_profiles
1031 cohe_integr = configuration.cohe_integr
1031 cohe_integr = configuration.cohe_integr
1032 profiles_block = configuration.profiles_block
1032 profiles_block = configuration.profiles_block
1033
1033
1034 conf['Num of Profiles'] = acq_profiles
1034 conf['Num of Profiles'] = acq_profiles
1035 conf['keys'].append('Num of Profiles')
1035 conf['keys'].append('Num of Profiles')
1036
1036
1037 conf['Prof per Block'] = profiles_block
1037 conf['Prof per Block'] = profiles_block
1038 conf['keys'].append('Prof per Block')
1038 conf['keys'].append('Prof per Block')
1039
1039
1040 conf['Blocks per File'] = configuration.raw_data_blocks
1040 conf['Blocks per File'] = configuration.raw_data_blocks
1041 conf['keys'].append('Blocks per File')
1041 conf['keys'].append('Blocks per File')
1042
1042
1043 if exp_type == 0: # Short
1043 if exp_type == 0: # Short
1044 bytes_ = 2
1044 bytes_ = 2
1045 b = nsa*2*bytes_*channels_number
1045 b = nsa*2*bytes_*channels_number
1046 else: # Float
1046 else: # Float
1047 bytes_ = 4
1047 bytes_ = 4
1048 channels = channels_number + spectral_number
1048 channels = channels_number + spectral_number
1049 b = nsa*2*bytes_*fftpoints*channels
1049 b = nsa*2*bytes_*fftpoints*channels
1050
1050
1051 codes_num = 7
1051 codes_num = 7
1052 if code_id == 2:
1052 if code_id == 2:
1053 codes_num = 7
1053 codes_num = 7
1054 elif code_id == 12:
1054 elif code_id == 12:
1055 codes_num = 15
1055 codes_num = 15
1056
1056
1057 #Jars filter values:
1057 #Jars filter values:
1058
1058
1059 clock = float(filter_parms['clock'])
1059 clock = float(filter_parms['clock'])
1060 filter_2 = int(filter_parms['cic_2'])
1060 filter_2 = int(filter_parms['cic_2'])
1061 filter_5 = int(filter_parms['cic_5'])
1061 filter_5 = int(filter_parms['cic_5'])
1062 filter_fir = int(filter_parms['fir'])
1062 filter_fir = int(filter_parms['fir'])
1063 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1063 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1064
1064
1065 #Jars values:
1065 #Jars values:
1066 if ipp is not None:
1066 if ipp is not None:
1067 IPP_units = ipp/0.15*Fs_MHz
1067 IPP_units = ipp/0.15*Fs_MHz
1068 IPP_us = IPP_units / Fs_MHz
1068 IPP_us = IPP_units / Fs_MHz
1069 IPP_s = IPP_units / (Fs_MHz * (10**6))
1069 IPP_s = IPP_units / (Fs_MHz * (10**6))
1070 Ts = 1/(Fs_MHz*(10**6))
1070 Ts = 1/(Fs_MHz*(10**6))
1071
1071
1072 Va = radar_lambda/(4*Ts*cohe_integr)
1072 Va = radar_lambda/(4*Ts*cohe_integr)
1073 rate_bh = ((nsa-codes_num)*channels_number*2 *
1073 rate_bh = ((nsa-codes_num)*channels_number*2 *
1074 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1074 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1075 rate_gh = rate_bh/(1024*1024*1024)
1075 rate_gh = rate_bh/(1024*1024*1024)
1076
1076
1077 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1077 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1078 conf['keys'].append('Time per Block')
1078 conf['keys'].append('Time per Block')
1079 conf['Acq time'] = IPP_s * acq_profiles
1079 conf['Acq time'] = IPP_s * acq_profiles
1080 conf['keys'].append('Acq time')
1080 conf['keys'].append('Acq time')
1081 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1081 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1082 conf['keys'].append('Data rate')
1082 conf['keys'].append('Data rate')
1083 conf['Va (m/s)'] = Va
1083 conf['Va (m/s)'] = Va
1084 conf['keys'].append('Va (m/s)')
1084 conf['keys'].append('Va (m/s)')
1085 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1085 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1086 conf['keys'].append('Vrange (m/s)')
1086 conf['keys'].append('Vrange (m/s)')
1087
1087
1088 kwargs['configurations'].append(conf)
1088 kwargs['configurations'].append(conf)
1089 kwargs['menu_experiments'] = 'active'
1089 kwargs['menu_experiments'] = 'active'
1090
1090
1091 ###### SIDEBAR ######
1091 ###### SIDEBAR ######
1092 kwargs.update(sidebar(experiment=experiment))
1092 kwargs.update(sidebar(experiment=experiment))
1093
1093
1094 return render(request, 'experiment_summary.html', kwargs)
1094 return render(request, 'experiment_summary.html', kwargs)
1095
1095
1096
1096
1097 @login_required
1097 @login_required
1098 def experiment_verify(request, id_exp):
1098 def experiment_verify(request, id_exp):
1099
1099
1100 experiment = get_object_or_404(Experiment, pk=id_exp)
1100 experiment = get_object_or_404(Experiment, pk=id_exp)
1101 experiment_data = experiment.parms_to_dict()
1101 experiment_data = experiment.parms_to_dict()
1102 configurations = Configuration.objects.filter(
1102 configurations = Configuration.objects.filter(
1103 experiment=experiment, type=0)
1103 experiment=experiment, type=0)
1104
1104
1105 kwargs = {}
1105 kwargs = {}
1106
1106
1107 kwargs['experiment_keys'] = ['template',
1107 kwargs['experiment_keys'] = ['template',
1108 'radar_system', 'name', 'start_time', 'end_time']
1108 'radar_system', 'name', 'start_time', 'end_time']
1109 kwargs['experiment'] = experiment
1109 kwargs['experiment'] = experiment
1110
1110
1111 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1111 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1112 'device__port_address', 'device__status']
1112 'device__port_address', 'device__status']
1113 kwargs['configurations'] = configurations
1113 kwargs['configurations'] = configurations
1114 kwargs['experiment_data'] = experiment_data
1114 kwargs['experiment_data'] = experiment_data
1115
1115
1116 kwargs['title'] = 'Verify Experiment'
1116 kwargs['title'] = 'Verify Experiment'
1117 kwargs['suptitle'] = 'Parameters'
1117 kwargs['suptitle'] = 'Parameters'
1118
1118
1119 kwargs['button'] = 'Update'
1119 kwargs['button'] = 'Update'
1120
1120
1121 jars_conf = False
1121 jars_conf = False
1122 rc_conf = False
1122 rc_conf = False
1123 dds_conf = False
1123 dds_conf = False
1124
1124
1125 for configuration in configurations:
1125 for configuration in configurations:
1126 #-------------------- JARS -----------------------:
1126 #-------------------- JARS -----------------------:
1127 if configuration.device.device_type.name == 'jars':
1127 if configuration.device.device_type.name == 'jars':
1128 jars_conf = True
1128 jars_conf = True
1129 jars = configuration
1129 jars = configuration
1130 kwargs['jars_conf'] = jars_conf
1130 kwargs['jars_conf'] = jars_conf
1131 filter_parms = json.loads(jars.filter_parms)
1131 filter_parms = json.loads(jars.filter_parms)
1132 kwargs['filter_parms'] = filter_parms
1132 kwargs['filter_parms'] = filter_parms
1133 #--Sampling Frequency
1133 #--Sampling Frequency
1134 clock = filter_parms['clock']
1134 clock = filter_parms['clock']
1135 filter_2 = filter_parms['cic_2']
1135 filter_2 = filter_parms['cic_2']
1136 filter_5 = filter_parms['cic_5']
1136 filter_5 = filter_parms['cic_5']
1137 filter_fir = filter_parms['fir']
1137 filter_fir = filter_parms['fir']
1138 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1138 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1139
1139
1140 kwargs['samp_freq_jars'] = samp_freq_jars
1140 kwargs['samp_freq_jars'] = samp_freq_jars
1141 kwargs['jars'] = configuration
1141 kwargs['jars'] = configuration
1142
1142
1143 #--------------------- RC ----------------------:
1143 #--------------------- RC ----------------------:
1144 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1144 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1145 rc_conf = True
1145 rc_conf = True
1146 rc = configuration
1146 rc = configuration
1147
1147
1148 rc_parms = configuration.parms_to_dict()
1148 rc_parms = configuration.parms_to_dict()
1149
1149
1150 win_lines = rc.get_lines(line_type__name='windows')
1150 win_lines = rc.get_lines(line_type__name='windows')
1151 if win_lines:
1151 if win_lines:
1152 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1152 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1153 #--Sampling Frequency
1153 #--Sampling Frequency
1154 samp_freq_rc = 0.15/dh
1154 samp_freq_rc = 0.15/dh
1155 kwargs['samp_freq_rc'] = samp_freq_rc
1155 kwargs['samp_freq_rc'] = samp_freq_rc
1156
1156
1157 kwargs['rc_conf'] = rc_conf
1157 kwargs['rc_conf'] = rc_conf
1158 kwargs['rc'] = configuration
1158 kwargs['rc'] = configuration
1159
1159
1160 #-------------------- DDS ----------------------:
1160 #-------------------- DDS ----------------------:
1161 if configuration.device.device_type.name == 'dds':
1161 if configuration.device.device_type.name == 'dds':
1162 dds_conf = True
1162 dds_conf = True
1163 dds = configuration
1163 dds = configuration
1164 dds_parms = configuration.parms_to_dict()
1164 dds_parms = configuration.parms_to_dict()
1165
1165
1166 kwargs['dds_conf'] = dds_conf
1166 kwargs['dds_conf'] = dds_conf
1167 kwargs['dds'] = configuration
1167 kwargs['dds'] = configuration
1168
1168
1169 #------------Validation------------:
1169 #------------Validation------------:
1170 #Clock
1170 #Clock
1171 if dds_conf and rc_conf and jars_conf:
1171 if dds_conf and rc_conf and jars_conf:
1172 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']):
1172 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']):
1173 messages.warning(request, "Devices don't have the same clock.")
1173 messages.warning(request, "Devices don't have the same clock.")
1174 elif rc_conf and jars_conf:
1174 elif rc_conf and jars_conf:
1175 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1175 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1176 messages.warning(request, "Devices don't have the same clock.")
1176 messages.warning(request, "Devices don't have the same clock.")
1177 elif rc_conf and dds_conf:
1177 elif rc_conf and dds_conf:
1178 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1178 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1179 messages.warning(request, "Devices don't have the same clock.")
1179 messages.warning(request, "Devices don't have the same clock.")
1180 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1180 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1181 messages.warning(
1181 messages.warning(
1182 request, "Devices don't have the same Frequency A.")
1182 request, "Devices don't have the same Frequency A.")
1183
1183
1184 #------------POST METHOD------------:
1184 #------------POST METHOD------------:
1185 if request.method == 'POST':
1185 if request.method == 'POST':
1186 if request.POST['suggest_clock']:
1186 if request.POST['suggest_clock']:
1187 try:
1187 try:
1188 suggest_clock = float(request.POST['suggest_clock'])
1188 suggest_clock = float(request.POST['suggest_clock'])
1189 except:
1189 except:
1190 messages.warning(request, "Invalid value in CLOCK IN.")
1190 messages.warning(request, "Invalid value in CLOCK IN.")
1191 return redirect('url_verify_experiment', id_exp=experiment.id)
1191 return redirect('url_verify_experiment', id_exp=experiment.id)
1192 else:
1192 else:
1193 suggest_clock = ""
1193 suggest_clock = ""
1194 if suggest_clock:
1194 if suggest_clock:
1195 if rc_conf:
1195 if rc_conf:
1196 rc.clock_in = suggest_clock
1196 rc.clock_in = suggest_clock
1197 rc.save()
1197 rc.save()
1198 if jars_conf:
1198 if jars_conf:
1199 filter_parms = jars.filter_parms
1199 filter_parms = jars.filter_parms
1200 filter_parms = ast.literal_eval(filter_parms)
1200 filter_parms = ast.literal_eval(filter_parms)
1201 filter_parms['clock'] = suggest_clock
1201 filter_parms['clock'] = suggest_clock
1202 jars.filter_parms = json.dumps(filter_parms)
1202 jars.filter_parms = json.dumps(filter_parms)
1203 jars.save()
1203 jars.save()
1204 kwargs['filter_parms'] = filter_parms
1204 kwargs['filter_parms'] = filter_parms
1205 if dds_conf:
1205 if dds_conf:
1206 dds.clock = suggest_clock
1206 dds.clock = suggest_clock
1207 dds.save()
1207 dds.save()
1208
1208
1209 if request.POST['suggest_frequencyA']:
1209 if request.POST['suggest_frequencyA']:
1210 try:
1210 try:
1211 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1211 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1212 except:
1212 except:
1213 messages.warning(request, "Invalid value in FREQUENCY A.")
1213 messages.warning(request, "Invalid value in FREQUENCY A.")
1214 return redirect('url_verify_experiment', id_exp=experiment.id)
1214 return redirect('url_verify_experiment', id_exp=experiment.id)
1215 else:
1215 else:
1216 suggest_frequencyA = ""
1216 suggest_frequencyA = ""
1217 if suggest_frequencyA:
1217 if suggest_frequencyA:
1218 if jars_conf:
1218 if jars_conf:
1219 filter_parms = jars.filter_parms
1219 filter_parms = jars.filter_parms
1220 filter_parms = ast.literal_eval(filter_parms)
1220 filter_parms = ast.literal_eval(filter_parms)
1221 filter_parms['fch'] = suggest_frequencyA
1221 filter_parms['fch'] = suggest_frequencyA
1222 jars.filter_parms = json.dumps(filter_parms)
1222 jars.filter_parms = json.dumps(filter_parms)
1223 jars.save()
1223 jars.save()
1224 kwargs['filter_parms'] = filter_parms
1224 kwargs['filter_parms'] = filter_parms
1225 if dds_conf:
1225 if dds_conf:
1226 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1226 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1227 dds.save()
1227 dds.save()
1228
1228
1229 kwargs['menu_experiments'] = 'active'
1229 kwargs['menu_experiments'] = 'active'
1230 kwargs.update(sidebar(experiment=experiment))
1230 kwargs.update(sidebar(experiment=experiment))
1231 return render(request, 'experiment_verify.html', kwargs)
1231 return render(request, 'experiment_verify.html', kwargs)
1232
1232
1233
1233
1234 def parse_mix_result(s):
1234 def parse_mix_result(s):
1235
1235
1236 values = s.split('-')
1236 values = s.split('-')
1237 html = 'EXP MOD OPE DELAY MASK\r\n'
1237 html = 'EXP MOD OPE DELAY MASK\r\n'
1238
1238
1239 if not values or values[0] in ('', ' '):
1239 if not values or values[0] in ('', ' '):
1240 return mark_safe(html)
1240 return mark_safe(html)
1241
1241
1242 for i, value in enumerate(values):
1242 for i, value in enumerate(values):
1243 if not value:
1243 if not value:
1244 continue
1244 continue
1245 pk, mode, operation, delay, mask = value.split('|')
1245 pk, mode, operation, delay, mask = value.split('|')
1246 conf = RCConfiguration.objects.get(pk=pk)
1246 conf = RCConfiguration.objects.get(pk=pk)
1247 if i == 0:
1247 if i == 0:
1248 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1248 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1249 conf.name,
1249 conf.name,
1250 mode,
1250 mode,
1251 ' ',
1251 ' ',
1252 delay,
1252 delay,
1253 mask)
1253 mask)
1254 else:
1254 else:
1255 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1255 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1256 conf.name,
1256 conf.name,
1257 mode,
1257 mode,
1258 operation,
1258 operation,
1259 delay,
1259 delay,
1260 mask)
1260 mask)
1261
1261
1262 return mark_safe(html)
1262 return mark_safe(html)
1263
1263
1264
1264
1265 def parse_mask(l):
1265 def parse_mask(l):
1266
1266
1267 values = []
1267 values = []
1268
1268
1269 for x in range(16):
1269 for x in range(16):
1270 if '{}'.format(x) in l:
1270 if '{}'.format(x) in l:
1271 values.append(1)
1271 values.append(1)
1272 else:
1272 else:
1273 values.append(0)
1273 values.append(0)
1274
1274
1275 values.reverse()
1275 values.reverse()
1276
1276
1277 return int(''.join([str(x) for x in values]), 2)
1277 return int(''.join([str(x) for x in values]), 2)
1278
1278
1279
1279
1280 def dev_confs(request):
1280 def dev_confs(request):
1281
1281
1282 page = request.GET.get('page')
1282 page = request.GET.get('page')
1283 order = ('-programmed_date', )
1283 order = ('-programmed_date', )
1284 filters = request.GET.copy()
1284 filters = request.GET.copy()
1285 if 'my configurations' in filters:
1285 if 'my configurations' in filters:
1286 filters.pop('my configurations', None)
1286 filters.pop('my configurations', None)
1287 filters['mine'] = request.user.id
1287 filters['mine'] = request.user.id
1288 kwargs = get_paginator(Configuration, page, order, filters)
1288 kwargs = get_paginator(Configuration, page, order, filters)
1289 fields = ['tags', 'template', 'historical']
1289 fields = ['tags', 'template', 'historical']
1290 if request.user.is_authenticated:
1290 if request.user.is_authenticated:
1291 fields.append('my configurations')
1291 fields.append('my configurations')
1292 form = FilterForm(initial=request.GET, extra_fields=fields)
1292 form = FilterForm(initial=request.GET, extra_fields=fields)
1293 kwargs['keys'] = ['name', 'experiment',
1293 kwargs['keys'] = ['name', 'experiment',
1294 'type', 'programmed_date', 'actions']
1294 'type', 'programmed_date', 'actions']
1295 kwargs['title'] = 'Configuration'
1295 kwargs['title'] = 'Configuration'
1296 kwargs['suptitle'] = 'List'
1296 kwargs['suptitle'] = 'List'
1297 kwargs['no_sidebar'] = True
1297 kwargs['no_sidebar'] = True
1298 kwargs['form'] = form
1298 kwargs['form'] = form
1299 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1299 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1300 filters = request.GET.copy()
1300 filters = request.GET.copy()
1301 filters.pop('page', None)
1301 filters.pop('page', None)
1302 kwargs['q'] = urlencode(filters)
1302 kwargs['q'] = urlencode(filters)
1303 kwargs['menu_configurations'] = 'active'
1303 kwargs['menu_configurations'] = 'active'
1304
1304
1305 return render(request, 'base_list.html', kwargs)
1305 return render(request, 'base_list.html', kwargs)
1306
1306
1307
1307
1308 def dev_conf(request, id_conf):
1308 def dev_conf(request, id_conf):
1309
1309
1310 conf = get_object_or_404(Configuration, pk=id_conf)
1310 conf = get_object_or_404(Configuration, pk=id_conf)
1311
1311
1312 return redirect(conf.get_absolute_url())
1312 return redirect(conf.get_absolute_url())
1313
1313
1314
1314
1315 @login_required
1315 @login_required
1316 def dev_conf_new(request, id_exp=0, id_dev=0):
1316 def dev_conf_new(request, id_exp=0, id_dev=0):
1317
1317
1318 if not is_developer(request.user):
1318 if not is_developer(request.user):
1319 messages.error(
1319 messages.error(
1320 request, 'Developer required, to create new configurations')
1320 request, 'Developer required, to create new configurations')
1321 return redirect('index')
1321 return redirect('index')
1322
1322
1323 initial = {}
1323 initial = {}
1324 kwargs = {}
1324 kwargs = {}
1325
1325
1326 if id_exp != 0:
1326 if id_exp != 0:
1327 initial['experiment'] = id_exp
1327 initial['experiment'] = id_exp
1328
1328
1329 if id_dev != 0:
1329 if id_dev != 0:
1330 initial['device'] = id_dev
1330 initial['device'] = id_dev
1331
1331
1332 if request.method == 'GET':
1332 if request.method == 'GET':
1333
1333
1334 if id_dev:
1334 if id_dev:
1335 kwargs['button'] = 'Create'
1335 kwargs['button'] = 'Create'
1336 device = Device.objects.get(pk=id_dev)
1336 device = Device.objects.get(pk=id_dev)
1337 DevConfForm = CONF_FORMS[device.device_type.name]
1337 DevConfForm = CONF_FORMS[device.device_type.name]
1338 initial['name'] = request.GET['name']
1338 initial['name'] = request.GET['name']
1339 form = DevConfForm(initial=initial)
1339 form = DevConfForm(initial=initial)
1340 else:
1340 else:
1341 if 'template' in request.GET:
1341 if 'template' in request.GET:
1342 if request.GET['template'] == '0':
1342 if request.GET['template'] == '0':
1343 choices = [(conf.pk, '{}'.format(conf))
1343 choices = [(conf.pk, '{}'.format(conf))
1344 for conf in Configuration.objects.filter(template=True)]
1344 for conf in Configuration.objects.filter(template=True)]
1345 form = NewForm(initial={'create_from': 2},
1345 form = NewForm(initial={'create_from': 2},
1346 template_choices=choices)
1346 template_choices=choices)
1347 else:
1347 else:
1348 kwargs['button'] = 'Create'
1348 kwargs['button'] = 'Create'
1349 conf = Configuration.objects.get(
1349 conf = Configuration.objects.get(
1350 pk=request.GET['template'])
1350 pk=request.GET['template'])
1351 id_dev = conf.device.pk
1351 id_dev = conf.device.pk
1352 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1352 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1353 form = DevConfForm(instance=conf,
1353 form = DevConfForm(instance=conf,
1354 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1354 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1355 'template': False,
1355 'template': False,
1356 'experiment': id_exp})
1356 'experiment': id_exp})
1357 elif 'blank' in request.GET:
1357 elif 'blank' in request.GET:
1358 kwargs['button'] = 'Create'
1358 kwargs['button'] = 'Create'
1359 form = ConfigurationForm(initial=initial)
1359 form = ConfigurationForm(initial=initial)
1360 else:
1360 else:
1361 form = NewForm()
1361 form = NewForm()
1362
1362
1363 if request.method == 'POST':
1363 if request.method == 'POST':
1364
1364
1365 device = Device.objects.get(pk=request.POST['device'])
1365 device = Device.objects.get(pk=request.POST['device'])
1366 DevConfForm = CONF_FORMS[device.device_type.name]
1366 DevConfForm = CONF_FORMS[device.device_type.name]
1367
1367
1368 form = DevConfForm(request.POST)
1368 form = DevConfForm(request.POST)
1369 kwargs['button'] = 'Create'
1369 kwargs['button'] = 'Create'
1370 if form.is_valid():
1370 if form.is_valid():
1371 conf = form.save(commit=False)
1371 conf = form.save(commit=False)
1372 conf.author = request.user
1372 conf.author = request.user
1373 conf.save()
1373 conf.save()
1374
1374
1375 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1375 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1376 lines = RCLine.objects.filter(
1376 lines = RCLine.objects.filter(
1377 rc_configuration=request.GET['template'])
1377 rc_configuration=request.GET['template'])
1378 for line in lines:
1378 for line in lines:
1379 line.clone(rc_configuration=conf)
1379 line.clone(rc_configuration=conf)
1380
1380
1381 new_lines = conf.get_lines()
1381 new_lines = conf.get_lines()
1382 for line in new_lines:
1382 for line in new_lines:
1383 line_params = json.loads(line.params)
1383 line_params = json.loads(line.params)
1384 if 'TX_ref' in line_params:
1384 if 'TX_ref' in line_params:
1385 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1385 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1386 line_params['TX_ref'] = ['{}'.format(
1386 line_params['TX_ref'] = ['{}'.format(
1387 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1387 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1388 line.params = json.dumps(line_params)
1388 line.params = json.dumps(line_params)
1389 line.save()
1389 line.save()
1390 elif conf.device.device_type.name == 'rc':
1390 elif conf.device.device_type.name == 'rc':
1391 clk = RCClock(rc_configuration=conf)
1391 clk = RCClock(rc_configuration=conf)
1392 clk.save()
1392 clk.save()
1393
1393
1394 return redirect('url_dev_conf', id_conf=conf.pk)
1394 return redirect('url_dev_conf', id_conf=conf.pk)
1395
1395
1396 kwargs['id_exp'] = id_exp
1396 kwargs['id_exp'] = id_exp
1397 kwargs['form'] = form
1397 kwargs['form'] = form
1398 kwargs['title'] = 'Configuration'
1398 kwargs['title'] = 'Configuration'
1399 kwargs['suptitle'] = 'New'
1399 kwargs['suptitle'] = 'New'
1400 kwargs['menu_configurations'] = 'active'
1400 kwargs['menu_configurations'] = 'active'
1401
1401
1402 if id_dev != 0:
1402 if id_dev != 0:
1403 device = Device.objects.get(pk=id_dev)
1403 device = Device.objects.get(pk=id_dev)
1404 kwargs['device'] = device.device_type.name
1404 kwargs['device'] = device.device_type.name
1405 print(id_exp)
1405 print(id_exp)
1406 return render(request, 'dev_conf_edit.html', kwargs)
1406 return render(request, 'dev_conf_edit.html', kwargs)
1407
1407
1408
1408
1409 @login_required
1409 @login_required
1410 def dev_conf_edit(request, id_conf):
1410 def dev_conf_edit(request, id_conf):
1411
1411
1412 conf = get_object_or_404(Configuration, pk=id_conf)
1412 conf = get_object_or_404(Configuration, pk=id_conf)
1413
1413
1414 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1414 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1415
1415
1416 if request.method == 'GET':
1416 if request.method == 'GET':
1417 form = DevConfForm(instance=conf)
1417 form = DevConfForm(instance=conf)
1418
1418
1419 if request.method == 'POST':
1419 if request.method == 'POST':
1420 form = DevConfForm(request.POST, instance=conf)
1420 form = DevConfForm(request.POST, instance=conf)
1421
1421
1422 if form.is_valid():
1422 if form.is_valid():
1423 form.save()
1423 form.save()
1424 return redirect('url_dev_conf', id_conf=id_conf)
1424 return redirect('url_dev_conf', id_conf=id_conf)
1425
1425
1426 kwargs = {}
1426 kwargs = {}
1427 kwargs['form'] = form
1427 kwargs['form'] = form
1428 kwargs['title'] = 'Device Configuration'
1428 kwargs['title'] = 'Device Configuration'
1429 kwargs['suptitle'] = 'Edit'
1429 kwargs['suptitle'] = 'Edit'
1430 kwargs['button'] = 'Update'
1430 kwargs['button'] = 'Update'
1431 kwargs['menu_configurations'] = 'active'
1431 kwargs['menu_configurations'] = 'active'
1432
1432
1433 ###### SIDEBAR ######
1433 ###### SIDEBAR ######
1434 kwargs.update(sidebar(conf=conf))
1434 kwargs.update(sidebar(conf=conf))
1435
1435
1436 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1436 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1437
1437
1438
1438
1439 @login_required
1439 @login_required
1440 def dev_conf_start(request, id_conf):
1440 def dev_conf_start(request, id_conf):
1441
1441
1442 conf = get_object_or_404(Configuration, pk=id_conf)
1442 conf = get_object_or_404(Configuration, pk=id_conf)
1443
1443
1444 if conf.start_device():
1444 if conf.start_device():
1445 messages.success(request, conf.message)
1445 messages.success(request, conf.message)
1446 else:
1446 else:
1447 messages.error(request, conf.message)
1447 messages.error(request, conf.message)
1448
1448
1449 #conf.status_device()
1449 #conf.status_device()
1450
1450
1451 return redirect(conf.get_absolute_url())
1451 return redirect(conf.get_absolute_url())
1452
1452
1453
1453
1454 @login_required
1454 @login_required
1455 def dev_conf_stop(request, id_conf):
1455 def dev_conf_stop(request, id_conf):
1456
1456
1457 conf = get_object_or_404(Configuration, pk=id_conf)
1457 conf = get_object_or_404(Configuration, pk=id_conf)
1458
1458
1459 if conf.stop_device():
1459 if conf.stop_device():
1460 messages.success(request, conf.message)
1460 messages.success(request, conf.message)
1461 else:
1461 else:
1462 messages.error(request, conf.message)
1462 messages.error(request, conf.message)
1463
1463
1464 #conf.status_device()
1464 #conf.status_device()
1465
1465
1466 return redirect(conf.get_absolute_url())
1466 return redirect(conf.get_absolute_url())
1467
1467
1468 @login_required
1468 @login_required
1469 def dev_conf_stop_mqtt(request, id_conf):
1469 def dev_conf_stop_mqtt(request, id_conf):
1470
1470
1471 conf = get_object_or_404(Configuration, pk=id_conf)
1471 conf = get_object_or_404(Configuration, pk=id_conf)
1472
1472
1473 if conf.stop_device_mqtt():
1473 if conf.stop_device_mqtt():
1474 messages.success(request, conf.message)
1474 messages.success(request, conf.message)
1475 else:
1475 else:
1476 messages.error(request, conf.message)
1476 messages.error(request, conf.message)
1477
1477
1478 #conf.status_device()
1478 #conf.status_device()
1479
1479
1480 return redirect(conf.get_absolute_url())
1480 return redirect(conf.get_absolute_url())
1481
1481
1482 @login_required
1482 @login_required
1483 def dev_conf_status(request, id_conf):
1483 def dev_conf_status(request, id_conf):
1484
1484
1485 conf = get_object_or_404(Configuration, pk=id_conf)
1485 conf = get_object_or_404(Configuration, pk=id_conf)
1486
1486
1487 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1487 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1488 if conf_active!=conf:
1488 if conf_active!=conf:
1489 url = '#' if conf_active is None else conf_active.get_absolute_url()
1489 url = '#' if conf_active is None else conf_active.get_absolute_url()
1490 label = 'None' if conf_active is None else conf_active.label
1490 label = 'None' if conf_active is None else conf_active.label
1491 messages.warning(
1491 messages.warning(
1492 request,
1492 request,
1493 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1493 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1494 url,
1494 url,
1495 label
1495 label
1496 ))
1496 ))
1497 )
1497 )
1498
1498
1499 return redirect(conf.get_absolute_url())
1499 return redirect(conf.get_absolute_url())
1500
1500
1501 if conf.status_device():
1501 if conf.status_device():
1502 messages.success(request, conf.message)
1502 messages.success(request, conf.message)
1503 else:
1503 else:
1504 messages.error(request, conf.message)
1504 messages.error(request, conf.message)
1505
1505
1506 return redirect(conf.get_absolute_url())
1506 return redirect(conf.get_absolute_url())
1507
1507
1508
1508
1509 @login_required
1509 @login_required
1510 def dev_conf_reset(request, id_conf):
1510 def dev_conf_reset(request, id_conf):
1511
1511
1512 conf = get_object_or_404(Configuration, pk=id_conf)
1512 conf = get_object_or_404(Configuration, pk=id_conf)
1513
1513
1514 if conf.reset_device():
1514 if conf.reset_device():
1515 messages.success(request, conf.message)
1515 messages.success(request, conf.message)
1516 else:
1516 else:
1517 messages.error(request, conf.message)
1517 messages.error(request, conf.message)
1518
1518
1519 return redirect(conf.get_absolute_url())
1519 return redirect(conf.get_absolute_url())
1520
1520
1521
1521
1522 @login_required
1522 @login_required
1523 def dev_conf_write(request, id_conf):
1523 def dev_conf_write(request, id_conf):
1524
1524
1525 conf = get_object_or_404(Configuration, pk=id_conf)
1525 conf = get_object_or_404(Configuration, pk=id_conf)
1526
1526
1527 if request.method == 'POST':
1527 if request.method == 'POST':
1528 if conf.write_device():
1528 if conf.write_device():
1529 conf.device.conf_active = conf.pk
1529 conf.device.conf_active = conf.pk
1530 conf.device.save()
1530 conf.device.save()
1531 messages.success(request, conf.message)
1531 messages.success(request, conf.message)
1532 if has_been_modified(conf):
1532 if has_been_modified(conf):
1533 conf.clone(type=1, template=False)
1533 conf.clone(type=1, template=False)
1534 else:
1534 else:
1535 messages.error(request, conf.message)
1535 messages.error(request, conf.message)
1536
1536
1537 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1537 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1538
1538
1539 kwargs = {
1539 kwargs = {
1540 'title': 'Write Configuration',
1540 'title': 'Write Configuration',
1541 'suptitle': conf.label,
1541 'suptitle': conf.label,
1542 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1542 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1543 'delete': False
1543 'delete': False
1544 }
1544 }
1545 kwargs['menu_configurations'] = 'active'
1545 kwargs['menu_configurations'] = 'active'
1546
1546
1547 return render(request, 'confirm.html', kwargs)
1547 return render(request, 'confirm.html', kwargs)
1548
1548
1549
1549
1550 @login_required
1550 @login_required
1551 def dev_conf_write_mqtt(request,id_conf):
1551 def dev_conf_write_mqtt(request,id_conf):
1552
1552
1553 conf = get_object_or_404(Configuration, pk=id_conf)
1553 conf = get_object_or_404(Configuration, pk=id_conf)
1554 beams = ABSBeam.objects.filter(abs_conf=conf)
1554 beams = ABSBeam.objects.filter(abs_conf=conf)
1555
1555
1556 if request.method == 'POST':
1556 if request.method == 'POST':
1557 if conf.write_device_mqtt():
1557 if conf.write_device_mqtt():
1558 conf.device.conf_active = conf.pk
1558 conf.device.conf_active = conf.pk
1559 conf.device.save()
1559 conf.device.save()
1560 messages.success(request, conf.message)
1560 messages.success(request, conf.message)
1561 if has_been_modified(conf):
1561 if has_been_modified(conf):
1562 conf.clone(type=1, template=False)
1562 conf.clone(type=1, template=False)
1563 else:
1563 else:
1564 messages.error(request, conf.message)
1564 messages.error(request, conf.message)
1565 print("return",flush=True)
1565 print("return",flush=True)
1566 #return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1566 #return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1567
1567
1568 module_messages = json.loads(conf.module_messages)
1568 module_messages = json.loads(conf.module_messages)
1569 kwargs = {}
1569 kwargs = {}
1570 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
1570 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
1571 kwargs['dev_conf'] = conf
1571 kwargs['dev_conf'] = conf
1572
1572
1573 if conf.operation_mode == 0:
1573 if conf.operation_mode == 0:
1574 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
1574 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
1575 else:
1575 else:
1576 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
1576 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
1577
1577
1578 kwargs['title'] = 'ABS Configuration'
1578 kwargs['title'] = 'ABS Configuration'
1579 kwargs['suptitle'] = 'Details'
1579 kwargs['suptitle'] = 'Details'
1580 kwargs['button'] = 'Edit Configuration'
1580 kwargs['button'] = 'Edit Configuration'
1581
1581
1582 print("conf.active_beam: {}".format(conf.active_beam))
1582 print("conf.active_beam: {}".format(conf.active_beam))
1583 if conf.active_beam != 0:
1583 if conf.active_beam != 0:
1584 kwargs['active_beam'] = int(conf.active_beam)
1584 kwargs['active_beam'] = int(conf.active_beam)
1585
1585
1586
1586
1587 kwargs['beams'] = beams
1587 kwargs['beams'] = beams
1588 # kwargs['modules_status'] = all_status
1588 # kwargs['modules_status'] = all_status
1589 # kwargs['color_status'] = color_status
1589 # kwargs['color_status'] = color_status
1590
1590
1591
1592 kwargs['module_messages'] = module_messages
1591 kwargs['module_messages'] = module_messages
1593
1592
1594 ###### SIDEBAR ######
1593 ###### SIDEBAR ######
1595 kwargs.update(sidebar(conf=conf))
1594 kwargs.update(sidebar(conf=conf))
1596
1595
1597
1598 return render(request, 'abs_conf_mqtt.html',kwargs)
1596 return render(request, 'abs_conf_mqtt.html',kwargs)
1599
1597
1600 kwargs = {
1598 kwargs = {
1601 'title': 'MQTT Write Configuration',
1599 'title': 'MQTT Write Configuration',
1602 'suptitle': conf.label,
1600 'suptitle': conf.label,
1603 'message': 'Are you sure yo want to write through MQTT this {} configuration?'.format(conf.device),
1601 'message': 'Are you sure yo want to write through MQTT this {} configuration?'.format(conf.device),
1604 'delete': False
1602 'delete': False
1605 }
1603 }
1606 kwargs['menu_configurations'] = 'active'
1604 kwargs['menu_configurations'] = 'active'
1607 print("Confirm",flush=True)
1605 print("Confirm",flush=True)
1608 return render(request, 'confirm.html', kwargs)
1606 return render(request, 'confirm.html', kwargs)
1609
1607
1610
1608
1611 @login_required
1609 @login_required
1612 def dev_conf_read(request, id_conf):
1610 def dev_conf_read(request, id_conf):
1613
1611
1614 conf = get_object_or_404(Configuration, pk=id_conf)
1612 conf = get_object_or_404(Configuration, pk=id_conf)
1615
1613
1616 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1614 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1617
1615
1618 if request.method == 'GET':
1616 if request.method == 'GET':
1619
1617
1620 parms = conf.read_device()
1618 parms = conf.read_device()
1621 #conf.status_device()
1619 #conf.status_device()
1622
1620
1623 if not parms:
1621 if not parms:
1624 messages.error(request, conf.message)
1622 messages.error(request, conf.message)
1625 return redirect(conf.get_absolute_url())
1623 return redirect(conf.get_absolute_url())
1626
1624
1627 form = DevConfForm(initial=parms, instance=conf)
1625 form = DevConfForm(initial=parms, instance=conf)
1628
1626
1629 if request.method == 'POST':
1627 if request.method == 'POST':
1630 form = DevConfForm(request.POST, instance=conf)
1628 form = DevConfForm(request.POST, instance=conf)
1631
1629
1632 if form.is_valid():
1630 if form.is_valid():
1633 form.save()
1631 form.save()
1634 return redirect(conf.get_absolute_url())
1632 return redirect(conf.get_absolute_url())
1635
1633
1636 messages.error(request, "Parameters could not be saved")
1634 messages.error(request, "Parameters could not be saved")
1637
1635
1638 kwargs = {}
1636 kwargs = {}
1639 kwargs['id_dev'] = conf.id
1637 kwargs['id_dev'] = conf.id
1640 kwargs['form'] = form
1638 kwargs['form'] = form
1641 kwargs['title'] = 'Device Configuration'
1639 kwargs['title'] = 'Device Configuration'
1642 kwargs['suptitle'] = 'Parameters read from device'
1640 kwargs['suptitle'] = 'Parameters read from device'
1643 kwargs['button'] = 'Save'
1641 kwargs['button'] = 'Save'
1644
1642
1645 ###### SIDEBAR ######
1643 ###### SIDEBAR ######
1646 kwargs.update(sidebar(conf=conf))
1644 kwargs.update(sidebar(conf=conf))
1647
1645
1648 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1646 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1649
1647
1650
1648
1651 @login_required
1649 @login_required
1652 def dev_conf_import(request, id_conf):
1650 def dev_conf_import(request, id_conf):
1653
1651
1654 conf = get_object_or_404(Configuration, pk=id_conf)
1652 conf = get_object_or_404(Configuration, pk=id_conf)
1655 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1653 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1656
1654
1657 if request.method == 'GET':
1655 if request.method == 'GET':
1658 file_form = UploadFileForm()
1656 file_form = UploadFileForm()
1659
1657
1660 if request.method == 'POST':
1658 if request.method == 'POST':
1661 file_form = UploadFileForm(request.POST, request.FILES)
1659 file_form = UploadFileForm(request.POST, request.FILES)
1662
1660
1663 if file_form.is_valid():
1661 if file_form.is_valid():
1664
1662
1665 data = conf.import_from_file(request.FILES['file'])
1663 data = conf.import_from_file(request.FILES['file'])
1666 parms = Params(data=data).get_conf(
1664 parms = Params(data=data).get_conf(
1667 dtype=conf.device.device_type.name)
1665 dtype=conf.device.device_type.name)
1668
1666
1669 if parms:
1667 if parms:
1670
1668
1671 form = DevConfForm(initial=parms, instance=conf)
1669 form = DevConfForm(initial=parms, instance=conf)
1672
1670
1673 kwargs = {}
1671 kwargs = {}
1674 kwargs['id_dev'] = conf.id
1672 kwargs['id_dev'] = conf.id
1675 kwargs['form'] = form
1673 kwargs['form'] = form
1676 kwargs['title'] = 'Device Configuration'
1674 kwargs['title'] = 'Device Configuration'
1677 kwargs['suptitle'] = 'Parameters imported'
1675 kwargs['suptitle'] = 'Parameters imported'
1678 kwargs['button'] = 'Save'
1676 kwargs['button'] = 'Save'
1679 kwargs['action'] = conf.get_absolute_url_edit()
1677 kwargs['action'] = conf.get_absolute_url_edit()
1680 kwargs['previous'] = conf.get_absolute_url()
1678 kwargs['previous'] = conf.get_absolute_url()
1681
1679
1682 ###### SIDEBAR ######
1680 ###### SIDEBAR ######
1683 kwargs.update(sidebar(conf=conf))
1681 kwargs.update(sidebar(conf=conf))
1684
1682
1685 messages.success(
1683 messages.success(
1686 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1684 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1687
1685
1688 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1686 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1689
1687
1690 messages.error(request, "Could not import parameters from file")
1688 messages.error(request, "Could not import parameters from file")
1691
1689
1692 kwargs = {}
1690 kwargs = {}
1693 kwargs['id_dev'] = conf.id
1691 kwargs['id_dev'] = conf.id
1694 kwargs['title'] = 'Device Configuration'
1692 kwargs['title'] = 'Device Configuration'
1695 kwargs['form'] = file_form
1693 kwargs['form'] = file_form
1696 kwargs['suptitle'] = 'Importing file'
1694 kwargs['suptitle'] = 'Importing file'
1697 kwargs['button'] = 'Import'
1695 kwargs['button'] = 'Import'
1698 kwargs['menu_configurations'] = 'active'
1696 kwargs['menu_configurations'] = 'active'
1699
1697
1700 kwargs.update(sidebar(conf=conf))
1698 kwargs.update(sidebar(conf=conf))
1701
1699
1702 return render(request, 'dev_conf_import.html', kwargs)
1700 return render(request, 'dev_conf_import.html', kwargs)
1703
1701
1704
1702
1705 @login_required
1703 @login_required
1706 def dev_conf_export(request, id_conf):
1704 def dev_conf_export(request, id_conf):
1707
1705
1708 conf = get_object_or_404(Configuration, pk=id_conf)
1706 conf = get_object_or_404(Configuration, pk=id_conf)
1709
1707
1710 if request.method == 'GET':
1708 if request.method == 'GET':
1711 file_form = DownloadFileForm(conf.device.device_type.name)
1709 file_form = DownloadFileForm(conf.device.device_type.name)
1712
1710
1713 if request.method == 'POST':
1711 if request.method == 'POST':
1714 file_form = DownloadFileForm(
1712 file_form = DownloadFileForm(
1715 conf.device.device_type.name, request.POST)
1713 conf.device.device_type.name, request.POST)
1716
1714
1717 if file_form.is_valid():
1715 if file_form.is_valid():
1718 fields = conf.export_to_file(
1716 fields = conf.export_to_file(
1719 format=file_form.cleaned_data['format'])
1717 format=file_form.cleaned_data['format'])
1720 if not fields['content']:
1718 if not fields['content']:
1721 messages.error(request, conf.message)
1719 messages.error(request, conf.message)
1722 return redirect(conf.get_absolute_url_export())
1720 return redirect(conf.get_absolute_url_export())
1723 response = HttpResponse(content_type=fields['content_type'])
1721 response = HttpResponse(content_type=fields['content_type'])
1724 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1722 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1725 response.write(fields['content'])
1723 response.write(fields['content'])
1726
1724
1727 return response
1725 return response
1728
1726
1729 messages.error(request, "Could not export parameters")
1727 messages.error(request, "Could not export parameters")
1730
1728
1731 kwargs = {}
1729 kwargs = {}
1732 kwargs['id_dev'] = conf.id
1730 kwargs['id_dev'] = conf.id
1733 kwargs['title'] = 'Device Configuration'
1731 kwargs['title'] = 'Device Configuration'
1734 kwargs['form'] = file_form
1732 kwargs['form'] = file_form
1735 kwargs['suptitle'] = 'Exporting file'
1733 kwargs['suptitle'] = 'Exporting file'
1736 kwargs['button'] = 'Export'
1734 kwargs['button'] = 'Export'
1737 kwargs['menu_configurations'] = 'active'
1735 kwargs['menu_configurations'] = 'active'
1738
1736
1739 return render(request, 'dev_conf_export.html', kwargs)
1737 return render(request, 'dev_conf_export.html', kwargs)
1740
1738
1741
1739
1742 @login_required
1740 @login_required
1743 def dev_conf_delete(request, id_conf):
1741 def dev_conf_delete(request, id_conf):
1744
1742
1745 conf = get_object_or_404(Configuration, pk=id_conf)
1743 conf = get_object_or_404(Configuration, pk=id_conf)
1746
1744
1747 if request.method == 'POST':
1745 if request.method == 'POST':
1748 if is_developer(request.user):
1746 if is_developer(request.user):
1749 conf.delete()
1747 conf.delete()
1750 return redirect('url_dev_confs')
1748 return redirect('url_dev_confs')
1751
1749
1752 messages.error(request, 'Not enough permission to delete this object')
1750 messages.error(request, 'Not enough permission to delete this object')
1753 return redirect(conf.get_absolute_url())
1751 return redirect(conf.get_absolute_url())
1754
1752
1755 kwargs = {
1753 kwargs = {
1756 'title': 'Delete',
1754 'title': 'Delete',
1757 'suptitle': 'Configuration',
1755 'suptitle': 'Configuration',
1758 'object': conf,
1756 'object': conf,
1759 'delete': True
1757 'delete': True
1760 }
1758 }
1761 kwargs['menu_configurations'] = 'active'
1759 kwargs['menu_configurations'] = 'active'
1762
1760
1763 return render(request, 'confirm.html', kwargs)
1761 return render(request, 'confirm.html', kwargs)
1764
1762
1765
1763
1766 def sidebar(**kwargs):
1764 def sidebar(**kwargs):
1767
1765
1768 side_data = {}
1766 side_data = {}
1769
1767
1770 conf = kwargs.get('conf', None)
1768 conf = kwargs.get('conf', None)
1771 experiment = kwargs.get('experiment', None)
1769 experiment = kwargs.get('experiment', None)
1772
1770
1773 if not experiment:
1771 if not experiment:
1774 experiment = conf.experiment
1772 experiment = conf.experiment
1775
1773
1776 if experiment:
1774 if experiment:
1777 side_data['experiment'] = experiment
1775 side_data['experiment'] = experiment
1778 campaign = experiment.campaign_set.all()
1776 campaign = experiment.campaign_set.all()
1779 if campaign:
1777 if campaign:
1780 side_data['campaign'] = campaign[0]
1778 side_data['campaign'] = campaign[0]
1781 experiments = campaign[0].experiments.all().order_by('name')
1779 experiments = campaign[0].experiments.all().order_by('name')
1782 else:
1780 else:
1783 experiments = [experiment]
1781 experiments = [experiment]
1784 configurations = experiment.configuration_set.filter(type=0)
1782 configurations = experiment.configuration_set.filter(type=0)
1785 side_data['side_experiments'] = experiments
1783 side_data['side_experiments'] = experiments
1786 side_data['side_configurations'] = configurations.order_by(
1784 side_data['side_configurations'] = configurations.order_by(
1787 'device__device_type__name')
1785 'device__device_type__name')
1788
1786
1789 return side_data
1787 return side_data
1790
1788
1791 def get_paginator(model, page, order, filters={}, n=8):
1789 def get_paginator(model, page, order, filters={}, n=8):
1792 kwargs = {}
1790 kwargs = {}
1793 query = Q()
1791 query = Q()
1794 if isinstance(filters, QueryDict):
1792 if isinstance(filters, QueryDict):
1795 filters = filters.dict()
1793 filters = filters.dict()
1796 copy_filters=filters.copy()
1794 copy_filters=filters.copy()
1797 [filters.pop(key) for key in copy_filters.keys() if copy_filters[key] in (' ', ' ')]
1795 [filters.pop(key) for key in copy_filters.keys() if copy_filters[key] in (' ', ' ')]
1798 filters.pop('page', None)
1796 filters.pop('page', None)
1799
1797
1800 fields = [f.name for f in model._meta.get_fields()]
1798 fields = [f.name for f in model._meta.get_fields()]
1801
1799
1802 if 'template' in copy_filters:
1800 if 'template' in copy_filters:
1803 filters['template'] = True
1801 filters['template'] = True
1804 if 'historical' in copy_filters:
1802 if 'historical' in copy_filters:
1805 filters.pop('historical')
1803 filters.pop('historical')
1806 filters['type'] = 1
1804 filters['type'] = 1
1807 elif 'type' in fields:
1805 elif 'type' in fields:
1808 filters['type'] = 0
1806 filters['type'] = 0
1809 if 'start_date' in copy_filters:
1807 if 'start_date' in copy_filters:
1810 filters['start_date__gte'] =filters.pop('start_date')
1808 filters['start_date__gte'] =filters.pop('start_date')
1811 if 'end_date' in copy_filters:
1809 if 'end_date' in copy_filters:
1812 filters['start_date__lte'] =filters.pop('end_date')
1810 filters['start_date__lte'] =filters.pop('end_date')
1813 if 'tags' in copy_filters:
1811 if 'tags' in copy_filters:
1814 tags =filters.pop('tags')
1812 tags =filters.pop('tags')
1815 if 'tags' in fields:
1813 if 'tags' in fields:
1816 query = query | Q(tags__icontains=tags)
1814 query = query | Q(tags__icontains=tags)
1817 if 'label' in fields:
1815 if 'label' in fields:
1818 query = query | Q(label__icontains=tags)
1816 query = query | Q(label__icontains=tags)
1819 if 'location' in fields:
1817 if 'location' in fields:
1820 query = query | Q(location__name__icontains=tags)
1818 query = query | Q(location__name__icontains=tags)
1821 if 'device' in fields:
1819 if 'device' in fields:
1822 query = query | Q(device__device_type__name__icontains=tags)
1820 query = query | Q(device__device_type__name__icontains=tags)
1823 query = query | Q(device__location__name__icontains=tags)
1821 query = query | Q(device__location__name__icontains=tags)
1824 if 'device_type' in fields:
1822 if 'device_type' in fields:
1825 query = query | Q(device_type__name__icontains=tags)
1823 query = query | Q(device_type__name__icontains=tags)
1826
1824
1827 if 'mine' in copy_filters:
1825 if 'mine' in copy_filters:
1828 filters['author_id'] =filters['mine']
1826 filters['author_id'] =filters['mine']
1829 filters.pop('mine')
1827 filters.pop('mine')
1830 object_list = model.objects.filter(query, **filters).order_by(*order)
1828 object_list = model.objects.filter(query, **filters).order_by(*order)
1831 paginator = Paginator(object_list, n)
1829 paginator = Paginator(object_list, n)
1832
1830
1833 try:
1831 try:
1834 objects = paginator.page(page)
1832 objects = paginator.page(page)
1835 except PageNotAnInteger:
1833 except PageNotAnInteger:
1836 objects = paginator.page(1)
1834 objects = paginator.page(1)
1837 except EmptyPage:
1835 except EmptyPage:
1838 objects = paginator.page(paginator.num_pages)
1836 objects = paginator.page(paginator.num_pages)
1839
1837
1840 kwargs['objects'] = objects
1838 kwargs['objects'] = objects
1841 kwargs['offset'] = (int(page)-1)*n if page else 0
1839 kwargs['offset'] = (int(page)-1)*n if page else 0
1842
1840
1843 return kwargs
1841 return kwargs
1844
1842
1845 # def get_paginator(model, page, order, filters={}, n=8):
1843 # def get_paginator(model, page, order, filters={}, n=8):
1846 # kwargs = {}
1844 # kwargs = {}
1847 # query = Q()
1845 # query = Q()
1848 # if isinstance(filters, QueryDict):
1846 # if isinstance(filters, QueryDict):
1849 # filters = filters.dict()
1847 # filters = filters.dict()
1850 # [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1848 # [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1851 # filters.pop('page', None)
1849 # filters.pop('page', None)
1852
1850
1853 # fields = [f.name for f in model._meta.get_fields()]
1851 # fields = [f.name for f in model._meta.get_fields()]
1854
1852
1855 # if 'template' in filters:
1853 # if 'template' in filters:
1856 # filters['template'] = True
1854 # filters['template'] = True
1857 # if 'historical' in filters:
1855 # if 'historical' in filters:
1858 # filters.pop('historical')
1856 # filters.pop('historical')
1859 # filters['type'] = 1
1857 # filters['type'] = 1
1860 # elif 'type' in fields:
1858 # elif 'type' in fields:
1861 # filters['type'] = 0
1859 # filters['type'] = 0
1862 # if 'start_date' in filters:
1860 # if 'start_date' in filters:
1863 # filters['start_date__gte'] = filters.pop('start_date')
1861 # filters['start_date__gte'] = filters.pop('start_date')
1864 # if 'end_date' in filters:
1862 # if 'end_date' in filters:
1865 # filters['start_date__lte'] = filters.pop('end_date')
1863 # filters['start_date__lte'] = filters.pop('end_date')
1866 # if 'tags' in filters:
1864 # if 'tags' in filters:
1867 # tags = filters.pop('tags')
1865 # tags = filters.pop('tags')
1868 # if 'tags' in fields:
1866 # if 'tags' in fields:
1869 # query = query | Q(tags__icontains=tags)
1867 # query = query | Q(tags__icontains=tags)
1870 # if 'label' in fields:
1868 # if 'label' in fields:
1871 # query = query | Q(label__icontains=tags)
1869 # query = query | Q(label__icontains=tags)
1872 # if 'location' in fields:
1870 # if 'location' in fields:
1873 # query = query | Q(location__name__icontains=tags)
1871 # query = query | Q(location__name__icontains=tags)
1874 # if 'device' in fields:
1872 # if 'device' in fields:
1875 # query = query | Q(device__device_type__name__icontains=tags)
1873 # query = query | Q(device__device_type__name__icontains=tags)
1876 # query = query | Q(device__location__name__icontains=tags)
1874 # query = query | Q(device__location__name__icontains=tags)
1877 # if 'device_type' in fields:
1875 # if 'device_type' in fields:
1878 # query = query | Q(device_type__name__icontains=tags)
1876 # query = query | Q(device_type__name__icontains=tags)
1879
1877
1880 # if 'mine' in filters:
1878 # if 'mine' in filters:
1881 # filters['author_id'] = filters['mine']
1879 # filters['author_id'] = filters['mine']
1882 # filters.pop('mine')
1880 # filters.pop('mine')
1883 # object_list = model.objects.filter(query, **filters).order_by(*order)
1881 # object_list = model.objects.filter(query, **filters).order_by(*order)
1884 # paginator = Paginator(object_list, n)
1882 # paginator = Paginator(object_list, n)
1885
1883
1886 # try:
1884 # try:
1887 # objects = paginator.page(page)
1885 # objects = paginator.page(page)
1888 # except PageNotAnInteger:
1886 # except PageNotAnInteger:
1889 # objects = paginator.page(1)
1887 # objects = paginator.page(1)
1890 # except EmptyPage:
1888 # except EmptyPage:
1891 # objects = paginator.page(paginator.num_pages)
1889 # objects = paginator.page(paginator.num_pages)
1892
1890
1893 # kwargs['objects'] = objects
1891 # kwargs['objects'] = objects
1894 # kwargs['offset'] = (int(page)-1)*n if page else 0
1892 # kwargs['offset'] = (int(page)-1)*n if page else 0
1895
1893
1896 # return kwargs
1894 # return kwargs
1897
1895
1898
1896
1899 def operation(request, id_camp=None):
1897 def operation(request, id_camp=None):
1900
1898
1901 kwargs = {}
1899 kwargs = {}
1902 kwargs['title'] = 'Radars Operation'
1900 kwargs['title'] = 'Radars Operation'
1903 kwargs['no_sidebar'] = True
1901 kwargs['no_sidebar'] = True
1904 kwargs['menu_operation'] = 'active'
1902 kwargs['menu_operation'] = 'active'
1905 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1903 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1906 end_date__gte=datetime.now()).order_by('-start_date')
1904 end_date__gte=datetime.now()).order_by('-start_date')
1907
1905
1908 if id_camp:
1906 if id_camp:
1909 campaign = get_object_or_404(Campaign, pk=id_camp)
1907 campaign = get_object_or_404(Campaign, pk=id_camp)
1910 form = OperationForm(
1908 form = OperationForm(
1911 initial={'campaign': campaign.id}, campaigns=campaigns)
1909 initial={'campaign': campaign.id}, campaigns=campaigns)
1912 kwargs['campaign'] = campaign
1910 kwargs['campaign'] = campaign
1913 else:
1911 else:
1914 # form = OperationForm(campaigns=campaigns)
1912 # form = OperationForm(campaigns=campaigns)
1915 kwargs['campaigns'] = campaigns
1913 kwargs['campaigns'] = campaigns
1916 return render(request, 'operation.html', kwargs)
1914 return render(request, 'operation.html', kwargs)
1917
1915
1918 #---Experiment
1916 #---Experiment
1919 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1917 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1920 kwargs['experiment_keys'] = keys[1:]
1918 kwargs['experiment_keys'] = keys[1:]
1921 kwargs['experiments'] = experiments
1919 kwargs['experiments'] = experiments
1922 #---Radar
1920 #---Radar
1923 kwargs['locations'] = campaign.get_experiments_by_radar()
1921 kwargs['locations'] = campaign.get_experiments_by_radar()
1924 kwargs['form'] = form
1922 kwargs['form'] = form
1925
1923
1926 return render(request, 'operation.html', kwargs)
1924 return render(request, 'operation.html', kwargs)
1927
1925
1928
1926
1929 @login_required
1927 @login_required
1930 def radar_start(request, id_camp, id_radar):
1928 def radar_start(request, id_camp, id_radar):
1931 print("Boton presionados",flush=True)
1929 print("Boton presionados",flush=True)
1932 campaign = get_object_or_404(Campaign, pk=id_camp)
1930 campaign = get_object_or_404(Campaign, pk=id_camp)
1933 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1931 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1934 now = datetime.now()
1932 now = datetime.now()
1935
1933
1936 for exp in experiments:
1934 for exp in experiments:
1937 #app.control.revoke(exp.task)
1935 #app.control.revoke(exp.task)
1938 print("----------------------")
1936 print("----------------------")
1939 print("status:->", exp.status,flush=True)
1937 print("status:->", exp.status,flush=True)
1940 start = datetime.combine(datetime.now().date(), exp.start_time)
1938 start = datetime.combine(datetime.now().date(), exp.start_time)
1941 end = datetime.combine(datetime.now().date(), exp.end_time)
1939 end = datetime.combine(datetime.now().date(), exp.end_time)
1942 print("start exp: ",exp.start_time,flush=True)
1940 print("start exp: ",exp.start_time,flush=True)
1943 print("end exp: ",exp.end_time,flush=True)
1941 print("end exp: ",exp.end_time,flush=True)
1944
1942
1945 print("start comb: ",start,flush=True)
1943 print("start comb: ",start,flush=True)
1946 print("end comb: ",end,flush=True)
1944 print("end comb: ",end,flush=True)
1947 print(is_aware(start),flush=True)
1945 print(is_aware(start),flush=True)
1948 print("start camp",campaign.start_date,flush=True)
1946 print("start camp",campaign.start_date,flush=True)
1949 print("end camp",campaign.end_date,flush=True)
1947 print("end camp",campaign.end_date,flush=True)
1950 print(is_aware(campaign.start_date),flush=True)
1948 print(is_aware(campaign.start_date),flush=True)
1951 if end < start:
1949 if end < start:
1952 end += timedelta(1)
1950 end += timedelta(1)
1953
1951
1954 if exp.status == 2:
1952 if exp.status == 2:
1955 messages.warning(
1953 messages.warning(
1956 request, 'Experiment {} already running'.format(exp))
1954 request, 'Experiment {} already running'.format(exp))
1957 #continue
1955 #continue
1958
1956
1959 if exp.status == 3:
1957 if exp.status == 3:
1960 messages.warning(
1958 messages.warning(
1961 request, 'Experiment {} already programmed'.format(exp))
1959 request, 'Experiment {} already programmed'.format(exp))
1962 #continue
1960 #continue
1963
1961
1964 if exp.status == 1:
1962 if exp.status == 1:
1965 messages.warning(
1963 messages.warning(
1966 request, 'Experiment {} stopped'.format(exp))
1964 request, 'Experiment {} stopped'.format(exp))
1967 #continue
1965 #continue
1968
1966
1969 if start > campaign.end_date:
1967 if start > campaign.end_date:
1970 messages.warning(
1968 messages.warning(
1971 request, 'Experiment {} out of date'.format(exp))
1969 request, 'Experiment {} out of date'.format(exp))
1972
1970
1973 #app.control.revoke(exp.task)
1971 #app.control.revoke(exp.task)
1974 print("Llego luego del revoke",flush=True)
1972 print("Llego luego del revoke",flush=True)
1975 if now >= start and now <= end:
1973 if now >= start and now <= end:
1976
1974
1977 print("Caso now > start and < end -- (1)",flush=True)
1975 print("Caso now > start and < end -- (1)",flush=True)
1978
1976
1979 # -------------------------------------------
1977 # -------------------------------------------
1980
1978
1981 # task = task_start.delay(exp.id)
1979 # task = task_start.delay(exp.id)
1982 # exp.task = task.id
1980 # exp.task = task.id
1983 # exp.status = task.get()
1981 # exp.status = task.get()
1984 # -------------------------------------------
1982 # -------------------------------------------
1985
1983
1986 #exp.status = task.wait()
1984 #exp.status = task.wait()
1987
1985
1988 if exp.status == 0:
1986 if exp.status == 0:
1989 messages.error(request, 'Experiment {} not start'.format(exp))
1987 messages.error(request, 'Experiment {} not start'.format(exp))
1990 if exp.status == 2:
1988 if exp.status == 2:
1991 messages.success(request, 'Experiment {} started'.format(exp))
1989 messages.success(request, 'Experiment {} started'.format(exp))
1992 elif now < start:
1990 elif now < start:
1993 print("Caso now <= start -- (2)",exp.pk)
1991 print("Caso now <= start -- (2)",exp.pk)
1994 #task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1992 #task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1995 # task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))#)
1993 # task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))#)
1996 # exp.task = task.id
1994 # exp.task = task.id
1997 # exp.status = 3
1995 # exp.status = 3
1998 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1996 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1999 else:
1997 else:
2000 print("Caso now > end -- (3)")
1998 print("Caso now > end -- (3)")
2001 exp.status = 4
1999 exp.status = 4
2002 messages.warning(
2000 messages.warning(
2003 request, 'Experiment {} out of date'.format(exp))
2001 request, 'Experiment {} out of date'.format(exp))
2004
2002
2005 exp.save()
2003 exp.save()
2006
2004
2007 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2005 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2008
2006
2009
2007
2010 @login_required
2008 @login_required
2011 def radar_stop(request, id_camp, id_radar):
2009 def radar_stop(request, id_camp, id_radar):
2012
2010
2013 campaign = get_object_or_404(Campaign, pk=id_camp)
2011 campaign = get_object_or_404(Campaign, pk=id_camp)
2014 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2012 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2015 print("Ingreso en stop radar_stop")
2013 print("Ingreso en stop radar_stop")
2016 #for exp in experiments:
2014 #for exp in experiments:
2017
2015
2018 # if exp.task:
2016 # if exp.task:
2019 # print("Ingreso antes de revoke stop")
2017 # print("Ingreso antes de revoke stop")
2020 # app.control.revoke(exp.task)
2018 # app.control.revoke(exp.task)
2021
2019
2022
2020
2023 # if exp.status == 2: #status 2 es started
2021 # if exp.status == 2: #status 2 es started
2024 # print("llama a exp.stop")
2022 # print("llama a exp.stop")
2025 # exp.stop()
2023 # exp.stop()
2026 # messages.warning(request, 'Experiment {} stopped'.format(exp))
2024 # messages.warning(request, 'Experiment {} stopped'.format(exp))
2027 # exp.status = 1
2025 # exp.status = 1
2028 # exp.save()
2026 # exp.save()
2029
2027
2030 #return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2028 #return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2031
2029
2032
2030
2033 @login_required
2031 @login_required
2034 def radar_refresh(request, id_camp, id_radar):
2032 def radar_refresh(request, id_camp, id_radar):
2035
2033
2036 campaign = get_object_or_404(Campaign, pk=id_camp)
2034 campaign = get_object_or_404(Campaign, pk=id_camp)
2037 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2035 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2038
2036
2039 i = app.control.inspect()
2037 i = app.control.inspect()
2040 print("inspect",i)
2038 print("inspect",i)
2041 print(i.scheduled())
2039 print(i.scheduled())
2042 print(i.scheduled().values())
2040 print(i.scheduled().values())
2043 scheduled = list(i.scheduled().values())[0]
2041 scheduled = list(i.scheduled().values())[0]
2044 revoked = list(i.revoked().values())[0]
2042 revoked = list(i.revoked().values())[0]
2045
2043
2046 # for exp in experiments:
2044 # for exp in experiments:
2047 # if exp.task in revoked:
2045 # if exp.task in revoked:
2048 # exp.status = 1
2046 # exp.status = 1
2049 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
2047 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
2050 # exp.status = 2
2048 # exp.status = 2
2051 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
2049 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
2052 # exp.status = 3
2050 # exp.status = 3
2053 # else:
2051 # else:
2054 # exp.status = 4
2052 # exp.status = 4
2055 # exp.save()
2053 # exp.save()
2056 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2054 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2057
2055
2058 #@login_required
2056 #@login_required
2059 # def revoke_tasks(request, id_camp):
2057 # def revoke_tasks(request, id_camp):
2060
2058
2061 # i = app.control.inspect()
2059 # i = app.control.inspect()
2062 # scheduled = list(i.scheduled().values())[0]
2060 # scheduled = list(i.scheduled().values())[0]
2063 # revoked = list(i.revoked().values())[0]
2061 # revoked = list(i.revoked().values())[0]
2064
2062
2065 # for t in scheduled:
2063 # for t in scheduled:
2066 # if t['request']['id'] in revoked:
2064 # if t['request']['id'] in revoked:
2067 # continue
2065 # continue
2068 # app.control.revoke(t['request']['id'])
2066 # app.control.revoke(t['request']['id'])
2069 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2067 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2070 # eta = t['eta']
2068 # eta = t['eta']
2071 # #task = t['request']['name'].split('.')[-1]
2069 # #task = t['request']['name'].split('.')[-1]
2072 # messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
2070 # messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
2073
2071
2074 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2072 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2075
2073
2076 # @login_required
2074 # @login_required
2077 # def show_tasks(request, id_camp):
2075 # def show_tasks(request, id_camp):
2078
2076
2079 # i = app.control.inspect()
2077 # i = app.control.inspect()
2080 # scheduled = list(i.scheduled().values())[0]
2078 # scheduled = list(i.scheduled().values())[0]
2081 # revoked = list(i.revoked().values())[0]
2079 # revoked = list(i.revoked().values())[0]
2082
2080
2083 # for t in scheduled:
2081 # for t in scheduled:
2084 # if t['request']['id'] in revoked:
2082 # if t['request']['id'] in revoked:
2085 # continue
2083 # continue
2086 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2084 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2087 # eta = t['eta']
2085 # eta = t['eta']
2088 # #task = t['request']['name'].split('.')[-1]
2086 # #task = t['request']['name'].split('.')[-1]
2089 # #messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
2087 # #messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
2090
2088
2091 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2089 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2092
2090
2093 def real_time(request):
2091 def real_time(request):
2094
2092
2095 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
2093 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
2096
2094
2097 kwargs = {}
2095 kwargs = {}
2098 kwargs['title'] = 'CLAIRE'
2096 kwargs['title'] = 'CLAIRE'
2099 kwargs['suptitle'] = 'Real Time'
2097 kwargs['suptitle'] = 'Real Time'
2100 kwargs['no_sidebar'] = True
2098 kwargs['no_sidebar'] = True
2101 kwargs['graphic_path'] = graphic_path
2099 kwargs['graphic_path'] = graphic_path
2102 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
2100 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
2103
2101
2104 return render(request, 'real_time.html', kwargs)
2102 return render(request, 'real_time.html', kwargs)
2105
2103
2106 def theme(request, theme):
2104 def theme(request, theme):
2107
2105
2108 user = request.user
2106 user = request.user
2109 user.profile.theme = theme
2107 user.profile.theme = theme
2110 user.save()
2108 user.save()
2111 return redirect('index')
2109 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now