Commit fc957772885aa46d620a14c9f2d06f5436a3b030
1 parent
dd5b2b4a
Exists in
dev
Control command PLC + minor changes on navbar
Showing
7 changed files
with
180 additions
and
93 deletions
Show diff stats
simulators/plc/plcSimulator.py
... | ... | @@ -19,86 +19,10 @@ class PLCSimulator(DeviceSim, StatusManager): |
19 | 19 | |
20 | 20 | # (EP) This simulator will generate some events ? |
21 | 21 | EVENT_GENERATOR=False |
22 | - | |
23 | - status = { | |
24 | - "name": "STATUS", "from": "Beckhoff", "version_firmware": "20170809", "site": "OSM-Mexico", | |
25 | - "date": "2017-03-03T13:45:00", | |
26 | - "device": [{"name": "WXT520", "type": "meteo", "serial_number": "14656423", "valid": "yes", | |
27 | - "values": [ | |
28 | - {"name": "OutsideTemp", "value": 12.12, "unit": "Celcius", "comment": ""}, | |
29 | - {"name": "OutsideHumidity", "value": 64.1, "unit": "percent", "comment": ""}, | |
30 | - {"name": "Pressure", "value": 769.2, "unit": "mbar", "comment": "At site elevation"}, | |
31 | - {"name": "RainRate", "value": 0.0, "unit": "mm/h", "comment": ""}, | |
32 | - {"name": "WindSpeed", "value": 3.1, "unit": "m/s", "comment": ""}, | |
33 | - {"name": "WindDir", "value": 202.3, "unit": "deg", "comment": "(N=0, E=90)"}, | |
34 | - {"name": "DewPoint", "value": 8.3, "unit": "deg", "comment": ""} | |
35 | - ] | |
36 | - }, | |
37 | - {"name": "DRD11", "type": "meteo", "serial_number": "RET6789", "valid": "yes", | |
38 | - "values": [ | |
39 | - {"name": "analog", "value": 2.345, "unit": "V", "comment": "3V=Dry <2.5V=Rain"}, | |
40 | - {"name": "digital", "value": 1, "unit": "bool", "comment": "1=Dry 0=Rain"} | |
41 | - ] | |
42 | - }, | |
43 | - {"name": "VantagePro", "type": "meteo", "serial_number": "ERTRY2344324", "valid": "no", | |
44 | - "values": [ | |
45 | - {"name": "OutsideTemp", "value": 12.45, "unit": "Celcius", "comment": ""}, | |
46 | - {"name": "InsideTemp", "value": 20.28, "unit": "Celcius", "comment": ""}, | |
47 | - {"name": "OutsideHumidity", "value": 65.3, "unit": "percent", "comment": ""}, | |
48 | - {"name": "InsideHumidity", "value": 45.6, "unit": "percent", "comment": ""}, | |
49 | - {"name": "Pressure", "value": 768.7, "unit": "mbar", "comment": "At site elevation"}, | |
50 | - {"name": "RainRate", "value": 0.0, "unit": "mm/h", "comment": ""}, | |
51 | - {"name": "WindSpeed", "value": 2.8, "unit": "m/s", "comment": ""}, | |
52 | - {"name": "WindDir", "value": 207.0, "unit": "deg", "comment": "(N=0, E=90)"}, | |
53 | - {"name": "WindDirCardinal", "value": "SW", "unit": "string", "comment": ""}, | |
54 | - {"name": "DewPoint", "value": 8.5, "unit": "deg", "comment": ""} | |
55 | - ] | |
56 | - }, | |
57 | - {"name": "MLX90614-1", "type": "meteo", "serial_number": "Unknown", "valid": "yes", | |
58 | - "values": [ | |
59 | - {"name": "SensorTemperature", "value": 23.56, "unit": "Celcius", "comment": ""}, | |
60 | - {"name": "SkyTemperature", "value": -15.67, "unit": "Celcius", | |
61 | - "comment": "Clear<-10 VeryCloudy>4"} | |
62 | - ] | |
63 | - }, | |
64 | - {"name": "LAMP_FLAT_CAGIRE", "type": "calib", "serial_number": "REF_3434", "valid": "yes", | |
65 | - "values": [ | |
66 | - {"name": "status", "value": "on", "unit": "string", "comment": "on or off"}, | |
67 | - {"name": "current", "value": 0.234, "unit": "Ampere", "comment": ""} | |
68 | - ] | |
69 | - }, | |
70 | - {"name": "LAMP FLAT CAGIRE", "type": "calib", "serial_number": "REF_3434", "valid": "yes", | |
71 | - "values": [ | |
72 | - {"name": "status", "value": "on", "unit": "string", "comment": "on or off"}, | |
73 | - {"name": "current", "value": 0.234, "unit": "Ampere", "comment": ""} | |
74 | - ] | |
75 | - }, | |
76 | - {"name": "GLOBAL", | |
77 | - "values": [ | |
78 | - {"name": "mode", "value": "AUTO", "unit": "String", "comment": "AUTO OFF MANU"}, | |
79 | - {"name": "is_safe", "value": True, "unit": "bool", "comment": "True or False"}, | |
80 | - ] | |
81 | - } | |
82 | - ], | |
83 | - } | |
84 | - | |
85 | - list = {"name": "LIST", "from": "Beckhoff", "version_firmware": "20170809", "site": "OSM-Mexico", | |
86 | - "date": "2017-03-03T13:42:46", | |
87 | - "command": [ | |
88 | - {"name": "LIST", "type": "", | |
89 | - "parameters": "" | |
90 | - }, | |
91 | - {"name": "SATUS", "type": "", | |
92 | - "parameters": "" | |
93 | - }, | |
94 | - {"name": "LAMP_FLAT_CAGIRE", "type": "calib", | |
95 | - "parameters": [ | |
96 | - {"name": "value", "unit": "string", "comment": "on or off", "default": ""}, | |
97 | - {"name": "current", "unit": "Ampere", "comment": "", "default": "0.345"} | |
98 | - ] | |
99 | - } | |
100 | - ] | |
101 | - } | |
22 | + | |
23 | + lights = "ON" | |
24 | + shutters = "CLOSE" | |
25 | + status ="" | |
102 | 26 | |
103 | 27 | def __init__(self, argv): |
104 | 28 | # DeviceSim init |
... | ... | @@ -151,15 +75,25 @@ class PLCSimulator(DeviceSim, StatusManager): |
151 | 75 | command_list = json_array["command"] |
152 | 76 | for command in command_list: |
153 | 77 | if command["name"] == "STATUS": |
154 | - if count: | |
155 | - answer += ',' | |
156 | - answer += json.dumps(self.status) | |
78 | + answer = self.get_status(count, answer) | |
157 | 79 | count = True |
158 | 80 | elif command["name"] == "LIST": |
159 | 81 | if count: |
160 | 82 | answer += ',' |
161 | 83 | answer += json.dumps(self.status) |
162 | 84 | count = True |
85 | + elif command["name"] == "SWITCH LINES ON": | |
86 | + self.lights = "ON" | |
87 | + answer = "[Lights turned on" | |
88 | + elif command["name"] == "SWITCH LINES OFF": | |
89 | + self.lights = "OFF" | |
90 | + answer = "[Lights turned off" | |
91 | + elif command["name"] == "OPEN SHUTTERS": | |
92 | + self.shutters = "OPEN" | |
93 | + answer = "[Shutters opened" | |
94 | + elif command["name"] == "CLOSE SHUTTERS": | |
95 | + self.shutters = "CLOSE" | |
96 | + answer = "[Shutters closed" | |
163 | 97 | else: |
164 | 98 | print("command received by PLC simulator : [>>> "+ str(command["name"]) + " <<<] unknown") |
165 | 99 | answer += ']' |
... | ... | @@ -190,6 +124,97 @@ class PLCSimulator(DeviceSim, StatusManager): |
190 | 124 | #return (0) |
191 | 125 | |
192 | 126 | |
127 | + def get_status(self, count, answer): | |
128 | + self.status = { | |
129 | + "name": "STATUS", "from": "Beckhoff", "version_firmware": "20170809", "site": "OSM-Mexico", | |
130 | + "date": "2017-03-03T13:45:00", | |
131 | + "device": [{"name": "WXT520", "type": "meteo", "serial_number": "14656423", "valid": "yes", | |
132 | + "values": [ | |
133 | + {"name": "OutsideTemp", "value": 12.12, "unit": "Celcius", "comment": ""}, | |
134 | + {"name": "OutsideHumidity", "value": 64.1, "unit": "percent", "comment": ""}, | |
135 | + {"name": "Pressure", "value": 769.2, "unit": "mbar", "comment": "At site elevation"}, | |
136 | + {"name": "RainRate", "value": 0.0, "unit": "mm/h", "comment": ""}, | |
137 | + {"name": "WindSpeed", "value": 3.1, "unit": "m/s", "comment": ""}, | |
138 | + {"name": "WindDir", "value": 202.3, "unit": "deg", "comment": "(N=0, E=90)"}, | |
139 | + {"name": "DewPoint", "value": 8.3, "unit": "deg", "comment": ""} | |
140 | + ] | |
141 | + }, | |
142 | + {"name": "DRD11", "type": "meteo", "serial_number": "RET6789", "valid": "yes", | |
143 | + "values": [ | |
144 | + {"name": "analog", "value": 2.345, "unit": "V", "comment": "3V=Dry <2.5V=Rain"}, | |
145 | + {"name": "digital", "value": 1, "unit": "bool", "comment": "1=Dry 0=Rain"} | |
146 | + ] | |
147 | + }, | |
148 | + {"name": "VantagePro", "type": "meteo", "serial_number": "ERTRY2344324", "valid": "no", | |
149 | + "values": [ | |
150 | + {"name": "OutsideTemp", "value": 12.45, "unit": "Celcius", "comment": ""}, | |
151 | + {"name": "InsideTemp", "value": 20.28, "unit": "Celcius", "comment": ""}, | |
152 | + {"name": "OutsideHumidity", "value": 65.3, "unit": "percent", "comment": ""}, | |
153 | + {"name": "InsideHumidity", "value": 45.6, "unit": "percent", "comment": ""}, | |
154 | + {"name": "Pressure", "value": 768.7, "unit": "mbar", "comment": "At site elevation"}, | |
155 | + {"name": "RainRate", "value": 0.0, "unit": "mm/h", "comment": ""}, | |
156 | + {"name": "WindSpeed", "value": 2.8, "unit": "m/s", "comment": ""}, | |
157 | + {"name": "WindDir", "value": 207.0, "unit": "deg", "comment": "(N=0, E=90)"}, | |
158 | + {"name": "WindDirCardinal", "value": "SW", "unit": "string", "comment": ""}, | |
159 | + {"name": "DewPoint", "value": 8.5, "unit": "deg", "comment": ""} | |
160 | + ] | |
161 | + }, | |
162 | + {"name": "MLX90614-1", "type": "meteo", "serial_number": "Unknown", "valid": "yes", | |
163 | + "values": [ | |
164 | + {"name": "SensorTemperature", "value": 23.56, "unit": "Celcius", "comment": ""}, | |
165 | + {"name": "SkyTemperature", "value": -15.67, "unit": "Celcius", | |
166 | + "comment": "Clear<-10 VeryCloudy>4"} | |
167 | + ] | |
168 | + }, | |
169 | + {"name": "LAMP_FLAT_CAGIRE", "type": "calib", "serial_number": "REF_3434", "valid": "yes", | |
170 | + "values": [ | |
171 | + {"name": "status", "value": "on", "unit": "string", "comment": "on or off"}, | |
172 | + {"name": "current", "value": 0.234, "unit": "Ampere", "comment": ""} | |
173 | + ] | |
174 | + }, | |
175 | + {"name": "LAMP FLAT CAGIRE", "type": "calib", "serial_number": "REF_3434", "valid": "yes", | |
176 | + "values": [ | |
177 | + {"name": "status", "value": "on", "unit": "string", "comment": "on or off"}, | |
178 | + {"name": "current", "value": 0.234, "unit": "Ampere", "comment": ""} | |
179 | + ] | |
180 | + }, | |
181 | + {"name": "GLOBAL", | |
182 | + "values": [ | |
183 | + {"name": "mode", "value": "AUTO", "unit": "String", "comment": "AUTO OFF MANU"}, | |
184 | + {"name": "is_safe", "value": True, "unit": "bool", "comment": "True or False"}, | |
185 | + {"name": "LIGHTS", "value": self.lights, "unit": "String", "comment": "ON or OFF"}, | |
186 | + {"name": "SHUTTERS", "value": self.shutters, "unit": "String", "comment": "OPEN OR CLOSE"}, | |
187 | + ] | |
188 | + } | |
189 | + ], | |
190 | + } | |
191 | + | |
192 | + ''' | |
193 | + Si on veut rajouter des éléments dans les json il faut penser a ajouter les méthodes correspondantes dans models.py | |
194 | + ''' | |
195 | + | |
196 | + list = {"name": "LIST", "from": "Beckhoff", "version_firmware": "20170809", "site": "OSM-Mexico", | |
197 | + "date": "2017-03-03T13:42:46", | |
198 | + "command": [ | |
199 | + {"name": "LIST", "type": "", | |
200 | + "parameters": "" | |
201 | + }, | |
202 | + {"name": "SATUS", "type": "", | |
203 | + "parameters": "" | |
204 | + }, | |
205 | + {"name": "LAMP_FLAT_CAGIRE", "type": "calib", | |
206 | + "parameters": [ | |
207 | + {"name": "value", "unit": "string", "comment": "on or off", "default": ""}, | |
208 | + {"name": "current", "unit": "Ampere", "comment": "", "default": "0.345"} | |
209 | + ] | |
210 | + } | |
211 | + ] | |
212 | + } | |
213 | + if count: | |
214 | + answer += ',' | |
215 | + answer += json.dumps(self.status) | |
216 | + return answer | |
217 | + | |
193 | 218 | if __name__ == "__main__": |
194 | 219 | sim = PLCSimulator(sys.argv) |
195 | 220 | sim.run() | ... | ... |
src/common/models.py
... | ... | @@ -88,6 +88,8 @@ class PlcDeviceStatus(models.Model): |
88 | 88 | current_unit = models.CharField(max_length=45, blank=True, null=True) |
89 | 89 | is_safe = models.BooleanField(default=True) |
90 | 90 | plc_mode = models.CharField(max_length=4, null=True) |
91 | + lights = models.CharField(max_length=3, null=True) | |
92 | + shutters = models.CharField(max_length=5, null=True) | |
91 | 93 | |
92 | 94 | class Meta: |
93 | 95 | managed = True |
... | ... | @@ -153,6 +155,10 @@ class PlcDeviceStatus(models.Model): |
153 | 155 | self.plc_mode = value |
154 | 156 | elif key == "is_safe": |
155 | 157 | self.is_safe = value |
158 | + elif key == "LIGHTS": | |
159 | + self.lights = value | |
160 | + elif key == "SHUTTERS": | |
161 | + self.shutters = value | |
156 | 162 | else: |
157 | 163 | raise KeyError("Key " + str(key) + " unrecognized") |
158 | 164 | ... | ... |
src/dashboard/templates/dashboard/send_command_to_plc.html
... | ... | @@ -26,6 +26,25 @@ |
26 | 26 | font-size: 30px; |
27 | 27 | } |
28 | 28 | |
29 | + div.hbox { | |
30 | + display: block; | |
31 | + font-size: 15pt; | |
32 | + /*background:#e7e4e4;*/ | |
33 | + border: 3px solid rgba(0, 0, 0, 0.125); | |
34 | + word-wrap: break-word; | |
35 | + border-color: #2FA4E7; | |
36 | + border-radius: 0.25rem; | |
37 | + padding: 3px 5px 3px 3px; | |
38 | + margin-top: 10px; | |
39 | + text-align: center; | |
40 | + | |
41 | +} | |
42 | + | |
43 | + #PLC_response | |
44 | + { | |
45 | + text-align: center; | |
46 | + margin-top: 30px; | |
47 | + } | |
29 | 48 | </style> |
30 | 49 | <body> |
31 | 50 | <form id="command_form_expert" method="POST" action="{% url "submit_command_to_telescope_expert" %}"> |
... | ... | @@ -41,6 +60,9 @@ |
41 | 60 | $("#command_form_expert").submit(function(event){ |
42 | 61 | |
43 | 62 | event.preventDefault(); |
63 | + | |
64 | + $("#global, #br, #PLC_response").remove(); | |
65 | + $("#command_form_expert").after('<h2 id="PLC_response">PLC Response: </h2><br id="br">'); | |
44 | 66 | $.post('send_command_to_plc/submit', $(this).serialize(), function(data){ |
45 | 67 | var obj = JSON.parse(data); |
46 | 68 | console.log(obj.message); |
... | ... | @@ -50,7 +72,8 @@ |
50 | 72 | else if (obj.response.startsWith("KO")) |
51 | 73 | alert(obj.response); |
52 | 74 | else |
53 | - alert("PLC answer: " + obj.response); | |
75 | + $("#br").after( '<div id=\"global\" class=\"container-fluid hbox\"><p>' + obj.response + '</p></div>' ); | |
76 | + //alert("PLC answer: " + obj.response); | |
54 | 77 | }) |
55 | 78 | .fail(function() { |
56 | 79 | alert( "An error occured" ); | ... | ... |
src/dashboard/templates/dashboard/system.html
src/dashboard/views.py
... | ... | @@ -20,6 +20,7 @@ from devices.Telescope import TelescopeController |
20 | 20 | from devices.TelescopeRemoteControlDefault import TelescopeRemoteControlDefault |
21 | 21 | from devices.CameraVISRemoteControlDefault import CameraVISRemoteControlDefault |
22 | 22 | from devices.CameraNIRRemoteControlDefault import CameraNIRRemoteControlDefault |
23 | +from devices import PLC | |
23 | 24 | from django.core.mail import send_mail |
24 | 25 | import time |
25 | 26 | import utils.celme as celme |
... | ... | @@ -522,13 +523,18 @@ def submit_command_to_telescope_expert(request): |
522 | 523 | @login_required |
523 | 524 | @level_required(3) |
524 | 525 | def submit_command_to_plc(request): |
525 | - #import os | |
526 | 526 | if request.method == 'POST': |
527 | 527 | param = request.POST.get("commande_expert") |
528 | 528 | if param: |
529 | - #response = TelescopeRemoteControlDefault(param, expert_mode=True).exec_command() | |
530 | - #os.system("echo \"status :" + response + "\" >> /home/portos/IRAP/pyros/src/status") | |
531 | - return HttpResponse(json.dumps({'message': "Command send OK", 'response': "ceci est un test"})) | |
529 | + plc_controller = PLC.PLCController() | |
530 | + response = "Unrecognized command" | |
531 | + if param.startswith("GET STATUS ") or param =="GET STATUS": #pas beau a revoir | |
532 | + response = plc_controller.getStatus(param) | |
533 | + elif param.startswith("SWITCH LIGHTS"): | |
534 | + response = plc_controller.switch_lights(param) | |
535 | + elif param.endswith(" SHUTTERS"): | |
536 | + response = plc_controller.manage_shutters(param) | |
537 | + return HttpResponse(json.dumps({'message': "Command send OK", 'response': response})) | |
532 | 538 | return HttpResponse(json.dumps({'message': "Missing command data"})) |
533 | 539 | return redirect('submit_command_to_plc') |
534 | 540 | ... | ... |
src/devices/PLC.py
... | ... | @@ -28,10 +28,36 @@ class PLCController(DeviceController): |
28 | 28 | # Read result FROM plc |
29 | 29 | return (self.blockAndReadBytes(4096)) |
30 | 30 | |
31 | + def switch_lights(self, command) : | |
32 | + command = command.split() | |
33 | + if len(command) > 2: | |
34 | + if command[2] == "ON": | |
35 | + return self.sendCommandWithAnswer([{"name": "SWITCH LINES ON"}]) | |
36 | + elif command[2] == "OFF": | |
37 | + return self.sendCommandWithAnswer([{"name": "SWITCH LINES OFF"}]) | |
38 | + else: | |
39 | + return "Invalid command" | |
40 | + | |
41 | + | |
42 | + def manage_shutters(self, command): | |
43 | + command = command.split() | |
44 | + if len(command) == 2: | |
45 | + if command[0] == "CLOSE": | |
46 | + return self.sendCommandWithAnswer([{"name": "CLOSE SHUTTERS"}]) | |
47 | + elif command[0] == "OPEN": | |
48 | + return self.sendCommandWithAnswer([{"name": "OPEN SHUTTERS"}]) | |
49 | + else: | |
50 | + return "Invalid command" | |
51 | + return "Invalid command" | |
52 | + | |
31 | 53 | def getList(self): |
32 | 54 | return self.sendCommandWithAnswer([{"name":"LIST"}]) |
33 | 55 | |
34 | - def getStatus(self): | |
56 | + def getStatus(self, command=""): | |
57 | + command = command.split() | |
58 | + if (len(command) > 2): | |
59 | + I = 0 #emplacement ou gérer la commande a envoyer pour le statut d'un capteur en particulier | |
60 | + | |
35 | 61 | s = self.sendCommandWithAnswer([{"name":"STATUS"}]) |
36 | 62 | return s |
37 | 63 | ''' | ... | ... |
src/misc/templates/base.html
... | ... | @@ -98,6 +98,7 @@ a { |
98 | 98 | } |
99 | 99 | #text_globalmode { |
100 | 100 | font-size: 14px; |
101 | + color: black; | |
101 | 102 | } |
102 | 103 | </style> |
103 | 104 | |
... | ... | @@ -153,7 +154,7 @@ a { |
153 | 154 | <li><a class="nav-brand" id="observatory_state" href="{% url "site" %}"><img id="obs_state_img"></a></li> |
154 | 155 | <li><a class="nav-brand" id="wind" href="{% url "weather" %}"><img id="wind_img"></a></li> |
155 | 156 | <li><a class="nav-brand" id="weather" href="{% url "weather" %}"><img id="weather_img"></a></li> |
156 | - <li><a class="nav-brand" id="globalmode" style="color: black;"> <p id="text_globalmode" >{% global_mode request %} </p></a> | |
157 | + <li><a class="nav-brand" id="globalmode" style="color: black;"> <p id="text_globalmode" >{% global_mode request %} </p></a> | |
157 | 158 | |
158 | 159 | <li> |
159 | 160 | <a class="nav-brand" href="{% url "profile" %}" style="color: black;"><i id="profile" class="fas fa-cog "></i></a> |
... | ... | @@ -195,7 +196,7 @@ a { |
195 | 196 | safe = "SAFE"; |
196 | 197 | |
197 | 198 | if (ack) { |
198 | - ack = "STAFF ACK: OK"; | |
199 | + ack = "ACK: OK"; | |
199 | 200 | if (!check_change) |
200 | 201 | window.location.reload(true); |
201 | 202 | check_change = true; |
... | ... | @@ -207,7 +208,7 @@ a { |
207 | 208 | check_change = false; |
208 | 209 | } |
209 | 210 | |
210 | - $("#plc_state").text("PLC: " + mode + ";" + safe + ";" + ack); | |
211 | + $("#plc_state").text("PLC: " + mode + '\u00A0\u00A0\u00A0\u00A0\u00A0' + safe + '\u00A0\u00A0\u00A0\u00A0\u00A0' + ack); | |
211 | 212 | $("#plc_state").css("color", "black"); |
212 | 213 | if (timeout > max_plc_timeout) |
213 | 214 | { | ... | ... |