Пример #1
0
        private static void Main(string[] args)
        {
            #region Setup for Reactive ASCOM

            var connectionString     = Settings.Default.ConnectionString; // Edit in App.config, default is "COM1:"
            var channelFactory       = new ChannelFactory();
            var channel              = channelFactory.FromConnectionString(connectionString);
            var transactionObserver  = new TransactionObserver(channel);
            var transactionProcessor = new ReactiveTransactionProcessor();
            transactionProcessor.SubscribeTransactionObserver(transactionObserver);
            channel.Open();

            #endregion Setup for Reactive ASCOM

            #region Submit some transactions

            // Ready to go. We are going to use tasks to submit the transactions, just to demonstrate thread safety.
            var raTransaction = new TerminatedStringTransaction(":GR#", '#', ':')
            {
                Timeout = TimeSpan.FromSeconds(2)
            };
            // The terminator and initiator are optional parameters and default to values that work for Meade style protocols.
            var decTransaction = new TerminatedStringTransaction(":GD#")
            {
                Timeout = TimeSpan.FromSeconds(2)
            };
            Task.Run(() => transactionProcessor.CommitTransaction(raTransaction));
            Task.Run(() => transactionProcessor.CommitTransaction(decTransaction));

            #endregion Submit some transactions

            #region Wait for the results

            // NOTE we are using the transactions in the reverse order that we committed them, just to prove a point.
            Console.WriteLine("Waiting for declination");
            decTransaction.WaitForCompletionOrTimeout();
            Console.WriteLine("Declination: {0}", decTransaction.Response);
            Console.WriteLine("Waiting for Right Ascensions");
            raTransaction.WaitForCompletionOrTimeout();
            Console.WriteLine("Right Ascension: {0}", raTransaction.Response);

            #endregion Wait for the results

            #region Cleanup

            /*
             * To clean up, we just need to dispose the transaction processor. This terminates the
             * sequence of transactions, which causes the TransactionObserver's OnCompleted method
             * to be called, which unsubscribes the receive sequence, which closes the
             * communications channel
             */
            transactionProcessor.Dispose();

            #endregion Cleanup

            Console.WriteLine("Press ENTER:");
            Console.ReadLine();
        }
Пример #2
0
        static void Main(string[] args)
        {
            var log = LogManager.GetCurrentClassLogger();
            var connectionString = "COM3:9600";
            var factory          = new ChannelFactory();
            var channel          = factory.FromConnectionString(connectionString);

            var observer  = new TransactionObserver(channel);
            var processor = new ReactiveTransactionProcessor();

            processor.SubscribeTransactionObserver(observer);

            channel.Open();                                                                                              // normmaly done in drivers Connected property

            var transaction = new TerminatedStringTransaction("*OPEN_MIRROR_COVER\r", initiator: '*', terminator: '\r'); // ":GR#"

            log.Debug($"Created transaction: {transaction}");
            processor.CommitTransaction(transaction);
            transaction.WaitForCompletionOrTimeout();
            log.Debug($"Finished transaction: {transaction}");

            if (transaction.Successful && transaction.Response.Any())
            {
                var response = transaction.Response.Single();
                log.Info($"received response: {response}");
            }

            Console.WriteLine("Press enter..");
            Console.Read();
        }
