|
3 | 3 | Concretes a subject for Eye/Camera features. |
4 | 4 | """ |
5 | 5 | import os |
| 6 | +from concurrent.futures import ThreadPoolExecutor |
6 | 7 | from datetime import datetime |
| 8 | +from threading import Lock |
7 | 9 | from time import sleep |
8 | | -from threading import Thread, Lock |
9 | 10 |
|
10 | 11 | import cv2 |
11 | 12 |
|
12 | | -from core.utils.logger import get_logger |
13 | | -from core.utils.datatypes import EyeStates, EyeStrategyResult |
14 | 13 | from core.observers.subject.base_subject import BaseSubject |
15 | 14 | from core.strategies.eye.base_eye_strategy import BaseEyeStrategy |
| 15 | +from core.utils.datatypes import EyeStates, EyeStrategyResult |
| 16 | +from core.utils.logger import get_logger |
16 | 17 |
|
17 | 18 | # Add logging support. |
18 | 19 | logger = get_logger(__name__) |
@@ -43,56 +44,72 @@ def get_default_state() -> EyeStates: |
43 | 44 | """This method is called when the observer is updated.""" |
44 | 45 | return EyeStates.UNREACHABLE |
45 | 46 |
|
| 47 | + def _cb_save(self, future) -> None: |
| 48 | + """This method is called when the observer is updated.""" |
| 49 | + logger.warning("[EyeSubject] The thread died.") |
| 50 | + # Create a txt file to indicate the thread died. |
| 51 | + file_location = "eyesubject_thread_died.txt" |
| 52 | + with open(file_location, "w", encoding="utf-8") as file: |
| 53 | + file.write("The thread died.") |
| 54 | + logger.warning("[EyeSubject] The thread died. A file is created at %s.", |
| 55 | + file_location) |
| 56 | + |
46 | 57 | def run(self, |
47 | 58 | eye_strategy: BaseEyeStrategy, |
48 | 59 | wifi_lock: Lock | None = None |
49 | 60 | ) -> None: |
50 | 61 | """This method is called when the observer is updated.""" |
51 | | - thread = Thread(target=self._run_in_loop, args=(self, eye_strategy, wifi_lock)) |
52 | | - thread.start() |
53 | | - logger.debug("EyeSubject is running...") |
| 62 | + thread = ThreadPoolExecutor( |
| 63 | + max_workers=1, |
| 64 | + thread_name_prefix="eyesubject" |
| 65 | + ).submit(self._run_in_loop, self, eye_strategy, wifi_lock) |
| 66 | + thread.add_done_callback(self._cb_save) |
54 | 67 |
|
55 | 68 | def _run_in_loop(self, |
56 | 69 | eye_strategy: BaseEyeStrategy, |
57 | 70 | wifi_lock: Lock | None = None |
58 | 71 | ) -> None: |
59 | 72 | """This method is called when the observer is updated.""" |
| 73 | + logger.debug("[EyeSubject] Thread is started.") |
60 | 74 | sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL |
61 | 75 |
|
62 | 76 | # Create a dummy lock instance if not given. |
63 | 77 | if wifi_lock is None: |
| 78 | + logger.debug("[EyeSubject] A lock instance is generated.") |
64 | 79 | wifi_lock = Lock() |
65 | 80 |
|
66 | 81 | while True: |
67 | 82 | # If WiFi subject would give rights to use camera, |
68 | 83 | # Check if any intruders detected. |
| 84 | + logger.debug("[EyeSubject] WiFi Lock Status: %s", wifi_lock.locked()) |
69 | 85 | if not wifi_lock.locked(): |
70 | 86 | result = eye_strategy.check_if_detected() |
71 | | - logger.debug("EyeStrategyResult: %s", str(result.result)) |
| 87 | + logger.debug("[EyeSubject] EyeStrategyResult: %s", str(result.result)) |
72 | 88 |
|
73 | 89 | if result.result: |
74 | | - logger.debug("Changing state to DETECTED...") |
| 90 | + logger.debug("[EyeSubject] Changing state to DETECTED...") |
75 | 91 | self._save_image(result) |
76 | 92 | self.set_state(EyeStates.DETECTED) |
77 | 93 | sleep_interval = EyeSubject.SLEEP_INTERVAL_DETECTED |
78 | 94 | else: |
79 | | - logger.debug("Changing state to NOT_DETECTED...") |
| 95 | + logger.debug("[EyeSubject] Changing state to NOT_DETECTED...") |
80 | 96 | self.set_state(EyeStates.NOT_DETECTED) |
81 | 97 | sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL |
82 | 98 |
|
83 | 99 | # If the WiFi subject does not give rights, |
84 | 100 | # aka: "There is protectors around the house." |
85 | 101 | else: |
86 | | - logger.debug("Changing state to UNREACHABLE...") |
| 102 | + logger.debug("[EyeSubject] Changing state to UNREACHABLE...") |
87 | 103 | self.set_state(EyeStates.UNREACHABLE) |
88 | 104 | sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL |
89 | 105 |
|
90 | 106 | sleep(sleep_interval) |
91 | 107 |
|
92 | 108 | def _save_image(self, result: EyeStrategyResult) -> None: |
93 | 109 | """This method is called when the observer is updated.""" |
94 | | - logger.debug("Saving image to the disk...") |
| 110 | + logger.debug("[EyeSubject] Saving image to the disk...") |
95 | 111 | time_now = datetime.now().strftime("%d-%m-%Y_%H-%M-%S") |
96 | 112 | file_location = f"{self._image_path}/intruder_{time_now}.jpg" |
97 | 113 | cv2.imwrite(file_location, result.image) |
98 | | - logger.debug("Image saved to the disk with name: intruder_%s.jpg", time_now) |
| 114 | + logger.debug("[EyeSubject] Image saved to the disk with name: intruder_%s.jpg", |
| 115 | + time_now) |
0 commit comments