Commit 617aeab83295516c4aeaad6fb54e68a516bb6c12
1 parent
bf051e5f
Exists in
dev
Ajout table unique AgentDeviceStatus pour tous les AgentDevice
Creation AgentDeviceTelescopeGemini qui herite de AgentDevice Reste a créer un mode "simulateur" par defaut pour AgentDevice dont heritera AgentDeviceTelescopeGemini
Showing
7 changed files
with
107 additions
and
81 deletions
Show diff stats
.gitignore
HOWTO_TEST.txt
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | - (1) Test with agentA and agentB sending commands to each other: |
17 | 17 | $ ./pyros.py -t start agentA,agentB |
18 | 18 | - (2) Test with agentTelescopeRequester sending commands to agentDevice: |
19 | - $ ./pyros.py -t start agentTelescopeRequester,agentDevice | |
19 | + $ ./pyros.py -t start agentTelescopeRequester,agentDeviceTelescopeGemini | |
20 | 20 | |
21 | 21 | (C) Interactive testing: |
22 | 22 | $ ./pyros.py shell | ... | ... |
pyros.py
... | ... | @@ -34,7 +34,8 @@ AGENTS = { |
34 | 34 | "agentA" : "AgentA", |
35 | 35 | "agentB" : "AgentB", |
36 | 36 | "agentM" : "AgentM", |
37 | - "agentDevice" : "AgentDevice", | |
37 | + #"agentDevice" : "AgentDevice", | |
38 | + "agentDeviceTelescopeGemini" : "agentDeviceTelescopeGemini", | |
38 | 39 | "agentTelescopeRequester" : "AgentTelescopeRequester", |
39 | 40 | "webserver" : "webserver", |
40 | 41 | "monitoring" : "monitoring", | ... | ... |
src/core/pyros_django/agent/AgentDevice.py
... | ... | @@ -8,9 +8,8 @@ import time |
8 | 8 | ##from .Agent import Agent |
9 | 9 | sys.path.append("..") |
10 | 10 | from agent.Agent import Agent, extract_parameters |
11 | -from common.models import AgentDeviceTelescopeStatus, get_or_create_unique_row_from_model | |
11 | +from common.models import AgentDeviceStatus, get_or_create_unique_row_from_model | |
12 | 12 | sys.path.append("../../..") |
13 | -from devices_controller.devices_controller_concrete.device_controller_Gemini.telescope_controller_gemini import TelescopeControllerGEMINI | |
14 | 13 | |
15 | 14 | ##log = L.setupLogger("AgentXTaskLogger", "AgentX") |
16 | 15 | |
... | ... | @@ -18,7 +17,7 @@ from devices_controller.devices_controller_concrete.device_controller_Gemini.tel |
18 | 17 | |
19 | 18 | class AgentDevice(Agent): |
20 | 19 | |
21 | - _agent_device_telescope_status = None | |
20 | + _agent_device_status = None | |
22 | 21 | |
23 | 22 | # FOR TEST ONLY |
24 | 23 | # Run this agent in simulator mode |
... | ... | @@ -73,27 +72,31 @@ class AgentDevice(Agent): |
73 | 72 | """ |
74 | 73 | |
75 | 74 | # @override |
76 | - def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True, device_controller=TelescopeControllerGEMINI): | |
75 | + #def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True, device_controller, host, port): | |
76 | + def __init__(self, name:str, config_filename, RUN_IN_THREAD, device_controller, host, port): | |
77 | 77 | if name is None: name = self.__class__.__name__ |
78 | 78 | super().__init__(name, config_filename, RUN_IN_THREAD) |
79 | 79 | |
80 | 80 | # Initialize the device table status |
81 | 81 | # If table is empty, create a default 1st row |
82 | - self._agent_device_telescope_status = get_or_create_unique_row_from_model(AgentDeviceTelescopeStatus) | |
82 | + ##self._agent_device_status = get_or_create_unique_row_from_model(AgentDeviceStatus) | |
83 | + self._agent_device_status = AgentDeviceStatus.getStatusForAgent(name) | |
83 | 84 | """ |
84 | 85 | if not AgentDeviceTelescopeStatus.objects.exists(): |
85 | 86 | print("CREATE first row") |
86 | - self._agent_device_telescope_status = AgentDeviceTelescopeStatus.objects.create(id=1) | |
87 | + self._agent_device_status = AgentDeviceTelescopeStatus.objects.create(id=1) | |
87 | 88 | # Get 1st row (will be updated at each iteration by routine_process() with current device status) |
88 | 89 | print("GET first row") |
89 | - self._agent_device_telescope_status = AgentDeviceTelescopeStatus.objects.get(id=1) | |
90 | + self._agent_device_status = AgentDeviceTelescopeStatus.objects.get(id=1) | |
90 | 91 | """ |
91 | 92 | |
92 | 93 | # Initialize the device socket |
93 | 94 | # Port local AK 8085 = redirigé sur l’IP du tele 192.168.0.12 sur port 11110 |
94 | - HOST, PORT = "82.64.28.71", 11110 | |
95 | + ##HOST, PORT = "82.64.28.71", 11110 | |
95 | 96 | #HOST, PORT = "localhost", 11110 |
96 | - self.tele_ctrl = TelescopeControllerGEMINI(HOST, PORT, True) | |
97 | + #self._device_ctrl = TelescopeControllerGEMINI(host, port, True) | |
98 | + ##self._device_ctrl = device_controller(HOST, PORT, True) | |
99 | + self._device_ctrl = device_controller(host, port, True) | |
97 | 100 | self._log.print(f"init done for {name}") |
98 | 101 | |
99 | 102 | |
... | ... | @@ -107,8 +110,8 @@ class AgentDevice(Agent): |
107 | 110 | |
108 | 111 | # Device socket init |
109 | 112 | # (optional) Only useful for TCP (does nothing for UDP) |
110 | - self.tele_ctrl._connect_to_device() | |
111 | - self.tele_ctrl.print_available_commands() | |
113 | + self._device_ctrl._connect_to_device() | |
114 | + self._device_ctrl.print_available_commands() | |
112 | 115 | |
113 | 116 | # Telescope (long) init |
114 | 117 | # TODO: |
... | ... | @@ -139,53 +142,66 @@ class AgentDevice(Agent): |
139 | 142 | |
140 | 143 | # @override |
141 | 144 | def routine_process(self): |
142 | - self.print("ROUTINE PROCESS START: reading my dedicated device status information and storing it in DB)") | |
143 | - self.print("...") | |
145 | + self.print("ROUTINE PROCESS START: reading my dedicated device status information and storing it in DB)...") | |
144 | 146 | |
147 | + # Save current device status to DB | |
148 | + #AgentDeviceTelescopeStatus.objects.create(radec=myradec) | |
149 | + self.save_device_status() | |
150 | + self.print("Status saved in DB") | |
151 | + | |
152 | + #time.sleep(3) | |
153 | + self.print("ROUTINE PROCESS END") | |
154 | + | |
155 | + | |
156 | + def save_device_status(self): | |
157 | + self._agent_device_status.status = self.get_device_status() | |
158 | + self._agent_device_status.save() | |
159 | + | |
160 | + | |
161 | + # To be overriden by subclass | |
162 | + def get_device_status(self): | |
163 | + """ | |
145 | 164 | cmd="get date" |
146 | - res = self.tele_ctrl.execute_cmd(cmd) | |
165 | + res = self._device_ctrl.execute_cmd(cmd) | |
147 | 166 | print("result is", str(res)) |
148 | 167 | if res.ok: print("OK") |
149 | 168 | time.sleep(1) |
150 | 169 | |
151 | 170 | cmd="get time" |
152 | - res = self.tele_ctrl.execute_cmd(cmd) | |
171 | + res = self._device_ctrl.execute_cmd(cmd) | |
153 | 172 | print("result is", str(res)) |
154 | 173 | if res.ok: print("OK") |
155 | 174 | time.sleep(1) |
156 | 175 | |
157 | 176 | cmd="get radec" |
158 | - res = self.tele_ctrl.execute_cmd(cmd) | |
177 | + res = self._device_ctrl.execute_cmd(cmd) | |
159 | 178 | print("result is", str(res)) |
160 | 179 | myradec = str(res) |
161 | 180 | if res.ok: print("OK") |
162 | 181 | time.sleep(1) |
163 | - | |
164 | - # Save current device status to DB | |
165 | - #AgentDeviceTelescopeStatus.objects.create(radec=myradec) | |
166 | - self._agent_device_telescope_status.radec = myradec | |
167 | - self._agent_device_telescope_status.save() | |
182 | + """ | |
183 | + return 'Abstract status' | |
168 | 184 | |
169 | 185 | |
170 | - #time.sleep(3) | |
171 | - self.print("ROUTINE PROCESS END") | |
172 | 186 | |
173 | 187 | # @override |
174 | 188 | def kill_running_specific_cmd_if_exists(self, abort_sender): |
175 | 189 | super().kill_running_specific_cmd_if_exists(abort_sender) |
176 | - print("Close telescope socket") | |
177 | - self.tele_ctrl.close() | |
190 | + print("Close device socket") | |
191 | + self._device_ctrl.close() | |
178 | 192 | |
193 | + """ | |
179 | 194 | # @override |
180 | 195 | def specific_process(self, cmd): |
181 | 196 | cmd.set_read_time() |
182 | 197 | cmd.set_as_running() |
183 | - res = self.tele_ctrl.execute_cmd(cmd.name) | |
198 | + res = self._device_ctrl.execute_cmd(cmd.name) | |
184 | 199 | cmd.set_result(str(res)) |
185 | 200 | print("result is", str(res)) |
186 | 201 | if res.ok: print("OK") |
187 | 202 | cmd.set_as_processed() |
188 | 203 | time.sleep(1) |
204 | + """ | |
189 | 205 | |
190 | 206 | """ |
191 | 207 | ================================================================= |
... | ... | @@ -194,61 +210,26 @@ class AgentDevice(Agent): |
194 | 210 | """ |
195 | 211 | |
196 | 212 | # Define your own command step(s) here |
197 | - def cmd_step1(self, step:int): | |
198 | - cmd = self._current_specific_cmd | |
199 | - cmd.result = f"in step #{step}/{self._thread_total_steps_number}" | |
200 | - cmd.save() | |
201 | - """ | |
202 | - if self.RUN_IN_THREAD: | |
203 | - print("(save from thread)") | |
204 | - cmd.save() | |
205 | - else: | |
206 | - #@transaction.atomic | |
207 | - print("(save from process)") | |
208 | - with transaction.atomic(): | |
209 | - cmd.save() | |
210 | - #Command.objects.select_for_update() | |
211 | - """ | |
212 | - | |
213 | - def cmd_step2(self, step:int): | |
214 | - self.cmd_step1(step) | |
215 | - def cmd_step3(self, step:int): | |
216 | - self.cmd_step1(step) | |
217 | - def cmd_step4(self, step:int): | |
218 | - self.cmd_step1(step) | |
219 | - | |
220 | - """ | |
221 | - # @override | |
222 | - def thread_exec_specific_cmd_step(self, step:int, sleep_time:float=1.0): | |
223 | - self.thread_stop_if_asked() | |
224 | - cmd = self._current_specific_cmd | |
225 | - print(f">>>>> Thread (cmd {cmd.name}): step #{step}/5") | |
226 | - self.sleep(sleep_time) | |
227 | - """ | |
228 | - | |
229 | - ''' | |
230 | - # @override | |
231 | - def exec_specific_cmd_start(self, cmd:Command, from_thread=True): | |
232 | - super().exec_specific_cmd_start(cmd, from_thread) | |
233 | - ''' | |
234 | - | |
213 | + def cmd_step(self, step:int): | |
214 | + cmd = self._current_specific_cmd | |
215 | + cmd.set_read_time() | |
216 | + cmd.set_as_running() | |
217 | + res = self._device_ctrl.execute_cmd(cmd.name) | |
218 | + cmd.set_result(str(res)) | |
219 | + print("result is", str(res)) | |
220 | + if res.ok: print("OK") | |
221 | + cmd.set_as_processed() | |
222 | + time.sleep(1) | |
223 | + cmd.set_result(f"in step #{step}/{self._thread_total_steps_number}") | |
235 | 224 | |
236 | 225 | # @override |
237 | 226 | def thread_exec_specific_cmd_main(self): |
238 | 227 | # This is optional |
239 | - self.thread_set_total_steps_number(5) | |
240 | - | |
228 | + self.thread_set_total_steps_number(1) | |
241 | 229 | # HERE, write your own scenario |
242 | - | |
243 | - # scenario OK | |
244 | - self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) | |
245 | - self.thread_exec_specific_cmd_step(2, self.cmd_step2, 3) | |
246 | - self.thread_exec_specific_cmd_step(3, self.cmd_step1, 5) | |
247 | - self.thread_exec_specific_cmd_step(4, self.cmd_step3, 10) | |
248 | - self.thread_exec_specific_cmd_step(5, self.cmd_step1, 4) | |
230 | + self.thread_exec_specific_cmd_step(1, self.cmd_step, 1) | |
249 | 231 | # ... as many as you need |
250 | - | |
251 | - """ autre scenario | |
232 | + """ other scenario | |
252 | 233 | self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) |
253 | 234 | self.thread_exec_specific_cmd_step(2, self.cmd_step2, 2) |
254 | 235 | self.thread_exec_specific_cmd_step(3, self.cmd_step1, 2) | ... | ... |
src/core/pyros_django/agent/AgentTelescopeRequester.py
... | ... | @@ -24,7 +24,7 @@ class AgentTelescopeRequester(Agent): |
24 | 24 | SIMULATOR_MAX_DURATION_SEC = 100 |
25 | 25 | # Who should I send commands to ? |
26 | 26 | #SIMULATOR_COMMANDS_DEST = "myself" |
27 | - SIMULATOR_COMMANDS_DEST = "AgentDevice" | |
27 | + SIMULATOR_COMMANDS_DEST = "AgentDeviceTelescopeGemini" | |
28 | 28 | # Scenario to be executed |
29 | 29 | SIMULATOR_COMMANDS_LIST = [ |
30 | 30 | # Ask receiver to delete all its previous commands | ... | ... |
src/core/pyros_django/common/admin.py
... | ... | @@ -236,7 +236,7 @@ class AlbumAdmin(PyrosModelAdmin): |
236 | 236 | admin.site.register(Command) |
237 | 237 | admin.site.register(AgentLogs) |
238 | 238 | admin.site.register(AgentSurvey) |
239 | -admin.site.register(AgentDeviceTelescopeStatus) | |
239 | +admin.site.register(AgentDeviceStatus) | |
240 | 240 | |
241 | 241 | |
242 | 242 | admin.site.register(Album, AlbumAdmin) | ... | ... |
src/core/pyros_django/common/models.py
... | ... | @@ -162,7 +162,8 @@ class Company(models.Model): |
162 | 162 | # --- Utility functions |
163 | 163 | # --- |
164 | 164 | def get_or_create_unique_row_from_model(model:models.Model): |
165 | - return model.objects.get(id=1) if model.objects.exists() else model.objects.create(id=1) | |
165 | + #return model.objects.get(id=1) if model.objects.exists() else model.objects.create(id=1) | |
166 | + return model.objects.first() if model.objects.exists() else model.objects.create(id=1) | |
166 | 167 | |
167 | 168 | |
168 | 169 | """ |
... | ... | @@ -219,6 +220,7 @@ class Request(models.Model): |
219 | 220 | ------------------------ |
220 | 221 | """ |
221 | 222 | |
223 | +#TODO: A VIRER car remplacé par AgentDeviceStatus | |
222 | 224 | class AgentDeviceTelescopeStatus(models.Model): |
223 | 225 | #created = models.DateTimeField('status date', blank=True, null=True, auto_now_add=True) |
224 | 226 | updated = models.DateTimeField('status date', blank=True, null=True, auto_now=True) |
... | ... | @@ -235,6 +237,43 @@ class AgentDeviceTelescopeStatus(models.Model): |
235 | 237 | return (f"Agent {self.name} at {self.updated} in mode {self.mode} and status {self.status}") |
236 | 238 | """ |
237 | 239 | |
240 | + | |
241 | +class AgentDeviceStatus(models.Model): | |
242 | + """Table storing various status parameters for EACH Device. | |
243 | + | |
244 | + Attributes: | |
245 | + attr1 (str): Description of `attr1`. | |
246 | + attr2 (:obj:`int`, optional): Description of `attr2`. | |
247 | + | |
248 | + """ | |
249 | + #created = models.DateTimeField('status date', blank=True, null=True, auto_now_add=True) | |
250 | + agent = models.CharField('Name of the agent that saved this parameter', max_length=45, blank=True, null=True) | |
251 | + #radec = models.CharField('agent mode', max_length=30, blank=True) | |
252 | + status = models.CharField('status parameters json dictionnary (ex: {radec:..., speed:...})', max_length=300, blank=True, null=True) | |
253 | + date_updated = models.DateTimeField('status parameter date', blank=True, null=True, auto_now=True) | |
254 | + | |
255 | + class Meta: | |
256 | + managed = True | |
257 | + db_table = 'agent_device_status' | |
258 | + verbose_name = "agent device status" | |
259 | + verbose_name_plural = "agent devices status" | |
260 | + | |
261 | + def __str__(self): | |
262 | + return (f"Agent {self.agent} last status is ({self.status}) (saved at {self.date_updated})") | |
263 | + | |
264 | + @classmethod | |
265 | + def getStatusForAgent(cls, agent:str) -> str: | |
266 | + return cls.objects.filter(agent=agent)[0] if cls.objects.filter(agent=agent).exists() else cls.objects.create(agent=agent) | |
267 | + ''' | |
268 | + return cls.objects.filter(agent=agent)[0].status if cls.objects.filter(agent=agent).exists() else cls.objects.create(agent=agent).status | |
269 | + agent_status = cls.objects.filter(agent=agent) | |
270 | + if agent_status.exists(): | |
271 | + return agent_status[0].status | |
272 | + else: | |
273 | + return cls.objects.create(agent=agent) | |
274 | + ''' | |
275 | + | |
276 | + | |
238 | 277 | class AgentLogs(models.Model): |
239 | 278 | created = models.DateTimeField(blank=True, null=True, auto_now_add=True) |
240 | 279 | name = models.CharField(max_length=50) | ... | ... |