David's Astronomy Pages
Notes - Session 1392 (2026-01-15)

 
Bullet Session Aims & Highlights
 - Observing Result
 - Night Summary Plot
 - Session Event Log
Bullet Operational Issues
- Critical Issues (0),  Major Issues (2),  Minor Issues (7),  Small Defects (8),  Continuous Improvement (22)
- Figures (1)
   
Bullet Images from 2026-01-17  >>           
   
2026-01-22
Bullet AstroMain - Further Refactoring, Obs Manager's MainLoop
2026-01-25
Bullet AstroMain - Observatory Services Refactoring
Bullet AstroMain - Copilot SDK
   

Session Aims & Highlights (2026-01-17)

Main aims

  1. Targets.  Acquire images of a selection of variable stars, nearby stars, comets & deep sky targets as allowed by sky conditions.
  2. AstroMain. Check overall stability and capability of AstroMain 3.80.4 following significant software changes made in during the last fortnight, including introrduction of a new StateMachine (based on restructure of existing SessionState code blocks) and a new ObsManager Main Loop and other refactoring of ObsManager class.
  3. StateMachine. Carry out second live session using AstroMain/ObsManager's new Session StateMachine.
  4. ObsManager. Carry out first live session using AstroMain's newly refactored ObsManager (3.80.4), comprising new slim Orchestrator routine & handlers instead of the monolithic MainLoop() routine.
  5. Active Session Pipeline. Carry out second live Observatory session using AstroMain's new Create/Reopen Session pipeline that has had modification/fixes since the first live session

 Equipment & Software

Highlights

NotesNotes

Summary Plots & Logs

Observing Plan
Image
  
Observing Result
Image
   
Image
 
Dome & Scope Slewing Performance
Image
  
Slew/Centering Performance
Image
  
Guiding Performance
Image
  
Sky Conditions (Locate Frames)
Image 
  
Night Sky Summary Plot
Top axis: Sky Brightness at Zenith (in ADU/s)
Lefthand axis: Local Time (hh LT). Righthand axis: Sun Altitude (degs)
Note:  The NorthCam Star Count line is unreliable and should be ignored
(The AstroNorthCam 'Find' Star method is producing many false positives from clouds)
Image   
  
Actual Weather vs Pre-Session Weather Forecast
Image
Image
 
