def main(args=None): global logwriter, csvfile, ml_dict, applog, cur_state, dimcap, video_dev global settings, hmqtt, show_windows, read_cam, read_local_resize, remote_cam global camera_spin, camera_capture_to_file global cap_prefix, backup_ml, have_cuda, use_three_arg # process cmdline arguments ap = argparse.ArgumentParser() loglevels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') ap.add_argument("-c", "--conf", required=True, type=str, help="path and name of the json configuration file") ap.add_argument("-d", "--debug", action='store', type=bool, default=False, nargs='?', help="show rectangles - no remote ml") ap.add_argument("-s", "--syslog", action = 'store_true', default=False, help="use syslog") ap.add_argument("-a", "--algorithm", required=False, type=str, default=None, help="detection algorithm override") ap.add_argument("-m", "--movement", required=False, type=str, help="movement algorithm override") ap.add_argument("-e", "--events", required=False, action = "store_true", default=False, help="log events to events.csv file") ap.add_argument("-r", "--remote", required=False, action = "store_true", default=False, help="log events to file") ap.add_argument("-p", "--port", action='store', type=int, default='4466', nargs='?', help="server port number, 4466 is default") ap.add_argument('-l', '--log', default='DEBUG', choices=loglevels) #ap.add_argument("-f", "--capture", required=False, type=str, # help="path and name for image captures") ap.add_argument('-3', "--three_arg", action = 'store_true', default=False, help="findContours has 3 return values") args = vars(ap.parse_args()) # frame capture setup #if args['capture']: # cap_prefix = args['capture'] #else: # cap_prefix = None # logging setup applog = logging.getLogger('mqttcamera') #applog.setLevel(args['log']) if args['syslog']: applog.setLevel(logging.DEBUG) handler = logging.handlers.SysLogHandler(address = '/dev/log') # formatter for syslog (no date/time or appname. Just msg, lux, luxavg formatter = logging.Formatter('%(name)s-%(levelname)-5s: %(message)-30s %(lux)s %(sum)s') handler.setFormatter(formatter) f = LuxLogFilter() applog.addFilter(f) applog.addHandler(handler) else: logging.basicConfig(level=logging.DEBUG,datefmt="%H:%M:%S",format='%(asctime)s %(message)-40s %(lux)s %(sum)s') f = LuxLogFilter() applog.addFilter(f) show_windows = False; # state_machine log file logwriter = None csvfile = None if args['events']: csvfile = open('events.csv', 'w', newline='') logwriter = csv.writer(csvfile, delimiter=',', quotechar='|') print("logging...") # Lets spin it up. settings = Settings(args["conf"], "/var/local/etc/mqtt-camera.json", applog, next_state) # cmd line args override settings file. if args['algorithm']: settings.ml_algo = args['algorithm'] applog.debug("cmd line algo override: %s", settings.ml_algo) if args['movement']: settings.mv_algo = args['movement'] applog.debug("cmd line movement override: %s", settings.mv_algo) if args['remote']: settings.use_ml = 'remote' ''' if args['port']: print('override port') settings.ml_port = args['port'] ''' if args['debug']: show_windows = True settings.use_ml = 'local' if args['three_arg']: # yet another damn global for a bug use_three_arg = True hmqtt = Homie_MQTT(settings, settings.get_active_hold, settings.set_active_hold) settings.display() settings.log = applog if logwriter: logwriter.writerow([settings.settings_serialize]) # setup ml_dict. Dealing with the backup is a bit hackish. # Rpc proxy's are setup the first time they are needed. have_cuda = is_cuda_cv() applog.info(f"Have CUDA: {check_cuda()}") if settings.use_ml == 'local': applog.info(f"Will use CUDA: {have_cuda}") ml_dict = build_ml_dict(False, None, None, applog) cur_state = State.motion_wait dimcap = (settings.camera_width, settings.camera_height) # Almost Done with setup. Maybe. if settings.camera_type == 'capture': video_dev = cv2.VideoCapture(settings.camera_number) read_cam = capture_read_cam read_local_resize = capture_read_local_resize remote_cam = capture_remote_cam camera_spin = capture_camera_spin camera_capture_to_file = capture_camera_capture_to_file elif settings.camera_type == 'nvidia-rtsp': video_dev = nvidia_cam_rtsp(settings.camera_number, settings.camera_width, settings.camera_height, 0) read_cam = stream_read_cam read_local_resize = stream_read_local_resize remote_cam = stream_remote_cam camera_spin = stream_camera_spin camera_capture_to_file = stream_camera_capture_to_file elif settings.camera_type == 'ffmpeg-rtsp': os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transpo rt;udp" video_dev = cv2.VideoCapture(settings.camera_number,cv2.CAP_FFMPEG) read_cam = stream_read_cam read_local_resize = stream_read_local_resize remote_cam = stream_remote_cam camera_spin = stream_camera_spin camera_capture_to_file = stream_camera_capture_to_file elif settings.camera_type == 'gst': video_dev = cv2.VideoCapture(settings.camera_prep,cv2.CAP_GSTREAMER) read_cam = stream_read_cam read_local_resize = stream_read_local_resize remote_cam = stream_remote_cam camera_spin = stream_camera_spin camera_capture_to_file = stream_camera_capture_to_file elif settings.camera_type == 'stream': video_dev = VideoStream(src=settings.camera_number, resolution = dimcap).start() read_cam = imstream_read_cam read_local_resize = imstream_read_local_resize remote_cam = imstream_remote_cam camera_spin = imstream_camera_spin camera_capture_to_file = imstream_camera_capture_to_file else: log('bad camera_type in settings file') exit() # a cross coupling hack? hmqtt.capture = camera_capture_to_file init_timers(settings) atexit.register(cleanup) # now we pick between movement detectors and start the choosen one if settings.mv_algo == 'adrian_1': while True: adrian_1_init() while True: adrian_1_movement(show_windows) if cur_state == State.restart: #log("restarting adrian_1 loop") break if show_windows and cv2.waitKey(40) == 27: break elif settings.mv_algo == 'intel': while True: intel_init() while True: intel_movement(show_windows, read_local_resize) if cur_state == State.restart: log("restarting intel loop") breakl else: print("No Movement Algorithm chosen") cleanup()