Skip to content

Commit 5bad157

Browse files
feat: add logging support
1 parent 313f7eb commit 5bad157

8 files changed

Lines changed: 89 additions & 23 deletions

File tree

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
"""
22
The observer for Home Security System.
33
"""
4+
import logging
45
from core.observers.observer.base_observer import BaseObserver
56
from core.observers.subject.base_subject import BaseSubject
67
from core.observers.subject.wifi_subject import WiFiSubject
78
from core.observers.subject.eye_subject import EyeSubject
8-
from core.utils.datatypes import EyeStates, WiFiStates, EyeStrategyResult
9+
from core.utils.datatypes import EyeStates, WiFiStates
910
from core.strategies.notifier.base_notifier_strategy import BaseNotifierStrategy
1011

12+
# Add logging support.
13+
logger = logging.getLogger(__name__)
14+
1115

1216
class HomeSecuritySystemObserver(BaseObserver):
1317
"""
@@ -22,22 +26,16 @@ def update(self, subject: BaseSubject) -> None:
2226
"""This method is called when the observer is updated."""
2327
if isinstance(subject, WiFiSubject):
2428
self.wifi_state = subject.get_state()
29+
logger.debug("WiFi state: " + str(self.wifi_state.name))
2530

2631
if isinstance(subject, EyeSubject):
2732
self.eye_state = subject.get_state()
28-
29-
print("Observer- WiFi state: " + str(self.wifi_state.name))
30-
print("Observer- Eye state: " + str(self.eye_state.name))
33+
logger.debug("Eye state: " + str(self.eye_state.name))
3134

3235
if self.wifi_state == WiFiStates.DISCONNECTED and self.eye_state == EyeStates.DETECTED:
36+
logger.info("There is an intruder!")
3337
self._notifier.notify_all("There is an intruder!")
34-
self._save_image()
3538

3639
def set_notifier(self, notifier: BaseNotifierStrategy) -> None:
3740
"""This method is called when the observer is updated."""
3841
self._notifier = notifier
39-
40-
# Internal methods
41-
def _save_image(result: EyeStrategyResult) -> None:
42-
"""This method is called when the observer is updated."""
43-
print("Image saved!")

core/observers/subject/eye_subject.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,32 @@
22
This class inherits from IBaseSubject.
33
Concretes a subject for Eye/Camera features.
44
"""
5+
import logging
6+
from datetime import datetime
57
from time import sleep
68
from threading import Thread
9+
10+
import cv2
11+
712
from core.utils.datatypes import EyeStates, EyeStrategyResult
813
from core.observers.subject.base_subject import BaseSubject
914
from core.strategies.eye.base_eye_strategy import BaseEyeStrategy
1015

16+
# Add logging support.
17+
logger = logging.getLogger(__name__)
18+
1119

1220
class EyeSubject(BaseSubject):
1321
"""
1422
This class inherits from IBaseSubject.
1523
Concretes a subject for Eye/Camera features.
1624
"""
17-
def __init__(self):
25+
DEFAULT_SLEEP_INTERVAL = 10
26+
SLEEP_INTERVAL_DETECTED = 5
27+
28+
def __init__(self, image_path: str):
1829
super().__init__()
19-
self._result: EyeStrategyResult = None
30+
self._image_path = image_path
2031

2132
@staticmethod
2233
def get_default_state() -> EyeStates:
@@ -27,22 +38,31 @@ def run(self, eye_strategy: BaseEyeStrategy) -> None:
2738
"""This method is called when the observer is updated."""
2839
thread = Thread(target=self._run_in_loop, args=(self, eye_strategy,))
2940
thread.start()
30-
31-
def save_result(self, result: EyeStrategyResult) -> None:
32-
"""This method is called when the observer is updated to DETECTED."""
33-
self._result = result
41+
logger.debug("EyeSubject is running...")
3442