Session Event Log
Time     Event Detail
02:34:12 Session Monitoring AutoStart monitoring for Live Session opportunity between 02:34 & 06:35
02:34:13 Session AutoStarting Session autostarting (02:34)
02:34:25 Session Created Session Created (Live, 2026-01-17 S01392)
02:34:27   CCDSoft Restarting CCDSoft being restarted (to set AutoSave No.)
02:34:47   Scope Switched On Telescope Power has been switched on via UPB Switch
02:36:34   Services Started Observatory Services started
02:36:44 Observatory (Auto) Observatory placed in Fully-Automated Mode
02:36:45 Session Pending Session pending (2026-01-17)
02:36:47 Session Initiating Session initiating (2026-01-17)
02:37:09   Camera1 Connected SBIG Camera connected (Set point -20°C)
02:37:13   Plan Requested Observing Plan requested from AstroPlan (1.46)
02:37:55   Plan Loaded Observing Plan loaded to queue (Plan ID: 1182)
02:42:41 Observatory (Manual) Observatory placed in Manual Mode
02:43:15 Session Monitoring AutoStart monitoring for Live Session opportunity between 02:43 & 06:35
02:43:17 Observatory (AutoStart) Observatory placed in Auto-Start Mode
02:43:19 Session AutoStarting Session autostarting (02:43)
02:43:27 Session Resumed Session Resumed (Live, 2026-01-17 S01392)
02:43:37   Services Started Observatory Services started
02:43:43 Observatory (Auto) Observatory placed in Fully-Automated Mode
02:43:58 Session Pending Session pending (2026-01-17)
02:44:00 Session Initiating Session initiating (2026-01-17)
02:44:14   Camera1 Connected SBIG Camera connected (Set point -20°C)
02:44:23   Plan Loaded Observing Plan loaded to queue (Plan ID: 1182)
02:45:08 Observatory (Manual) Observatory placed in Manual Mode
02:45:53 Session Monitoring AutoStart monitoring for Live Session opportunity between 02:45 & 06:35
02:45:55 Observatory (AutoStart) Observatory placed in Auto-Start Mode
02:45:57 Session AutoStarting Session autostarting (02:45)
02:46:05 Session Resumed Session Resumed (Live, 2026-01-17 S01392)
02:46:13 Obs.Manager Obs.Manager is frozen in 'Waiting (AutoStart)' (last cycle was at 02:46:13)
02:46:14   Services Started Observatory Services started
02:46:20 Observatory (Auto) Observatory placed in Fully-Automated Mode
02:48:18   Make Observatory Safe Obs.Overseer intervened to Make Observatory Safe
02:48:46 Session Pending Session pending (2026-01-17)
02:48:48 Session Initiating Session initiating (2026-01-17)
02:48:50 Obs.Manager Obs.Manager has resumed again after 2.6 min
02:49:01   Camera1 Connected SBIG Camera connected (Set point -20°C)
02:49:11   Plan Loaded Observing Plan loaded to queue (Plan ID: 1182)
02:53:34 Observatory (Manual) Observatory placed in Manual Mode
02:54:42   Services Stopped Observatory Services stopped
02:58:31 Session Resumed Session Resumed (Live, 2026-01-17 S01392)
02:58:32 Program Opened Program Opened (AstroMain 3.80.2)
02:58:35   Obs.Overseer Started Obs.Overseer started
02:59:34   Obs.Manager Started Obs.Manager started
02:59:39   Services Started Observatory Services started
03:00:03 Session Monitoring AutoStart monitoring for Live Session opportunity between 03:00 & 06:35
03:00:06 Observatory (AutoStart) Observatory placed in Auto-Start Mode
03:00:08 Session AutoStarting Session autostarting (03:00)
03:00:15 Session Resumed Session Resumed (Live, 2026-01-17 S01392)
03:01:00   Services Started Observatory Services started
03:01:10 Observatory (Auto) Observatory placed in Fully-Automated Mode
03:01:12 Session Pending Session pending (2026-01-17)
03:01:14 Session Initiating Session initiating (2026-01-17)
03:01:27   Camera1 Connected SBIG Camera connected (Set point -20°C)
03:01:36   Plan Loaded Observing Plan loaded to queue (Plan ID: 1182)
03:01:41 Session Resumed Session Resumed (Live, 2026-01-17 S01392)
03:02:16   Telescope Connected Telescope connected (TheSky6)
03:02:40 Session Equilibration Session ready to Open Dome
03:03:26   Dome Opened Dome opened (Opening time 45s, Zigbee 40s)
03:03:28 Session Running Session running
03:03:31   Queue Started Observing Queue started (13 targets selected)
03:03:33     Target Started (NrZen) Target started (Focus Field 11, HIP 53798)
03:03:46       Dome Unparked Dome unparked
03:07:24       Focusing Started-Foc1 Foc1 Focusing Started (TCF-S)
03:10:15       Focusing Completed Foc1 AutoFocus Completed (Profile No 1, wide)
03:12:37       Focusing Completed Foc1 AutoFocus Completed (Profile No 1)
03:12:41       Focusing Started-Foc2 Foc2 Focusing Started (Secondary Scope, using ShCap)
03:14:43       Focusing Failed Foc2 focusing failed (failed QC check - Range)
03:14:47     Target Completed (NrZen) Target completed (Focus Field 11, HIP 53798)
03:14:49     Target Missed (1/13) Target's time slot was missed (1/13, UGC 3028 w/SN2026gm)
03:16:01     Target Started (2/13) Target started (2/13, UGC 5381 w/SN2025ahep)
03:19:54       Focusing Skipped Foc1 focusing skipped - star is too dim (TCF-LSI)
03:36:03     Target Completed Target completed (2/13, UGC 5381 w/SN2025ahep)
03:38:02     Target Started (3/13) Target started (3/13, UGC 5607 w/SN2026kc)
03:41:39       Focusing Skipped Foc1 focusing skipped - star is lost (TCF-LSI)
03:58:07     Target Completed Target completed (3/13, UGC 5607 w/SN2026kc)
04:00:21     Target Started (4/13) Target started (4/13, 29P/Schwassmann-Wachmann)
04:04:09       Focusing Skipped Foc1 focusing skipped - star is lost (TCF-LSI)
04:05:07       SoftSuspend Called Soft Suspend called due to Deteriorating Conditions (too few stars)
04:12:53       SoftSuspend Cancelled Soft Suspend is cancelled due to improved conditions
04:13:33       SoftSuspend Called Soft Suspend called due to Deteriorating Conditions (too few stars)
04:19:24     Target Completed Target completed (4/13, 29P/Schwassmann-Wachmann)
04:19:26   Queue Paused Queue paused for Session Suspension
04:19:29 Session Suspending Session suspending
04:20:19   Dome Closed Dome closed (Closing time 50s, Zigbee 43s)
04:20:21 Session Suspended Session suspended
04:20:23 Obs.Manager Obs.Manager is frozen in 'Suspended Stage 1880423 (Pre-Shutter Closure)' (last cycle was at 04:20:23)
04:21:34   Job Queue Frozen Job Queue appears to have frozen at around 04:19 - 04:21
04:22:28   Make Observatory Safe Obs.Overseer intervened to Make Observatory Safe
04:23:14   Dome Parked Dome moved to Az 90° (Park Position)
04:29:40   CCDSoft Restarting CCDSoft being restarted (attempt to fix locked thread)
04:29:45   SBIG Camera Reset SBIG Camera being power-cycled
04:31:12   Camera1 Connected SBIG Camera connected (Set point -20°C)
04:31:39   Make Observatory Safe Obs.Overseer intervened to Make Observatory Safe
 
