def early_message_to_client (self): xml = XML_Object () CLIENT_COUNT = xml.get_client_count () i = 0 while (i < CLIENT_COUNT): CLIENT_LISTNER_UDP_IP = xml.get_client_ip (i) CLIENT_LISTNER_UDP_PORT = xml.get_client_port (i) CLIENT_ADDR = (CLIENT_LISTNER_UDP_IP, CLIENT_LISTNER_UDP_PORT) udp_send_sock.sendto ('LISTEN_TO_STREAM', CLIENT_ADDR) del xml
def __init__(self): xml = XML_Object () self.__is_cam_started = False self.__mjpeg_streamer_root_path = xml.get_mjpg_streamer_path () self.__mjpg_streamer_path = xml.get_mjpg_streamer_path () # Returns numerical port number self.__CAM_SERVER_PORT = str (xml.get_cam_server_port ()) Popen ('export LD_LIBRARY_PATH=' + self.__mjpeg_streamer_root_path, shell=True, stdout=PIPE) del xml
def stream_video_to_display(self, fps=5): if self.__omxplayer_running: log.print_high("pitft: stream_video_to_display: Omxplayer already running") return log.print_high("pitft: stream_video_to_display: Entered") xml = XML_Object() tcp_ip = xml.get_remote_cam_server_ip() tcp_port = xml.get_remote_cam_server_port() timeout = 10 log.print_high("Starting omxplayer") Popen( "/usr/bin/omxplayer --live --no-keys --fps 10 http://" + str(tcp_ip) + ":" + str(tcp_port) + "/?action=stream", shell=True, stdout=PIPE, ) print "/usr/bin/omxplayer --live --no-keys --fps 10 http://" + str(tcp_ip) + ":" + str( tcp_port ) + "/?action=stream" sleep(0.1) # Check if the process is running. If not, restart the process while ((is_process_running("omxplayer.bin") == False) and (is_process_running("omxplayer") == False)) and ( timeout > 0 ): Popen( "/usr/bin/omxplayer --live --no-keys --fps 10 http://" + str(tcp_ip) + ":" + str(tcp_port) + "/?action=stream", shell=True, stdout=PIPE, ) timeout = timeout - 1 log.print_high("Starting omxplayer. Number retries left: " + str(timeout)) sleep(0.5) if is_process_running("omxplayer.bin") or is_process_running("omxplayer"): self.__omxplayer_running = True log.print_high("pitft: stream_video_to_display: Exit")
def __init__(self): self.__xml = XML_Object () # self.__JOB_SCHED_IP = self.__xml.get_job_scheduler_ip () # self.__JOB_SCHED_PORT = self.__xml.get_job_scheduler_port () # self.__JOB_SCHED_RECV_ADDR = (self.__JOB_SCHED_IP, self.__JOB_SCHED_PORT) #-------------------------------------------------------------------------# #----------------------------- SCHEDULER INIT ----------------------------# #-------------------------------------------------------------------------# self.__sched = BackgroundScheduler() self.__sched.start() # start the scheduler log.print_high ('Scheduler started') #-------------------------------------------------------------------------# #----------------------------- INSTAPUSH INIT ----------------------------# #-------------------------------------------------------------------------# self.__INSTAPUSH_NOTIF_IP = self.__xml.get_instapush_notif_ip () self.__INSTAPUSH_NOTIF_PORT = self.__xml.get_instapush_notif_port () self.__INSTAPUSH_NOTIF_ADDR = (self.__INSTAPUSH_NOTIF_IP, self.__INSTAPUSH_NOTIF_PORT) self.__udp_send_sock = socket(AF_INET, SOCK_DGRAM) self.__min_gap_between_two_instapush_notif = self.__xml.min_gap_between_two_instapush_notif () # Record the timestamp when the last instapush notification was sent self.__last_instapush_notif_sent_at = datetime.datetime.now () self.__is_stream_job_running = False self.__outside_PIR_interrupt_count = 0 self.__instapush_notif_timeout_job = self.__sched.add_job(self.send_instapush_notif, 'interval', seconds = 5, args=['Dummy message']) self.__instapush_notif_timeout_job.remove () #-------------------------------------------------------------------------# #--------------------------- PITFT SCREEN INIT ---------------------------# #-------------------------------------------------------------------------# # Create TFT display object self.__pitft = PiTFT_Screen () log.print_high ('Created TFT display object') # Start Framebuffer copy daemon self.__pitft.start_fbcp_process() self.__cam = Cam_Object () log.print_high ('Created camera object') # Create a dummy job and cancel it self.__stream_job = self.__sched.add_job(self.stop_streaming_cb, 'interval', seconds = 5) self.__stream_job.remove () log.print_high ('Scheduler init done') #-------------------------------------------------------------------------# #---------------------------- INTERRUPTS INIT ----------------------------# #-------------------------------------------------------------------------# self.__last_inside_pir_interrupt_triggered_at = datetime.datetime.now () self.__last_outside_pir_interrupt_triggered_at = datetime.datetime.now () self.__last_door_switch_interrupt_triggered_at = datetime.datetime.now ()
class Sched_Obj: #=========================================================================# #-------------------------------- INIT -----------------------------------# #=========================================================================# def __init__(self): self.__xml = XML_Object () # self.__JOB_SCHED_IP = self.__xml.get_job_scheduler_ip () # self.__JOB_SCHED_PORT = self.__xml.get_job_scheduler_port () # self.__JOB_SCHED_RECV_ADDR = (self.__JOB_SCHED_IP, self.__JOB_SCHED_PORT) #-------------------------------------------------------------------------# #----------------------------- SCHEDULER INIT ----------------------------# #-------------------------------------------------------------------------# self.__sched = BackgroundScheduler() self.__sched.start() # start the scheduler log.print_high ('Scheduler started') #-------------------------------------------------------------------------# #----------------------------- INSTAPUSH INIT ----------------------------# #-------------------------------------------------------------------------# self.__INSTAPUSH_NOTIF_IP = self.__xml.get_instapush_notif_ip () self.__INSTAPUSH_NOTIF_PORT = self.__xml.get_instapush_notif_port () self.__INSTAPUSH_NOTIF_ADDR = (self.__INSTAPUSH_NOTIF_IP, self.__INSTAPUSH_NOTIF_PORT) self.__udp_send_sock = socket(AF_INET, SOCK_DGRAM) self.__min_gap_between_two_instapush_notif = self.__xml.min_gap_between_two_instapush_notif () # Record the timestamp when the last instapush notification was sent self.__last_instapush_notif_sent_at = datetime.datetime.now () self.__is_stream_job_running = False self.__outside_PIR_interrupt_count = 0 self.__instapush_notif_timeout_job = self.__sched.add_job(self.send_instapush_notif, 'interval', seconds = 5, args=['Dummy message']) self.__instapush_notif_timeout_job.remove () #-------------------------------------------------------------------------# #--------------------------- PITFT SCREEN INIT ---------------------------# #-------------------------------------------------------------------------# # Create TFT display object self.__pitft = PiTFT_Screen () log.print_high ('Created TFT display object') # Start Framebuffer copy daemon self.__pitft.start_fbcp_process() self.__cam = Cam_Object () log.print_high ('Created camera object') # Create a dummy job and cancel it self.__stream_job = self.__sched.add_job(self.stop_streaming_cb, 'interval', seconds = 5) self.__stream_job.remove () log.print_high ('Scheduler init done') #-------------------------------------------------------------------------# #---------------------------- INTERRUPTS INIT ----------------------------# #-------------------------------------------------------------------------# self.__last_inside_pir_interrupt_triggered_at = datetime.datetime.now () self.__last_outside_pir_interrupt_triggered_at = datetime.datetime.now () self.__last_door_switch_interrupt_triggered_at = datetime.datetime.now () #=========================================================================# #------------------------------ INIT END ---------------------------------# #=========================================================================# #-------------------------------------------------------------------------# #-------------------- INTERRUPT TRIGGERED FUNCTIONS ---------------------# #-------------------------------------------------------------------------# def update_inside_pir_interrupt_timestamp (self): self.__last_inside_pir_interrupt_triggered_at = datetime.datetime.now () def how_long_ago_was_last_inside_pir_interrupt_triggered (self): return get_elapsed_seconds_since (self.__last_inside_pir_interrupt_triggered_at) #-------------------------------------------------------------------------# def update_outside_pir_interrupt_timestamp (self): self.__last_outside_pir_interrupt_triggered_at = datetime.datetime.now () def how_long_ago_was_last_inside_pir_interrupt_triggered (self): return get_elapsed_seconds_since (self.__last_outside_pir_interrupt_triggered_at) #-------------------------------------------------------------------------# def update_door_switch_interrupt_timestamp (self): self.__last_door_switch_interrupt_triggered_at = datetime.datetime.now () def how_long_ago_was_last_inside_pir_interrupt_triggered (self): return get_elapsed_seconds_since (self.__last_door_switch_interrupt_triggered_at) #-------------------------------------------------------------------------# #---------------------- INSTAPUSH NOTIFICATION HANDLER -------------------# #-------------------------------------------------------------------------# def how_long_ago_was_last_instapush_notif_sent (self): return get_elapsed_seconds_since (self.__last_instapush_notif_sent_at) #-------------------------------------------------------------------------# # Send an instapush notification if we get more than # 2 interrupts (reconfigurable) during the timout (also reconfigurable) # To avoid flooding notifications, allow a minimum gap between two # notifications. Currently set to 5 minutes (reconfigurable) def send_instapush_notif (self, notif_message): # Remove the interval job self.__instapush_notif_timeout_job.remove () log.print_high ('send_instapush_notif triggered') # Check the interrupt count during the timeout. If greater than the # threshold, send a notification. # Also check when the last notification was sent. if ( (self.__outside_PIR_interrupt_count > self.__xml.get_instapush_notif_interrupt_count()) and (self.how_long_ago_was_last_instapush_notif_sent () > self.__min_gap_between_two_instapush_notif) ): log.print_high ('Will send a notif now') self.__udp_send_sock.sendto (notif_message, self.__INSTAPUSH_NOTIF_ADDR) self.__last_instapush_notif_sent_at = datetime.datetime.now () else: log.print_high ('No notif. Last notif sent ' + str (self.how_long_ago_was_last_instapush_notif_sent ()) + 's ago. Interrupt count = ' + str (self.__outside_PIR_interrupt_count)) # Reset the counter for the current cycle self.__outside_PIR_interrupt_count = 0 return #-------------------------------------------------------------------------# # Count the number of interrupts in 20 seconds (reconfigurable) to ensure a # person is standing outside the door def schedule_instapush_notif_timeout (self, instapush_notif_timeout = 20): instapush_notif_timeout = self.__xml.get_instapush_notif_timeout () self.__instapush_notif_timeout_job = self.__sched.add_job(self.send_instapush_notif, 'interval', seconds=instapush_notif_timeout, args=['Someone at the door']) log.print_high ('Scheduled instapush_notif_timeout for ' + str (instapush_notif_timeout) + 's') return #-------------------------------------------------------------------------# def check_if_door_opened_from_outside_and_send_notif (self): # Check if someone was recently inside the house, behind the door if (self.how_long_ago_was_last_inside_pir_interrupt_triggered () > xml.inside_home_presence_timeout()): # If no one was inside the house and door was opened, send a notification self.send_instapush_notif ('Door opened') #-------------------------------------------------------------------------# # Increment interrupt count and start a timer def increment_outside_PIR_interrupt_count (self): if (self.__outside_PIR_interrupt_count == 0): self.schedule_instapush_notif_timeout () self.__outside_PIR_interrupt_count = self.__outside_PIR_interrupt_count + 1 log.print_high ('# of interrupts = ' + str (self.__outside_PIR_interrupt_count)) return #-------------------------------------------------------------------------# #------------------------------ STREAM HANDLER ---------------------------# #-------------------------------------------------------------------------# # Implemented as a callback function def start_streaming_cb (self): if (not self.__is_stream_job_running): log.print_high ('Starting camera...') if (self.__cam.start_camera ('320x240', '5', 'night')): self.__pitft.Backlight (True) log.print_high ('scheduler: Starting stream_video_to_display...') self.__pitft.stream_video_to_display () else: log.print_high ('scheduler: Camera already on') self.__is_stream_job_running = True return #-------------------------------------------------------------------------# # Turns off camera streaming. # Turns off local display def stop_streaming_cb (self): # First cancel the interval job self.__stream_job.remove () log.print_high ('Stopping stream...') self.__pitft.stop_stream_video_to_display () log.print_high ('Stream stoppped. Turning backlight off...') self.__pitft.Backlight (False) log.print_high ('Backlight off. Stopping camera...') if (self.__cam.stop_camera ()): log.print_high ('scheduler: Camera off') self.__is_stream_job_running = False else: log.print_high ('scheduler: Could not turn off camera') log.print_high ('exiting inside_pir_triggered_callback') return #-------------------------------------------------------------------------# # Default schedule delay is 0 minutes def schedule_start_streaming (self, delay = 0): if (delay == 0): self.start_streaming_cb () return #-------------------------------------------------------------------------# # Default schedule delay is 4 minutes def schedule_stop_streaming (self, seconds_delay = 240): # Blindly cancel the job before scheduling it self.__stream_job.remove () self.__stream_job = self.__sched.add_job(self.stop_streaming_cb, 'interval', seconds = seconds_delay) #self.__stream_job = self.__sched.add_date_job(self.stop_streaming_cb, datetime.datetime.today () + datetime.timedelta (seconds = seconds_delay)) log.print_high ('Will turn off stream after ' + str (seconds_delay) + 's from now') return
from xml_handler import XML_Object from logger import log_handler from apscheduler.schedulers.background import BackgroundScheduler #=========================================================================# #-------------------------------- INIT -----------------------------------# #=========================================================================# log = log_handler (True) log.set_log_level (log.LOG_LEVEL_LOW) # This number is different for every client MY_CLIENT_NUMBER = 0 BUFSIZE = 128 xml = XML_Object () MY_IP = xml.get_client_ip (MY_CLIENT_NUMBER) MY_PORT = xml.get_client_port (MY_CLIENT_NUMBER) MY_LISTENING_ADDR = ('', MY_PORT) udp_send_sock = socket( AF_INET,SOCK_DGRAM) udp_recv_client = socket( AF_INET,SOCK_DGRAM) udp_recv_client.setsockopt (SOL_SOCKET, SO_REUSEADDR, 1) udp_recv_client.bind (MY_LISTENING_ADDR) DISPLAY_STREAM_LAUNCHER_IP = xml.get_display_stream_launcher_ip () DISPLAY_STREAM_LAUNCHER_PORT = xml.get_display_stream_launcher_port () DISPLAY_STREAM_LAUNCHER_ADDR = (DISPLAY_STREAM_LAUNCHER_IP, DISPLAY_STREAM_LAUNCHER_PORT) del xml # Wait for display stream launcher to start first
#!/usr/bin/python # main.py # Python script to co-ordinate the sensors and actions # ------------------------------------------------------------------------ from time import sleep from sensors import Sensors from xml_handler import XML_Object from logger import log_handler from job_scheduler import Sched_Obj #=========================================================================# #-------------------------------- INIT -----------------------------------# #=========================================================================# xml = XML_Object () INSIDE_PIR_STREAM_DURATION = xml.inside_pir_trigger_stream_duration () OUTSIDE_PIR_STREAM_DURATION = xml.outside_pir_trigger_stream_duration () DOOR_SWITCH_STREAM_DURATION = xml.door_switch_trigger_stream_duration () del xml # Set log level to LOW log = log_handler (True) log.set_log_level (log.LOG_LEVEL_LOW) scheduler_obj = Sched_Obj () #=========================================================================#
import time import pycurl, json from socket import * from StringIO import StringIO from xml_handler import XML_Object from logger import log_handler xml = XML_Object() HOST = xml.get_instapush_notif_ip() RX_PORT = xml.get_instapush_notif_port() RX_ADDR = (HOST, RX_PORT) BUFSIZE = 256 udp_recv_client = socket(AF_INET, SOCK_DGRAM) udp_recv_client.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) udp_recv_client.bind(RX_ADDR) log = log_handler(True) log.set_log_level(log.LOG_LEVEL_LOW) # setup InstaPush variables # add your Instapush Application ID appID = "55f90a63a4c48a3b1f997fea" # add your Instapush Application Secret appSecret = "31fecf9743e4adffda5ae016c05f05bf" pushEvent = "CamAlert" pushMessage = "Door Opened!" # use this to capture the response from our push API call
# video. # if the message is STOP_LISTENING_TO_STREAM, it kills all instances of # omxplayer and turns off the display. from socket import * from time import sleep from commands import getoutput from xml_handler import XML_Object from subprocess import Popen, PIPE from logger import log_handler log = log_handler (True) log.set_log_level (log.LOG_LEVEL_LOW) xml = XML_Object () DISPLAY_STREAM_LAUNCHER_ADDR = xml.get_display_stream_launcher_ip () DISPLAY_STREAM_LAUNCHER_PORT = xml.get_display_stream_launcher_port () REMOTE_TCP_IP_ADDR = xml.get_cam_server_ip () REMOTE_TCP_IP_PORT = xml.get_cam_server_port () # This number is different for every client MY_CLIENT_NUMBER = 0 DISPLAY_TYPE = xml.get_client_display_type (MY_CLIENT_NUMBER) del xml log = log_handler (True) log.set_log_level (log.LOG_LEVEL_LOW)