Пример #3
0
        private string TalkWithAxis(AXISID axis, char cmd, string cmdDataStr)
        {
            string         response = string.Empty;
            DeviceEndpoint endPoint = SerialDeviceEndpoint.FromConnectionString(ConnectionString);

            const int     BufferSize = 20;
            StringBuilder sb         = new StringBuilder(BufferSize);

            sb.Append(cStartChar_Out);           // 0: Leading char
            sb.Append(cmd);                      // 1: Length of command( Source, distination, command char, data )

            // Target Device
            sb.Append(((int)axis + 1).ToString()); // 2: Target Axis
                                                   // Copy command data to buffer
            sb.Append(cmdDataStr);

            sb.Append(cEndChar); // CR Character

            string cmdString = sb.ToString();


            var cmdTransaction = new EQTransaction(cmdString)
            {
                Timeout = TimeSpan.FromSeconds(TimeOut)
            };


            using (ICommunicationChannel channel = new SerialCommunicationChannel(endPoint))
                using (var processor = new ReactiveTransactionProcessor())
                {
                    var transactionObserver = new TransactionObserver(channel);
                    processor.SubscribeTransactionObserver(transactionObserver);
                    try
                    {
                        channel.Open();

                        // prepare to communicate
                        for (int i = 0; i < Retry; i++)
                        {
                            Task.Run(() => processor.CommitTransaction(cmdTransaction));
                            cmdTransaction.WaitForCompletionOrTimeout();
                            if (!cmdTransaction.Failed)
                            {
                                response = cmdTransaction.Value;
                                break;
                            }
                            else
                            {
                                Trace.TraceError(cmdTransaction.ErrorMessage.Single());
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Connnection Lost");
                        throw new Exception("AstroEQ not responding", ex);
                    }
                    finally
                    {
                        // To clean up, we just need to dispose the TransactionObserver and the channel is closed automatically.
                        // Not strictly necessary, but good practice.
                        transactionObserver.OnCompleted(); // There will be no more transactions.
                        transactionObserver = null;        // not necessary, but good practice.
                        endPoint            = null;
                    }
                }
            return(response);
        }
Пример #4
0
        private static void Main(string[] args)
        {
            #region Setup for Reactive ASCOM

            /*
             * First create our channel factory.
             * This is also the place where we can inject a logging service.
             * If you don't provide a logging service here, there will be no logging!
             * Note that logging is configured in NLog.config.
             * See also: TA.Utils.Core.Diagnostics
             *
             * The channel factory knows about serial ports by default, but we are going to
             * register a custom channel implementation that contains a hardware simulator.
             * (the simulator is abstracted from the Digital Domeworks dome driver).
             * If you make your own custom channels, you can register them the same way.
             */
            var log = new LoggingService(); // TA.Utils.Logging.NLog
            log.Info()
            .Message("Program start. Version {gitversion}", GitVersion.GitInformationalVersion)
            .Property("CommitSha", GitVersion.GitCommitSha)
            .Property("CommitDate", GitVersion.GitCommitDate)
            .Write();

            var channelFactory = new ChannelFactory(log);
            channelFactory.RegisterChannelType(
                SimulatorEndpoint.IsConnectionStringValid,
                SimulatorEndpoint.FromConnectionString,
                endpoint => new SimulatorCommunicationsChannel((SimulatorEndpoint)endpoint, log));

            /*
             * Now get our connection string from the AppSettings.json file.
             */

            var connectionString = Configuration["ConnectionString"];

            /*
             * Create the communications channel and connect it to the transaction observer.
             * The TransactionObserver is the beating heart of Rx Comms and is where everything is synchronized.
             */
            var channel             = channelFactory.FromConnectionString(connectionString);
            var transactionObserver = new TransactionObserver(channel);

            /*
             * TransactionObsever is an IObservable<DeviceTransaction>, so we need a sequence for it to observe.
             * The transaction sequence can be created by any convenient means, and Rx Comms provides
             * a handy helper class for doing this, called ReactiveTransactionProcessor.
             *
             * However the sequence is created, it must be fed into the transaction observer
             * by creating a subscription. ReactiveTransactionProcessor has a helper method for that.
             * The helper method also gives us a way to rate-limit commands to the hardware, if needed.
             */
            var transactionProcessor = new ReactiveTransactionProcessor();
            transactionProcessor.SubscribeTransactionObserver(transactionObserver, TimeSpan.FromSeconds(1));
            channel.Open();
            #endregion Setup for Reactive ASCOM

            // All set up and ready to go.
            try
            {
                // First we'll create a StatusTransaction and get the device's status.
                var statusTransaction = new StatusTransaction();
                transactionProcessor.CommitTransaction(statusTransaction);
                statusTransaction.WaitForCompletionOrTimeout(); // There is also an async version

                // If the transaction failed, log and throw TransactionException.
                TransactionExtensions.ThrowIfFailed(statusTransaction, log);

                // Now we can retrieve the results and use them.
                // If the transaction succeeded, we should be assured of a valid result.
                // When you write your own transactions, make sure this is so!
                var status = statusTransaction.HardwareStatus;
                log.Debug().Message("Got status: {deviceStatus}", status).Write();

                // Get the user GPIO pins and flip the value of pin 0.
                var gpioPins        = status.UserPins;
                var gpioPinsToWrite = gpioPins.WithBitSetTo(0, !gpioPins[0]);

                // Now we'll use another transaction to set the new GPIO pin state.
                var gpioTransaction = new SetUserPinTransaction(gpioPinsToWrite);
                transactionProcessor.CommitTransaction(gpioTransaction);
                gpioTransaction.WaitForCompletionOrTimeout();

                TransactionExtensions.ThrowIfFailed(gpioTransaction, log);
                var newPinState = gpioTransaction.UserPins;
                if (newPinState != gpioPinsToWrite)
                {
                    throw new ApplicationException("Failed to write GPIO pins");
                }
                log.Info()
                .Message("Successfully changed GPIO pins {oldState} => {newState}", gpioPins, newPinState)
                .Write();
            }
            catch (TransactionException exception)
            {
                log.Error().Exception(exception)
                .Message("Transaction failed {transaction}", exception.Transaction)
                .Write();
                Console.WriteLine(exception);
            }
            catch (ApplicationException exception)
            {
                log.Error().Message("Failed to set teh GPIO pins.").Exception(exception).Write();
            }
            finally
            {
                /*
                 * We just need to dispose the transaction processor. This terminates the
                 * sequence of transactions, which causes the TransactionObserver's OnCompleted method
                 * to be called, which unsubscribes the receive sequence, which closes the
                 * communications channel.
                 */
                transactionProcessor.Dispose();
                log.Info().Message("Cleanup complete").Write();

                /*
                 * It is best practice to explicitly shut down the logging service,
                 * otherwise any buffered log entries might not be written to the log.
                 * This may take a few seconds if you are using a slow log target.
                 */
                log.Shutdown();
            }
        }