Session Alerts & Alarms
Time     Type       Name Detail
02:48:18 Red Alert Obs.Manager Obs.Manager is frozen in 'Waiting (AutoStart)' (last cycle at 02:46:13)
02:48:48 Green Clear Obs.Manager Obs.Manager has resumed again after 2.6 min
04:22:28 Red Alert Obs.Manager Obs.Manager is frozen in 'Suspended Stage 1878580 (Pre-Shutter Closure)' (last cycle at 04:20:23)
04:31:39 Red Alert Job Queue Job Queue appears to be frozen (last IamAlive message at 04:19:24)
 

Back to Top


Operational Issues (2026-01-17 S1392)

[ Prev | Next ]

Critical Issues

Major Issues

Minor Issues

Small Defects

Continuous Improvement

[ Prev | Next ]

Back to Top Issue,  Back to Top


Fig 1.  'The AutoStartThread is Busy' dialog

AstroMain has started to become prone to dialogs appearing during AutoStart / Pending which blocks ObsManager execution until dismissed by user. Block of ObsManager is not acceptable, and issue needs to be fixed

Image

[ Prev | Next ]

Back to Top Issue,  Back to Top


2026-01-16


AstroMain - Refactoring FetchPlan Pipeline

1. Introduction


2. New Pipeline

2.1 PlanManager Pipeline Diagram

FetchPlanInBackground()
        │
        ▼
   [Thread Start]
        │
        ▼
   SelectPlan()
        │
        ├── SelectPlanFromDatabase()
        │         │
        │         └── GetPlansForNight()
        │
        ├── If no plan:
        │        │
        │        ├── InitiateNewPlan()
        │        │        └── SendAstroPlanMessage()
        │        │
        │        └── Wait for bNewPlanIsReady
        │
        └── SelectedPlan found
                │
                ▼
            LoadPlan()
                │
                ├── LoadPlanFromDatabaseInBackground()
                │         │
                │         └── [Thread Start]
                │                   │
                │                   ▼
                │         LoadPlanFromDatabase()
                │                   │
                │                   ├── RetrievePlan()
                │                   ├── Build TIS
                │                   ├── Compute timings
                │                   ├── Update UI
                │                   └── PlanStatus = Loaded/Failed
                │
                └── Wait for PlanStatus
                        │
                        └── Copy charts
 

2.2. New Entry Point

2.3 New Plan Selection Stage

2.4. Modified Plan Creation Stage

2.5. New Plan Loading Stage

3.0 Technical Details

3.1. Classes & Objects

3.2 Fields

3.3. Threading Model

3.4. Plan State Transitions

3.5 Helper Functions / Routines

Back to Top


AstroMain - Observatory Services Refactoring

Summary

During this development cycle, the Observatory Control System underwent a structural refactoring of its Services module. The goal was to preserve all existing behaviour while improving clarity, maintainability, and long‑term architectural stability. No functional changes were introduced; instead, the focus was on reorganising and renaming components to reflect their true responsibilities.

Key Outcomes

1. Clear Separation of Responsibilities

The system now distinguishes between three conceptual categories:

2. Intention - Revealing Naming

Lifecycle routines now follow a consistent naming scheme:

