Esempio n. 1
0
        public static async Task Main(string[] args)
        {
            Logo();

            try
            {
                // TODO PrepareLogger();

                // If this returns true, args were sent to an already-running instance, we can exit.
                if (await CommandLineSwitchPipe.TrySendArgs(args))
                {
                    return;
                }

                // Read appsettings.json and do some basic checks like path validity
                ValidateConfiguration();

                // Set up a pipe to receive switches once we're running
                ctsSwitchPipe = new CancellationTokenSource();
                _             = Task.Run(() => CommandLineSwitchPipe.StartServer(ProcessSwitches, ctsSwitchPipe.Token));

                // The localpath should be clear of files at startup
                FileProcessing.MoveSnapshotsToStorage();
                FileProcessing.MoveAbandonedVideoToStorage(); // TODO remove zero-length circular buffer h264, don't move it
                FileProcessing.ClearLocalStorage();

                // The default state, although some command-line switches may change this
                RequestedState = new MotionDetectionState();

                // If command-line args were passed to this instance, process them now
                if (args.Length > 0)
                {
                    ProcessSwitches(args, false);

                    if (RequestedState == null)
                    {
                        Console.WriteLine("No new execution state requested, exiting.");
                        return;
                    }
                }

                // If a command-line switch arrives in the SwitchPipe thread, it can
                // cancel the state-change token to end the current processing state
                // and request a different processing state. We loop until no new state
                // is requested, at which point the app exits.
                while (RequestedState != null)
                {
                    RunningState    = RequestedState;
                    RequestedState  = null;
                    ctsRunningState = new CancellationTokenSource();
                    await RunningState.RunAsync(ctsRunningState.Token).ConfigureAwait(false);

                    RunningState.Dispose();
                    RunningState = null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"\nException of type {ex.GetType().Name}\n{ex.Message}");
                if (ex.InnerException != null)
                {
                    Console.Write(ex.InnerException.Message);
                }
                Console.WriteLine($"\n{ex.StackTrace}");
            }
            finally
            {
                // Stephen Cleary says CTS disposal is unnecessary as long as you cancel
                ctsSwitchPipe?.Cancel();
                ctsRunningState?.Cancel();
                RequestedState?.Dispose();
                RunningState?.Dispose();
            }

            Console.WriteLine("Exiting spicam.");
        }
Esempio n. 2
0
        private static void ProcessSwitches(string[] args, bool argsReceivedFromPipe)
        {
            if (args.Length == 0)
            {
                return;
            }

            bool showHelp = true;
            var  command  = args[0].Trim().ToLower();

            switch (command)
            {
            case "-quit":
            case "-exit":
            case "-stop":
            {
                showHelp = false;

                if (!argsReceivedFromPipe)
                {
                    throw new Exception("Nothing to stop, no running instance of spicam found.");
                }

                // Cancel the current processing state. Setting RequestedState
                // to null will cause the application to exit.
                RequestedState = null;
                ctsRunningState.Cancel();
            }
            break;

            case "-quiet":
            {
                showHelp = false;

                if (args.Length != 2 || !int.TryParse(args[1], out var minutes))
                {
                    Console.WriteLine("The -quiet switch requires a 'minutes' parameter.");
                    return;
                }

                // Ensure the target of this switch is doing motion detection (or will be)
                var target = (argsReceivedFromPipe)
                            ? RunningState as MotionDetectionState
                            : RequestedState as MotionDetectionState;

                if (target == null)
                {
                    Console.WriteLine("The -quiet switch only applies to motion detection.");
                    return;
                }

                Console.WriteLine($"Motion detection suppressed for {minutes} minutes.");
                target.SetQuietTime(minutes);
            }
            break;

            case "-snapshot":
            {
                Console.WriteLine($"\n\n{command} switch not implemented yet...\n\n");
                showHelp = false;
            }
            break;

            case "-video":
            {
                Console.WriteLine($"\n\n{command} switch not implemented yet...\n\n");
                showHelp = false;

                if (args.Length != 2)
                {
                    Console.WriteLine("The -video switch requires a 'seconds' parameter.");
                    return;
                }
            }
            break;

            case "-stream":
            {
                Console.WriteLine($"\n\n{command} switch not implemented yet...\n\n");
                showHelp = false;

                if (args.Length != 2)
                {
                    Console.WriteLine("The -stream switch requires an 'on' or 'off' parameter.");
                    return;
                }
            }
            break;

            case "-analysis":
            {
                Console.WriteLine($"\n\n{command} switch not implemented yet...\n\n");
                showHelp = false;

                if (args.Length != 2)
                {
                    Console.WriteLine("The -analysis switch requires an 'on' or 'off' parameter.");
                    return;
                }
            }
            break;

            case "-getmask":
            {
                Console.WriteLine($"\n\n{command} switch not implemented yet...\n\n");
                showHelp = false;

                if (args.Length != 2)
                {
                    Console.WriteLine("The -getmask switch requires a 'directory' parameter.");
                    return;
                }
            }
            break;

            case "-?":
            case "-help":
                break;

            default:
                Console.WriteLine($"\nUnrecognized switch {command}, cancelling requested state");
                RequestedState = null;
                break;
            }

            if (showHelp)
            {
                Console.WriteLine("\nspicam command-line switches:\n");
                Console.WriteLine("-?                      help (this list)");
                Console.WriteLine("-stop                   terminates an already-running instance of spicam");
                Console.WriteLine("-quiet [minutes]        disables motion detection for the specified time");
                Console.WriteLine("-snapshot               write a full-sized timestamped snapshot JPG to the storagepath");
                Console.WriteLine("-video [seconds]        write full-sized timestamped MP4 video(s) to the storagepath");
                Console.WriteLine("-stream [on | off]      MJPEG stream of the camera's view");
                Console.WriteLine("-analysis [on | off]    MJPEG stream of the spicam motion detection algorithm");
                Console.WriteLine("-getmask [directory]    write a 640 x 480 x 24bpp snapshot.bmp to the directory");
                Console.WriteLine("\nSwitches may not be combined. The -quiet, -snapshot, and -video switches are only accepted");
                Console.WriteLine("when spicam is already running in normal motion detection mode. The -stream and -analysis");
                Console.WriteLine("switches are intended for short-term use. The -stream, -analysis, and -getmask switches will");
                Console.WriteLine("interrupt motion detection, if running. Set streaming to 'off' to resume motion detection.");
                Console.WriteLine();
            }
        }