private void ShutdownObservatory(string reason)
        {
            DomeDigest domeDigest;

            try
            {
                Angle domeAz = DomeAzimuth; // Possibly force dome calibration

                if (!wisetelescope.AtPark || !ObservatoryIsPhysicallyParked)
                {
                    if (CT.IsCancellationRequested)
                    {
                        throw new Exception("Shutdown aborted");
                    }

                    Log(string.Format("   Starting Wise40 park (reason: {0}) ...", reason));

                    Log(string.Format("    Parking telescope at {0} {1} and dome at {2} ...",
                                      wisesite.LocalSiderealTime,
                                      (new Angle(66, Angle.Type.Dec)).ToString(),
                                      (new Angle(90, Angle.Type.Az).ToNiceString())));

                    Task telescopeShutdownTask = Task.Run(() =>
                    {
                        try
                        {
                            if (wisetelescope.Action("shutdown", reason) != "ok")
                            {
                                throw new OperationCanceledException("Action(\"telescope:shutdown\") did not reply with \"ok\"");
                            }
                        }
                        catch (Exception ex)
                        {
                            Log(string.Format("ShutdownObservatory:Exception: {0}", ex.InnerException == null ? ex.Message : ex.InnerException.Message));
                        }
                    }, CT);

                    ShutterState  shutterState;
                    List <string> activities;
                    bool          done = false;

                    do
                    {
                        if (CT.IsCancellationRequested)
                        {
                            telescopeShutdownTask.Dispose();
                            throw new Exception("Shutdown aborted");
                        }
                        SleepWhileProcessingEvents();
                        if (CT.IsCancellationRequested)
                        {
                            telescopeShutdownTask.Dispose();
                            throw new Exception("Shutdown aborted");
                        }

                        try
                        {
                            UpdateCheckingStatus("telescope status");
                            telescopeDigest = JsonConvert.DeserializeObject <TelescopeDigest>(wisetelescope.Action("status", ""));

                            UpdateCheckingStatus("safetooperate status");
                            domeDigest = JsonConvert.DeserializeObject <DomeDigest>(wisedome.Action("status", ""));
                            UpdateCheckingStatus("");

                            Angle ra, dec, az;
                            ra           = Angle.FromHours(telescopeDigest.Current.RightAscension, Angle.Type.RA);
                            dec          = Angle.FromDegrees(telescopeDigest.Current.Declination, Angle.Type.Dec);
                            az           = Angle.FromDegrees(domeDigest.Azimuth, Angle.Type.Az);
                            shutterState = domeDigest.Shutter.State;
                            activities   = telescopeDigest.Activities;

                            done = telescopeDigest.AtPark && domeDigest.AtPark && shutterState == ShutterState.shutterClosed;

                            Log(string.Format("    Telescope at {0} {1}, dome at {2}, shutter {3} ...",
                                              ra.ToNiceString(),
                                              dec.ToNiceString(),
                                              az.ToNiceString(),
                                              shutterState.ToString().ToLower().Remove(0, "shutter".Length)),
                                _simulated ? 1 : 10);
                        } catch (Exception ex)
                        {
                            //Log(string.Format("    ShutdownObservatory:Exception: {0}", ex.Message));
                        }
                    } while (!done);

                    Log("   Done parking Wise40.");
                }

                if (!telescopeDigest.EnslavesDome)
                {
                    if (!wisedome.AtPark)
                    {
                        Log("    Starting dome park ...");
                        wisedome.Park();
                        do
                        {
                            if (CT.IsCancellationRequested)
                            {
                                wisedome.AbortSlew();
                                throw new Exception("Shutdown aborted");
                            }
                            SleepWhileProcessingEvents();
                            Angle az = DomeAzimuth;
                            Log(string.Format("  Dome at {0} ...", az.ToNiceString()), 10);
                        } while (!wisedome.AtPark);
                        Log("    Dome is parked");
                    }

                    if (wisedome.ShutterStatus != ShutterState.shutterClosed && wisedome.ShutterStatus != ShutterState.shutterClosing)
                    {
                        Log("    Starting shutter close ...");
                        wisedome.CloseShutter();
                        do
                        {
                            if (CT.IsCancellationRequested)
                            {
                                throw new Exception("Shutdown aborted");
                            }
                            SleepWhileProcessingEvents();
                            Log("    Shutter is closing ...", 10);
                        } while (wisedome.ShutterStatus != ShutterState.shutterClosed);
                        Log("    Shutter is closed.");
                    }
                }

                Log("Wise40 is parked and closed");
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                if (ex.Message == "Shutdown aborted")
                {
                    Log("Shutdown aborted by operator");
                }
                else
                {
                    Log(string.Format("ShutdownObservatory:Exception occurred:\n{0}, aborting shutdown!", ex.Message));
                }

                wisetelescope.Action("abort-shutdown", "");
            }
            ShuttingDown = false;
        }
        private void CheckSituation()
        {
            if (ShuttingDown)
            {
                return;
            }

            #region GetStatus
            try
            {
                UpdateCheckingStatus("telescope status");
                telescopeDigest = JsonConvert.DeserializeObject <TelescopeDigest>(wisetelescope.Action("status", ""));

                UpdateCheckingStatus("safetooperate status");
                safetooperateDigest = JsonConvert.DeserializeObject <SafeToOperateDigest>(wisesafetooperate.Action("status", ""));
            } catch (Exception ex)
            {
                UpdateCheckingStatus("");
                Log(string.Format("CheckSituation:Exception: {0}", ex.InnerException == null ? ex.Message : ex.InnerException.Message));
                return;
            }
            #endregion

            #region UpdateDisplay

            UpdateConditionsBypassToolStripMenuItem(safetooperateDigest.Bypassed);

            #region ComputerControlLabel
            if (safetooperateDigest.ComputerControlIsSafe)
            {
                labelComputerControl.Text      = "Operational";
                labelComputerControl.ForeColor = safeColor;
                toolTip.SetToolTip(labelComputerControl, "Computer Control is ON");
            }
            else
            {
                labelComputerControl.Text      = "Maintenance";
                labelComputerControl.ForeColor = unsafeColor;
                toolTip.SetToolTip(labelComputerControl, "Computer Control is OFF");
            }
            #endregion

            #region ActivityLabel
            if (telescopeDigest.Active)
            {
                labelActivity.Text      = "Active";
                labelActivity.ForeColor = safeColor;
                toolTip.SetToolTip(labelActivity, string.Join(",", telescopeDigest.Activities));
            }
            else
            {
                labelActivity.Text      = "Idle";
                labelActivity.ForeColor = unsafeColor;
                toolTip.SetToolTip(labelActivity, "");
            }
            #endregion

            UpdateProjectorControls();
            #endregion

            #region DecideIfShutdownIsNeeded
            List <string> reasonsList = new List <string>();

            if (!safetooperateDigest.Safe)
            {
                reasonsList.Add(string.Join(Const.recordSeparator, safetooperateDigest.UnsafeReasons));
            }

            if (!telescopeDigest.Active)
            {
                reasonsList.Add("Telescope is Idle");
            }

            if (reasonsList.Count != 0)
            {
                #region ShouldShutdown
                string shutdownReason = String.Join(" and ", reasonsList);

                if (telescopeDigest.ShuttingDown)
                {
                    Log("Wise40 already shutting down");
                }
                else if (ObservatoryIsLogicallyParked && ObservatoryIsPhysicallyParked)
                {
                    Log("Wise40 already parked.");
                }
                else
                {
                    if (!safetooperateDigest.ComputerControlIsSafe)
                    {
                        Log("No ComputerControl, shutdown skipped.");
                    }
                    else
                    {
                        DoShutdownObservatory(shutdownReason);
                    }
                }
                #endregion
            }
            else
            {
                #region NoNeedToShutdown
                string safetyMessage = "", activityMessage = "";

                if (safetooperateDigest.Safe)
                {
                    safetyMessage = "Safe";
                    if (safetooperateDigest.Bypassed)
                    {
                        safetyMessage += " (due to safety bypass)";
                    }
                }
                else
                {
                    safetyMessage = "Not safe";
                    if (safetooperateDigest.UnsafeBecauseNotReady)
                    {
                        safetyMessage += " (inconclusive safety info)";
                    }
                    else if (!safetooperateDigest.HumanInterventionIsSafe)
                    {
                        safetyMessage += " (intervention)";
                    }
                }

                if (telescopeDigest.Active)
                {
                    activityMessage = "active (" + string.Join(", ", telescopeDigest.Activities) + ")";
                }
                else
                {
                    activityMessage = "idle";
                }

                Log(safetyMessage + " and " + activityMessage);
                #endregion
            }
            #endregion
        }