EndOfNight

Bases: KPFFunction

Send KPF in to an end of night configuration.

  • kpffiu.MODE = Stowed
  • Power off FVCs
  • Power off LED back illuminators
  • close AO hatch
  • HEPA on
  • Send PCU to Home

ARGS:

:AO: (bool) Close AO hatch, home PCU, and turn on HEPA? (default=True)

Source code in kpf/utils/EndOfNight.py
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class EndOfNight(KPFFunction):
    '''Send KPF in to an end of night configuration.

    - kpffiu.MODE = Stowed
    - Power off FVCs
    - Power off LED back illuminators
    - close AO hatch
    - HEPA on
    - Send PCU to Home

    ARGS:
    =====
    :AO: (bool) Close AO hatch, home PCU, and turn on HEPA? (default=True)
    '''
    @classmethod
    @obey_scriptrun
    def pre_condition(cls, args):
        pass

    @classmethod
    @add_script_log(Path(__file__).name.replace(".py", ""))
    def perform(cls, args):
        # Check Scripts
        kpfconfig = ktl.cache('kpfconfig')
        expose = ktl.cache('kpfexpose', 'EXPOSE')
        scriptname = kpfconfig['SCRIPTNAME'].read()
        pid = kpfconfig['SCRIPTPID'].read(binary=True)
        script_running = scriptname not in ['', 'None', None] or pid >= 0
        if script_running and args.get('confirm', False) is True:
            log.error('Non-interactive mode set and script is running')
            return
        if script_running:
            # ---------------------------------
            # User Verification
            # ---------------------------------
            msg = ["",
                   "--------------------------------------------------------------",
                   f"A script ({scriptname}, {pid}) is currently running. ",
                   "",
                   "Do you wish to end the current exposure and request a script",
                   "stop in order to proceed with running EndOfNight?",
                   "",
                   "End Exposure and Request Script Stop?",
                   "(y/n) [y]:",
                   "--------------------------------------------------------------",
                   "",
                   ]
            for line in msg:
                print(line)
            user_input = input()
            if user_input.lower() in ['n', 'no', 'q', 'quit', 'abort']:
                log.warning(f'User aborted End Of Night')
                return
            else:
                log.info('User opted to stop existing script')
                kpfconfig['SCRIPTSTOP'].write(1)
                expose.write('End')
                waittime = 120
                log.info(f'Waiting up to {waittime:.0f}s for running script to end')
                kpfconfig['SCRIPTPID'].waitFor("==-1", timeout=waittime)
                time.sleep(2) # time shim
                check_script_running()

        # Stop tip tilt and agitator
        StopTipTilt.execute({})
        StopAgitator.execute({})

        # Start FIU stow
        log.info('Setting FIU mode to Stowed')
        ConfigureFIU.execute({'mode': 'Stowed', 'wait': False})

        # ---------------------------------
        # AO Shutdown
        # ---------------------------------
        if args.get('AO', True) is True and args.get('confirm', False) is False:
            msg = ["",
                   "--------------------------------------------------------------",
                   "Perform shutdown of AO? This will move the AO hatch and PCU.",
                   "The AO area should be clear of personnel before proceeding.",
                   "",
                   "Do you wish to shutdown AO?",
                   "(y/n) [y]:",
                   "--------------------------------------------------------------",
                   "",
                   ]
            for line in msg:
                print(line)
            user_input = input()
            if user_input.lower() in ['y', 'yes', '']:
                log.debug('User chose to shut down AO')
                log.info('Closing AO Hatch')
                try:
                    ControlAOHatch.execute({'destination': 'closed'})
                except FailedToReachDestination:
                    log.error(f"AO hatch did not move successfully")
                log.info('Sending PCU stage to Home position')
                SendPCUtoHome.execute({})
    #             log.info('Turning on AO HEPA Filter System')
    #             TurnHepaOn.execute({})
            else:
                log.warning(f'User chose to skip AO shutdown')

        # ---------------------------------
        # Remaining non-AO Actions
        # ---------------------------------
        # Power off FVCs
        for camera in ['SCI', 'CAHK', 'CAL']:
            FVCPower.execute({'camera': camera, 'power': 'off'})
        # Power off LEDs
        for LED in ['ExpMeterLED', 'CaHKLED', 'SciLED', 'SkyLED']:
            CalLampPower.execute({'lamp': LED, 'power': 'off'})
        # Finish FIU shutdown
        WaitForConfigureFIU.execute({'mode': 'Stowed'})
        # Set PROGNAME
        log.info('Clearing values for PROGNAME, OBSERVER, OBJECT')
        WaitForReady.execute({})
        SetProgram.execute({'progname': ''})
        SetObserver.execute({'observer': ''})
        SetObject.execute({'Object': ''})
        # Power off Simulcal lamp
        kpfconfig = ktl.cache('kpfconfig')
        calsource = kpfconfig['SIMULCALSOURCE'].read()
        if calsource in ['U_gold', 'U_daily', 'Th_daily', 'Th_gold']:
            CalLampPower.execute({'lamp': calsource, 'power': 'off'})
        # Allow scheduled cals
        log.info('Set ALLOWSCHEDULEDCALS to Yes')
        kpfconfig = ktl.cache('kpfconfig')
        kpfconfig['ALLOWSCHEDULEDCALS'].write('Yes')

    @classmethod
    def post_condition(cls, args):
        pass

    @classmethod
    def add_cmdline_args(cls, parser):
        parser.add_argument("--noAO", dest="AO",
                            default=True, action="store_false",
                            help="Skip configuring AO?")
        parser.add_argument("--confirm", dest="confirm",
                            default=False, action="store_true",
                            help="Skip confirmation questions (script will be non interactive)?")
        return super().add_cmdline_args(parser)