notc

Untitled

May 26th, 2025
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.06 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. """
  3. Combined SOS Emergency Alert System for Raspberry Pi Zero 2W
  4. Features:
  5. - GPS location tracking (GPIO 14, 15)
  6. - SIM900A GSM module (GPIO 13, 19)
  7. - Email alerts
  8. - Telegram messages with images
  9. - SMS to multiple contacts
  10. - Voice calls (miss calls) to emergency contacts
  11. - Emergency button and buzzer
  12. """
  13.  
  14. import RPi.GPIO as GPIO
  15. import time
  16. import smtplib
  17. import subprocess
  18. import requests
  19. import serial
  20. from email.mime.text import MIMEText
  21. from email.mime.multipart import MIMEMultipart
  22. from threading import Thread, Lock
  23. import socket
  24. from datetime import datetime
  25. import queue
  26. import threading
  27. import logging
  28.  
  29. # Configure logging
  30. logging.basicConfig(
  31. level=logging.INFO,
  32. format='%(asctime)s - %(levelname)s - %(message)s'
  33. )
  34. logger = logging.getLogger(__name__)
  35.  
  36. # --- GPIO SETUP ---
  37. button_pin = 17 # GPIO17 (Pin 11) - SOS Button
  38. buzzer_pin = 18 # GPIO18 (Pin 12) - Buzzer
  39. # GPS uses GPIO 14, 15 (hardware UART)
  40. # SIM900A uses GPIO 13, 19 (software serial)
  41.  
  42. GPIO.setmode(GPIO.BCM)
  43. GPIO.setup(button_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  44. GPIO.setup(buzzer_pin, GPIO.OUT)
  45.  
  46. # --- EMAIL SETUP ---
  47. sender_email = "[email protected]"
  48. receiver_email = "[email protected]"
  49. app_password = "ytaf rttf gcwk fatf"
  50. subject = "🚨 SOS ALERT"
  51. body_template = """EMERGENCY ALERT!
  52.  
  53. 🚨 I need immediate assistance!
  54. šŸ“ Location: {location_info}
  55. šŸ•’ Time: {timestamp}
  56. šŸ“¶ IP Address: {ip_address}
  57.  
  58. Google Maps: {google_maps_link}
  59.  
  60. This is an automated alert from my Raspberry Pi SOS device."""
  61.  
  62. # --- TELEGRAM SETUP ---
  63. BOT_TOKEN = "7606896913:AAF-qQKNwlIgf4GEHyu2uZgE1osVSEFz87c"
  64. CHAT_ID = "5994490090"
  65.  
  66. # --- EMERGENCY CONTACTS FOR SMS AND CALLS ---
  67. EMERGENCY_CONTACTS = [
  68. "+919876543210", # Replace with actual emergency contact numbers
  69. "+919876543211",
  70. "+919876543212",
  71. "+919876543213",
  72. "+919876543214"
  73. ]
  74.  
  75. # --- GPS LOCK ---
  76. gps_lock = Lock()
  77.  
  78. # --- SOFTWARE SERIAL FOR SIM900A ---
  79. class SoftwareSerial:
  80. """Software serial implementation for GPIO communication"""
  81.  
  82. def __init__(self, tx_pin: int, rx_pin: int, baudrate: int = 9600):
  83. self.tx_pin = tx_pin
  84. self.rx_pin = rx_pin
  85. self.baudrate = baudrate
  86. self.bit_duration = 1.0 / baudrate
  87. self.rx_buffer = queue.Queue()
  88. self.rx_thread = None
  89. self.rx_running = False
  90.  
  91. # Setup GPIO for SIM900A
  92. GPIO.setup(self.tx_pin, GPIO.OUT, initial=GPIO.HIGH)
  93. GPIO.setup(self.rx_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  94.  
  95. def start_rx(self):
  96. """Start RX thread for receiving data"""
  97. self.rx_running = True
  98. self.rx_thread = threading.Thread(target=self._rx_worker, daemon=True)
  99. self.rx_thread.start()
  100.  
  101. def stop_rx(self):
  102. """Stop RX thread"""
  103. self.rx_running = False
  104. if self.rx_thread:
  105. self.rx_thread.join(timeout=1)
  106.  
  107. def _rx_worker(self):
  108. """RX thread worker - continuously monitor for incoming data"""
  109. while self.rx_running:
  110. if GPIO.input(self.rx_pin) == GPIO.LOW: # Start bit detected
  111. # Wait for middle of start bit
  112. time.sleep(self.bit_duration * 1.5)
  113.  
  114. byte_val = 0
  115. # Read 8 data bits
  116. for bit in range(8):
  117. if GPIO.input(self.rx_pin) == GPIO.HIGH:
  118. byte_val |= (1 << bit)
  119. time.sleep(self.bit_duration)
  120.  
  121. # Stop bit (no need to check)
  122. time.sleep(self.bit_duration)
  123.  
  124. # Add to buffer
  125. self.rx_buffer.put(byte_val)
  126. else:
  127. time.sleep(self.bit_duration * 0.1)
  128.  
  129. def write(self, data: bytes):
  130. """Send data via TX pin"""
  131. for byte_val in data:
  132. # Start bit
  133. GPIO.output(self.tx_pin, GPIO.LOW)
  134. time.sleep(self.bit_duration)
  135.  
  136. # Data bits (LSB first)
  137. for bit in range(8):
  138. if byte_val & (1 << bit):
  139. GPIO.output(self.tx_pin, GPIO.HIGH)
  140. else:
  141. GPIO.output(self.tx_pin, GPIO.LOW)
  142. time.sleep(self.bit_duration)
  143.  
  144. # Stop bit
  145. GPIO.output(self.tx_pin, GPIO.HIGH)
  146. time.sleep(self.bit_duration)
  147.  
  148. def read(self, size: int = 1) -> bytes:
  149. """Read data from RX buffer"""
  150. data = bytearray()
  151. for _ in range(size):
  152. try:
  153. byte_val = self.rx_buffer.get(timeout=0.1)
  154. data.append(byte_val)
  155. except queue.Empty:
  156. break
  157. return bytes(data)
  158.  
  159. def in_waiting(self) -> int:
  160. """Return number of bytes waiting in RX buffer"""
  161. return self.rx_buffer.qsize()
  162.  
  163. def reset_input_buffer(self):
  164. """Clear RX buffer"""
  165. while not self.rx_buffer.empty():
  166. try:
  167. self.rx_buffer.get_nowait()
  168. except queue.Empty:
  169. break
  170.  
  171. # --- SIM900A GSM MODULE CLASS ---
  172. class SIM900A:
  173. def __init__(self, tx_pin: int = 13, rx_pin: int = 19, baudrate: int = 9600, timeout: int = 10):
  174. self.tx_pin = tx_pin
  175. self.rx_pin = rx_pin
  176. self.baudrate = baudrate
  177. self.timeout = timeout
  178. self.serial = None
  179. self.initialized = False
  180.  
  181. def connect(self) -> bool:
  182. """Establish software serial connection with SIM900A module"""
  183. try:
  184. self.serial = SoftwareSerial(self.tx_pin, self.rx_pin, self.baudrate)
  185. self.serial.start_rx()
  186. logger.info(f"SIM900A connected via GPIO - TX:{self.tx_pin}, RX:{self.rx_pin}")
  187. time.sleep(2)
  188. return self.test_connection()
  189. except Exception as e:
  190. logger.error(f"SIM900A connection failed: {e}")
  191. return False
  192.  
  193. def disconnect(self):
  194. """Close serial connection"""
  195. if self.serial:
  196. self.serial.stop_rx()
  197. logger.info("SIM900A disconnected")
  198.  
  199. def send_at_command(self, command: str, expected_response: str = "OK", timeout: int = None) -> tuple:
  200. """Send AT command and wait for response"""
  201. if not self.serial:
  202. return False, "Serial connection not available"
  203.  
  204. timeout = timeout or self.timeout
  205.  
  206. try:
  207. self.serial.reset_input_buffer()
  208. cmd = f"{command}\r\n"
  209. self.serial.write(cmd.encode())
  210. logger.debug(f"SIM900A sent: {command}")
  211.  
  212. start_time = time.time()
  213. response = ""
  214.  
  215. while (time.time() - start_time) < timeout:
  216. if self.serial.in_waiting() > 0:
  217. new_data = self.serial.read(self.serial.in_waiting())
  218. response += new_data.decode('utf-8', errors='ignore')
  219.  
  220. if expected_response in response:
  221. logger.debug(f"SIM900A received: {response.strip()}")
  222. return True, response.strip()
  223.  
  224. time.sleep(0.1)
  225.  
  226. logger.warning(f"SIM900A timeout waiting for '{expected_response}'. Got: {response.strip()}")
  227. return False, response.strip()
  228.  
  229. except Exception as e:
  230. logger.error(f"SIM900A AT command error: {e}")
  231. return False, str(e)
  232.  
  233. def test_connection(self) -> bool:
  234. """Test if module is responding"""
  235. logger.info("Testing SIM900A connection...")
  236. success, _ = self.send_at_command("AT")
  237. if success:
  238. logger.info("SIM900A is responding")
  239. return True
  240. else:
  241. logger.error("SIM900A not responding")
  242. return False
  243.  
  244. def initialize_module(self) -> bool:
  245. """Initialize and configure the SIM900A module"""
  246. logger.info("Initializing SIM900A module...")
  247.  
  248. if not self.test_connection():
  249. return False
  250.  
  251. # Disable echo
  252. self.send_at_command("ATE0")
  253.  
  254. # Check SIM card
  255. success, _ = self.send_at_command("AT+CPIN?", timeout=10)
  256. if not success:
  257. logger.error("SIM card not detected or PIN required")
  258. return False
  259.  
  260. # Wait for network registration
  261. max_attempts = 12
  262. for attempt in range(max_attempts):
  263. success, response = self.send_at_command("AT+CREG?", timeout=15)
  264. if success and ("+CREG: 0,1" in response or "+CREG: 0,5" in response):
  265. logger.info("Network registered successfully")
  266. self.initialized = True
  267. return True
  268. logger.info(f"Waiting for network registration... ({attempt + 1}/{max_attempts})")
  269. time.sleep(5)
  270.  
  271. logger.error("Failed to register to network")
  272. return False
  273.  
  274. def send_sms(self, phone_number: str, message: str) -> bool:
  275. """Send SMS to specified number"""
  276. if not self.initialized:
  277. logger.error("SIM900A not initialized")
  278. return False
  279.  
  280. logger.info(f"Sending SMS to {phone_number}")
  281.  
  282. # Set SMS text mode
  283. success, _ = self.send_at_command("AT+CMGF=1")
  284. if not success:
  285. return False
  286.  
  287. # Set recipient
  288. success, response = self.send_at_command(f'AT+CMGS="{phone_number}"', expected_response=">", timeout=10)
  289. if not success:
  290. return False
  291.  
  292. # Send message content
  293. try:
  294. self.serial.write(f"{message}\x1A".encode())
  295.  
  296. start_time = time.time()
  297. response = ""
  298.  
  299. while (time.time() - start_time) < 30:
  300. if self.serial.in_waiting() > 0:
  301. new_data = self.serial.read(self.serial.in_waiting())
  302. response += new_data.decode('utf-8', errors='ignore')
  303.  
  304. if "OK" in response or "+CMGS:" in response:
  305. logger.info(f"SMS sent successfully to {phone_number}")
  306. return True
  307. elif "ERROR" in response:
  308. logger.error(f"SMS sending failed: {response}")
  309. return False
  310.  
  311. time.sleep(0.5)
  312.  
  313. logger.error("SMS sending timeout")
  314. return False
  315.  
  316. except Exception as e:
  317. logger.error(f"SMS sending error: {e}")
  318. return False
  319.  
  320. def make_call(self, phone_number: str, duration: int = 3) -> bool:
  321. """Make a miss call to specified number"""
  322. if not self.initialized:
  323. logger.error("SIM900A not initialized")
  324. return False
  325.  
  326. logger.info(f"Making call to {phone_number}")
  327.  
  328. # Initiate call
  329. success, response = self.send_at_command(f"ATD{phone_number};", expected_response="OK", timeout=15)
  330. if not success:
  331. logger.error(f"Failed to initiate call to {phone_number}")
  332. return False
  333.  
  334. logger.info(f"Call initiated, waiting {duration} seconds...")
  335. time.sleep(duration)
  336.  
  337. # Hang up call
  338. success, _ = self.send_at_command("ATH", timeout=10)
  339. if success:
  340. logger.info(f"Miss call completed to {phone_number}")
  341. return True
  342. else:
  343. logger.error("Failed to hang up call")
  344. return False
  345.  
  346. # --- GPS FUNCTIONS ---
  347. def convert_to_decimal(degree_min, direction):
  348. """Convert NMEA coordinate format to decimal degrees"""
  349. if not degree_min:
  350. return 0.0
  351. degrees = int(float(degree_min) / 100)
  352. minutes = float(degree_min) - degrees * 100
  353. decimal = degrees + minutes / 60
  354. return -decimal if direction in ['S', 'W'] else decimal
  355.  
  356. def parse_gps_data(line):
  357. """Parse NMEA sentences and extract relevant data"""
  358. if line.startswith('$GNRMC') or line.startswith('$GPRMC'):
  359. parts = line.split(',')
  360. if len(parts) >= 10 and parts[2] == 'A':
  361. return {
  362. 'time': parts[1][:2] + ":" + parts[1][2:4] + ":" + parts[1][4:6],
  363. 'lat': convert_to_decimal(parts[3], parts[4]),
  364. 'lon': convert_to_decimal(parts[5], parts[6]),
  365. 'speed': float(parts[7]) if parts[7] else 0.0,
  366. 'course': float(parts[8]) if parts[8] else 0.0,
  367. 'date': parts[9][:2] + "/" + parts[9][2:4] + "/20" + parts[9][4:6],
  368. 'valid': True
  369. }
  370. return None
  371.  
  372. def get_gps_location(max_attempts=10, attempt_delay=1):
  373. """Get GPS location with multiple attempts"""
  374. location_info = "Location not available"
  375. google_maps_link = "Location not available"
  376.  
  377. # Try GPS on hardware UART (GPIO 14, 15)
  378. possible_ports = ['/dev/serial0', '/dev/ttyS0', '/dev/ttyAMA0']
  379.  
  380. for port in possible_ports:
  381. try:
  382. with gps_lock:
  383. print(f"šŸ” Trying GPS on {port}...")
  384. with serial.Serial(port, 115200, timeout=1) as ser:
  385. print(f"šŸ“” GPS connected on {port}, waiting for fix...")
  386.  
  387. attempts = 0
  388. while attempts < max_attempts:
  389. try:
  390. line = ser.readline().decode('ascii', errors='ignore').strip()
  391. if not line:
  392. continue
  393.  
  394. data = parse_gps_data(line)
  395. if data and 'valid' in data:
  396. location_info = (
  397. f"Coordinates: {data['lat']:.6f}°N, {data['lon']:.6f}°E\n"
  398. f"Time: {data['time']} UTC | Date: {data['date']}\n"
  399. f"Speed: {data['speed']:.1f} knots | Course: {data['course']:.1f}°"
  400. )
  401. google_maps_link = f"https://www.google.com/maps?q={data['lat']},{data['lon']}"
  402. print("šŸ“ GPS location acquired!")
  403. return location_info, google_maps_link
  404.  
  405. except Exception as e:
  406. print(f"⚠ GPS read error: {str(e)}")
  407.  
  408. attempts += 1
  409. print(f"šŸ”„ GPS attempt {attempts}/{max_attempts}")
  410. time.sleep(attempt_delay)
  411.  
  412. except serial.SerialException as e:
  413. print(f"āŒ Could not open {port}: {str(e)}")
  414. continue
  415.  
  416. # Fallback to IP location
  417. try:
  418. ip = get_ip_address()
  419. if ip != "IP not available":
  420. location_info = f"IP Address: {ip}\nApproximate location based on network"
  421. google_maps_link = f"https://www.google.com/maps/search/?api=1&query={ip}"
  422. print("🌐 Using IP-based location fallback")
  423. except Exception as e:
  424. print(f"⚠ IP location error: {str(e)}")
  425.  
  426. return location_info, google_maps_link
  427.  
  428. def get_ip_address():
  429. """Get the device's IP address"""
  430. try:
  431. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  432. s.connect(("8.8.8.8", 80))
  433. ip = s.getsockname()[0]
  434. s.close()
  435. return ip
  436. except:
  437. return "IP not available"
  438.  
  439. # --- EMERGENCY ALERT FUNCTIONS ---
  440. def send_emergency_email(location_info, google_maps_link):
  441. """Send emergency email"""
  442. try:
  443. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  444. ip_address = get_ip_address()
  445.  
  446. body = body_template.format(
  447. location_info=location_info,
  448. timestamp=timestamp,
  449. ip_address=ip_address,
  450. google_maps_link=google_maps_link
  451. )
  452.  
  453. msg = MIMEMultipart()
  454. msg['From'] = sender_email
  455. msg['To'] = receiver_email
  456. msg['Subject'] = subject
  457. msg.attach(MIMEText(body, 'plain'))
  458.  
  459. server = smtplib.SMTP('smtp.gmail.com', 587)
  460. server.starttls()
  461. server.login(sender_email, app_password)
  462. server.send_message(msg)
  463. server.quit()
  464.  
  465. print("šŸ“§ SOS email sent successfully!")
  466. return True
  467.  
  468. except Exception as e:
  469. print(f"šŸ“§ Email error: {str(e)}")
  470. return False
  471.  
  472. def send_emergency_sms(gsm_module, location_info, google_maps_link):
  473. """Send emergency SMS to all contacts"""
  474. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  475. sms_message = f"🚨 EMERGENCY ALERT! 🚨\n\nI need immediate assistance!\n\nšŸ“ Location:\n{location_info}\n\nšŸ•’ Time: {timestamp}\nšŸ“Œ Maps: {google_maps_link}\n\nPlease send help!"
  476.  
  477. print("šŸ“± Sending emergency SMS to all contacts...")
  478. success_count = 0
  479.  
  480. for i, contact in enumerate(EMERGENCY_CONTACTS, 1):
  481. print(f"Sending SMS {i}/{len(EMERGENCY_CONTACTS)} to {contact}")
  482. if gsm_module.send_sms(contact, sms_message):
  483. print(f"āœ“ SMS sent to {contact}")
  484. success_count += 1
  485. else:
  486. print(f"āœ— Failed to send SMS to {contact}")
  487.  
  488. # Small delay between SMS
  489. if i < len(EMERGENCY_CONTACTS):
  490. time.sleep(2)
  491.  
  492. print(f"šŸ“± SMS sending completed: {success_count}/{len(EMERGENCY_CONTACTS)} successful")
  493. return success_count > 0
  494.  
  495. def make_emergency_calls(gsm_module):
  496. """Make miss calls to all emergency contacts"""
  497. print("šŸ“ž Making emergency miss calls...")
  498. success_count = 0
  499. call_duration = 3 # seconds
  500. call_delay = 8 # seconds between calls
  501.  
  502. for i, contact in enumerate(EMERGENCY_CONTACTS, 1):
  503. print(f"Making call {i}/{len(EMERGENCY_CONTACTS)} to {contact}")
  504. if gsm_module.make_call(contact, call_duration):
  505. print(f"āœ“ Miss call completed to {contact}")
  506. success_count += 1
  507. else:
  508. print(f"āœ— Failed to call {contact}")
  509.  
  510. # Delay between calls (except after last call)
  511. if i < len(EMERGENCY_CONTACTS):
  512. print(f"Waiting {call_delay} seconds before next call...")
  513. time.sleep(call_delay)
  514.  
  515. print(f"šŸ“ž Emergency calls completed: {success_count}/{len(EMERGENCY_CONTACTS)} successful")
  516. return success_count > 0
  517.  
  518. def send_images_with_location(location_info, google_maps_link):
  519. """Continuously send images with location to Telegram"""
  520. while True:
  521. try:
  522. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  523. image_file = f"/home/pi/image_{timestamp.replace(':', '-')}.jpg"
  524.  
  525. # Capture image
  526. subprocess.run([
  527. "libcamera-still",
  528. "-o", image_file,
  529. "--width", "640",
  530. "--height", "480",
  531. "-n",
  532. "--timeout", "1000"
  533. ], check=True)
  534.  
  535. # Prepare message
  536. caption = f"""🚨 EMERGENCY ALERT! 🚨
  537.  
  538. šŸ“ Location Information:
  539. {location_info}
  540.  
  541. šŸ•’ Time: {timestamp}
  542. šŸ“Œ Google Maps: {google_maps_link}
  543.  
  544. ⚠ Please send help immediately!"""
  545.  
  546. # Send to Telegram
  547. url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendPhoto"
  548. with open(image_file, 'rb') as img:
  549. files = {'photo': img}
  550. data = {'chat_id': CHAT_ID, 'caption': caption}
  551. response = requests.post(url, files=files, data=data)
  552. print(f"šŸ“¤ Telegram image sent (Status: {response.status_code})")
  553.  
  554. except subprocess.CalledProcessError as e:
  555. print(f"šŸ“· Camera error: {str(e)}")
  556. except Exception as e:
  557. print(f"šŸ“± Telegram error: {str(e)}")
  558.  
  559. time.sleep(5)
  560.  
  561. # --- MAIN FUNCTION ---
  562. def main():
  563. print("🚨 SOS Emergency Alert System Starting...")
  564. print("šŸ“Ÿ Initializing GSM module...")
  565.  
  566. # Initialize SIM900A module
  567. gsm = SIM900A(tx_pin=13, rx_pin=19)
  568. gsm_available = False
  569.  
  570. if gsm.connect():
  571. if gsm.initialize_module():
  572. gsm_available = True
  573. print("āœ… SIM900A module ready!")
  574. else:
  575. print("⚠ SIM900A failed to initialize - SMS/Calls disabled")
  576. else:
  577. print("⚠ SIM900A not connected - SMS/Calls disabled")
  578.  
  579. print("šŸ“Ÿ System armed. Waiting for SOS button press...")
  580.  
  581. try:
  582. while True:
  583. if GPIO.input(button_pin) == GPIO.LOW:
  584. print("\n🚨 SOS TRIGGERED! EMERGENCY PROTOCOL ACTIVATED!")
  585.  
  586. # Activate buzzer immediately
  587. GPIO.output(buzzer_pin, GPIO.HIGH)
  588.  
  589. # Get location information
  590. print("šŸ›° Getting GPS location...")
  591. location_info, google_maps_link = get_gps_location(max_attempts=10, attempt_delay=1)
  592.  
  593. # Send emergency email
  594. print("šŸ“§ Sending emergency email...")
  595. Thread(target=send_emergency_email, args=(location_info, google_maps_link), daemon=True).start()
  596.  
  597. # Send initial Telegram message
  598. print("šŸ“± Sending initial Telegram alert...")
  599. try:
  600. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  601. initial_message = f"""🚨 EMERGENCY ALERT! 🚨
  602.  
  603. šŸ“ Location Information:
  604. {location_info}
  605.  
  606. šŸ•’ Time: {timestamp}
  607. šŸ“Œ Google Maps: {google_maps_link}
  608.  
  609. ⚠ Emergency button pressed! All alert systems activated!"""
  610.  
  611. url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
  612. data = {'chat_id': CHAT_ID, 'text': initial_message}
  613. response = requests.post(url, data=data)
  614. print(f"šŸ“¤ Initial Telegram message sent (Status: {response.status_code})")
  615. except Exception as e:
  616. print(f"šŸ“± Initial Telegram message failed: {str(e)}")
  617.  
  618. # Start image streaming to Telegram
  619. print("šŸ“ø Starting continuous image updates...")
  620. Thread(target=send_images_with_location, args=(location_info, google_maps_link), daemon=True).start()
  621.  
  622. # Send SMS alerts if GSM available
  623. if gsm_available:
  624. print("šŸ“± Sending emergency SMS alerts...")
  625. Thread(target=send_emergency_sms, args=(gsm, location_info, google_maps_link), daemon=True).start()
  626.  
  627. # Wait a bit before making calls to avoid interference
  628. time.sleep(5)
  629.  
  630. print("šŸ“ž Making emergency calls...")
  631. Thread(target=make_emergency_calls, args=(gsm,), daemon=True).start()
  632. else:
  633. print("⚠ GSM module not available - Skipping SMS and calls")
  634.  
  635. print("🚨 ALL EMERGENCY SYSTEMS ACTIVATED!")
  636. print("šŸ’” System will continue sending updates until manually stopped...")
  637.  
  638. # Keep system active
  639. while True:
  640. time.sleep(1)
  641.  
  642. time.sleep(0.1)
  643.  
  644. except KeyboardInterrupt:
  645. print("\nšŸ›‘ Emergency system interrupted by user.")
  646.  
  647. finally:
  648. print("šŸ”„ Shutting down emergency system...")
  649. GPIO.output(buzzer_pin, GPIO.LOW)
  650. if gsm_available:
  651. gsm.disconnect()
  652. GPIO.cleanup()
  653. print("šŸ”“ Emergency system shut down safely.")
  654.  
  655. if __name__ == '__main__':
  656. main()
Advertisement
Add Comment
Please, Sign In to add comment