Can I "reset" a MIDI device in a gig script?

I have a gig script that processes messages from a MIDI device.

This processing stops working after I disconnect and then reconnect the MIDI device until I recompile the script.

The script itself doesn’t stop, nothing crashes, no errors are shown in the log. There’s a function in the script that detects device connection status and updates an environment variable, it works as intended.

But no MIDI input is received or processed.

I assume that’s because the script doesn’t “realize” the device is available again? So can I somehow refresh it without restarting the whole thing?

Here’s the script itself (sorry, it’s in a very raw shape, work in progress):

Const
    CCA: Integer = 20 //Footswitch button A
    CCB: Integer = 21 //Footswitch button B
    CCC: Integer = 22 //Footswitch button C
    CCD: Integer = 23 //Footswitch button D
    
    FSChan: Integer = 1 //Footswitch MIDI channel

    BankUpCCA: Integer = 115 //CC# for bank up button A
    BankUpCCB: Integer = 116 //CC# for bank up button B
    BankUpCCC: Integer = 117 //CC# for bank up button C
    BankUpCCD: Integer = 118 //CC# for bank up button D
    
    BankUpChannel: Integer = 16 //MIDI channel for bank up
    
    ControlCC: Integer = 127 //CC# to send to notify racks for bank change
    
    LPSidle: Integer = 0 //status before long press is registered
    LPSover: Integer = 1 //status after long press is registered
    LongTime: Integer = 1000 //time to wait to register long press

Var
    SWITCH: MidiInDeviceAlias //Rig Manager alias for the footswitch
    SWITCHOUT: String = "iRig BlueBoard Bluetooth" //text name of the footswitch to blink LEDs
    

    LongPress: Ramp //timer for the footswitch
    LongPressState: Integer = LPSidle //initialization of status
    CCBuffer: Integer
    ChannelBuffer: Integer
    
    IsBankUp: Boolean = false //initialization of bank up or down flag

    LEDOn: Ramp //timer for LED blinking

Function BlinkFS (time: Integer) //this function blinks LEDs

    SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCA, 127, FSChan)) //turning LEDs on
    SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCB, 127, FSChan))
    SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCC, 127, FSChan))
    SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCD, 127, FSChan))
    TriggerOneShotRamp(LEDOn, time, 10) //starting timer

End
    
On ControlChangeEvent (m: ControlChangeMessage) from SWITCH //intercepting key presses

    Var
        OldCC: Integer = GetCCNumber(m)
        OldValue: Integer = GetCCValue(m)
        OldChannel: Integer = GetChannel(m)
        //InLongPress: Boolean
        //KeyUpHappened: Boolean
        Print("OldCC " + OldCC + " OldValue " + OldValue + " OldChannel " + OldChannel + " IsBankUp " + IsBankUp )
   
    If OldValue > 64 Then //detecting button down
        
        //If LongPressState == LPSover And KeyUpHappened == false Then
        //    InLongPress = true
        //Else
        //    InLongPress = false
        //End
        
        If IsBankUp == false Then CCBuffer = OldCC
        Else CCBuffer = OldCC + 95 End
        If IsBankUp == false Then ChannelBuffer = OldChannel
        Else ChannelBuffer = BankUpChannel End
        Print ("key down, CCBuffer " + CCBuffer + " ChannelBuffer " + ChannelBuffer)
        LongPressState = LPSidle
        //KeyUpHappened = false
        TriggerOneShotRamp(LongPress, LongTime, 10) //starting timer when the button goes down
        
    Else
        StopOneShotRamp(LongPress)
        //InLongPress = false
        //KeyUpHappened = true
        //LongPressState = LPSidle
    End
    Print("lps is " + LongPressState)
    //Print("key up happened is " + KeyUpHappened)
    If IsBankUp == true And LongPressState == LPSidle /*And InLongPress == false*/ Then //checking if the upper bank is on to rewrite messages
        If LongPressState == LPSidle Then Print("lps idle, injecting rewritten message") Else Print ("lps not idle, suppressing rewritten message") End
        Select
            OldCC == CCA Do
                InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(BankUpCCA, OldValue, BankUpChannel)) //reassigning to new channel and CC#
            OldCC == CCB Do
                InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(BankUpCCB, OldValue, BankUpChannel))
            OldCC == CCC Do
                InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(BankUpCCC, OldValue, BankUpChannel))
            OldCC == CCD Do
                InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(BankUpCCD, OldValue, BankUpChannel))
        End
    Else
        If LongPressState == LPSidle /*And InLongPress == false And KeyUpHappened == true*/ Then
            Print("lps idle and in long press is, injecting original message")
            InjectMidiEventViaRigManager (SWITCH, m) //if no reassignment is needed, sending the message as is
            //SendLater (SWITCH, MakeControlChangeMessageEx(BankUpCCD, 0, BankUpChannel), 10)
        //Else
            //Print("lps not idle, suppressing original message")
        End
    End

