Commit fc957772885aa46d620a14c9f2d06f5436a3b030

Authored by Quentin Durand
1 parent dd5b2b4a
Exists in dev

Control command PLC + minor changes on navbar

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
... ... @@ -20,7 +20,7 @@
20 20  
21 21 .fixed {
22 22 height: 400px;
23   - width: 430px;
  23 + width: 500px;
24 24 overflow: scroll;
25 25 background-color: black;
26 26 }
... ...
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 {
... ...