Todd --
OK, yes the weather and dome handling was changed in a big way with 3.5. The objective was to allow the weather to remain connected no matter what, until shutdown/dawn flats time.
The readback will be closed then go opening, and then back to closed then the roof controller relay finally clicks and starts to open and then roof condition is reporting opening again. This is with the Foster systems roll off roof controller. I think the query is happening too quickly and the sequence from the controller is confusing scheduler. Nothing has changed with the hardware and everything was working fine with Scheduler 3.4.
That's what's doing it. The polling rate is a lazy once every 15 seconds. The new logic is designed to monitor dome/roof operations and handle the situation where a hardware weather closure happens while it is in the process of opening up. That situation would like Scheduler before. As you might imagine, I never expected the "shutter" status to switch back and forth like that. It's the switch from opening back to closed that's doing it. The exception is the result of the apparent problems opening. How ugly. I held 3.5 in beta for so long... Now that's several dome and weather related things, one mine (dawn cal frames with bad weather) and the rest due to quirks in weather and dome operation that I couldn't have anticipated. Dang it. Here's the opening code if you're curious:
Code:
//
// Dome shutter control. Harmless if no dome/roof or already open. Throws on dome errors (typ.)
// WE DO NOT HAVE WEATHER KNOWLEDGE!
//
// NOTE: This is an unclean interface. It returns false if the dome wasn't opened because
// it was found to be closing or remained closed after being told to open. The
// assumption is that an external hardware closure is in effect.
//
public bool OpenDome()
{
ACP.Dome Dome = m_ACPUtil.Dome; // Shortcut
if (!Dome.Available || !Dome.CanSetShutter)
return true;
if (!WeatherSafe) // Just went unsafe
return false;
if (Dome.Available && Dome.ShutterStatus != ACP.ShutterState.shutterOpen)
{
switch (Dome.ShutterStatus)
{
case ACP.ShutterState.shutterClosed:
Logger.Log("Open the observatory dome/roof", LogLevel.Verbose);
//
// TODO What happens here if an external hardware closure
// is in effect? It is undefined. If an exception is raised,
// what do we do? I elected to just let the error fly and
// kill the dispatcher.
//
Dome.OpenShutter();
//
// HACK! My tester has MaxDome, and it can take "some time" before it
// reports that it is Opening. Immediately after returning from this,
// it says it's still Closed and triggers the "assuming weather closure"
// case in the second switch statement below.
//
Thread.Sleep(10000);
// HACK!
break;
case ACP.ShutterState.shutterClosing: // Probably a weather initiated closure
Logger.Log("**Dome closing when asked to open. Assuming weather closure.", LogLevel.Brief);
return false;
case ACP.ShutterState.shutterError:
throw new Exception("DOME FAILURE: Dome reports shutter error status");
case ACP.ShutterState.shutterOpen: // It JUST finished opening!
Thread.Sleep(5000); // Just pause for a sec, then
Dome.UnParkHome(); // Assure slaved!
return true;
case ACP.ShutterState.shutterOpening: // Weird, already opening, oh well...
break;
}
int i;
for (i = 0; i < 20; i++) // Wait up to 5 minutes
{
if (!WeatherSafe) // If the weather went unsafe
{
Logger.Log("**Weather went unsafe while dome opening.", LogLevel.Brief);
return false;
}
//
// The first two cases here probably aren't needed as the weather unsafe
// just got caught. Nonetheless I'm leaving them here as a sort of assert.
//
switch (Dome.ShutterStatus)
{
case ACP.ShutterState.shutterClosed:
Logger.Log("**Dome closed while opening. Assuming weather closure.", LogLevel.Brief);
return false;
case ACP.ShutterState.shutterClosing: // Probably a weather initiated closure
Logger.Log("**Dome found closing while opening. Assuming weather closure.", LogLevel.Brief);
return false;
case ACP.ShutterState.shutterError:
throw new Exception("DOME FAILURE: Dome reports shutter error status while opening");
case ACP.ShutterState.shutterOpen: // Open! OK.
break;
}
if (Dome.ShutterStatus == ACP.ShutterState.shutterOpen)
break; // DONE!
Thread.Sleep(15000); // Wait 15 sec and look again
}
if (i >= 20)
throw new Exception("Dome failed to open within 5 minutes");
Dome.UnParkHome(); // Assure slaved!
//
// Allow Dome to complete its initial slave slew
//
Thread.Sleep(15000); // Wait for plenty more than slaving time
for (i = 0; i < 20; i++) // Wait up to 5 minutes
{
if (!WeatherSafe) // If the weather went unsafe
{
Logger.Log("**Weather went unsafe while dome opening.", LogLevel.Brief);
return false;
}
if (!Dome.Slewing)
break;
Thread.Sleep(15000);
}
if (i >= 20)
throw new Exception("Dome failed to complete initial slave slew within 5 minutes");
}
return true;
}
It's all the new tests for hardware closure that are now picking up the "unusual" conditions while the roof is opening. I'll be back on Monday and maybe I'll have ideas. I hate to start putting kludges into the Scheduler for stuff like this (though I already have one new one for weather servers that return from Connected = true yet aren't ready to be called for "a while").