End


On GeneratorEndCycle (timeX: Integer) from LongPress //checking the timer, changing state, blinking LEDs to indicate bank change 
    Print("long cycle end event triggered")
    If LongPressState == LPSidle Then
        LongPressState = LPSover //changing state if button is pressed for long enough 
        Print("changing state to over, long press is " + LongPressState)
        InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(CCBuffer, 0, ChannelBuffer)) //emulating key up
        If IsBankUp == false Then
            //InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 127, BankUpChannel)) //sending control message
            BlinkFS (500) //blinking LEDs long
            //Notify("Footswitch Bank 2")
        Else
            //InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 0, BankUpChannel))
            //Notify("Footswitch Bank 1")
            BlinkFS (15) //blinking LEDs short
        End
        //IsBankUp = !IsBankUp //changing bank flag
    Else
        StopOneShotRamp(LongPress)
        LongPressState = LPSidle
        Print("changing state to idle, long press is " + LongPressState)
    End
End

On GeneratorEndCycle (timeX: Integer) from LEDOn //turning LEDs off, sending control message to racks, toggling bank flag 

       //SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCA, 0, FSChan))
       //SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCB, 0, FSChan))
       //SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCC, 0, FSChan))
       //SendNowToMidiOutDevice (SWITCHOUT, MakeControlChangeMessageEx(CCD, 0, FSChan))
       //InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(CCBuffer, 0, ChannelBuffer))
       If IsBankUp == false Then
        //InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(CCBuffer, 0, FSChan))    
        InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 127, BankUpChannel)) //sending control message
            //BlinkFS (500) //blinking LEDs long
            Notify("Footswitch Bank 2")
       Else
            //InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(CCBuffer, 0, BankUpChannel))
            InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 0, BankUpChannel))
            Notify("Footswitch Bank 1")
            //BlinkFS (15) //blinking LEDs short
       End
       IsBankUp = !IsBankUp //changing bank flag

End

On DeviceStatusChanged (deviceName: String, connected: Boolean, reserved: Integer)
//Var index: Integer = GetCurrentSongPartIndex()
    //Print("device is " + deviceName + " status is " + connected + " index is " + index)
    If deviceName == SWITCHOUT Then
        IsBankUp = false
    End
    If deviceName == SWITCHOUT And connected == True Then
        SetEnvVariable ("SwitchConnected", "true")
        InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 0, BankUpChannel))
    Elsif deviceName == SWITCHOUT And connected == False Then
        SetEnvVariable ("SwitchConnected", "false")
    End
    
    
    /*If deviceName == SWITCHOUT And connected == True Then
        //Print("condition met")
        IsBankUp = false
        //Sleep (5000)
        InjectMidiEventViaRigManager (SWITCH, MakeControlChangeMessageEx(ControlCC, 0, BankUpChannel))
        
        Notify ("Footswitch in sync, bank up is " + IsBankUp)
    End*/
    Print(GetEnvVariable("SwitchConnected"))
End
    
// Called when you switch to another song
On Song(oldSongIndex : integer, newSongIndex : integer)
    OSC_SendStringSpecific("/GP/Song", GetSongName(newSongIndex), "127.0.0.1", OSC_GetGPListeningPort())
End

Hm, I also use a similar gig script processing MIDI from an external device, but I can not remember such a behaviour.

I will check it this evening.