3. Clean Orchestration

The StartObservatoryServices() and StopObservatoryServices() routines now read like clear operational scripts. Each line expresses a single, intention-revealing action.

4. Behaviour Fully Preserved

All refactoring was performed with strict behavioural fidelity. No operational logic or device behaviour was changed.

5. TelePosition Analysis (parked)

The TelePosition subsystem requires deeper lifecycle analysis and will be addressed separately


Start / Stop Pipelines

Start-Up Pipeline (High Level)

StartObservatoryServices()
    ├── StartOverseerService()
    ├── StartCloudSensorService()
    ├── StartWeatherStationService()
    ├── StartObservatoryManager()
    ├── StartScorecardReceiver()
    ├── StartAllSkyStarMonitor()
    ├── StartTelePositionService()
    ├── StartObsEnvService()
    ├── StartPulsarDomeMonitor()
    ├── StartDomeConnection()
    ├── StartScopeConnection()
    ├── StartPHD2Connection()
    ├── StartSharpCapConnection()
    ├── StartObsMonitor()
    ├── StartPowerMonitor()
    ├── StartTheSkyScopeMonitor()
    ├── StartFocuser1Connection()
    ├── StartTempMonitor()
    ├── StartCcdCameraConnection()
    ├── StartCcdMonitor()
    ├── StartNetworkMonitor()
    ├── StartUpsMonitor()
    ├── StartZigbeeConnection()
    ├── StartPowerBoxConnection()
    └── StartCamera2Connection()

Night-Time Start Pipeline

StartNightObservatoryServices()
    ├── StartScopeConnection()
    ├── StartPHD2Connection()
    ├── StartCamera2Connection()
    └── StartSharpCapConnection()

Shutdown Pipeline (High Level)

StopObservatoryServices()
    ├── StopOverseerService()
    ├── StopCloudSensorService()
    ├── StopWeatherStationService()
    ├── StopObservatoryManager()
    ├── StopScorecardReceiver()
    ├── StopAllSkyStarMonitor()
    ├── StopTelePositionService()
    ├── StopObsEnvService()
    ├── StopPulsarDomeMonitor()
    ├── StopDomeConnection()
    ├── StopScopeConnection()
    ├── StopPHD2Connection()
    ├── StopSharpCapConnection()
    ├── StopObsMonitor()
    ├── StopPowerMonitor()
    ├── StopTheSkyScopeMonitor()
    ├── StopFocuser1Connection()
    ├── StopTempMonitor()
    ├── StopCcdCameraConnection()
    ├── StopCcdMonitor()
    ├── StopNetworkMonitor()
    ├── StopUpsMonitor()
    ├── StopZigbeeConnection()
    ├── StopPowerBoxConnection()
    └── StopCamera2Connection()

Night-Time Stop Pipeline

StopNightObservatoryServices()
    ├── StopScopeConnection()
    ├── StopPHD2Connection()
    ├── StopCamera2Connection()
    └── StopSharpCapConnection()

Back to TTop


AstroMain - Observatory Monitor Refactoring

1. Introduction

The Monitors Module had grown organically over many years, accumulating complexity, implicit behaviour, and tightly coupled logic. The goal of the refactor was to create a unified, intention-revealing architecture that:

This report summarises the architectural principles developed during the refactor and the key concepts that now underpin the new monitoring framework.

2. Core Problems Identified in the Legacy Design

2.1 Monolithic Structure

The original Monitors Module contained large, multi-responsibility blocks of code with intertwined timing, health, and domain logic. This made reasoning about behaviour difficult and increased the risk of unintended side effects.

2.2 Thread Lifecycle Fragility

Monitors relied on ad-hoc thread creation and invalidation flags. This created several risks:

2.3 Lack of Clear Domain Boundaries

Domain specific logic (e.g., network checks, device polling) was mixed with lifecycle mechanics (timing, cancellation, health tracking), making the code harder to maintain and extend.

3. Architectural Principles Developed

3.1 Separation of Concerns

The refactor established a strict separation between:

This separation is embodied in the new TMonitorBase class.

3.2 Intention Revealing Naming

Naming conventions were standardised to reflect true responsibility:

This makes the code navigable and self-documenting.

3.3 Uniform Control Flow

All monitors now follow the same lifecycle:

  1. Start
  2. Initialise
  3. Loop
  4. Execute domain logic
  5. Sleep
  6. Exit cleanly