3543
@staticmethod
3644
def _run_in_loop(self, eye_strategy: BaseEyeStrategy) -> None:
3745
"""This method is called when the observer is updated."""
46+
sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL
47+
3848
while True:
3949
result = eye_strategy.check_if_detected()
40-
print("Eye result: " + str(result.result))
41-
print("Eye state: " + str(self.get_state().name))
50+
logger.debug("EyeStrategyResult: " + str(result.result))
51+
4252
if result.result:
4353
self.set_state(EyeStates.DETECTED)
44-
self.save_result(result)
54+
self._save_image(result)
55+
sleep_interval = EyeSubject.SLEEP_INTERVAL_DETECTED
4556
else:
4657
self.set_state(EyeStates.NOT_DETECTED)
47-
sleep(5)
58+
sleep_interval = EyeSubject.DEFAULT_SLEEP_INTERVAL
59+
60+
sleep(sleep_interval)
61+
62+
def _save_image(self, result: EyeStrategyResult) -> None:
63+
"""This method is called when the observer is updated."""
64+
time_now = datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
65+
file_location = f"{self._image_path}/intruder_{time_now}.jpg"
66+
cv2.imwrite(file_location, result.image)
67+
logger.debug("Image saved to the disk with name: " + f"intruder_{time_now}.jpg")
4868

core/observers/subject/wifi_subject.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
This class inherits from IBaseSubject.
33
Concretes a subject WiFi features.
44
"""
5+
import logging
56
from threading import Thread
67
from time import sleep
8+
79
from core.utils.datatypes import WiFiStates
810
from core.observers.subject.base_subject import BaseSubject
911
from core.strategies.wifi.base_wifi_strategy import BaseWiFiStrategy
1012

13+
# Add logging support.
14+
logger = logging.getLogger(__name__)
15+
1116

1217
class WiFiSubject(BaseSubject):
1318
"""
@@ -23,12 +28,15 @@ def run(self, wifi_strategy: BaseWiFiStrategy) -> None:
2328
"""This method is called when the observer is updated."""
2429
thread = Thread(target=self._run_in_loop, args=(self, wifi_strategy,))
2530
thread.start()
31+
logger.debug("WiFiSubject is running...")
2632

2733
@staticmethod
2834
def _run_in_loop(self, wifi_strategy: BaseWiFiStrategy) -> None:
2935
"""This method is called when the observer is updated."""
3036
while True:
3137
protectors = wifi_strategy.check_protectors()
38+
logger.debug("Protectors: " + str(protectors.result) + " " + str(protectors.protector))
39+
3240
if protectors.result:
3341
self.set_state(WiFiStates.CONNECTED)
3442
else:

core/strategies/eye/camera_strategy.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""
22
The Camera strategy for eye strategies.
33
"""
4+
import logging
45
from datetime import datetime
6+
57
import cv2
68
import numpy
9+
710
from core.strategies.eye.base_eye_strategy import BaseEyeStrategy
811
from core.utils.datatypes import EyeStrategyResult
912

13+
# Add logging support.
14+
logger = logging.getLogger(__name__)
15+
1016

1117
class CameraStrategy(BaseEyeStrategy):
1218
"""
@@ -50,6 +56,8 @@ def _detect_humans(self, frame: numpy.ndarray) -> tuple[list[tuple[int, int, int
5056
padding=(4, 4),
5157
scale=1.05
5258
)
59+
logger.debug("Number of detections: " + str(num_detections)
60+
+ " Regions: " + str(regions))
5361
return regions, num_detections
5462

5563
def _outline_the_regions(self, frame: numpy.ndarray, regions: list[tuple[int, int, int, int]]) -> None:

core/strategies/notifier/whatsapp_strategy.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
This module contains the Whatsapp notifier strategy.
33
"""
44
import logging
5+
56
import requests
7+
68
from core.utils.datatypes import WhatsappReciever
79
from core.strategies.notifier.base_notifier_strategy import BaseNotifierStrategy
810

@@ -24,6 +26,7 @@ def notify_all(self, message: str) -> None:
2426

2527
def _send_message(self, reciever: WhatsappReciever, message: str) -> bool:
2628
"""Send a WhatsApp message to the user."""
29+
logger.debug("Sending WhatsApp message (%s) to %s", message, reciever.telephone_number)
2730
# Send the request.
2831
request_url = f"{self.API_URL}?phone={reciever.telephone_number}&text={message}&apikey={reciever.api_key}"
2932
response = requests.get(request_url, timeout=10)

core/strategies/wifi/ipaddress_strategy.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
"""
22
The strategy which searches for IP addresses.
33
"""
4+
import logging
45
from core.utils.program_launcher import run_program, PingCommands
56
from core.strategies.wifi.base_wifi_strategy import BaseWiFiStrategy
67
from core.utils.datatypes import WiFiStrategyResult
78

9+
# Add logging support.
10+
logger = logging.getLogger(__name__)
11+
812

913
class IpAddressStrategy(BaseWiFiStrategy):
1014
"""
@@ -16,17 +20,20 @@ def __init__(self):
1620
# Check if the program is installed.
1721
try:
1822
run_program(PingCommands.GET_VERSION_INFO)
23+
logger.debug("Program is already installed.")
1924
except RuntimeError:
25+
logger.debug("Program is not installed. Installing...")
2026
run_program(PingCommands.INSTALL_PROGRAM)
2127

2228
def check_protectors(self) -> WiFiStrategyResult:
2329
"""This method checks if there are any protectors around."""
2430
for protector in self.protectors:
2531
# Send a ping to the protector.
32+
logger.debug("Sending ping to " + protector.name)
2633
output = run_program(PingCommands.PING_TO + " " + protector.address)
2734
# Check if the ping was successful.
2835
if "Destination Host Unreachable" not in output:
29-
print("Protector found: " + protector.name)
36+
logger.debug("Protector found: " + protector.name)
3037
return WiFiStrategyResult(protector, True)
31-
print("Protector not found.")
38+
logger.debug("No protectors found.")
3239
return WiFiStrategyResult(None, False)

core/strategies/wifi/macaddress_strategy.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
"""
22
The strategy which searches for MAC addresses.
33
"""
4+
import logging
5+
46
from core.utils.program_launcher import run_program, ArpScanCommands
57
from core.strategies.wifi.base_wifi_strategy import BaseWiFiStrategy
68
from core.utils.datatypes import WiFiStrategyResult, ConnectedDeviceResult
79

10+
# Add logging support.
11+
logger = logging.getLogger(__name__)
12+
813

914
class MacAddressStrategy(BaseWiFiStrategy):
1015
"""
@@ -14,15 +19,20 @@ def __init__(self):
1419
super().__init__()
1520
# Check if the program is installed.
1621
try:
22+
logger.debug("Checking if the program is installed...")
1723
run_program(ArpScanCommands.GET_VERSION_INFO)
1824
except RuntimeError:
25+
logger.debug("Program is not installed. Installing...")
1926
run_program(ArpScanCommands.INSTALL_PROGRAM)
2027

2128
def check_protectors(self) -> WiFiStrategyResult:
2229
"""This method checks if there are any protectors around."""
2330
for protector in self.protectors:
31+
# Check if the protector is connected to the network.
2432
if protector.address in [device.address for device in self._get_all_connected()]:
33+
logger.debug("Protector found: " + protector.name)
2534
return WiFiStrategyResult(protector, True)
35+
logger.debug("No protectors found.")
2636
return WiFiStrategyResult(None, False)
2737

2838
# Internal methods
@@ -31,4 +41,5 @@ def _get_all_connected(self) -> list[ConnectedDeviceResult]:
3141
output = run_program(ArpScanCommands.GET_CONNECTED_MAC_ADDRESSES)
3242
mac_addrs = output.split('\n')
3343
mac_addrs = mac_addrs[:-1]
44+
logger.debug("Connected devices: " + str(mac_addrs))
3445
return [ConnectedDeviceResult(mac_addr.upper()) for mac_addr in mac_addrs]

main.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Main application layer for Home Security System.
33
"""
4+
import logging
45
from core.observers.subject.eye_subject import EyeSubject
56
from core.observers.subject.wifi_subject import WiFiSubject
67
from core.observers.observer.hss_observer import HomeSecuritySystemObserver
@@ -10,6 +11,16 @@
1011
from core.utils.datatypes import WhatsappReciever, Protector
1112

1213

14+
# Add logging support.
15+
logging.basicConfig(
16+
level=logging.DEBUG,
17+
format='[%(asctime)s] -- [%(levelname)s] -- %(name)s (%(funcName)s): %(message)s',
18+
datefmt='%Y-%m-%d %H:%M:%S',
19+
filename='hss.log',
20+
filemode='a',
21+
)
22+
23+
1324
def main():
1425
"""
1526
This method is the entry point of the application.
@@ -29,7 +40,7 @@ def main():
2940
# Create subjects to observe.
3041
wifi_subject = WiFiSubject()
3142
wifi_subject.attach(hss_observer)
32-
eye_subject = EyeSubject()
43+
eye_subject = EyeSubject("images/")
3344
eye_subject.attach(hss_observer)
3445

3546
# Run subjects.

0 commit comments

Comments
 (0)