Skip to content

Commit a3a68a6

Browse files
feat: Apply minor changes (#8)
* feat: apply minor changes on project * feat: reorder imports * chore: add settings.json to ignore
1 parent 2e1575a commit a3a68a6

23 files changed

Lines changed: 124 additions & 60 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ __pycache__/
88
.vscode-test/
99
.vagra
1010
DS_Store
11-
*.log
11+
*.log
12+
.vscode/*

core/observers/observer/hss_observer.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"""
22
The observer for Home Security System.
33
"""
4-
from core.utils.logger import get_logger
54
from core.observers.observer.base_observer import BaseObserver
65
from core.observers.subject.base_subject import BaseSubject
7-
from core.observers.subject.wifi_subject import WiFiSubject
86
from core.observers.subject.eye_subject import EyeSubject
9-
from core.utils.datatypes import EyeStates, WiFiStates
10-
from core.utils.fileio_adaptor import upload_to_fileio, read_latest_file
7+
from core.observers.subject.wifi_subject import WiFiSubject
118
from core.strategies.notifier.base_notifier_strategy import BaseNotifierStrategy
9+
from core.utils.datatypes import EyeStates, WiFiStates
10+
from core.utils.fileio_adaptor import read_latest_file, upload_to_fileio
11+
from core.utils.logger import get_logger
1212

1313
# Add logging support.
1414
logger = get_logger(__name__)

core/observers/subject/base_subject.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
This observer is used to create subjects.
44
"""
55
from abc import ABCMeta, abstractmethod
6-
from core.utils.datatypes import ObserverStates
6+
77
from core.observers.observer.base_observer import BaseObserver
8+
from core.utils.datatypes import ObserverStates
9+
from core.utils.logger import get_logger
10+
11+
# Create a logger instance.
12+
logger = get_logger(__name__)
813

914

1015
class BaseSubject(metaclass=ABCMeta):
@@ -26,6 +31,8 @@ def detach(self, observer: BaseObserver) -> None:
2631

2732
def notify(self) -> None:
2833
"""This method is called when the observer is updated."""
34+
logger.debug("[Subject: %s] Notifying observers...",
35+
self.__class__.__name__)
2936
for observer in self._observers:
3037
observer.update(self)
3138

@@ -35,6 +42,10 @@ def get_state(self) -> ObserverStates:
3542

3643
def set_state(self, state: ObserverStates) -> None:
3744
"""This method is called when the observer is updated."""
45+
logger.debug("[Subject: %s] %s->%s",
46+
self.__class__.__name__,
47+
self._current_state.name,
48+
state.name)
3849
self._current_state = state
3950
self.notify()
4051

core/observers/subject/eye_subject.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
Concretes a subject for Eye/Camera features.
44
"""
55
import os
6+
from concurrent.futures import ThreadPoolExecutor
67
from datetime import datetime
8+
from threading import Lock
79
from time import sleep
8-
from threading import Thread, Lock
910

1011
import cv2
1112

12-
from core.utils.logger import get_logger
13-
from core.utils.datatypes import EyeStates, EyeStrategyResult
1413
from core.observers.subject.base_subject import BaseSubject
1514
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
1617

1718
# Add logging support.
1819
logger = get_logger(__name__)
@@ -43,56 +44,72 @@ def get_default_state() -> EyeStates:
4344
"""This method is called when the observer is updated."""
4445
return EyeStates.UNREACHABLE
4546

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+
4657
def run(self,
4758
eye_strategy: BaseEyeStrategy,
4859
wifi_lock: Lock | None = None
4960
) -> None:
5061
"""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)
5467

5568
def _run_in_loop(self,
5669
eye_strategy: BaseEyeStrategy,
5770
wifi_lock: Lock | None = None
5871
) -> None:
5972
"""This method is called when the observer is updated."""
73+
logger.debug("[EyeSubject] Thread is started.")
6074
sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL
6175

6276
# Create a dummy lock instance if not given.
6377
if wifi_lock is None:
78+
logger.debug("[EyeSubject] A lock instance is generated.")
6479
wifi_lock = Lock()
6580

6681
while True:
6782
# If WiFi subject would give rights to use camera,
6883
# Check if any intruders detected.
84+
logger.debug("[EyeSubject] WiFi Lock Status: %s", wifi_lock.locked())
6985
if not wifi_lock.locked():
7086
result = eye_strategy.check_if_detected()
71-
logger.debug("EyeStrategyResult: %s", str(result.result))
87+
logger.debug("[EyeSubject] EyeStrategyResult: %s", str(result.result))
7288

7389
if result.result:
74-
logger.debug("Changing state to DETECTED...")
90+
logger.debug("[EyeSubject] Changing state to DETECTED...")
7591
self._save_image(result)
7692
self.set_state(EyeStates.DETECTED)
7793
sleep_interval = EyeSubject.SLEEP_INTERVAL_DETECTED
7894
else:
79-
logger.debug("Changing state to NOT_DETECTED...")
95+
logger.debug("[EyeSubject] Changing state to NOT_DETECTED...")
8096
self.set_state(EyeStates.NOT_DETECTED)
8197
sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL
8298

8399
#  If the WiFi subject does not give rights,
84100
# aka: "There is protectors around the house."
85101
else:
86-
logger.debug("Changing state to UNREACHABLE...")
102+
logger.debug("[EyeSubject] Changing state to UNREACHABLE...")
87103
self.set_state(EyeStates.UNREACHABLE)
88104
sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL
89105

90106
sleep(sleep_interval)
91107

92108
def _save_image(self, result: EyeStrategyResult) -> None:
93109
"""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...")
95111
time_now = datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
96112
file_location = f"{self._image_path}/intruder_{time_now}.jpg"
97113
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)

core/observers/subject/wifi_subject.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
This class inherits from IBaseSubject.
33
Concretes a subject WiFi features.
44
"""
5-
from threading import Thread, Lock
5+
from concurrent.futures import ThreadPoolExecutor
6+
from threading import Lock
67
from time import sleep
78

8-
from core.utils.logger import get_logger
9-
from core.utils.datatypes import WiFiStates
109
from core.observers.subject.base_subject import BaseSubject
1110
from core.strategies.wifi.base_wifi_strategy import BaseWiFiStrategy
11+
from core.utils.datatypes import WiFiStates
12+
from core.utils.logger import get_logger
1213

1314
# Add logging support.
1415
logger = get_logger(__name__)
@@ -27,11 +28,22 @@ def get_default_state() -> WiFiStates:
2728
"""This method is called when the observer is updated."""
2829
return WiFiStates.UNREACHABLE
2930

31+
def _cb_save(self, future) -> None:
32+
"""This method is called when the observer is updated."""
33+
logger.warning("[WiFiSubject] The thread died.")
34+
file_location = "wifisubject_thread_died.txt"
35+
with open(file_location, "w", encoding="utf-8") as file:
36+
file.write("The thread died.")
37+
logger.warning("[WiFiSubject] The thread died. A file is created at %s.",
38+
file_location)
39+
3040
def run(self, wifi_strategy: BaseWiFiStrategy) -> None:
3141
"""This method is called when the observer is updated."""
32-
thread = Thread(target=self._run_in_loop, args=(wifi_strategy,))
33-
thread.start()
34-
logger.debug("WiFiSubject is running...")
42+
thread = ThreadPoolExecutor(
43+
max_workers=1,
44+
thread_name_prefix="wifisubject"
45+
).submit(self._run_in_loop, self, wifi_strategy)
46+
thread.add_done_callback(self._cb_save)
3547

3648
@classmethod
3749
def get_protector_lock(cls) -> Lock:
@@ -43,20 +55,27 @@ def get_protector_lock(cls) -> Lock:
4355
cls.SINGLETON_LOCK = Lock()
4456
return cls.SINGLETON_LOCK
4557

58+
@staticmethod
4659
def _run_in_loop(self, wifi_strategy: BaseWiFiStrategy) -> None:
4760
"""This method is called when the observer is updated."""
61+
logger.debug("[WiFiSubject] Thread is started.")
62+
4863
protector_lock: Lock = self.get_protector_lock()
4964

5065
while True:
5166
protectors = wifi_strategy.check_protectors()
52-
logger.debug("Protectors: %s %s", str(protectors.result), str(protectors.protector))
67+
logger.debug("[WiFiSubject] Protectors: %s %s",
68+
str(protectors.result),
69+
str(protectors.protector))
5370

5471
if protectors.result:
5572
self.set_state(WiFiStates.CONNECTED)
5673
if not protector_lock.locked():
5774
protector_lock.acquire()
75+
logger.debug("[WiFiSubject] Protector lock is acquired.")
5876
else:
5977
self.set_state(WiFiStates.DISCONNECTED)
6078
if protector_lock.locked():
6179
protector_lock.release()
80+
logger.debug("[WiFiSubject] Protector lock is released.")
6281
sleep(self.CHECK_INTERVAL)

core/strategies/detectors/base_detector_strategy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This strategy is used to define the interface for all detector strategies.
44
"""
55

6-
from abc import abstractmethod, ABCMeta
6+
from abc import ABCMeta, abstractmethod
77
from dataclasses import dataclass
88

99
import numpy

core/strategies/detectors/efficientdet_strategy.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
An TinyML detection technique using Efficientdet model.
33
"""
44
from typing import Any
5+
56
import cv2
67
import numpy
7-
from tflite_runtime.interpreter import Interpreter
88
from base_detector_strategy import BaseDetectorStrategy, DetectorResult
9+
from tflite_runtime.interpreter import Interpreter
910

1011

1112
class EfficientdetStrategy(BaseDetectorStrategy):

core/strategies/eye/base_eye_strategy.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
The base strategy for eye strategies.
33
This strategy is used to define the interface for all eye strategies.
44
"""
5-
from abc import abstractmethod, ABCMeta
5+
from abc import ABCMeta, abstractmethod
6+
67
from numpy import ndarray
8+
9+
from core.strategies.detectors.base_detector_strategy import (
10+
BaseDetectorStrategy,
11+
DetectorResult,
12+
)
713
from core.utils.datatypes import EyeStrategyResult
8-
from core.strategies.detectors.base_detector_strategy import BaseDetectorStrategy, DetectorResult
914

1015

1116
class BaseEyeStrategy(metaclass=ABCMeta):

core/strategies/eye/picamera_strategy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import numpy
55
from picamera2 import Picamera2
66

7-
from core.utils.logger import get_logger
87
from core.strategies.detectors.base_detector_strategy import BaseDetectorStrategy
98
from core.strategies.eye.base_eye_strategy import BaseEyeStrategy
9+
from core.utils.logger import get_logger
1010

1111
# Add logging support.
1212
logger = get_logger(__name__)

core/strategies/eye/usbcamera_strategy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import cv2
55
import numpy
66

7-
from core.utils.logger import get_logger
87
from core.strategies.detectors.base_detector_strategy import BaseDetectorStrategy
98
from core.strategies.eye.base_eye_strategy import BaseEyeStrategy
9+
from core.utils.logger import get_logger
1010

1111
# Add logging support.
1212
logger = get_logger(__name__)

0 commit comments

Comments
 (0)