This uniformity reduces cognitive load and makes behaviour predictable.

4. The Generation-Counter Model

4.1 The Problem It Solves

A key challenge was ensuring that:

The previous invalidation model could not guarantee this.

4.2 The Solution

A generation counter was introduced:

This guarantees:

4.3 Why It Works

The key insight is the distinction between:

The snapshot (thisGeneration) is a local variable, stored on the thread's stack, and cannot be overwritten by other threads. This makes the model deterministic and race-free.

5. The New TMonitorBase

The new base class provides:

Domain monitors inherit from this class and override only the parts relevant to their domain. This results in:

6. Domain Monitor Structure

Each domain monitor now follows a clear pattern:

This structure is simple, predictable, and easy to extend.

7. Handling Frozen Threads

The refactor acknowledges a fundamental truth of .NET:

A truly frozen thread cannot be safely killed in-process.

The new architecture handles this by:

For hard freezes, the architecture supports escalation to higher-level supervisors or out-of-process isolation if needed.

8. Outcomes and Benefits

8.1 Behavioural Fidelity

All existing monitor behaviour is preserved.

8.2 Improved Maintainability

The code is now:

8.3 Robust Thread Safety

The generation model eliminates:

8.4 Extensibility

New monitors can be added with minimal boilerplate.

8.5 Debugging Clarity

Uniform lifecycle and naming make issues easier to isolate.

9. Future Directions

10. Conclusion

The refactor of the Monitors Module represents a significant architectural improvement. By introducing a unified lifecycle, clear naming, domain separation, and the generation-counter model, the system is now:

This work lays a strong foundation for future enhancements and long-term operational stability.

Back to Top


AstroMain - Copilot SDK Installation

Steps :  VB.NET + Copilot SDK "Hello World" Setup (Visual Studio 2022)

1. Ensure you have a GitHub Copilot subscription

You need an active GitHub Copilot subscription (individual or business) for the SDK to work.

2. Install GitHub Copilot CLI (Windows)

Open PowerShell and install the Copilot CLI:

winget install GitHub.Copilot    (note: not GitHub.CopilotCLI)

If winget is unavailable, download the installer from the GitHub Copilot CLI releases page.

3. Authenticate the Copilot CLI

In PowerShell, run:

copilot login

This opens a browser window where you sign in with your GitHub account. After this, the CLI is authenticated.

4. Verify the CLI is working

Run the following commands in PowerShell:

copilot --version
copilot ask "hello"

If you receive a valid response to copilot ask, the CLI is ready.

5. Ensure Visual Studio 2022 is set up for .NET desktop development

Open the Visual Studio Installer and confirm that the .NET Desktop Development workload is installed, including support for .NET 6/7/8.

6. Create a new VB.NET WinForms project

  1. File --> New --> Project
  2. Select Windows Forms App (.NET)
  3. Language: Visual Basic
  4. Target Framework: .NET 6 or .NET 8

7. Add the Copilot SDK NuGet package

  1. In Visual Studio, go to Project --> Manage NuGet Packages
  2. Search for: GitHub.Copilot.SDK
  3. Install the latest version of the package.

8. Add UI controls to the form

On Form1, add:

9. Add the VB.NET "Hello Copilot" code

In Form1.vb, add the following code:

Imports GitHub.Copilot
Imports GitHub.Copilot.Agent

Public Class Form1
    Private Async Sub btnAsk_Click(sender As Object, e As EventArgs) Handles btnAsk.Click
        Try
            ' Create a Copilot client (connects to Copilot CLI)
            Dim client = CopilotClient.Create()

            ' Start a session
            Dim session = Await client.CreateSessionAsync()

            ' Send a simple prompt
            Dim response = Await session.SendAsync("Say hello from Copilot SDK.")

            ' Display the result
            txtOutput.Text = response.Text

        Catch ex As Exception
            txtOutput.Text = "Error: " & ex.Message
        End Try
    End Sub
End Class

10. Run and test the program

  1. Press F5 to run the application.
  2. Click the Ask button.
  3. If everything is configured correctly, Copilot's response will appear in txtOutput.

11. Optional: Enable streaming responses later

Once the basics work, you can explore streaming responses, for example:

' Example idea (not wired yet):
Await session.SendStreamingAsync(
    "Explain the weather in Scotland today",
    Sub(token) txtOutput.AppendText(token)
)

This would let you show Copilot's response as it streams in, token by token.

Back to Top