S1F1RAre You Online? Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 1, secs_receive_S1F1R)

def secs_receive_S1F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S1F1R

S1F2On Line Data Different Host and Equipment Use

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F2 Python Parse Equipment reply 
    rcr = sp.sendSecsMsg(1, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 MDLN SOFTREV
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def
from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F2 Python Parse Host reply
    rcr = sp.sendSecsMsg(1, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:0
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 1 or pylist0[0] != "L:0":
            ok = False
            break
        # single token data such as L:0 or U4:0 has been received as expected
        return # finished ok
    # end while(ok)
# end def

S1F3RSelected Equipment Status Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 3, secs_receive_S1F3R)

def secs_receive_S1F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n SVID
        # SVID U4:1 (varies)  status variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeSVID, lengthSVID) = pylist1[0].split(':')
            SVID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F3R

S1F4Selected Equipment Status Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F4 Python Parse reply
    rcr = sp.sendSecsMsg(1, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n SV
        # SV A:n (varies)  status variable value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeSV, lengthSV) = pylist1[0].split(':')
            SV = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F5RFormatted Status Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 5, secs_receive_S1F5R)

def secs_receive_S1F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SFCD
        # SFCD B:1 (always)  status form code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        SFCD = sp.binToInt(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F5R

S1F6Formatted Status Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F6 Python Parse reply
    rcr = sp.sendSecsMsg(1, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n SV
        # SV A:n (varies)  status variable value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeSV, lengthSV) = pylist1[0].split(':')
            SV = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F7Fixed Form Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 7, secs_receive_S1F7)

def secs_receive_S1F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SFCD
        # SFCD B:1 (always)  status form code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        SFCD = sp.binToInt(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F7

S1F8Fixed Form Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F8 Python Parse reply
    rcr = sp.sendSecsMsg(1, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:2 SVNAME SV0}
        # SVNAME A:n (always)  status variable name
        # SV0 A:0 (varies)  Zero length value used to convey format type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            SVNAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeSV0, lengthSV0) = pylist2[0].split(':')
            SV0 = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F9RMaterial Transfer Status Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 9, secs_receive_S1F9R)

def secs_receive_S1F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F9R

S1F10Material Transfer Status Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F10 Python Parse reply
    rcr = sp.sendSecsMsg(1, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TSIP TSOP
        # TSIP (list)B:n (always)  transfer status of input ports
        # TSOP (list)B:n (always)  transfer status of output ports
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("B:"):
            ok = False
            break
        TSIP = []
        for i in range(0, len(TSIP)):
            TSIP.append(sp.binToInt(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("B:"):
            ok = False
            break
        TSOP = []
        for i in range(0, len(TSOP)):
            TSOP.append(sp.binToInt(pylist1[1+i])
        return # finished ok
    # end while(ok)
# end def

S1F11RStatus Variable Namelist Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 11, secs_receive_S1F11R)

def secs_receive_S1F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n SVID
        # SVID U4:1 (varies)  status variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeSVID, lengthSVID) = pylist1[0].split(':')
            SVID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F11R

S1F12Status Variable Namelist Reply Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F12 Python Parse reply
    rcr = sp.sendSecsMsg(1, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 SVID SVNAME UNITS}
        # SVID U4:1 (varies)  status variable ID
        # SVNAME A:n (always)  status variable name
        # UNITS A:n (always)  units identifier (see E5 Section 9)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeSVID, lengthSVID) = pylist2[0].split(':')
            SVID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            SVNAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            UNITS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F13REstablish Communications Request Different Host and Equipment Use

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F13R Python Receive Equipment message - add next line to setupn
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 13, secs_receive_S1F13R)

def secs_receive_S1F13R(sp:SecsHost, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MDLN SOFTREV
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S1F13R
from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F13R Python Receive Host message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 13, secs_receive_S1F13R)

def secs_receive_S1F13R(sp:SecsEquip, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:0
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 1 or pylist0[0] != "L:0":
            ok = False
            break
        # single token data such as L:0 or U4:0 has been received as expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F13R

S1F14Establish Communications Request Acknowledge Different Host and Equipment Use

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F14 Python Parse Equipment reply 
    rcr = sp.sendSecsMsg(1, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 COMMACK {L:2 MDLN SOFTREV}
        # COMMACK B:1 (always)  establish communications acknowledgement code
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        COMMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist2[1] if len(pylist2) == 2 else "")
        return # finished ok
    # end while(ok)
# end def
from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F14 Python Parse Host reply
    rcr = sp.sendSecsMsg(1, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 COMMACK L:0
        # COMMACK B:1 (always)  establish communications acknowledgement code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        COMMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 1 or pylist1[0] != "L:0":
            ok = False
            break
        # single token data such as L:0 or U4:0 has been received as expected
        return # finished ok
    # end while(ok)
# end def

S1F15RRequest OFF-LINE Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 15, secs_receive_S1F15R)

def secs_receive_S1F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F15R

S1F16OFF-LINE Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F16 Python Parse reply
    rcr = sp.sendSecsMsg(1, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect OFLACK
        # OFLACK B:1 (always)  offline acknowledge, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        OFLACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S1F17RRequest ON-LINE Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 17, secs_receive_S1F17R)

def secs_receive_S1F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F17R

S1F18ON-LINE Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F18 Python Parse reply
    rcr = sp.sendSecsMsg(1, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ONLACK
        # ONLACK B:1 (always)  online acknowledge, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ONLACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S1F19RGet Attribute Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 19, secs_receive_S1F19R)

def secs_receive_S1F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 OBJTYPE {L:m OBJID} {L:n ATTRID}
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJID, lengthOBJID) = pylist2[0].split(':')
            OBJID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist2[0].split(':')
            ATTRID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S1F19R

S1F20Attribute Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F20 Python Parse reply
    rcr = sp.sendSecsMsg(1, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:m {L:n ATTRDATA}} {L:p {L:2 ERRCODE ERRTEXT}}
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1:
                ok = False
                break
            for n in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[n])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
                ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F21RData Variable Namelist Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 21, secs_receive_S1F21R)

def secs_receive_S1F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n VID
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist1[0].split(':')
            VID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F21R

S1F22Data Variable Namelist Reply Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F22 Python Parse reply
    rcr = sp.sendSecsMsg(1, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 VID DVVALNAME UNITS}
        # VID A:n (varies)  A variable ID
        # DVVALNAME A:n (always)  a descriptive name for a Data Value variable (DVVAL)
        # UNITS A:n (always)  units identifier (see E5 Section 9)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist2[0].split(':')
            VID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            DVVALNAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            UNITS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S1F23RCollection Event Namelist Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 1, 23, secs_receive_S1F23R)

def secs_receive_S1F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S1F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n CEID
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist1[0].split(':')
            CEID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 1, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S1F23R

S1F24Collection Event Namelist Reply Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S1F24 Python Parse reply
    rcr = sp.sendSecsMsg(1, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 CEID CENAME {L:a VID}}
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # CENAME A:n (always)  a descriptive name for a Data Collection Event
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist2[0].split(':')
            CEID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            CENAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeVID, lengthVID) = pylist3[0].split(':')
                VID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F1Service Program Load Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F1 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 1, secs_receive_S2F1)

def secs_receive_S2F1(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F1.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 SPID LENGTH
        # SPID A:6 (always)  service program identifier
        # LENGTH U4:1 (always)  program length in bytes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SPID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LENGTH = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F1

S2F2Service Program Load Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F2 Python Parse reply
    rcr = sp.sendSecsMsg(2, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F3Service Program Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 3, secs_receive_S2F3)

def secs_receive_S2F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SPD
        # SPD (list)B:n (always)  service program data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        SPD = []
        for i in range(0, len(SPD)):
            SPD.append(sp.binToInt(pylist0[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F3

S2F4Service Program Send Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F4 Python Parse reply
    rcr = sp.sendSecsMsg(2, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SPAACK
        # SPAACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        SPAACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F5Service Program Load Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F5 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 5, secs_receive_S2F5)

def secs_receive_S2F5(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F5.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SPID
        # SPID A:6 (always)  service program identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        SPID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F5

S2F6Service Program Load Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F6 Python Parse reply
    rcr = sp.sendSecsMsg(2, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SPD
        # SPD (list)B:n (always)  service program data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        SPD = []
        for i in range(0, len(SPD)):
            SPD.append(sp.binToInt(pylist0[1+i])
        return # finished ok
    # end while(ok)
# end def

S2F7Service Program Run Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 7, secs_receive_S2F7)

def secs_receive_S2F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SPID
        # SPID A:6 (always)  service program identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        SPID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F7

S2F8Service Program Run Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F8 Python Parse reply
    rcr = sp.sendSecsMsg(2, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect CSAACK
        # CSAACK U1:1 (always)  equipment acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        CSAACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F9Service Program Results Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 9, secs_receive_S2F9)

def secs_receive_S2F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SPID
        # SPID A:6 (always)  service program identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        SPID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F9

S2F10Service Program Results Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F10 Python Parse reply
    rcr = sp.sendSecsMsg(2, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SPR
        # SPR A:n (varies)  device dependent, any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeSPR, lengthSPR) = pylist0[0].split(':')
        SPR = (pylist0[1] if len(pylist0) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S2F11Service Program Directory Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 11, secs_receive_S2F11)

def secs_receive_S2F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F11.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F11

S2F12Service Program Directory Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F12 Python Parse reply
    rcr = sp.sendSecsMsg(2, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n SPID
        # SPID A:6 (always)  service program identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            SPID = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F13REquipment Constant Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 13, secs_receive_S2F13R)

def secs_receive_S2F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n ECID
        # ECID U4:1 (varies)  equipment constant ID, GEM requires U4
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeECID, lengthECID) = pylist1[0].split(':')
            ECID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F13R

S2F14Equipment Constant Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F14 Python Parse reply
    rcr = sp.sendSecsMsg(2, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n ECV
        # ECV A:n (varies)  equipment constant value, any scalar type (constant is a misnomer)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeECV, lengthECV) = pylist1[0].split(':')
            ECV = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F15RNew Equipment Constant Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 15, secs_receive_S2F15R)

def secs_receive_S2F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n {L:2 ECID ECV}
        # ECID U4:1 (varies)  equipment constant ID, GEM requires U4
        # ECV A:n (varies)  equipment constant value, any scalar type (constant is a misnomer)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECID, lengthECID) = pylist2[0].split(':')
            ECID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECV, lengthECV) = pylist2[0].split(':')
            ECV = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F15R

S2F16New Equipment Constant Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F16 Python Parse reply
    rcr = sp.sendSecsMsg(2, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect EAC
        # EAC B:1 (always)  equipment acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        EAC = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F17RDate and Time Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 17, secs_receive_S2F17R)

def secs_receive_S2F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F17R

S2F18Date and Time Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F18 Python Parse reply
    rcr = sp.sendSecsMsg(2, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect TIME
        # TIME A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        TIME = (pylist0[1] if len(pylist0) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S2F19RReset/Initialize Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 19, secs_receive_S2F19R)

def secs_receive_S2F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RIC
        # RIC U1:1 (varies)  reset code, 1 means power up reset
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeRIC, lengthRIC) = pylist0[0].split(':')
        RIC = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F19R

S2F20Reset Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F20 Python Parse reply
    rcr = sp.sendSecsMsg(2, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect RAC
        # RAC U1:1 (varies)  reset acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeRAC, lengthRAC) = pylist0[0].split(':')
        RAC = (pylist0[1] if len(pylist0) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S2F21[R]Remote Command Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F21 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 21, secs_receive_S2F21)

def secs_receive_S2F21(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F21.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RCMD
        # RCMD A:n (varies)  remote command, GEM requires a maximum length of 20 printable characters, taken from hex 21-7E (no spaces)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeRCMD, lengthRCMD) = pylist0[0].split(':')
        RCMD = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F21

S2F22Remote Command Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F22 Python Parse reply
    rcr = sp.sendSecsMsg(2, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect CMDA
        # CMDA B:1 (always)  command acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        CMDA = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F23RTrace Initialize Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 23, secs_receive_S2F23R)

def secs_receive_S2F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 TRID DSPER TOTSMP REPGSZ {L:n SVID}
        # TRID A:n (varies)  trace request ID
        # DSPER A:6 (varies)  data sample period, hhmmss is always supported, A:8 hhmmsscc may be supported
        # TOTSMP U4:1 (varies)  total samples to be made, should be an even multiple of REPGSZ
        # REPGSZ U4:1 (varies)  reporting group size, TOTSMP modulo REPGSZ should be 0
        # SVID U4:1 (varies)  status variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSPER, lengthDSPER) = pylist1[0].split(':')
        DSPER = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTOTSMP, lengthTOTSMP) = pylist1[0].split(':')
        TOTSMP = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeREPGSZ, lengthREPGSZ) = pylist1[0].split(':')
        REPGSZ = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeSVID, lengthSVID) = pylist2[0].split(':')
            SVID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F23R

S2F24Trace Initialize Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F24 Python Parse reply
    rcr = sp.sendSecsMsg(2, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect TIAACK
        # TIAACK B:1 (always)  trace acknowledgement code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        TIAACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F25RLoopback Diagnostic Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 25, secs_receive_S2F25R)

def secs_receive_S2F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect ABS
        # ABS (list)B:n (always)  any binary string 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        ABS = []
        for i in range(0, len(ABS)):
            ABS.append(sp.binToInt(pylist0[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S2F25R

S2F26Loopback Diagnostic Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F26 Python Parse reply
    rcr = sp.sendSecsMsg(2, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ABS
        # ABS (list)B:n (always)  any binary string 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        ABS = []
        for i in range(0, len(ABS)):
            ABS.append(sp.binToInt(pylist0[1+i])
        return # finished ok
    # end while(ok)
# end def

S2F27RInitiate Processing Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 27, secs_receive_S2F27R)

def secs_receive_S2F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 LOC PPID {L:n MID}
        # LOC B:1 (always)  material location code
        # PPID A:80 (varies)  process program ID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        LOC = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeMID, lengthMID) = pylist2[0].split(':')
            MID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F27R

S2F28Initiate Processing Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F28 Python Parse reply
    rcr = sp.sendSecsMsg(2, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect CMDA
        # CMDA B:1 (always)  command acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        CMDA = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F29REquipment Constant Namelist Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 29, secs_receive_S2F29R)

def secs_receive_S2F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n ECID
        # ECID U4:1 (varies)  equipment constant ID, GEM requires U4
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeECID, lengthECID) = pylist1[0].split(':')
            ECID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F29R

S2F30Equipment Constant Namelist Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F30 Python Parse reply
    rcr = sp.sendSecsMsg(2, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:6 ECID ECNAME ECMIN ECMAX ECDEF UNITS}
        # ECID U4:1 (varies)  equipment constant ID, GEM requires U4
        # ECNAME A:n (always)  equipment constant name
        # ECMIN A:n (varies)  equipment constant minimum value, any scalar type
        # ECMAX A:n (varies)  equipment constant maximum value, any scalar type
        # ECDEF A:n (varies)  equipment constant default value
        # UNITS A:n (always)  units identifier (see E5 Section 9)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 7 or pylist1[0] != "L:6":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECID, lengthECID) = pylist2[0].split(':')
            ECID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ECNAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECMIN, lengthECMIN) = pylist2[0].split(':')
            ECMIN = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[4])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECMAX, lengthECMAX) = pylist2[0].split(':')
            ECMAX = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[5])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeECDEF, lengthECDEF) = pylist2[0].split(':')
            ECDEF = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[6])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            UNITS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F31RDate and Time Set Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F31R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 31, secs_receive_S2F31R)

def secs_receive_S2F31R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F31R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TIME
        # TIME A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        TIME = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F31R

S2F32Date and Time Set Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F32 Python Parse reply
    rcr = sp.sendSecsMsg(2, 31, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect TIACK
        # TIACK B:1 (always)  time set acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        TIACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F33RDefine Report Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F33R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 33, secs_receive_S2F33R)

def secs_receive_S2F33R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F33R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID {L:a {L:2 RPTID {L:b VID}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RPTID U4:1 (varies)  report ID
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeVID, lengthVID) = pylist4[0].split(':')
                VID = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F33R

S2F34Define Report Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F34 Python Parse reply
    rcr = sp.sendSecsMsg(2, 33, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect DRACK
        # DRACK B:1 (always)  define report acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        DRACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F35RLink Event Report Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F35R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 35, secs_receive_S2F35R)

def secs_receive_S2F35R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F35R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID {L:a {L:2 CEID {L:b RPTID}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist3[0].split(':')
            CEID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeRPTID, lengthRPTID) = pylist4[0].split(':')
                RPTID = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 36, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F35R

S2F36Link Event Report Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F36 Python Parse reply
    rcr = sp.sendSecsMsg(2, 35, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect LRACK
        # LRACK B:1 (always)  link report acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        LRACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F37REnable/Disable Event Report Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F37R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 37, secs_receive_S2F37R)

def secs_receive_S2F37R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F37R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 CEED {L:n CEID}
        # CEED TF:1 (always)  collection event or trace enablement, true is enabled
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        CEED = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist2[0].split(':')
            CEID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 38, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F37R

S2F38Enable/Disable Event Report Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F38 Python Parse reply
    rcr = sp.sendSecsMsg(2, 37, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ERACK
        # ERACK B:1 (always)  enable/disable event report acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ERACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F39RMulti-block Inquire Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F39R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 39, secs_receive_S2F39R)

def secs_receive_S2F39R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F39R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 40, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F39R

S2F40Multi-block Grant Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F40 Python Parse reply
    rcr = sp.sendSecsMsg(2, 39, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S2F41RHost Command Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F41R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 41, secs_receive_S2F41R)

def secs_receive_S2F41R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F41R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 RCMD {L:n {L:2 CPNAME CPVAL}}
        # RCMD A:n (varies)  remote command, GEM requires a maximum length of 20 printable characters, taken from hex 21-7E (no spaces)
        # CPNAME A:n (varies)  command parameter name
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRCMD, lengthRCMD) = pylist1[0].split(':')
        RCMD = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPVAL, lengthCPVAL) = pylist3[0].split(':')
            CPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 42, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F41R

S2F42Host Command Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F42 Python Parse reply
    rcr = sp.sendSecsMsg(2, 41, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 HCACK {L:n {L:2 CPNAME CPACK}}
        # HCACK B:1 (always)  remote command acknowledge
        # CPNAME A:n (varies)  command parameter name
        # CPACK B:1 (always)  remote command parameter acknowledge, only received if error
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        HCACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            CPACK = sp.binToInt(pylist3[1])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F43RConfigure Spooling Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F43R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 43, secs_receive_S2F43R)

def secs_receive_S2F43R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F43R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:m {L:2 STRID {L:n FCNID}}
        # STRID U1:1 (always)  stream value
        # FCNID U1:1 (always)  message type function value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for m in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[m])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            STRID = int(pylist2[1])
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for n in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[n])
                if len(pylist3) < 1 or pylist3[0] != "U1:1":
                    ok = False
                    break
                FCNID = int(pylist3[1])
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 44, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F43R

S2F44Configure Spooling Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F44 Python Parse reply
    rcr = sp.sendSecsMsg(2, 43, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RSPACK {L:m {L:3 STRID STRACK {L:n FCNID}}}
        # RSPACK B:1 (always)  spooling response
        # STRID U1:1 (always)  stream value
        # STRACK B:1 (always)  spooling stream acknowledge
        # FCNID U1:1 (always)  message type function value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RSPACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            STRID = int(pylist3[1])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            STRACK = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            for n in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[n])
                if len(pylist4) < 1 or pylist4[0] != "U1:1":
                    ok = False
                    break
                FCNID = int(pylist4[1])
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F45RDefine Variable Limit Attributes Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F45R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 45, secs_receive_S2F45R)

def secs_receive_S2F45R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F45R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID {L:m {L:2 VID {L:n {L:2 LIMITID {L:2* UPPERDB LOWERDB}}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # VID A:n (varies)  A variable ID
        # LIMITID B:1 (always)  identifies a specific limit
        # UPPERDB F4:1 (varies)  the upper bound of a deadband limit
        # LOWERDB F4:1 (varies)  the lower bound of a deadband limit
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist3[0].split(':')
            VID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for n in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[n])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1 or pylist5[0] != "B:1":
                    ok = False
                    break
                LIMITID = sp.binToInt(pylist5[1])
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) == 3:   # 2 optional items found
                    pylist6 = lsplit(pylist5[1])
                    if len(pylist6) < 1:
                        ok = False
                        break
                    #(typeUPPERDB, lengthUPPERDB) = pylist6[0].split(':')
                    UPPERDB = (pylist6[1] if len(pylist6) == 2 else None)
                    pylist6 = lsplit(pylist5[2])
                    if len(pylist6) < 1:
                        ok = False
                        break
                    #(typeLOWERDB, lengthLOWERDB) = pylist6[0].split(':')
                    LOWERDB = (pylist6[1] if len(pylist6) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 46, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F45R

S2F46Define Variable Limit Attributes Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F46 Python Parse reply
    rcr = sp.sendSecsMsg(2, 45, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 VLAACK {L:m {L:3 VID LVACK {L:2* LIMITID LIMITACK}}}
        # VLAACK B:1 (always)  variable limit attribute acknowledge
        # VID A:n (varies)  A variable ID
        # LVACK B:1 (always)  variable limit error code
        # LIMITID B:1 (always)  identifies a specific limit
        # LIMITACK B:1 (always)  variable limit value error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        VLAACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist3[0].split(':')
            VID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            LVACK = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) == 3:   # 2 optional items found
                pylist4 = lsplit(pylist3[1])
                if len(pylist4) < 1 or pylist4[0] != "B:1":
                    ok = False
                    break
                LIMITID = sp.binToInt(pylist4[1])
                pylist4 = lsplit(pylist3[2])
                if len(pylist4) < 1 or pylist4[0] != "B:1":
                    ok = False
                    break
                LIMITACK = sp.binToInt(pylist4[1])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F47RVariable Limit Attribute Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F47R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 47, secs_receive_S2F47R)

def secs_receive_S2F47R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F47R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:m VID
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for m in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[m])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist1[0].split(':')
            VID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 48, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F47R

S2F48Variable Limit Attribute Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F48 Python Parse reply
    rcr = sp.sendSecsMsg(2, 47, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:m {L:2 VID {L:4* UNITS LIMITMIN LIMITMAX {L:n {L:3 LIMITID UPPERDB LOWERDB}}}}
        # VID A:n (varies)  A variable ID
        # UNITS A:n (always)  units identifier (see E5 Section 9)
        # LIMITMIN F4:1 (varies)  The minimum value allowed for the lower dead band limit
        # LIMITMAX F4:1 (varies)  The maximum value allowed for the upper dead band limit
        # LIMITID B:1 (always)  identifies a specific limit
        # UPPERDB F4:1 (varies)  the upper bound of a deadband limit
        # LOWERDB F4:1 (varies)  the lower bound of a deadband limit
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for m in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[m])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist2[0].split(':')
            VID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) == 5:   # 4 optional items found
                pylist3 = lsplit(pylist2[1])
                if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                    ok = False
                    break
                UNITS = (pylist3[1] if len(pylist3) == 2 else "")
                pylist3 = lsplit(pylist2[2])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeLIMITMIN, lengthLIMITMIN) = pylist3[0].split(':')
                LIMITMIN = (pylist3[1] if len(pylist3) == 2 else None)
                pylist3 = lsplit(pylist2[3])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeLIMITMAX, lengthLIMITMAX) = pylist3[0].split(':')
                LIMITMAX = (pylist3[1] if len(pylist3) == 2 else None)
                pylist3 = lsplit(pylist2[4])
                if len(pylist3) < 1:
                    ok = False
                    break
                for n in range(1, len(pylist3)):
                    pylist4 = lsplit(pylist3[n])
                    if len(pylist4) != 4 or pylist4[0] != "L:3":
                        ok = False
                        break
                    pylist5 = lsplit(pylist4[1])
                    if len(pylist5) < 1 or pylist5[0] != "B:1":
                        ok = False
                        break
                    LIMITID = sp.binToInt(pylist5[1])
                    pylist5 = lsplit(pylist4[2])
                    if len(pylist5) < 1:
                        ok = False
                        break
                    #(typeUPPERDB, lengthUPPERDB) = pylist5[0].split(':')
                    UPPERDB = (pylist5[1] if len(pylist5) == 2 else None)
                    pylist5 = lsplit(pylist4[3])
                    if len(pylist5) < 1:
                        ok = False
                        break
                    #(typeLOWERDB, lengthLOWERDB) = pylist5[0].split(':')
                    LOWERDB = (pylist5[1] if len(pylist5) == 2 else None)
                if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F49REnhanced Remote Command Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F49R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 49, secs_receive_S2F49R)

def secs_receive_S2F49R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F49R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID OBJSPEC RCMD {L:m {L:2 CPNAME CEPVAL}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # RCMD A:n (varies)  remote command, GEM requires a maximum length of 20 printable characters, taken from hex 21-7E (no spaces)
        # CPNAME A:n (varies)  command parameter name
        # CEPVAL A:n (varies)  an enhanced parameter value, may be a scalar of any type, a list of values of the same type, or a list of possibly nested {L:2 CPNAME CEPVAL}
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRCMD, lengthRCMD) = pylist1[0].split(':')
        RCMD = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCEPVAL, lengthCEPVAL) = pylist3[0].split(':')
            CEPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 50, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F49R

S2F50Enhanced Remote Command Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F50 Python Parse reply
    rcr = sp.sendSecsMsg(2, 49, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 HCACK {L:n {L:2 CPNAME CEPACK}}
        # HCACK B:1 (always)  remote command acknowledge
        # CPNAME A:n (varies)  command parameter name
        # CEPACK B:1 (always)  command enhanced parameter acknowledge, may be a list or nested list structure to mirror the input structure of a CEPVAL
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        HCACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            CEPACK = sp.binToInt(pylist3[1])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F51RRequest Report Identifiers Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F51R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 51, secs_receive_S2F51R)

def secs_receive_S2F51R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F51R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 52, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F51R

S2F52Return Report Identifiers Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F52 Python Parse reply
    rcr = sp.sendSecsMsg(2, 51, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n RPTID
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
            RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F53RRequest Report Definitions Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F53R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 53, secs_receive_S2F53R)

def secs_receive_S2F53R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F53R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n RPTID
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
            RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 54, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F53R

S2F54Return Report Definitions Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F54 Python Parse reply
    rcr = sp.sendSecsMsg(2, 53, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:2 RPTID {L:a VID}} 
        # RPTID U4:1 (varies)  report ID
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist2[0].split(':')
            RPTID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeVID, lengthVID) = pylist3[0].split(':')
                VID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F55RRequest Event Report Links Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F55R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 55, secs_receive_S2F55R)

def secs_receive_S2F55R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F55R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n CEID
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist1[0].split(':')
            CEID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 56, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F55R

S2F56Return Event Report Links Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F56 Python Parse reply
    rcr = sp.sendSecsMsg(2, 55, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 CEID CENAME {L:a RPTID}}
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # CENAME A:n (always)  a descriptive name for a Data Collection Event
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist2[0].split(':')
            CEID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            CENAME = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
                RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F57RRequest Enabled Events Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F57R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 57, secs_receive_S2F57R)

def secs_receive_S2F57R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F57R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 58, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F57R

S2F58Return Enabled Events Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F58 Python Parse reply
    rcr = sp.sendSecsMsg(2, 57, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n CEID
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeCEID, lengthCEID) = pylist1[0].split(':')
            CEID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F59RRequest Spool Streams and Functions Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F59R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 59, secs_receive_S2F59R)

def secs_receive_S2F59R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F59R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 60, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F59R

S2F60Return Spool Streams and Functions Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F60 Python Parse reply
    rcr = sp.sendSecsMsg(2, 59, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:2 STRID {L:a FCNID}}
        # STRID U1:1 (always)  stream value
        # FCNID U1:1 (always)  message type function value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            STRID = int(pylist2[1])
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1 or pylist3[0] != "U1:1":
                    ok = False
                    break
                FCNID = int(pylist3[1])
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F61RRequest Trace Identifiers Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F61R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 61, secs_receive_S2F61R)

def secs_receive_S2F61R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F61R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 62, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F61R

S2F62Return Trace Identifiers Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F62 Python Parse reply
    rcr = sp.sendSecsMsg(2, 61, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist1[0].split(':')
            TRID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S2F63RRequest Trace Definitions Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F63R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 2, 63, secs_receive_S2F63R)

def secs_receive_S2F63R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S2F63R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist1[0].split(':')
            TRID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 2, 64, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S2F63R

S2F64Return Trace Definitions Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S2F64 Python Parse reply
    rcr = sp.sendSecsMsg(2, 63, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:5 TRID DSPER TOTSMP REPGSZ {L:a SVID}}
        # TRID A:n (varies)  trace request ID
        # DSPER A:6 (varies)  data sample period, hhmmss is always supported, A:8 hhmmsscc may be supported
        # TOTSMP U4:1 (varies)  total samples to be made, should be an even multiple of REPGSZ
        # REPGSZ U4:1 (varies)  reporting group size, TOTSMP modulo REPGSZ should be 0
        # SVID U4:1 (varies)  status variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 6 or pylist1[0] != "L:5":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist2[0].split(':')
            TRID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeDSPER, lengthDSPER) = pylist2[0].split(':')
            DSPER = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTOTSMP, lengthTOTSMP) = pylist2[0].split(':')
            TOTSMP = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[4])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeREPGSZ, lengthREPGSZ) = pylist2[0].split(':')
            REPGSZ = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[5])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeSVID, lengthSVID) = pylist3[0].split(':')
                SVID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F1RMaterial Status Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 1, secs_receive_S3F1R)

def secs_receive_S3F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F1R

S3F2Material Status Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F2 Python Parse reply
    rcr = sp.sendSecsMsg(3, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 MF {L:m {L:3 LOC QUA MID}} 
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # LOC B:1 (always)  material location code
        # QUA B:1 (always)  quantity (format limits max to 255!)
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            LOC = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            QUA = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeMID, lengthMID) = pylist3[0].split(':')
            MID = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F3RTime to Completion Data Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 3, secs_receive_S3F3R)

def secs_receive_S3F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F3R

S3F4Time to Completion Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F4 Python Parse reply
    rcr = sp.sendSecsMsg(3, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 MF {L:m {L:3 TTC QUA MID}}
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # TTC U4:1 (varies)  time to completion, standard does not specify units, in seconds??
        # QUA B:1 (always)  quantity (format limits max to 255!)
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeTTC, lengthTTC) = pylist3[0].split(':')
            TTC = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            QUA = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeMID, lengthMID) = pylist3[0].split(':')
            MID = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F5[R]Material Found Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F5 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 5, secs_receive_S3F5)

def secs_receive_S3F5(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F5.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MF QUA
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # QUA B:1 (always)  quantity (format limits max to 255!)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        QUA = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F5

S3F6Material Found Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F6 Python Parse reply
    rcr = sp.sendSecsMsg(3, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC3
        # ACKC3 B:1 (always)  acknowledge code, 0 ok 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC3 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S3F7[R]Material Lost Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 7, secs_receive_S3F7)

def secs_receive_S3F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 MF QUA MID
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # QUA B:1 (always)  quantity (format limits max to 255!)
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        QUA = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F7

S3F8Material Lost Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F8 Python Parse reply
    rcr = sp.sendSecsMsg(3, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC3
        # ACKC3 B:1 (always)  acknowledge code, 0 ok 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC3 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S3F9RMatl ID Equate Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 9, secs_receive_S3F9R)

def secs_receive_S3F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MID EMID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # EMID A:16 (varies)  equivalent material ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeEMID, lengthEMID) = pylist1[0].split(':')
        EMID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F9R

S3F10Matl ID Equate Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F10 Python Parse reply
    rcr = sp.sendSecsMsg(3, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC3
        # ACKC3 B:1 (always)  acknowledge code, 0 ok 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC3 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S3F11RMatl ID Request Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 11, secs_receive_S3F11R)

def secs_receive_S3F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect PTN
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist0[0].split(':')
        PTN = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F11R

S3F12Matl ID Request Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F12 Python Parse reply
    rcr = sp.sendSecsMsg(3, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 PTN MIDRA MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MIDRA B:1 (always)  material ID Ack code
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        MIDRA = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S3F13RMatl ID Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 13, secs_receive_S3F13R)

def secs_receive_S3F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F13R

S3F14Matl ID Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F14 Python Parse reply
    rcr = sp.sendSecsMsg(3, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect MIDAC
        # MIDAC B:1 (always)  material ID ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        MIDAC = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S3F15RSECS-I Matls Multi-block Inquire, not required for HSMS Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 15, secs_receive_S3F15R)

def secs_receive_S3F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F15R

S3F16Matls Multi-block Grant Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F16 Python Parse reply
    rcr = sp.sendSecsMsg(3, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S3F17RCarrier Action Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 17, secs_receive_S3F17R)

def secs_receive_S3F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID CARRIERACTION CARRIERID PTN {L:n {L:2 CATTRID CATTRDATA}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CARRIERACTION A:n (always)  carrier action request
        # CARRIERID A:n (always)  carrier ID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # CATTRID A:n (varies)  carrier attribute identifier, E87 requires text per E39.1, Sec 6
        # CATTRDATA A:n (varies)  carrier attribute value (any data type)
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        CARRIERACTION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        CARRIERID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCATTRID, lengthCATTRID) = pylist3[0].split(':')
            CATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCATTRDATA, lengthCATTRDATA) = pylist3[0].split(':')
            CATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F17R

S3F18Carrier Action Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F18 Python Parse reply
    rcr = sp.sendSecsMsg(3, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F19RCancel All Carrier Out Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 19, secs_receive_S3F19R)

def secs_receive_S3F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F19R

S3F20Cancel All Carrier Out Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F20 Python Parse reply
    rcr = sp.sendSecsMsg(3, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F21RPort Group Defn Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 21, secs_receive_S3F21R)

def secs_receive_S3F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 PORTGRPNAME ACCESSMODE {L:n PTN}
        # PORTGRPNAME A:n (always)  name of a group of ports
        # ACCESSMODE U1:1 (always)  load port access mode
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PORTGRPNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        ACCESSMODE = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePTN, lengthPTN) = pylist2[0].split(':')
            PTN = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F21R

S3F22Port Group Defn Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F22 Python Parse reply
    rcr = sp.sendSecsMsg(3, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F23RPort Group Action Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 23, secs_receive_S3F23R)

def secs_receive_S3F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 PGRPACTION PORTGRPNAME {L:m {L:2 PARAMNAME PARAMVAL}}
        # PGRPACTION A:n (always)  port group command, an alias for PORTACTION?
        # PORTGRPNAME A:n (always)  name of a group of ports
        # PARAMNAME A:n (always)  argument name
        # PARAMVAL U1:1 (varies)  argument value, only defined use is ServiceStatus, 0 = OUT OF SERVICE, 1 = IN SERVICE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PGRPACTION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PORTGRPNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PARAMNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typePARAMVAL, lengthPARAMVAL) = pylist3[0].split(':')
            PARAMVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F23R

S3F24Port Group Action Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F24 Python Parse reply
    rcr = sp.sendSecsMsg(3, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F25RPort Action Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 25, secs_receive_S3F25R)

def secs_receive_S3F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 PORTACTION PTN {L:m {L:2 PARAMNAME PARAMVAL}}
        # PORTACTION A:n (always)  ChangeServiceStatus, CancelReservationAtPort or ReserveAtPort
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # PARAMNAME A:n (always)  argument name
        # PARAMVAL U1:1 (varies)  argument value, only defined use is ServiceStatus, 0 = OUT OF SERVICE, 1 = IN SERVICE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PORTACTION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PARAMNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typePARAMVAL, lengthPARAMVAL) = pylist3[0].split(':')
            PARAMVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F25R

S3F26Port Action Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F26 Python Parse reply
    rcr = sp.sendSecsMsg(3, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F27RChange Access Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 27, secs_receive_S3F27R)

def secs_receive_S3F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 ACCESSMODE {L:n PTN}
        # ACCESSMODE U1:1 (always)  load port access mode
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        ACCESSMODE = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePTN, lengthPTN) = pylist2[0].split(':')
            PTN = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F27R

S3F28Change Access Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F28 Python Parse reply
    rcr = sp.sendSecsMsg(3, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:3 PTN ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typePTN, lengthPTN) = pylist3[0].split(':')
            PTN = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F29RCarrier Tag Read Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 29, secs_receive_S3F29R)

def secs_receive_S3F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 LOCID CARRIERSPEC DATASEG DATALENGTH
        # LOCID A:n (varies)  logical ID of carrier location, E87 requires text
        # CARRIERSPEC A:n (always)  carrier object specifier (OBJSPEC)
        # DATASEG A:n (varies)  identifies data requested, E87 requires text
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeLOCID, lengthLOCID) = pylist1[0].split(':')
        LOCID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        CARRIERSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATASEG, lengthDATASEG) = pylist1[0].split(':')
        DATASEG = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F29R

S3F30Carrier Tag Read Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F30 Python Parse reply
    rcr = sp.sendSecsMsg(3, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 DATA {L:2 CAACK {L:s {L:2 ERRCODE ERRTEXT}}}
        # DATA A:n (varies)  unformatted data
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATA, lengthDATA) = pylist1[0].split(':')
        DATA = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for s in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[s])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F31RCarrier Tag Write Data Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F31R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 31, secs_receive_S3F31R)

def secs_receive_S3F31R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F31R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 LOCID CARRIERSPEC DATASEG DATALENGTH DATA
        # LOCID A:n (varies)  logical ID of carrier location, E87 requires text
        # CARRIERSPEC A:n (always)  carrier object specifier (OBJSPEC)
        # DATASEG A:n (varies)  identifies data requested, E87 requires text
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        # DATA A:n (varies)  unformatted data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeLOCID, lengthLOCID) = pylist1[0].split(':')
        LOCID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        CARRIERSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATASEG, lengthDATASEG) = pylist1[0].split(':')
        DATASEG = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATA, lengthDATA) = pylist1[0].split(':')
        DATA = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S3F31R

S3F32Carrier Tag Write Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F32 Python Parse reply
    rcr = sp.sendSecsMsg(3, 31, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:s {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F33Cancel All Pod Out Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F33 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 33, secs_receive_S3F33)

def secs_receive_S3F33(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F33.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F33

S3F34Cancel All Pod Out Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F34 Python Parse reply
    rcr = sp.sendSecsMsg(3, 33, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 CAACK {L:n {L:2 ERRCODE ERRTEXT}}
        # CAACK U1:1 (always)  carrier action acknowledge 
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CAACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S3F35Reticle Transfer Job Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F35 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 3, 35, secs_receive_S3F35)

def secs_receive_S3F35(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S3F35.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:7 JOBACTION PODID INPTN OUTPTN {L:n {L:2 ATTRID ATTRDATA}} {L:m {L:3 RETICLEID RETREMOVEINSTR {L:r {L:2 ATTRID ATTRDATA}}}} {L:k {L:2 RETICLEID2 RETPLACEINSTR}}
        # JOBACTION A:n (always)  reticle transfer command
        # PODID A:n (always)  OBJSPEC for a Pod instance
        # INPTN B:1 (always)  input material port number
        # OUTPTN B:1 (varies)  output port (PTN)
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # RETICLEID A:n (always)  OBJSPEC value for a reticle
        # RETREMOVEINSTR U1:1 (always)  pod slot reticle remove instruction
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # RETICLEID2 A:n (always)  OBJSPEC value for a second reticle
        # RETPLACEINSTR U1:1 (always)  pod slot reticle place instruction
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        JOBACTION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PODID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        INPTN = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOUTPTN, lengthOUTPTN) = pylist1[0].split(':')
        OUTPTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RETICLEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            RETREMOVEINSTR = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            for r in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[r])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRID, lengthATTRID) = pylist5[0].split(':')
                ATTRID = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRDATA, lengthATTRDATA) = pylist5[0].split(':')
                ATTRDATA = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for k in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[k])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RETICLEID2 = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            RETPLACEINSTR = int(pylist3[1])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 3, 36, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S3F35

S3F36Reticle Transfer Job Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S3F36 Python Parse reply
    rcr = sp.sendSecsMsg(3, 35, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RPMACK {L:n {L:2 ERRCODE ERRTEXT}}
        # RPMACK U1:1 (always)  reticle pod management ack code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RPMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S4F1RReady to Send Materials Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 1, secs_receive_S4F1R)

def secs_receive_S4F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F1R

S4F2Ready to Send Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F2 Python Parse reply
    rcr = sp.sendSecsMsg(4, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect RSACK
        # RSACK B:1 (always)  ready to send acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        RSACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S4F3Send Material Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 3, secs_receive_S4F3)

def secs_receive_S4F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F3

S4F5Handshake Complete Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F5 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 5, secs_receive_S4F5)

def secs_receive_S4F5(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F5.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F5

S4F7Not Ready to Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 7, secs_receive_S4F7)

def secs_receive_S4F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F7

S4F9Stuck in Sender Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 9, secs_receive_S4F9)

def secs_receive_S4F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F9

S4F11Stuck in Receiver Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 11, secs_receive_S4F11)

def secs_receive_S4F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F11.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F11

S4F13Send Incomplete Timeout Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F13 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 13, secs_receive_S4F13)

def secs_receive_S4F13(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F13.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F13

S4F15Material Received Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F15 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 15, secs_receive_S4F15)

def secs_receive_S4F15(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F15.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F15

S4F17RRequest to Receive Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 17, secs_receive_S4F17R)

def secs_receive_S4F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PTN MID
        # PTN U1:1 (varies)  material port number, E87 shows type U1:1 with data 1-255
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePTN, lengthPTN) = pylist1[0].split(':')
        PTN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F17R

S4F18Request to Receive Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F18 Python Parse reply
    rcr = sp.sendSecsMsg(4, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect RRACK
        # RRACK B:1 (always)  request to receive acknowledge
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        RRACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S4F19RTransfer Job Create Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 19, secs_receive_S4F19R)

def secs_receive_S4F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID {L:2 TRJOBNAME {L:n {L:12 TRLINK TRPORT TROBJNAME TROBJTYPE TRROLE TRRCP TRPTNR TRPTPORT TRDIR TRTYPE TRLOCATION TRAUTOSTART}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # TRJOBNAME A:80 (always)  host assigned id for transfer job
        # TRLINK U4:1 (varies)  task identifier correlation value
        # TRPORT U4:1 (varies)  port identifier
        # TROBJNAME A:n (varies)  identifies material to be transferred
        # TROBJTYPE U4:1 (varies)  identifies type of object to be transferred
        # TRROLE U1:1 (always)  indicates equipment transfer role
        # TRRCP A:80 (always)  name of transfer recipe for this handoff
        # TRPTNR A:n (always)  EQNAME of transfer partner equipment
        # TRPTPORT U4:1 (varies)  transfer partner port
        # TRDIR U1:1 (always)  transfer direction
        # TRTYPE U1:1 (always)  equipment is active or passive transfer participant
        # TRLOCATION U4:1 (varies)  material transfer location
        # TRAUTOSTART TF:1 (always)  if true material transfer is initiated by the primary when ready
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        TRJOBNAME = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 13 or pylist3[0] != "L:12":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTRLINK, lengthTRLINK) = pylist4[0].split(':')
            TRLINK = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTRPORT, lengthTRPORT) = pylist4[0].split(':')
            TRPORT = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[3])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTROBJNAME, lengthTROBJNAME) = pylist4[0].split(':')
            TROBJNAME = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[4])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTROBJTYPE, lengthTROBJTYPE) = pylist4[0].split(':')
            TROBJTYPE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[5])
            if len(pylist4) < 1 or pylist4[0] != "U1:1":
                ok = False
                break
            TRROLE = int(pylist4[1])
            pylist4 = lsplit(pylist3[6])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            TRRCP = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[7])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            TRPTNR = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[8])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTRPTPORT, lengthTRPTPORT) = pylist4[0].split(':')
            TRPTPORT = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[9])
            if len(pylist4) < 1 or pylist4[0] != "U1:1":
                ok = False
                break
            TRDIR = int(pylist4[1])
            pylist4 = lsplit(pylist3[10])
            if len(pylist4) < 1 or pylist4[0] != "U1:1":
                ok = False
                break
            TRTYPE = int(pylist4[1])
            pylist4 = lsplit(pylist3[11])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeTRLOCATION, lengthTRLOCATION) = pylist4[0].split(':')
            TRLOCATION = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[12])
            if len(pylist4) < 1 or pylist4[0] != "TF:1":
                ok = False
                break
            TRAUTOSTART = int(pylist4[1])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S4F19R

S4F20Transfer Job Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F20 Python Parse reply
    rcr = sp.sendSecsMsg(4, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TRJOBID {L:m TRATOMCID} {L:2 TRACK {L:n {L:2 ERRCODE ERRTEXT}}}
        # TRJOBID B:1 (always)  assigned identifier for transfer job
        # TRATOMCID U4:1 (varies)  assigned identifier for atomic transfer
        # TRACK TF:1 (always)  transfer activity success flag
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TRJOBID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTRATOMCID, lengthTRATOMCID) = pylist2[0].split(':')
            TRATOMCID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        TRACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S4F21RTransfer Job Command Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 21, secs_receive_S4F21R)

def secs_receive_S4F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 TRJOBID TRCMDNAME {L:n {L:2 CPNAME CPVAL}}
        # TRJOBID B:1 (always)  assigned identifier for transfer job
        # TRCMDNAME A:n (always)  text enum, CANCEL, PAUSE, RESUME, ABORT, STOP, STARTHANDOFF
        # CPNAME A:n (varies)  command parameter name
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TRJOBID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TRCMDNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPVAL, lengthCPVAL) = pylist3[0].split(':')
            CPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S4F21R

S4F22Transfer Job Command Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F22 Python Parse reply
    rcr = sp.sendSecsMsg(4, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TRACK {L:n {L:2 ERRCODE ERRTEXT}}
        # TRACK TF:1 (always)  transfer activity success flag
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        TRACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S4F23[R]Transfer Command Alert Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F23 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 23, secs_receive_S4F23)

def secs_receive_S4F23(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F23.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TRJOBID TRJOBNAME TRJOBMS {L:2 TRACK {L:n {L:2 ERRCODE  ERRTEXT}}}
        # TRJOBID B:1 (always)  assigned identifier for transfer job
        # TRJOBNAME A:80 (always)  host assigned id for transfer job
        # TRJOBMS U1:1 (always)  transfer job milestone
        # TRACK TF:1 (always)  transfer activity success flag
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TRJOBID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TRJOBNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        TRJOBMS = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        TRACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F23

S4F24Transfer Alert Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F24 Python Parse reply
    rcr = sp.sendSecsMsg(4, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S4F25RMulti-block Inquire Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 25, secs_receive_S4F25R)

def secs_receive_S4F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S4F25R

S4F26Multi-block Grant Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F26 Python Parse reply
    rcr = sp.sendSecsMsg(4, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S4F27Handoff Ready Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F27 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 27, secs_receive_S4F27)

def secs_receive_S4F27(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F27.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 EQNAME {L:11 TRLINK TRPORT TROBJNAME TROBJTYPE TRROLE TRPTNR TRPTPORT TRDIR TRTYPE TRLOCATION}
        # EQNAME A:80 (always)  factory assigned equipment identifier
        # TRLINK U4:1 (varies)  task identifier correlation value
        # TRPORT U4:1 (varies)  port identifier
        # TROBJNAME A:n (varies)  identifies material to be transferred
        # TROBJTYPE U4:1 (varies)  identifies type of object to be transferred
        # TRROLE U1:1 (always)  indicates equipment transfer role
        # TRPTNR A:n (always)  EQNAME of transfer partner equipment
        # TRPTPORT U4:1 (varies)  transfer partner port
        # TRDIR U1:1 (always)  transfer direction
        # TRTYPE U1:1 (always)  equipment is active or passive transfer participant
        # TRLOCATION U4:1 (varies)  material transfer location
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EQNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 12 or pylist1[0] != "L:11":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist2[0].split(':')
        TRLINK = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTRPORT, lengthTRPORT) = pylist2[0].split(':')
        TRPORT = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[3])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTROBJNAME, lengthTROBJNAME) = pylist2[0].split(':')
        TROBJNAME = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[4])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTROBJTYPE, lengthTROBJTYPE) = pylist2[0].split(':')
        TROBJTYPE = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[5])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        TRROLE = int(pylist2[1])
        pylist2 = lsplit(pylist1[6])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        TRPTNR = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[7])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTRPTPORT, lengthTRPTPORT) = pylist2[0].split(':')
        TRPTPORT = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[8])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        TRDIR = int(pylist2[1])
        pylist2 = lsplit(pylist1[9])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        TRTYPE = int(pylist2[1])
        pylist2 = lsplit(pylist1[10])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeTRLOCATION, lengthTRLOCATION) = pylist2[0].split(':')
        TRLOCATION = (pylist2[1] if len(pylist2) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F27

S4F29Handoff Command Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F29 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 29, secs_receive_S4F29)

def secs_receive_S4F29(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F29.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TRLINK MCINDEX HOCMDNAME {L:n {L:2 CPNAME CPVAL}}
        # TRLINK U4:1 (varies)  task identifier correlation value
        # MCINDEX U4:1 (varies)  correlation value for handoff command 
        # HOCMDNAME A:n (varies)  handoff command identifier
        # CPNAME A:n (varies)  command parameter name
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist1[0].split(':')
        TRLINK = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMCINDEX, lengthMCINDEX) = pylist1[0].split(':')
        MCINDEX = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHOCMDNAME, lengthHOCMDNAME) = pylist1[0].split(':')
        HOCMDNAME = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPVAL, lengthCPVAL) = pylist3[0].split(':')
            CPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F29

S4F31Handoff Command Complete Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F31 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 31, secs_receive_S4F31)

def secs_receive_S4F31(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F31.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 TRLINK MCINDEX {L:2 HOACK {L:n {L:2 ERRCODE ERRTEXT}}}
        # TRLINK U4:1 (varies)  task identifier correlation value
        # MCINDEX U4:1 (varies)  correlation value for handoff command 
        # HOACK TF:1 (always)  handoff success flag
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist1[0].split(':')
        TRLINK = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMCINDEX, lengthMCINDEX) = pylist1[0].split(':')
        MCINDEX = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        HOACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F31

S4F33Handoff Verified Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F33 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 33, secs_receive_S4F33)

def secs_receive_S4F33(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F33.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TRLINK {L:2 HOACK {L:n ERRCODE ERRTEXT}} 
        # TRLINK U4:1 (varies)  task identifier correlation value
        # HOACK TF:1 (always)  handoff success flag
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist1[0].split(':')
        TRLINK = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        HOACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F33

S4F35Handoff Cancel Ready Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F35 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 35, secs_receive_S4F35)

def secs_receive_S4F35(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F35.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TRLINK
        # TRLINK U4:1 (varies)  task identifier correlation value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist0[0].split(':')
        TRLINK = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 36, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F35

S4F37Handoff Cancel Ready Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F37 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 37, secs_receive_S4F37)

def secs_receive_S4F37(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F37.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TRLINK HOCANCELACK
        # TRLINK U4:1 (varies)  task identifier correlation value
        # HOCANCELACK U1:1 (always)  hand off cancel ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist1[0].split(':')
        TRLINK = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        HOCANCELACK = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 38, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F37

S4F39Handoff Halt Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F39 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 39, secs_receive_S4F39)

def secs_receive_S4F39(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F39.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TRLINK
        # TRLINK U4:1 (varies)  task identifier correlation value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist0[0].split(':')
        TRLINK = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 40, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F39

S4F41Handoff Halt Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S4F41 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 4, 41, secs_receive_S4F41)

def secs_receive_S4F41(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S4F41.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TRLINK HOHALTACK
        # TRLINK U4:1 (varies)  task identifier correlation value
        # HOHALTACK U1:1 (always)  hand off halt ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRLINK, lengthTRLINK) = pylist1[0].split(':')
        TRLINK = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        HOHALTACK = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 4, 42, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S4F41

S5F1[R]Alarm Report Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F1 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 1, secs_receive_S5F1)

def secs_receive_S5F1(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F1.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 ALCD ALID ALTX
        # ALCD B:1 (always)  alarm code byte, >= 128 alarm is set, bit field use is deprecated
        # ALID U4:1 (varies)  Alarm type ID
        # ALTX A:120 (always)  alarm text, the length limit was recently raised from 40
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ALCD = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeALID, lengthALID) = pylist1[0].split(':')
        ALID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ALTX = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S5F1

S5F2Alarm Report Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F2 Python Parse reply
    rcr = sp.sendSecsMsg(5, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC5
        # ACKC5 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC5 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S5F3[R]Enable/Disable Alarm Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 3, secs_receive_S5F3)

def secs_receive_S5F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 ALED ALID
        # ALED B:1 (always)  enable/disable alarm, 128 means enable, 0 disable
        # ALID U4:1 (varies)  Alarm type ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ALED = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeALID, lengthALID) = pylist1[0].split(':')
        ALID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S5F3

S5F4Enable/Disable Alarm Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F4 Python Parse reply
    rcr = sp.sendSecsMsg(5, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC5
        # ACKC5 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC5 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S5F5RList Alarms Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 5, secs_receive_S5F5R)

def secs_receive_S5F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect ALIDVECTOR
        # ALIDVECTOR (list)U4:n (varies)  alarm ID vector
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeALIDVECTOR, lengthALIDVECTOR) = pylist0[0].split(':')
        ALIDVECTOR = []
        for i in range(0, len(ALIDVECTOR)):
            ALIDVECTOR.append(int(pylist0[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S5F5R

S5F6List Alarm Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F6 Python Parse reply
    rcr = sp.sendSecsMsg(5, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 ALCD ALID ALTX}
        # ALCD B:1 (always)  alarm code byte, >= 128 alarm is set, bit field use is deprecated
        # ALID U4:1 (varies)  Alarm type ID
        # ALTX A:120 (always)  alarm text, the length limit was recently raised from 40
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or pylist2[0] != "B:1":
                ok = False
                break
            ALCD = sp.binToInt(pylist2[1])
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeALID, lengthALID) = pylist2[0].split(':')
            ALID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ALTX = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S5F7RList Enabled Alarm Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 7, secs_receive_S5F7R)

def secs_receive_S5F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S5F7R

S5F8List Enabled Alarm Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F8 Python Parse reply
    rcr = sp.sendSecsMsg(5, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 ALCD ALID ALTX}
        # ALCD B:1 (always)  alarm code byte, >= 128 alarm is set, bit field use is deprecated
        # ALID U4:1 (varies)  Alarm type ID
        # ALTX A:120 (always)  alarm text, the length limit was recently raised from 40
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or pylist2[0] != "B:1":
                ok = False
                break
            ALCD = sp.binToInt(pylist2[1])
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeALID, lengthALID) = pylist2[0].split(':')
            ALID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ALTX = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S5F9[R]Exception Post Notify Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 9, secs_receive_S5F9)

def secs_receive_S5F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 TIMESTAMP EXID EXTYPE EXMESSAGE {L:n EXRECVRA}
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # EXID A:20 (always)  exception identifier
        # EXTYPE A:5 (always)  exception type, "ALARM" or "ERROR"
        # EXMESSAGE A:n (always)  exception description
        # EXRECVRA A:40 (always)  exception recovery action description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXMESSAGE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            EXRECVRA = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S5F9

S5F10Exception Post Confirm Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F10 Python Parse reply
    rcr = sp.sendSecsMsg(5, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S5F11[R]Exception Clear Notify Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 11, secs_receive_S5F11)

def secs_receive_S5F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F11.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TIMESTAMP EXID EXTYPE EXMESSAGE
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # EXID A:20 (always)  exception identifier
        # EXTYPE A:5 (always)  exception type, "ALARM" or "ERROR"
        # EXMESSAGE A:n (always)  exception description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXMESSAGE = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S5F11

S5F12Exception Clear Confirm Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F12 Python Parse reply
    rcr = sp.sendSecsMsg(5, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S5F13RException Recover Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 13, secs_receive_S5F13R)

def secs_receive_S5F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 EXID EXRECVRA
        # EXID A:20 (always)  exception identifier
        # EXRECVRA A:40 (always)  exception recovery action description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXRECVRA = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S5F13R

S5F14Exception Recover Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F14 Python Parse reply
    rcr = sp.sendSecsMsg(5, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 EXID {L:2 ACKA {L:2* ERRCODE ERRTEXT}}
        # EXID A:20 (always)  exception identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) == 3:   # 2 optional items found
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S5F15[R]Exception Recovery Complete Notify Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F15 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 15, secs_receive_S5F15)

def secs_receive_S5F15(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F15.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 TIMESTAMP EXID {L:2 ACKA {L:2* ERRCODE ERRTEXT}}
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # EXID A:20 (always)  exception identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) == 3:   # 2 optional items found
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S5F15

S5F16Exception Recovery Complete Confirm Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F16 Python Parse reply
    rcr = sp.sendSecsMsg(5, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S5F17RException Recovery Abort Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 5, 17, secs_receive_S5F17R)

def secs_receive_S5F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S5F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect EXID
        # EXID A:20 (always)  exception identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 5, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S5F17R

S5F18Exception Recovery Abort Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S5F18 Python Parse reply
    rcr = sp.sendSecsMsg(5, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 EXID {L:2 ACKA {L:2* ERRCODE ERRTEXT}}
        # EXID A:20 (always)  exception identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EXID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) == 3:   # 2 optional items found
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S6F1[R]Trace Data Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F1 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 1, secs_receive_S6F1)

def secs_receive_S6F1(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F1.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TRID SMPLN STIME {L:n SV}
        # TRID A:n (varies)  trace request ID
        # SMPLN U4:1 (varies)  sample number
        # STIME A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # SV A:n (varies)  status variable value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeSMPLN, lengthSMPLN) = pylist1[0].split(':')
        SMPLN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        STIME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeSV, lengthSV) = pylist2[0].split(':')
            SV = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F1

S6F2Trace Data Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F2 Python Parse reply
    rcr = sp.sendSecsMsg(6, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F3[R]Discrete Variable Data Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 3, secs_receive_S6F3)

def secs_receive_S6F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID CEID {L:n {L:2 DSID {L:m {L:2 DVNAME DVVAL}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # DSID A:n (varies)  data set ID, akin to a report type
        # DVNAME U4:1 (varies)  data value name, generically a VID, therefore GEM requires Un type
        # DVVAL A:n (varies)  data value, any format including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeDSID, lengthDSID) = pylist3[0].split(':')
            DSID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for m in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[m])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeDVNAME, lengthDVNAME) = pylist5[0].split(':')
                DVNAME = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeDVVAL, lengthDVVAL) = pylist5[0].split(':')
                DVVAL = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F3

S6F4Discrete Variable Data Send Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F4 Python Parse reply
    rcr = sp.sendSecsMsg(6, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F5RMulti-block Data Send Inquire Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 5, secs_receive_S6F5R)

def secs_receive_S6F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F5R

S6F6Multi-block Grant Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F6 Python Parse reply
    rcr = sp.sendSecsMsg(6, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT6
        # GRANT6 B:1 (always)  multblock permission grant
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F7RData Transfer Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 7, secs_receive_S6F7R)

def secs_receive_S6F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DATAID
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist0[0].split(':')
        DATAID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F7R

S6F8Data Transfer Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F8 Python Parse reply
    rcr = sp.sendSecsMsg(6, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 DATAID CEID {L:n DSID {L:m {L:2 DVNAME DVVAL}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # DSID A:n (varies)  data set ID, akin to a report type
        # DVNAME U4:1 (varies)  data value name, generically a VID, therefore GEM requires Un type
        # DVVAL A:n (varies)  data value, any format including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeDSID, lengthDSID) = pylist2[0].split(':')
            DSID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            for m in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[m])
                if len(pylist3) != 3 or pylist3[0] != "L:2":
                    ok = False
                    break
                pylist4 = lsplit(pylist3[1])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeDVNAME, lengthDVNAME) = pylist4[0].split(':')
                DVNAME = (pylist4[1] if len(pylist4) == 2 else None)
                pylist4 = lsplit(pylist3[2])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeDVVAL, lengthDVVAL) = pylist4[0].split(':')
                DVVAL = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S6F9[R]Formatted Variable Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 9, secs_receive_S6F9)

def secs_receive_S6F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 PFCD DATAID CEID {L:n {L:2 DSID {L:m DVVAL}}}
        # PFCD B:1 (always)  predefined form selector
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # DSID A:n (varies)  data set ID, akin to a report type
        # DVVAL A:n (varies)  data value, any format including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        PFCD = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeDSID, lengthDSID) = pylist3[0].split(':')
            DSID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for m in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[m])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeDVVAL, lengthDVVAL) = pylist4[0].split(':')
                DVVAL = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F9

S6F10Formatted Variable Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F10 Python Parse reply
    rcr = sp.sendSecsMsg(6, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F11REvent Report Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 11, secs_receive_S6F11R)

def secs_receive_S6F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID CEID {L:a {L:2 RPTID {L:b V}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeV, lengthV) = pylist4[0].split(':')
                V = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F11R

S6F12Event Report Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F12 Python Parse reply
    rcr = sp.sendSecsMsg(6, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F13RAnnotated Event Report Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 13, secs_receive_S6F13R)

def secs_receive_S6F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID CEID {L:a {L:2 RPTID {L:b {L:2 VID V}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        # VID A:n (varies)  A variable ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeVID, lengthVID) = pylist5[0].split(':')
                VID = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeV, lengthV) = pylist5[0].split(':')
                V = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F13R

S6F14Annotated Event Report Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F14 Python Parse reply
    rcr = sp.sendSecsMsg(6, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F15REvent Report Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 15, secs_receive_S6F15R)

def secs_receive_S6F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect CEID
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist0[0].split(':')
        CEID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F15R

S6F16Event Report Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F16 Python Parse reply
    rcr = sp.sendSecsMsg(6, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 DATAID CEID {L:a {L:2 RPTID {L:b V}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeV, lengthV) = pylist4[0].split(':')
                V = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S6F17RAnnotated Event Report Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 17, secs_receive_S6F17R)

def secs_receive_S6F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect CEID
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist0[0].split(':')
        CEID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F17R

S6F18Annotated Event Report Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F18 Python Parse reply
    rcr = sp.sendSecsMsg(6, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 DATAID CEID {L:a {L:2 RPTID {L:b {L:2 VID V}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        # VID A:n (varies)  A variable ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for b in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[b])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeVID, lengthVID) = pylist5[0].split(':')
                VID = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeV, lengthV) = pylist5[0].split(':')
                V = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S6F19RIndividual Report Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 19, secs_receive_S6F19R)

def secs_receive_S6F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RPTID
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist0[0].split(':')
        RPTID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F19R

S6F20Individual Report Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F20 Python Parse reply
    rcr = sp.sendSecsMsg(6, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n V
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeV, lengthV) = pylist1[0].split(':')
            V = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S6F21RAnnotated Individual Report Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 21, secs_receive_S6F21R)

def secs_receive_S6F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RPTID
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist0[0].split(':')
        RPTID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F21R

S6F22Annotated Individual Report Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F22 Python Parse reply
    rcr = sp.sendSecsMsg(6, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:2 VID V}
        # VID A:n (varies)  A variable ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist2[0].split(':')
            VID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeV, lengthV) = pylist2[0].split(':')
            V = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S6F23RRequest or Purge Spooled Data Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 23, secs_receive_S6F23R)

def secs_receive_S6F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RSDC
        # RSDC U1:1 (always)  spool request code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        RSDC = int(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F23R

S6F24Request or Purge Spooled Data Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F24 Python Parse reply
    rcr = sp.sendSecsMsg(6, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect RSDA
        # RSDA B:1 (always)  spool request reply
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        RSDA = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F25[R]Notification Report Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F25 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 25, secs_receive_S6F25)

def secs_receive_S6F25(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F25.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:7 DATAID OPID LINKID RCPSPEC RMCHGSTAT {L:m {L:2 RCPATTRID RCPATTRDATA}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OPID U4:1 (varies)  operation identifier
        # LINKID U4:1 (always)  correlates the RMOPID value in a request to a completion report
        # RCPSPEC A:n (always)  recipe specifier
        # RMCHGSTAT U4:1 (varies)  object change type
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LINKID = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMCHGSTAT, lengthRMCHGSTAT) = pylist1[0].split(':')
        RMCHGSTAT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F25

S6F26Notification Report Send Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F26 Python Parse reply
    rcr = sp.sendSecsMsg(6, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC6
        # ACKC6 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC6 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S6F27[R]Trace Report Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F27 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 27, secs_receive_S6F27)

def secs_receive_S6F27(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F27.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID TRID {L:n {L:p {L:2 RPTID {L:m V}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # TRID A:n (varies)  trace request ID
        # RPTID U4:1 (varies)  report ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            for p in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[p])
                if len(pylist3) != 3 or pylist3[0] != "L:2":
                    ok = False
                    break
                pylist4 = lsplit(pylist3[1])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeRPTID, lengthRPTID) = pylist4[0].split(':')
                RPTID = (pylist4[1] if len(pylist4) == 2 else None)
                pylist4 = lsplit(pylist3[2])
                if len(pylist4) < 1:
                    ok = False
                    break
                for m in range(1, len(pylist4)):
                    pylist5 = lsplit(pylist4[m])
                    if len(pylist5) < 1:
                        ok = False
                        break
                    #(typeV, lengthV) = pylist5[0].split(':')
                    V = (pylist5[1] if len(pylist5) == 2 else None)
                if not ok: break
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S6F27

S6F28Trace Report Send Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F28 Python Parse reply
    rcr = sp.sendSecsMsg(6, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist0[0].split(':')
        TRID = (pylist0[1] if len(pylist0) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S6F29RTrace Report Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 6, 29, secs_receive_S6F29R)

def secs_receive_S6F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S6F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist0[0].split(':')
        TRID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 6, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S6F29R

S6F30Trace Report Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S6F30 Python Parse reply
    rcr = sp.sendSecsMsg(6, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TRID {L:n {L:2 RPTID {L:m V}}} ERRCODE
        # TRID A:n (varies)  trace request ID
        # RPTID U4:1 (varies)  report ID
        # V A:n (varies)  variable value, any type including list
        # ERRCODE U4:1 (varies)  error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for m in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[m])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeV, lengthV) = pylist4[0].split(':')
                V = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist1[0].split(':')
        ERRCODE = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S7F1RProcess Program Load Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 1, secs_receive_S7F1R)

def secs_receive_S7F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PPID LENGTH
        # PPID A:80 (varies)  process program ID
        # LENGTH U4:1 (always)  program length in bytes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LENGTH = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F1R

S7F2Process Program Load Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F2 Python Parse reply
    rcr = sp.sendSecsMsg(7, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PPGNT
        # PPGNT B:1 (always)  process program transfer grant status
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        PPGNT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F3RProcess Program Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 3, secs_receive_S7F3R)

def secs_receive_S7F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PPID PPBODY
        # PPID A:80 (varies)  process program ID
        # PPBODY (list)B:n (varies)  process program data, any non-list type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPBODY, lengthPPBODY) = pylist1[0].split(':')
        PPBODY = []
        for i in range(0, len(PPBODY)):
            PPBODY.append(sp.binToInt(pylist1[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F3R

S7F4Process Program Send Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F4 Python Parse reply
    rcr = sp.sendSecsMsg(7, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F5RProcess Program Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 5, secs_receive_S7F5R)

def secs_receive_S7F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect PPID
        # PPID A:80 (varies)  process program ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist0[0].split(':')
        PPID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F5R

S7F6Process Program Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F6 Python Parse reply
    rcr = sp.sendSecsMsg(7, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 PPID PPBODY
        # PPID A:80 (varies)  process program ID
        # PPBODY (list)B:n (varies)  process program data, any non-list type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPBODY, lengthPPBODY) = pylist1[0].split(':')
        PPBODY = []
        for i in range(0, len(PPBODY)):
            PPBODY.append(sp.binToInt(pylist1[1+i])
        return # finished ok
    # end while(ok)
# end def

S7F7RProcess Program ID Request Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 7, secs_receive_S7F7R)

def secs_receive_S7F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist0[0].split(':')
        MID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F7R

S7F8Process Program ID Data Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F8 Python Parse reply
    rcr = sp.sendSecsMsg(7, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 PPID MID
        # PPID A:80 (varies)  process program ID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S7F9RMatl/Process Matrix Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 9, secs_receive_S7F9R)

def secs_receive_S7F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F9R

S7F10Matl/Process Matrix Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F10 Python Parse reply
    rcr = sp.sendSecsMsg(7, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:2 PPID {L:a MID}}
        # PPID A:80 (varies)  process program ID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePPID, lengthPPID) = pylist2[0].split(':')
            PPID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeMID, lengthMID) = pylist3[0].split(':')
                MID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S7F11[R]Matl/Process Matrix Update Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 11, secs_receive_S7F11)

def secs_receive_S7F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F11.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n {L:2 PPID {L:a MID}}
        # PPID A:80 (varies)  process program ID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePPID, lengthPPID) = pylist2[0].split(':')
            PPID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeMID, lengthMID) = pylist3[0].split(':')
                MID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F11

S7F12Matl/Process Matrix Update Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F12 Python Parse reply
    rcr = sp.sendSecsMsg(7, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F13[R]Matl/Process Matrix Delete Entry Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F13 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 13, secs_receive_S7F13)

def secs_receive_S7F13(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F13.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n {L:2 PPID {L:a MID}}
        # PPID A:80 (varies)  process program ID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePPID, lengthPPID) = pylist2[0].split(':')
            PPID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeMID, lengthMID) = pylist3[0].split(':')
                MID = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F13

S7F14Delete Matl/Process Matrix Entry Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F14 Python Parse reply
    rcr = sp.sendSecsMsg(7, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F15RMatrix Mode Select Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 15, secs_receive_S7F15R)

def secs_receive_S7F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MMODE
        # MMODE B:1 (always)  matrix mode selection
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        MMODE = sp.binToInt(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F15R

S7F16Matrix Mode Select Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F16 Python Parse reply
    rcr = sp.sendSecsMsg(7, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F17RDelete Process Program Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 17, secs_receive_S7F17R)

def secs_receive_S7F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n PPID
        # PPID A:80 (varies)  process program ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typePPID, lengthPPID) = pylist1[0].split(':')
            PPID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F17R

S7F18Delete Process Program Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F18 Python Parse reply
    rcr = sp.sendSecsMsg(7, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F19RCurrent Process Program Dir Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 19, secs_receive_S7F19R)

def secs_receive_S7F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F19R

S7F20Current Process Program Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F20 Python Parse reply
    rcr = sp.sendSecsMsg(7, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n PPID
        # PPID A:80 (varies)  process program ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typePPID, lengthPPID) = pylist1[0].split(':')
            PPID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S7F21Process Capabilities Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F21 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 21, secs_receive_S7F21)

def secs_receive_S7F21(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F21.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F21

S7F22Process Capabilities Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F22 Python Parse reply
    rcr = sp.sendSecsMsg(7, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:5 MDLN SOFTREV CMDMAX BYTMAX {L:c {L:11 CCODE CNAME RQCMD BLKDEF BCDS IBCDS NBCDS ACDS IACDS NACDS {L:p L:x}}}
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        # CMDMAX U1:1 (varies)  maximum number of commands allowed, 0=unlimited
        # BYTMAX U4:1 (varies)  process program maximum byte length, 0 means no limit
        # CCODE A:n (varies)  process operation command code
        # CNAME A:16 (always)  text name for a CCODE
        # RQCMD TF:1 (always)  flag that command is required
        # BLKDEF I1:1 (always)  command definition block relationship, standard incorrectly says type U1 is possible
        # BCDS (list)U2:n (varies)  before command code vector
        # IBCDS (list)U2:n (varies)  vector of immediately before command codes
        # NBCDS (list)U2:n (varies)  vector of not before command codes
        # ACDS U2:1 (varies)  after command codes
        # IACDS (list)U2:n (varies)  vector of immediately after command codes
        # NACDS (list)U2:n (varies)  vector of not after command codes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCMDMAX, lengthCMDMAX) = pylist1[0].split(':')
        CMDMAX = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeBYTMAX, lengthBYTMAX) = pylist1[0].split(':')
        BYTMAX = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) != 12 or pylist2[0] != "L:11":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCCODE, lengthCCODE) = pylist3[0].split(':')
            CCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            CNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "TF:1":
                ok = False
                break
            RQCMD = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "I1:1":
                ok = False
                break
            BLKDEF = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeBCDS, lengthBCDS) = pylist3[0].split(':')
            BCDS = []
            for i in range(0, len(BCDS)):
                BCDS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeIBCDS, lengthIBCDS) = pylist3[0].split(':')
            IBCDS = []
            for i in range(0, len(IBCDS)):
                IBCDS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeNBCDS, lengthNBCDS) = pylist3[0].split(':')
            NBCDS = []
            for i in range(0, len(NBCDS)):
                NBCDS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeACDS, lengthACDS) = pylist3[0].split(':')
            ACDS = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeIACDS, lengthIACDS) = pylist3[0].split(':')
            IACDS = []
            for i in range(0, len(IACDS)):
                IACDS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[10])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeNACDS, lengthNACDS) = pylist3[0].split(':')
            NACDS = []
            for i in range(0, len(NACDS)):
                NACDS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[11])
            if len(pylist3) < 1:
                ok = False
                break
            for p in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[p])
                if len(pylist4) != 1 or pylist4[0] != "L:x":
                    ok = False
                    break
                # single token data such as L:0 or U4:0 has been received as expected
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S7F23RFormatted Process Program Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 23, secs_receive_S7F23R)

def secs_receive_S7F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 PPID MDLN SOFTREV {L:c {L:2 CCODE {L:p PPARM}}}
        # PPID A:80 (varies)  process program ID
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        # CCODE A:n (varies)  process operation command code
        # PPARM A:n (varies)  process parameter, any scalar or vector
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCCODE, lengthCCODE) = pylist3[0].split(':')
            CCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for p in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[p])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typePPARM, lengthPPARM) = pylist4[0].split(':')
                PPARM = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F23R

S7F24Formatted Process Program Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F24 Python Parse reply
    rcr = sp.sendSecsMsg(7, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F25RFormatted Process Program Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 25, secs_receive_S7F25R)

def secs_receive_S7F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect PPID
        # PPID A:80 (varies)  process program ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist0[0].split(':')
        PPID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F25R

S7F26Formatted Process Program Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F26 Python Parse reply
    rcr = sp.sendSecsMsg(7, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 PPID MDLN SOFTREV {L:c {L:2 CCODE {L:p PPARM}}}
        # PPID A:80 (varies)  process program ID
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        # CCODE A:n (varies)  process operation command code
        # PPARM A:n (varies)  process parameter, any scalar or vector
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCCODE, lengthCCODE) = pylist3[0].split(':')
            CCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for p in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[p])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typePPARM, lengthPPARM) = pylist4[0].split(':')
                PPARM = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S7F27RProcess Program Verification Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 27, secs_receive_S7F27R)

def secs_receive_S7F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PPID {L:n {L:3 ACKC7A SEQNUM ERRW7}}
        # PPID A:80 (varies)  process program ID
        # ACKC7A U4:1 (varies)  process program check code
        # SEQNUM U4:1 (varies)  process program command number
        # ERRW7 A:n (varies)  process program error description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeACKC7A, lengthACKC7A) = pylist3[0].split(':')
            ACKC7A = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeSEQNUM, lengthSEQNUM) = pylist3[0].split(':')
            SEQNUM = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRW7, lengthERRW7) = pylist3[0].split(':')
            ERRW7 = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F27R

S7F28Process Program Verification Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F28 Python Parse reply
    rcr = sp.sendSecsMsg(7, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S7F29RProcess Program Verification Inquire Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 29, secs_receive_S7F29R)

def secs_receive_S7F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect LENGTH
        # LENGTH U4:1 (always)  program length in bytes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U4:1":
            ok = False
            break
        LENGTH = int(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F29R

S7F30Process Program Verification Grant Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F30 Python Parse reply
    rcr = sp.sendSecsMsg(7, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PPGNT
        # PPGNT B:1 (always)  process program transfer grant status
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        PPGNT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F31RVerification Request Send Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F31R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 31, secs_receive_S7F31R)

def secs_receive_S7F31R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F31R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 PPID MDLN SOFTREV {L:c {L:2 CCODE {L:p PPARM}}}
        # PPID A:80 (varies)  process program ID
        # MDLN A:20 (always)  equipment model type
        # SOFTREV A:20 (always)  software revision
        # CCODE A:n (varies)  process operation command code
        # PPARM A:n (varies)  process parameter, any scalar or vector
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MDLN = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SOFTREV = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCCODE, lengthCCODE) = pylist3[0].split(':')
            CCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for p in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[p])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typePPARM, lengthPPARM) = pylist4[0].split(':')
                PPARM = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S7F31R

S7F32Verification Request Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F32 Python Parse reply
    rcr = sp.sendSecsMsg(7, 31, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F33RProcess Program Available Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F33R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 33, secs_receive_S7F33R)

def secs_receive_S7F33R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F33R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect PPID
        # PPID A:80 (varies)  process program ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist0[0].split(':')
        PPID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F33R

S7F34Process Program Availability Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F34 Python Parse reply
    rcr = sp.sendSecsMsg(7, 33, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 PPID UNFLEN FRMLEN
        # PPID A:80 (varies)  process program ID
        # UNFLEN U4:1 (varies)  unformatted process program length if available, else 0
        # FRMLEN U4:1 (varies)  formatted process program length if available, else 0
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeUNFLEN, lengthUNFLEN) = pylist1[0].split(':')
        UNFLEN = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeFRMLEN, lengthFRMLEN) = pylist1[0].split(':')
        FRMLEN = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S7F35RProcess Program for MID Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F35R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 35, secs_receive_S7F35R)

def secs_receive_S7F35R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F35R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MID
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist0[0].split(':')
        MID = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 36, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F35R

S7F36Process Program for MID Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F36 Python Parse reply
    rcr = sp.sendSecsMsg(7, 35, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 MID PPID PPBODY
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # PPID A:80 (varies)  process program ID
        # PPBODY (list)B:n (varies)  process program data, any non-list type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPID, lengthPPID) = pylist1[0].split(':')
        PPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePPBODY, lengthPPBODY) = pylist1[0].split(':')
        PPBODY = []
        for i in range(0, len(PPBODY)):
            PPBODY.append(sp.binToInt(pylist1[1+i])
        return # finished ok
    # end while(ok)
# end def

S7F37RLarge PP Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F37R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 37, secs_receive_S7F37R)

def secs_receive_S7F37R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F37R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist0[0].split(':')
        DSNAME = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 38, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F37R

S7F38Large PP Send Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F38 Python Parse reply
    rcr = sp.sendSecsMsg(7, 37, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F39RLarge Formatted PP Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F39R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 39, secs_receive_S7F39R)

def secs_receive_S7F39R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F39R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist0[0].split(':')
        DSNAME = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 40, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F39R

S7F40Large Formatted PP Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F40 Python Parse reply
    rcr = sp.sendSecsMsg(7, 39, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F41RLarge PP Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F41R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 41, secs_receive_S7F41R)

def secs_receive_S7F41R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F41R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist0[0].split(':')
        DSNAME = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 42, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F41R

S7F42Large PP Req Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F42 Python Parse reply
    rcr = sp.sendSecsMsg(7, 41, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S7F43RLarge Formatted PP Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F43R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 7, 43, secs_receive_S7F43R)

def secs_receive_S7F43R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S7F43R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist0[0].split(':')
        DSNAME = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 7, 44, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S7F43R

S7F44Large Formatted PP Req Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S7F44 Python Parse reply
    rcr = sp.sendSecsMsg(7, 43, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC7
        # ACKC7 B:1 (always)  S7 acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC7 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S8F1RBoot Program Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S8F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 8, 1, secs_receive_S8F1R)

def secs_receive_S8F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S8F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 8, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S8F1R

S8F2Boot Program Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S8F2 Python Parse reply
    rcr = sp.sendSecsMsg(8, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect BPD
        # BPD (list)B:n (always)  boot program data,  the fantasy of using SECS for boot programs has been revived
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        BPD = []
        for i in range(0, len(BPD)):
            BPD.append(sp.binToInt(pylist0[1+i])
        return # finished ok
    # end while(ok)
# end def

S8F3RExecutive Program Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S8F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 8, 3, secs_receive_S8F3R)

def secs_receive_S8F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S8F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 8, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S8F3R

S8F4Executive Program Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S8F4 Python Parse reply
    rcr = sp.sendSecsMsg(8, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect EPD
        # EPD (list)B:n (always)  executive program data, the fantasy of using SECS for this has been revived
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        EPD = []
        for i in range(0, len(EPD)):
            EPD.append(sp.binToInt(pylist0[1+i])
        return # finished ok
    # end while(ok)
# end def

S9F1Unknown Device ID Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F1 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 1, secs_receive_S9F1)

def secs_receive_S9F1(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F1.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MHEAD
        # MHEAD (list)B:10 (always)  message header of received block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        MHEAD = []
        for i in range(0, len(MHEAD)):
            MHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F1

S9F3Unknown Stream Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 3, secs_receive_S9F3)

def secs_receive_S9F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MHEAD
        # MHEAD (list)B:10 (always)  message header of received block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        MHEAD = []
        for i in range(0, len(MHEAD)):
            MHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F3

S9F5Unknown Function Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F5 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 5, secs_receive_S9F5)

def secs_receive_S9F5(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F5.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MHEAD
        # MHEAD (list)B:10 (always)  message header of received block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        MHEAD = []
        for i in range(0, len(MHEAD)):
            MHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F5

S9F7Illegal Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 7, secs_receive_S9F7)

def secs_receive_S9F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MHEAD
        # MHEAD (list)B:10 (always)  message header of received block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        MHEAD = []
        for i in range(0, len(MHEAD)):
            MHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F7

S9F9Transaction Timeout Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 9, secs_receive_S9F9)

def secs_receive_S9F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect SHEAD
        # SHEAD (list)B:10 (always)  message header of sent block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        SHEAD = []
        for i in range(0, len(SHEAD)):
            SHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F9

S9F11Data Too Long Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 11, secs_receive_S9F11)

def secs_receive_S9F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F11.'''
    ok = True
    while ok:   # break out of loop on error
        # expect MHEAD
        # MHEAD (list)B:10 (always)  message header of received block
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("B:"):
            ok = False
            break
        MHEAD = []
        for i in range(0, len(MHEAD)):
            MHEAD.append(sp.binToInt(pylist0[1+i])
    # here by break from while ok
# end recv_S9F11

S9F13Conversation Timeout Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S9F13 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 9, 13, secs_receive_S9F13)

def secs_receive_S9F13(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S9F13.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MEXP EDID
        # MEXP A:6 (always)  message expected in form of SxxFyy
        # EDID A:80 (varies)  expected data identification, PPID or SPID or PTN
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        MEXP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeEDID, lengthEDID) = pylist1[0].split(':')
        EDID = (pylist1[1] if len(pylist1) == 2 else None)
    # here by break from while ok
# end recv_S9F13

S10F1[R]Terminal Request Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F1 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 10, 1, secs_receive_S10F1)

def secs_receive_S10F1(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S10F1.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TID TEXT
        # TID B:1 (always)  terminal ID
        # TEXT A:120 (varies)  line of text for display, no standard max size
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTEXT, lengthTEXT) = pylist1[0].split(':')
        TEXT = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 10, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S10F1

S10F2Terminal Request Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F2 Python Parse reply
    rcr = sp.sendSecsMsg(10, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC10
        # ACKC10 B:1 (always)  acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC10 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S10F3[R]Terminal Display, Single Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F3 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 10, 3, secs_receive_S10F3)

def secs_receive_S10F3(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S10F3.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TID TEXT
        # TID B:1 (always)  terminal ID
        # TEXT A:120 (varies)  line of text for display, no standard max size
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTEXT, lengthTEXT) = pylist1[0].split(':')
        TEXT = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 10, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S10F3

S10F4Terminal Display, Single Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F4 Python Parse reply
    rcr = sp.sendSecsMsg(10, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC10
        # ACKC10 B:1 (always)  acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC10 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S10F5[R]Terminal Display, Multi-Block Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F5 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 10, 5, secs_receive_S10F5)

def secs_receive_S10F5(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S10F5.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TID {L:n TEXT}
        # TID B:1 (always)  terminal ID
        # TEXT A:120 (varies)  line of text for display, no standard max size
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        TID = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTEXT, lengthTEXT) = pylist2[0].split(':')
            TEXT = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 10, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S10F5

S10F6Terminal Display, Multi-Block Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F6 Python Parse reply
    rcr = sp.sendSecsMsg(10, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC10
        # ACKC10 B:1 (always)  acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC10 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S10F7Multi-block Not Allowed Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 10, 7, secs_receive_S10F7)

def secs_receive_S10F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S10F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TID
        # TID B:1 (always)  terminal ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        TID = sp.binToInt(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 10, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S10F7

S10F9Broadcast Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 10, 9, secs_receive_S10F9)

def secs_receive_S10F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S10F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TEXT
        # TEXT A:120 (varies)  line of text for display, no standard max size
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeTEXT, lengthTEXT) = pylist0[0].split(':')
        TEXT = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 10, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S10F9

S10F10Broadcast Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S10F10 Python Parse reply
    rcr = sp.sendSecsMsg(10, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC10
        # ACKC10 B:1 (always)  acknowledge code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC10 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F1RMap Setup Data Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 1, secs_receive_S12F1R)

def secs_receive_S12F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:15 MID IDTYP FNLOC FFROT ORLOC RPSEL {L:n REFP} DUTMS XDIES YDIES ROWCT COLCT NULBC PRDCT PRAXI
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # FNLOC U2:1 (always)  flat/notch location in degrees clockwise from bottom
        # FFROT U2:1 (always)  film frame location in degrees clockwise from bottom
        # ORLOC B:1 (always)  origin location
        # RPSEL U1:1 (always)  reference point select 
        # REFP (list)I4:2 (varies)  x y reference point
        # DUTMS A:n (always)  die units of measure (per E5 Section 12)
        # XDIES F4:1 (varies)  X-axis die size
        # YDIES F4:1 (varies)  Y-axis die size
        # ROWCT U4:1 (varies)  row count in die increments
        # COLCT U4:1 (varies)  column count in die increments
        # NULBC A:n (varies)  null bin code value
        # PRDCT U4:1 (varies)  process die count
        # PRAXI B:1 (always)  process access
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 16 or pylist0[0] != "L:15":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        FNLOC = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        FFROT = int(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ORLOC = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RPSEL = int(pylist1[1])
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeREFP, lengthREFP) = pylist2[0].split(':')
            REFP = []
            for i in range(0, len(REFP)):
                REFP.append(int(pylist2[1+i])
        if not ok: break
        pylist1 = lsplit(pylist0[8])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        DUTMS = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[9])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeXDIES, lengthXDIES) = pylist1[0].split(':')
        XDIES = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[10])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeYDIES, lengthYDIES) = pylist1[0].split(':')
        YDIES = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[11])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeROWCT, lengthROWCT) = pylist1[0].split(':')
        ROWCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[12])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCOLCT, lengthCOLCT) = pylist1[0].split(':')
        COLCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[13])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeNULBC, lengthNULBC) = pylist1[0].split(':')
        NULBC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[14])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePRDCT, lengthPRDCT) = pylist1[0].split(':')
        PRDCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[15])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        PRAXI = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F1R

S12F2Map Setup Data Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F2 Python Parse reply
    rcr = sp.sendSecsMsg(12, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SDACK
        # SDACK B:1 (always)  setup data ack, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        SDACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F3RMap Setup Data Request Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 3, secs_receive_S12F3R)

def secs_receive_S12F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:9 MID IDTYP MAPFT FNLOC FFROT ORLOC PRAXI BCEQU NULBC
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # MAPFT B:1 (always)  map data format type
        # FNLOC U2:1 (always)  flat/notch location in degrees clockwise from bottom
        # FFROT U2:1 (always)  film frame location in degrees clockwise from bottom
        # ORLOC B:1 (always)  origin location
        # PRAXI B:1 (always)  process access
        # BCEQU (list)U1:n (varies)  array of bin code equivalents
        # NULBC A:n (varies)  null bin code value
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 10 or pylist0[0] != "L:9":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        MAPFT = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        FNLOC = int(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        FFROT = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ORLOC = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        PRAXI = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[8])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeBCEQU, lengthBCEQU) = pylist1[0].split(':')
        BCEQU = []
        for i in range(0, len(BCEQU)):
            BCEQU.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[9])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeNULBC, lengthNULBC) = pylist1[0].split(':')
        NULBC = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F3R

S12F4Map Setup Data Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F4 Python Parse reply
    rcr = sp.sendSecsMsg(12, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:15 MID IDTYP FNLOC ORLOC RPSEL {L:n REFP} DUTMS XDIES YDIES ROWCT COLCT PRDCT BCEQU NULBC MLCL
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # FNLOC U2:1 (always)  flat/notch location in degrees clockwise from bottom
        # ORLOC B:1 (always)  origin location
        # RPSEL U1:1 (always)  reference point select 
        # REFP (list)I4:2 (varies)  x y reference point
        # DUTMS A:n (always)  die units of measure (per E5 Section 12)
        # XDIES F4:1 (varies)  X-axis die size
        # YDIES F4:1 (varies)  Y-axis die size
        # ROWCT U4:1 (varies)  row count in die increments
        # COLCT U4:1 (varies)  column count in die increments
        # PRDCT U4:1 (varies)  process die count
        # BCEQU (list)U1:n (varies)  array of bin code equivalents
        # NULBC A:n (varies)  null bin code value
        # MLCL U4:1 (varies)  message length in bytes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 16 or pylist0[0] != "L:15":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        FNLOC = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ORLOC = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RPSEL = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeREFP, lengthREFP) = pylist2[0].split(':')
            REFP = []
            for i in range(0, len(REFP)):
                REFP.append(int(pylist2[1+i])
        if not ok: break
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        DUTMS = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[8])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeXDIES, lengthXDIES) = pylist1[0].split(':')
        XDIES = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[9])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeYDIES, lengthYDIES) = pylist1[0].split(':')
        YDIES = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[10])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeROWCT, lengthROWCT) = pylist1[0].split(':')
        ROWCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[11])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCOLCT, lengthCOLCT) = pylist1[0].split(':')
        COLCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[12])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePRDCT, lengthPRDCT) = pylist1[0].split(':')
        PRDCT = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[13])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeBCEQU, lengthBCEQU) = pylist1[0].split(':')
        BCEQU = []
        for i in range(0, len(BCEQU)):
            BCEQU.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[14])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeNULBC, lengthNULBC) = pylist1[0].split(':')
        NULBC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[15])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMLCL, lengthMLCL) = pylist1[0].split(':')
        MLCL = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S12F5RMap Transmit Inquire Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 5, secs_receive_S12F5R)

def secs_receive_S12F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 MID IDTYP MAPFT MLCL
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # MAPFT B:1 (always)  map data format type
        # MLCL U4:1 (varies)  message length in bytes
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        MAPFT = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMLCL, lengthMLCL) = pylist1[0].split(':')
        MLCL = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F5R

S12F6Map Transmit Grant Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F6 Python Parse reply
    rcr = sp.sendSecsMsg(12, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRNT1
        # GRNT1 B:1 (always)  grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRNT1 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F7RMap Data Send Type 1 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 7, secs_receive_S12F7R)

def secs_receive_S12F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 MID IDTYP {L:n {L:2 RSINF BINLT}}
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # RSINF (list)I4:3 (varies)  starting location for row or column, x,y,direction triplet
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRSINF, lengthRSINF) = pylist3[0].split(':')
            RSINF = []
            for i in range(0, len(RSINF)):
                RSINF.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeBINLT, lengthBINLT) = pylist3[0].split(':')
            BINLT = []
            for i in range(0, len(BINLT)):
                BINLT.append(int(pylist3[1+i])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F7R

S12F8Map Data Ack Type 1 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F8 Python Parse reply
    rcr = sp.sendSecsMsg(12, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect MDACK
        # MDACK B:1 (always)  map data ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        MDACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F9RMap Data Send Type 2 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 9, secs_receive_S12F9R)

def secs_receive_S12F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 MID IDTYP STRP BINLT
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # STRP (list)I2:2 (varies)  x y die coordinate starting position
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeSTRP, lengthSTRP) = pylist1[0].split(':')
        STRP = []
        for i in range(0, len(STRP)):
            STRP.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeBINLT, lengthBINLT) = pylist1[0].split(':')
        BINLT = []
        for i in range(0, len(BINLT)):
            BINLT.append(int(pylist1[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F9R

S12F10Map Data Ack Type 2 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F10 Python Parse reply
    rcr = sp.sendSecsMsg(12, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect MDACK
        # MDACK B:1 (always)  map data ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        MDACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F11RMap Data Send Type 3 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 11, secs_receive_S12F11R)

def secs_receive_S12F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 MID IDTYP {L:n {L:2 XYPOS BINLT}}
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # XYPOS (list)I2:2 (varies)  x y coordinate position
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeXYPOS, lengthXYPOS) = pylist3[0].split(':')
            XYPOS = []
            for i in range(0, len(XYPOS)):
                XYPOS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeBINLT, lengthBINLT) = pylist3[0].split(':')
            BINLT = []
            for i in range(0, len(BINLT)):
                BINLT.append(int(pylist3[1+i])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F11R

S12F12Map Data Ack Type 3 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F12 Python Parse reply
    rcr = sp.sendSecsMsg(12, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect MDACK
        # MDACK B:1 (always)  map data ack
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        MDACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S12F13RMap Data Request Type 1 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 13, secs_receive_S12F13R)

def secs_receive_S12F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MID IDTYP
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F13R

S12F14Map Data Type 1 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F14 Python Parse reply
    rcr = sp.sendSecsMsg(12, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 MID IDTYP {L:n {L:2 RSINF BINLT}}
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # RSINF (list)I4:3 (varies)  starting location for row or column, x,y,direction triplet
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRSINF, lengthRSINF) = pylist3[0].split(':')
            RSINF = []
            for i in range(0, len(RSINF)):
                RSINF.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeBINLT, lengthBINLT) = pylist3[0].split(':')
            BINLT = []
            for i in range(0, len(BINLT)):
                BINLT.append(int(pylist3[1+i])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S12F15RMap Data Request Type 2 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 15, secs_receive_S12F15R)

def secs_receive_S12F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MID IDTYP
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F15R

S12F16Map Data Type 2 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F16 Python Parse reply
    rcr = sp.sendSecsMsg(12, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 MID IDTYP STRP BINLT
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # STRP (list)I2:2 (varies)  x y die coordinate starting position
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeSTRP, lengthSTRP) = pylist1[0].split(':')
        STRP = []
        for i in range(0, len(STRP)):
            STRP.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeBINLT, lengthBINLT) = pylist1[0].split(':')
        BINLT = []
        for i in range(0, len(BINLT)):
            BINLT.append(int(pylist1[1+i])
        return # finished ok
    # end while(ok)
# end def

S12F17RMap Data Request Type 3 Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 17, secs_receive_S12F17R)

def secs_receive_S12F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 MID IDTYP SDBIN
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # SDBIN B:1 (always)  send bin data flag, 0=send, else do not
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        SDBIN = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F17R

S12F18Map Data Type 3 Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F18 Python Parse reply
    rcr = sp.sendSecsMsg(12, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 MID IDTYP {L:n {L:2 XYPOS BINLT}}
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # IDTYP B:1 (always)  ID type
        # XYPOS (list)I2:2 (varies)  x y coordinate position
        # BINLT (list)U1:n (varies)  array of bin values, text or U1 array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        IDTYP = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeXYPOS, lengthXYPOS) = pylist3[0].split(':')
            XYPOS = []
            for i in range(0, len(XYPOS)):
                XYPOS.append(int(pylist3[1+i])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeBINLT, lengthBINLT) = pylist3[0].split(':')
            BINLT = []
            for i in range(0, len(BINLT)):
                BINLT.append(int(pylist3[1+i])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S12F19Map Error Report Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S12F19 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 12, 19, secs_receive_S12F19)

def secs_receive_S12F19(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S12F19.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 MAPER DATLC
        # MAPER B:1 (always)  map error
        # DATLC U1:1 (always)  location of invalid data, offset in bytes in the SECS-II message body
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        MAPER = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        DATLC = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 12, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S12F19

S13F1RSend Data Set Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 1, secs_receive_S13F1R)

def secs_receive_S13F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:1 DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 2 or pylist0[0] != "L:1":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist1[0].split(':')
        DSNAME = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F1R

S13F2Send Data Set Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F2 Python Parse reply
    rcr = sp.sendSecsMsg(13, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 DSNAME ACKC13
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        # ACKC13 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist1[0].split(':')
        DSNAME = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ACKC13 = sp.binToInt(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S13F3ROpen Data Set Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 3, secs_receive_S13F3R)

def secs_receive_S13F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 HANDLE DSNAME CKPNT
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        # CKPNT U4:1 (always)  data set checkpoint defined by sender
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist1[0].split(':')
        DSNAME = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        CKPNT = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F3R

S13F4Open Data Set Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F4 Python Parse reply
    rcr = sp.sendSecsMsg(13, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:5 HANDLE DSNAME ACKC13 RTYPE RECLEN
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        # ACKC13 B:1 (always)  acknowledge code, 0 ok
        # RTYPE U1:1 (varies)  type of data record
        # RECLEN U4:1 (varies)  maximum number of bytes or characters in a discrete record
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist1[0].split(':')
        DSNAME = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ACKC13 = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRTYPE, lengthRTYPE) = pylist1[0].split(':')
        RTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRECLEN, lengthRECLEN) = pylist1[0].split(':')
        RECLEN = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S13F5RRead Data Set Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 5, secs_receive_S13F5R)

def secs_receive_S13F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 HANDLE READLN
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        # READLN U4:1 (varies)  maximum number of bytes or characters to read
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeREADLN, lengthREADLN) = pylist1[0].split(':')
        READLN = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F5R

S13F6Read Data Set Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F6 Python Parse reply
    rcr = sp.sendSecsMsg(13, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 HANDLE ACKC13 CKPNT {L:n FILDAT}
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        # ACKC13 B:1 (always)  acknowledge code, 0 ok
        # CKPNT U4:1 (always)  data set checkpoint defined by sender
        # FILDAT (list)B (varies)  Data Set Data, binary or ascii.  Max length is the RECLEN from open.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ACKC13 = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        CKPNT = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeFILDAT, lengthFILDAT) = pylist2[0].split(':')
            FILDAT = []
            for i in range(0, len(FILDAT)):
                FILDAT.append(sp.binToInt(pylist2[1+i])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S13F7RClose Data Set Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 7, secs_receive_S13F7R)

def secs_receive_S13F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:1 HANDLE
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 2 or pylist0[0] != "L:1":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F7R

S13F8Close Data Set Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F8 Python Parse reply
    rcr = sp.sendSecsMsg(13, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 HANDLE ACKC13
        # HANDLE (list)U4 (varies)  logical unit or handle for a data set
        # ACKC13 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeHANDLE, lengthHANDLE) = pylist1[0].split(':')
        HANDLE = []
        for i in range(0, len(HANDLE)):
            HANDLE.append(int(pylist1[1+i])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ACKC13 = sp.binToInt(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S13F9RReset Data Set Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 9, secs_receive_S13F9R)

def secs_receive_S13F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F9R

S13F10Reset Data Set Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F10 Python Parse reply
    rcr = sp.sendSecsMsg(13, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S13F11RData Set Obj Multi-Block Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 11, secs_receive_S13F11R)

def secs_receive_S13F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID OBJSPEC DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F11R

S13F12Data Set Obj Multi-Block Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F12 Python Parse reply
    rcr = sp.sendSecsMsg(13, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S13F13RTable Data Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 13, secs_receive_S13F13R)

def secs_receive_S13F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:8 DATAID OBJSPEC TBLTYP TBLID TBLCMD {L:n {L:2 ATTRID ATTRDATA}} {L:c COLHDR} {L:r {L:m TBLELT}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # TBLTYP A:n (always)  denotes the format and application of the table, conforms to OBJTYPE
        # TBLID A:80 (varies)  table identifier, a kind of OBJSPEC
        # TBLCMD U1:1 (always)  table command
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # COLHDR A:20 (always)  table column name
        # TBLELT A:n (varies)  table element any type, list types or array types are discouraged, first column type must be a primary key value and not be a list or array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 9 or pylist0[0] != "L:8":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TBLTYP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTBLID, lengthTBLID) = pylist1[0].split(':')
        TBLID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        TBLCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            COLHDR = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[8])
        if len(pylist1) < 1:
            ok = False
            break
        for r in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[r])
            if len(pylist2) < 1:
                ok = False
                break
            for m in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[m])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeTBLELT, lengthTBLELT) = pylist3[0].split(':')
                TBLELT = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F13R

S13F14Table Data Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F14 Python Parse reply
    rcr = sp.sendSecsMsg(13, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TBLACK {L:p {L:2 ERRCODE ERRTEXT}}
        # TBLACK U1:1 (always)  acknowledge code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        TBLACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S13F15RTable Data Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 13, 15, secs_receive_S13F15R)

def secs_receive_S13F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S13F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:7 DATAID OBJSPEC TBLTYP TBLID TBLCMD {L:p COLHDR} {L:q TBLELT}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # TBLTYP A:n (always)  denotes the format and application of the table, conforms to OBJTYPE
        # TBLID A:80 (varies)  table identifier, a kind of OBJSPEC
        # TBLCMD U1:1 (always)  table command
        # COLHDR A:20 (always)  table column name
        # TBLELT A:n (varies)  table element any type, list types or array types are discouraged, first column type must be a primary key value and not be a list or array
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TBLTYP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTBLID, lengthTBLID) = pylist1[0].split(':')
        TBLID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        TBLCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            COLHDR = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for q in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[q])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTBLELT, lengthTBLELT) = pylist2[0].split(':')
            TBLELT = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 13, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S13F15R

S13F16Table Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S13F16 Python Parse reply
    rcr = sp.sendSecsMsg(13, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:6 TBLTYP TBLID {L:n {L:2 ATTRID ATTRDATA}} {L:c COLHDR} {L:r {L:c TBLELT}} {L:2 TBLACK {L:p ERRCODE ERRTEXT}}
        # TBLTYP A:n (always)  denotes the format and application of the table, conforms to OBJTYPE
        # TBLID A:80 (varies)  table identifier, a kind of OBJSPEC
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # COLHDR A:20 (always)  table column name
        # TBLELT A:n (varies)  table element any type, list types or array types are discouraged, first column type must be a primary key value and not be a list or array
        # TBLACK U1:1 (always)  acknowledge code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TBLTYP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTBLID, lengthTBLID) = pylist1[0].split(':')
        TBLID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            COLHDR = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for r in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[r])
            if len(pylist2) < 1:
                ok = False
                break
            for c in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[c])
                if len(pylist3) < 1:
                    ok = False
                    break
                #(typeTBLELT, lengthTBLELT) = pylist3[0].split(':')
                TBLELT = (pylist3[1] if len(pylist3) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        TBLACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F1RGet Attributes Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 1, secs_receive_S14F1R)

def secs_receive_S14F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJSPEC OBJTYPE {L:i OBJID} {L:q {L:3 ATTRID ATTRDATA ATTRRELN}} {L:a ATTRID}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # ATTRRELN U1:1 (always)  relationship of a value to an attribute value of an object
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for i in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[i])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJID, lengthOBJID) = pylist2[0].split(':')
            OBJID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for q in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[q])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ATTRRELN = int(pylist3[1])
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist2[0].split(':')
            ATTRID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F1R

S14F2Attribute Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F2 Python Parse reply
    rcr = sp.sendSecsMsg(14, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:2 OBJID {L:a {L:2 ATTRID ATTRDATA}}}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeOBJID, lengthOBJID) = pylist3[0].split(':')
            OBJID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for a in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[a])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRID, lengthATTRID) = pylist5[0].split(':')
                ATTRID = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRDATA, lengthATTRDATA) = pylist5[0].split(':')
                ATTRDATA = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F3RSet Attributes Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 3, secs_receive_S14F3R)

def secs_receive_S14F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJSPEC OBJTYPE {L:i OBJID} {L:n {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for i in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[i])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJID, lengthOBJID) = pylist2[0].split(':')
            OBJID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F3R

S14F4Set Attributes Reply Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F4 Python Parse reply
    rcr = sp.sendSecsMsg(14, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:i {L:2 OBJID {L:n {L:2 ATTRID ATTRDATA}}}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for i in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[i])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeOBJID, lengthOBJID) = pylist3[0].split(':')
            OBJID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for n in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[n])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRID, lengthATTRID) = pylist5[0].split(':')
                ATTRID = (pylist5[1] if len(pylist5) == 2 else None)
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeATTRDATA, lengthATTRDATA) = pylist5[0].split(':')
                ATTRDATA = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F5RGet Type Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 5, secs_receive_S14F5R)

def secs_receive_S14F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect OBJSPEC
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist0[0].split(':')
        OBJSPEC = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F5R

S14F6Type Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F6 Python Parse reply
    rcr = sp.sendSecsMsg(14, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n OBJTYPE} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJTYPE, lengthOBJTYPE) = pylist2[0].split(':')
            OBJTYPE = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F7RGet Attribute Names for the types Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 7, secs_receive_S14F7R)

def secs_receive_S14F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 OBJSPEC {L:n OBJTYPE}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJTYPE, lengthOBJTYPE) = pylist2[0].split(':')
            OBJTYPE = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F7R

S14F8Attribute Names of the object types Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F8 Python Parse reply
    rcr = sp.sendSecsMsg(14, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:2 OBJTYPE {L:a ATTRID}}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeOBJTYPE, lengthOBJTYPE) = pylist3[0].split(':')
            OBJTYPE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for a in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[a])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typeATTRID, lengthATTRID) = pylist4[0].split(':')
                ATTRID = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F9RCreate Obj Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 9, secs_receive_S14F9R)

def secs_receive_S14F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 OBJSPEC OBJTYPE {L:a {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F9R

S14F10Create Obj Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F10 Python Parse reply
    rcr = sp.sendSecsMsg(14, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 OBJSPEC {L:b {L:2 ATTRID ATTRDATA}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for b in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[b])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F11RDelete Obj Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 11, secs_receive_S14F11R)

def secs_receive_S14F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 OBJSPEC {L:a {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F11R

S14F12Delete Obj Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F12 Python Parse reply
    rcr = sp.sendSecsMsg(14, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:b {L:2 ATTRID ATTRDATA}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for b in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[b])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F13RObject Attach Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 13, secs_receive_S14F13R)

def secs_receive_S14F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 OBJSPEC {L:a {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F13R

S14F14Object Attach Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F14 Python Parse reply
    rcr = sp.sendSecsMsg(14, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 OBJTOKEN {L:b {L:2 ATTRID ATTRDATA}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJTOKEN U4:1 (always)  token used for authorization
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        OBJTOKEN = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for b in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[b])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F15RAttached Obj Action Req. Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 15, secs_receive_S14F15R)

def secs_receive_S14F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJSPEC OBJCMD OBJTOKEN {L:a {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJCMD U1:1 (always)  Specifies an action to be performed by an object
        # OBJTOKEN U4:1 (always)  token used for authorization
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OBJCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        OBJTOKEN = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F15R

S14F16Attached Obj Action Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F16 Python Parse reply
    rcr = sp.sendSecsMsg(14, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:b {L:2 ATTRID ATTRDATA}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for b in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[b])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F17RSupervised Obj Action Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 17, secs_receive_S14F17R)

def secs_receive_S14F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJSPEC OBJCMD TARGETSPEC {L:a {L:2 ATTRID ATTRDATA}}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJCMD U1:1 (always)  Specifies an action to be performed by an object
        # TARGETSPEC A:40 (always)  Specifier of target object
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OBJCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for a in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[a])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F17R

S14F18Supervised Obj Action Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F18 Python Parse reply
    rcr = sp.sendSecsMsg(14, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:b {L:2 ATTRID ATTRDATA}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for b in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[b])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F19RGeneric Service Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 19, secs_receive_S14F19R)

def secs_receive_S14F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID OPID OBJSPEC SVCNAME {L:m {L:2 SPNAME SPVAL}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OPID U4:1 (varies)  operation identifier
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # SVCNAME A:n (always)  service name
        # SPNAME A:n (always)  service parameter name
        # SPVAL A:n (varies)  service parameter value, any format type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SVCNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            SPNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeSPVAL, lengthSPVAL) = pylist3[0].split(':')
            SPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S14F19R

S14F20Generic Service Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F20 Python Parse reply
    rcr = sp.sendSecsMsg(14, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 SVCACK LINKID {L:n {L:2 SPNAME SPVAL}} {L:2 SVCACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # SVCACK B:1 (always)  service acknowledge code
        # LINKID U4:1 (always)  correlates the RMOPID value in a request to a completion report
        # SPNAME A:n (always)  service parameter name
        # SPVAL A:n (varies)  service parameter value, any format type
        # SVCACK B:1 (always)  service acknowledge code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        SVCACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LINKID = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            SPNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeSPVAL, lengthSPVAL) = pylist3[0].split(':')
            SPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "B:1":
            ok = False
            break
        SVCACK = sp.binToInt(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F21RGeneric Service Completion Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 21, secs_receive_S14F21R)

def secs_receive_S14F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID OPID LINKID {L:n {L:2 SPNAME SPVAL}} {L:2 SVCACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OPID U4:1 (varies)  operation identifier
        # LINKID U4:1 (always)  correlates the RMOPID value in a request to a completion report
        # SPNAME A:n (always)  service parameter name
        # SPVAL A:n (varies)  service parameter value, any format type
        # SVCACK B:1 (always)  service acknowledge code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LINKID = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            SPNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeSPVAL, lengthSPVAL) = pylist3[0].split(':')
            SPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "B:1":
            ok = False
            break
        SVCACK = sp.binToInt(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F21R

S14F22Generic Service Comp Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F22 Python Parse reply
    rcr = sp.sendSecsMsg(14, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect DATAACK
        # DATAACK B:1 (always)  Acknowledgement code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        DATAACK = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S14F23RMulti-block Generic Service Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 23, secs_receive_S14F23R)

def secs_receive_S14F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F23R

S14F24Multi-block Generic Service Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F24 Python Parse reply
    rcr = sp.sendSecsMsg(14, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S14F25RService Name Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 25, secs_receive_S14F25R)

def secs_receive_S14F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 OBJSPEC {L:n OBJTYPE}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOBJTYPE, lengthOBJTYPE) = pylist2[0].split(':')
            OBJTYPE = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F25R

S14F26Service Name Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F26 Python Parse reply
    rcr = sp.sendSecsMsg(14, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:2 OBJTYPE {L:a SVCNAME}}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # SVCNAME A:n (always)  service name
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeOBJTYPE, lengthOBJTYPE) = pylist3[0].split(':')
            OBJTYPE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for a in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[a])
                if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                    ok = False
                    break
                SVCNAME = (pylist4[1] if len(pylist4) == 2 else "")
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S14F27RService Parameter Name Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 14, 27, secs_receive_S14F27R)

def secs_receive_S14F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S14F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 OBJSPEC OBJTYPE {L:n SVCNAME}
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # SVCNAME A:n (always)  service name
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            SVCNAME = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 14, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S14F27R

S14F28Service Parameter Name Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S14F28 Python Parse reply
    rcr = sp.sendSecsMsg(14, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:2 SVCNAME {L:a SPNAME}}} {L:2 OBJACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # SVCNAME A:n (always)  service name
        # SPNAME A:n (always)  service parameter name
        # OBJACK U1:1 (always)  acknowledge code, 0 ok, 1 error
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            SVCNAME = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for a in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[a])
                if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                    ok = False
                    break
                SPNAME = (pylist4[1] if len(pylist4) == 2 else "")
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        OBJACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F1RRecipe Management Multi-Block Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 1, secs_receive_S15F1R)

def secs_receive_S15F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID RCPSPEC RMDATASIZE
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPSPEC A:n (always)  recipe specifier
        # RMDATASIZE U4:1 (varies)  the maximum total message body length of a SECS-II message
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMDATASIZE, lengthRMDATASIZE) = pylist1[0].split(':')
        RMDATASIZE = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F1R

S15F2Recipe Management Multi-block Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F2 Python Parse reply
    rcr = sp.sendSecsMsg(15, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect RMGRNT
        # RMGRNT B:1 (always)  grant code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        RMGRNT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S15F3RRecipe Namespace Action Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 3, secs_receive_S15F3R)

def secs_receive_S15F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 RMNSSPEC RMNSCMD
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # RMNSCMD U1:1 (always)  recipe namespace command
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMNSCMD = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F3R

S15F4Recipe Namespace Action Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F4 Python Parse reply
    rcr = sp.sendSecsMsg(15, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F5RRecipe Namespace Rename Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 5, secs_receive_S15F5R)

def secs_receive_S15F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 RMNSSPEC RMNEWNS
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # RMNEWNS A:n (always)  new name for a recipe namespace
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNEWNS = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F5R

S15F6Recipe Namespace Rename Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F6 Python Parse reply
    rcr = sp.sendSecsMsg(15, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F7RRecipe Space Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 7, secs_receive_S15F7R)

def secs_receive_S15F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect OBJSPEC
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist0[0].split(':')
        OBJSPEC = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F7R

S15F8Recipe Space Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F8 Python Parse reply
    rcr = sp.sendSecsMsg(15, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMSPACE {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RMSPACE U4:1 (varies)  the amount of storage available in bytes for at least one recipe
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMSPACE, lengthRMSPACE) = pylist1[0].split(':')
        RMSPACE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F9RRecipe Status Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 9, secs_receive_S15F9R)

def secs_receive_S15F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RCPSPEC
        # RCPSPEC A:n (always)  recipe specifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F9R

S15F10Recipe Status Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F10 Python Parse reply
    rcr = sp.sendSecsMsg(15, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 RCPSTAT RCPVERS {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPSTAT U1:1 (always)  Recipe status code
        # RCPVERS A:n (always)  recipe version
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RCPSTAT = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPVERS = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F11RRecipe Version Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 11, secs_receive_S15F11R)

def secs_receive_S15F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 RMNSSPEC RCPCLASS RCPNAME AGENT
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # RCPCLASS A:n (always)  Recipe class
        # RCPNAME A:n (always)  recipe name
        # AGENT A:n (always)  no description, no max length
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPCLASS = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        AGENT = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F11R

S15F12Recipe Version Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F12 Python Parse reply
    rcr = sp.sendSecsMsg(15, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 AGENT RCPVERS {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # AGENT A:n (always)  no description, no max length
        # RCPVERS A:n (always)  recipe version
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        AGENT = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPVERS = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F13RRecipe Create Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 13, secs_receive_S15F13R)

def secs_receive_S15F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID RCPUPDT RCPSPEC {L:m {L:2 RCPATTRID RCPATTRDATA}} RCPBODY
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPUPDT TF:1 (always)  true for a recipe update, false for create
        # RCPSPEC A:n (always)  recipe specifier
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RCPBODY (list)B:n (varies)  Recipe body
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        RCPUPDT = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRCPBODY, lengthRCPBODY) = pylist1[0].split(':')
        RCPBODY = []
        for i in range(0, len(RCPBODY)):
            RCPBODY.append(sp.binToInt(pylist1[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F13R

S15F14Recipe Create Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F14 Python Parse reply
    rcr = sp.sendSecsMsg(15, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F15RRecipe Store Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 15, secs_receive_S15F15R)

def secs_receive_S15F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID RCPSPEC RCPSECCODE {L:3 {L:2* RCPSECNM {L:g {L:2 RCPATTRID RCPATTRDATA}}} RCPBODY {L:m {L:2 RCPSECNM {L:a {L:2 RCPATTRID RCPATTRDATA}}}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPSPEC A:n (always)  recipe specifier
        # RCPSECCODE B:1 (always)  indicates the sections of a recipe
        # RCPSECNM A:n (always)  Recipe section name, "Generic", "Body", "ASDS"
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RCPBODY (list)B:n (varies)  Recipe body
        # RCPSECNM A:n (always)  Recipe section name, "Generic", "Body", "ASDS"
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RCPSECCODE = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 4 or pylist1[0] != "L:3":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) == 3:   # 2 optional items found
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPSECNM = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for g in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[g])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1 or not pylist5[0].startswith("A:"):
                    ok = False
                    break
                RCPATTRID = (pylist5[1] if len(pylist5) == 2 else "")
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist5[0].split(':')
                RCPATTRDATA = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeRCPBODY, lengthRCPBODY) = pylist2[0].split(':')
        RCPBODY = []
        for i in range(0, len(RCPBODY)):
            RCPBODY.append(sp.binToInt(pylist2[1+i])
        pylist2 = lsplit(pylist1[3])
        if len(pylist2) < 1:
            ok = False
            break
        for m in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[m])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            RCPSECNM = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1:
                ok = False
                break
            for a in range(1, len(pylist4)):
                pylist5 = lsplit(pylist4[a])
                if len(pylist5) != 3 or pylist5[0] != "L:2":
                    ok = False
                    break
                pylist6 = lsplit(pylist5[1])
                if len(pylist6) < 1 or not pylist6[0].startswith("A:"):
                    ok = False
                    break
                RCPATTRID = (pylist6[1] if len(pylist6) == 2 else "")
                pylist6 = lsplit(pylist5[2])
                if len(pylist6) < 1:
                    ok = False
                    break
                #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist6[0].split(':')
                RCPATTRDATA = (pylist6[1] if len(pylist6) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F15R

S15F16Recipe Store Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F16 Python Parse reply
    rcr = sp.sendSecsMsg(15, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RCPSECCODE {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPSECCODE B:1 (always)  indicates the sections of a recipe
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RCPSECCODE = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F17RRecipe Retrieve Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 17, secs_receive_S15F17R)

def secs_receive_S15F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 RCPSPEC RCPSECCODE
        # RCPSPEC A:n (always)  recipe specifier
        # RCPSECCODE B:1 (always)  indicates the sections of a recipe
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RCPSECCODE = sp.binToInt(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F17R

S15F18Recipe Retrieve Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F18 Python Parse reply
    rcr = sp.sendSecsMsg(15, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:q {L:r RCPSECNM {L:g {L:2 RCPATTRID RCPATTRDATA}}} RCPBODY {L:m {L:2 RCPSECNM {L:a {L:2 RCPATTRID RCPATTRDATA}}}}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPSECNM A:n (always)  Recipe section name, "Generic", "Body", "ASDS"
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RCPBODY (list)B:n (varies)  Recipe body
        # RCPSECNM A:n (always)  Recipe section name, "Generic", "Body", "ASDS"
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for q in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[q])
            if len(pylist2) < 1:
                ok = False
                break
            for r in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[r])
                if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                    ok = False
                    break
                RCPSECNM = (pylist3[1] if len(pylist3) == 2 else "")
                pylist3 = lsplit(pylist2[r])
                if len(pylist3) < 1:
                    ok = False
                    break
                for g in range(1, len(pylist3)):
                    pylist4 = lsplit(pylist3[g])
                    if len(pylist4) != 3 or pylist4[0] != "L:2":
                        ok = False
                        break
                    pylist5 = lsplit(pylist4[1])
                    if len(pylist5) < 1 or not pylist5[0].startswith("A:"):
                        ok = False
                        break
                    RCPATTRID = (pylist5[1] if len(pylist5) == 2 else "")
                    pylist5 = lsplit(pylist4[2])
                    if len(pylist5) < 1:
                        ok = False
                        break
                    #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist5[0].split(':')
                    RCPATTRDATA = (pylist5[1] if len(pylist5) == 2 else None)
                if not ok: break
            if not ok: break
            pylist2 = lsplit(pylist1[q])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeRCPBODY, lengthRCPBODY) = pylist2[0].split(':')
            RCPBODY = []
            for i in range(0, len(RCPBODY)):
                RCPBODY.append(sp.binToInt(pylist2[1+i])
            pylist2 = lsplit(pylist1[q])
            if len(pylist2) < 1:
                ok = False
                break
            for m in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[m])
                if len(pylist3) != 3 or pylist3[0] != "L:2":
                    ok = False
                    break
                pylist4 = lsplit(pylist3[1])
                if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                    ok = False
                    break
                RCPSECNM = (pylist4[1] if len(pylist4) == 2 else "")
                pylist4 = lsplit(pylist3[2])
                if len(pylist4) < 1:
                    ok = False
                    break
                for a in range(1, len(pylist4)):
                    pylist5 = lsplit(pylist4[a])
                    if len(pylist5) != 3 or pylist5[0] != "L:2":
                        ok = False
                        break
                    pylist6 = lsplit(pylist5[1])
                    if len(pylist6) < 1 or not pylist6[0].startswith("A:"):
                        ok = False
                        break
                    RCPATTRID = (pylist6[1] if len(pylist6) == 2 else "")
                    pylist6 = lsplit(pylist5[2])
                    if len(pylist6) < 1:
                        ok = False
                        break
                    #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist6[0].split(':')
                    RCPATTRDATA = (pylist6[1] if len(pylist6) == 2 else None)
                if not ok: break
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F19RRecipe Rename Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 19, secs_receive_S15F19R)

def secs_receive_S15F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 RCPSPEC RCPRENAME RCPNEWID
        # RCPSPEC A:n (always)  recipe specifier
        # RCPRENAME TF:1 (always)  whether a recipe is to be renamed (TRUE) or copied (FALSE)
        # RCPNEWID A:n (always)  the new recipe identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        RCPRENAME = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPNEWID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F19R

S15F20Recipe Rename Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F20 Python Parse reply
    rcr = sp.sendSecsMsg(15, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F21RRecipe Action Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 21, secs_receive_S15F21R)

def secs_receive_S15F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 DATAID RCPCMD RMNSSPEC OPID AGENT {L:n RCPID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPCMD U1:1 (always)  recipe action
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # OPID U4:1 (varies)  operation identifier
        # AGENT A:n (always)  no description, no max length
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RCPCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        AGENT = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F21R

S15F22Recipe Action Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F22 Python Parse reply
    rcr = sp.sendSecsMsg(15, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 AGENT LINKID RCPCMD {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # AGENT A:n (always)  no description, no max length
        # LINKID U4:1 (always)  correlates the RMOPID value in a request to a completion report
        # RCPCMD U1:1 (always)  recipe action
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        AGENT = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LINKID = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RCPCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F23RRecipe Descriptor Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 23, secs_receive_S15F23R)

def secs_receive_S15F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID OBJSPEC {L:n RCPID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F23R

S15F24Recipe Descriptor Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F24 Python Parse reply
    rcr = sp.sendSecsMsg(15, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:a {L:3* RCPDESCNM RCPDESCTIME RCPDESCLTH}}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPDESCNM A:n (always)  Identifies a descriptor type "ASDesc", "BodyDesc", "GenDesc"
        # RCPDESCTIME A:16 (always)  timestamp of a recipe section "YYYYMMDDhhmmsscc"
        # RCPDESCLTH U4:1 (varies)  the byte length of a recipe
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            for a in range(1, len(pylist2)):
                pylist3 = lsplit(pylist2[a])
                if len(pylist3) == 4:   # 3 optional items found
                    pylist4 = lsplit(pylist3[1])
                    if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                        ok = False
                        break
                    RCPDESCNM = (pylist4[1] if len(pylist4) == 2 else "")
                    pylist4 = lsplit(pylist3[2])
                    if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                        ok = False
                        break
                    RCPDESCTIME = (pylist4[1] if len(pylist4) == 2 else "")
                    pylist4 = lsplit(pylist3[3])
                    if len(pylist4) < 1:
                        ok = False
                        break
                    #(typeRCPDESCLTH, lengthRCPDESCLTH) = pylist4[0].split(':')
                    RCPDESCLTH = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F25RRecipe Parameter Update Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 25, secs_receive_S15F25R)

def secs_receive_S15F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID RMNSSPEC AGENT {L:n {L:3 RCPPARNM RCPPARVAL RCPPARRULE}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # AGENT A:n (always)  no description, no max length
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        # RCPPARRULE A:80 (always)  the restrictions applied to a recipe variable parameter setting
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        AGENT = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPPARNM = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPPARVAL, lengthRCPPARVAL) = pylist3[0].split(':')
            RCPPARVAL = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPPARRULE = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F25R

S15F26Recipe Parameter Update Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F26 Python Parse reply
    rcr = sp.sendSecsMsg(15, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F27RRecipe Download Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 27, secs_receive_S15F27R)

def secs_receive_S15F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID RCPOWCODE RCPSPEC {L:m {L:2 RCPATTRID RCPATTRDATA}} RCPBODY
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPOWCODE TF:1 (always)  recipe overwrite code, true=overwrite ok, false=do not overwrite
        # RCPSPEC A:n (always)  recipe specifier
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RCPBODY (list)B:n (varies)  Recipe body
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        RCPOWCODE = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRCPBODY, lengthRCPBODY) = pylist1[0].split(':')
        RCPBODY = []
        for i in range(0, len(RCPBODY)):
            RCPBODY.append(sp.binToInt(pylist1[1+i])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F27R

S15F28Recipe Download Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F28 Python Parse reply
    rcr = sp.sendSecsMsg(15, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 RCPID {L:n {L:2 RCPATTRID RCPATTRDATA}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F29RRecipe Verify Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 29, secs_receive_S15F29R)

def secs_receive_S15F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID OPID RESPEC {L:m RCPID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OPID U4:1 (varies)  operation identifier
        # RESPEC A:n (always)  object specifier for the recipe executor
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RESPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F29R

S15F30Recipe Verify Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F30 Python Parse reply
    rcr = sp.sendSecsMsg(15, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:5 OPID LINKID RCPID {L:n {L:2 RCPATTRID RCPATTRDATA}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # OPID U4:1 (varies)  operation identifier
        # LINKID U4:1 (always)  correlates the RMOPID value in a request to a completion report
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        LINKID = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F31RRecipe Unload Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F31R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 31, secs_receive_S15F31R)

def secs_receive_S15F31R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F31R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect RCPSPEC
        # RCPSPEC A:n (always)  recipe specifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F31R

S15F32Recipe Unload Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F32 Python Parse reply
    rcr = sp.sendSecsMsg(15, 31, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 RCPSPEC {L:m {L:2 RCPATTRID RCPATTRDATA}} RCPBODY {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPSPEC A:n (always)  recipe specifier
        # RCPATTRID A:n (always)  the name of a recipe attribute, but not used to indicate the recipe identifier
        # RCPATTRDATA A:n (varies)  the value of a recipe attribute, any type of data including list
        # RCPBODY (list)B:n (varies)  Recipe body
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPATTRID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPATTRDATA, lengthRCPATTRDATA) = pylist3[0].split(':')
            RCPATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRCPBODY, lengthRCPBODY) = pylist1[0].split(':')
        RCPBODY = []
        for i in range(0, len(RCPBODY)):
            RCPBODY.append(sp.binToInt(pylist1[1+i])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F33RRecipe Select Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F33R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 33, secs_receive_S15F33R)

def secs_receive_S15F33R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F33R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID RESPEC {L:r {L:2 RCPID {L:p {L:2 RCPPARNM RCPPARVAL}}}} 
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RESPEC A:n (always)  object specifier for the recipe executor
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RESPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for r in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[r])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for p in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[p])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1 or not pylist5[0].startswith("A:"):
                    ok = False
                    break
                RCPPARNM = (pylist5[1] if len(pylist5) == 2 else "")
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typeRCPPARVAL, lengthRCPPARVAL) = pylist5[0].split(':')
                RCPPARVAL = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F33R

S15F34Recipe Select Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F34 Python Parse reply
    rcr = sp.sendSecsMsg(15, 33, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F35RRecipe Delete Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F35R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 35, secs_receive_S15F35R)

def secs_receive_S15F35R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F35R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID RESPEC RCPDEL {L:n RCPID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RESPEC A:n (always)  object specifier for the recipe executor
        # RCPDEL U1:1 (always)  recipe action
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RESPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RCPDEL = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 36, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F35R

S15F36Recipe Delete Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F36 Python Parse reply
    rcr = sp.sendSecsMsg(15, 35, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F37RDRNS Segment Approve Action Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F37R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 37, secs_receive_S15F37R)

def secs_receive_S15F37R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F37R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 RMSEGSPEC OBJTOKEN RMGRNT OPID RCPID RMCHGTYPE
        # RMSEGSPEC A:n (always)  The object ID of a distributed recipe namespace segment
        # OBJTOKEN U4:1 (always)  token used for authorization
        # RMGRNT B:1 (always)  grant code, 0 ok
        # OPID U4:1 (varies)  operation identifier
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RMCHGTYPE U4:1 (varies)  type of change for a recipe
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMSEGSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        OBJTOKEN = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RMGRNT = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMCHGTYPE, lengthRMCHGTYPE) = pylist1[0].split(':')
        RMCHGTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 38, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F37R

S15F38DRNS Segment Approve Action Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F38 Python Parse reply
    rcr = sp.sendSecsMsg(15, 37, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F39RDRNS Recorder Seg Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F39R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 39, secs_receive_S15F39R)

def secs_receive_S15F39R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F39R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID RMNSCMD RMRECSPEC RMSEGSPEC OBJTOKEN
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RMNSCMD U1:1 (always)  recipe namespace command
        # RMRECSPEC A:n (always)  object id of a distributed recipe namespace recorder
        # RMSEGSPEC A:n (always)  The object ID of a distributed recipe namespace segment
        # OBJTOKEN U4:1 (always)  token used for authorization
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMNSCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMRECSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMSEGSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        OBJTOKEN = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 40, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F39R

S15F40DRNS Recorder Seg Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F40 Python Parse reply
    rcr = sp.sendSecsMsg(15, 39, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F41RDRNS Recorder Mod Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F41R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 41, secs_receive_S15F41R)

def secs_receive_S15F41R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F41R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID RMRECSPEC OBJTOKEN RMNSCMD {L:c RCPID RCPNEWID RMSEGSPEC RMCHGTYPE OPID TIMESTAMP RMREQUESTOR}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RMRECSPEC A:n (always)  object id of a distributed recipe namespace recorder
        # OBJTOKEN U4:1 (always)  token used for authorization
        # RMNSCMD U1:1 (always)  recipe namespace command
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RCPNEWID A:n (always)  the new recipe identifier
        # RMSEGSPEC A:n (always)  The object ID of a distributed recipe namespace segment
        # RMCHGTYPE U4:1 (varies)  type of change for a recipe
        # OPID U4:1 (varies)  operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # RMREQUESTOR TF:1 (always)  True when the initiator of a change request is an attached segment, otherwise false
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMRECSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        OBJTOKEN = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMNSCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RCPNEWID = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RMSEGSPEC = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeRMCHGTYPE, lengthRMCHGTYPE) = pylist2[0].split(':')
            RMCHGTYPE = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeOPID, lengthOPID) = pylist2[0].split(':')
            OPID = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or pylist2[0] != "TF:1":
                ok = False
                break
            RMREQUESTOR = int(pylist2[1])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 42, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F41R

S15F42DRNS Recorder Mod Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F42 Python Parse reply
    rcr = sp.sendSecsMsg(15, 41, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F43RDRNS Get Change Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F43R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 43, secs_receive_S15F43R)

def secs_receive_S15F43R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F43R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 DATAID OBJSPEC TARGETSPEC
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # TARGETSPEC A:40 (always)  Specifier of target object
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 44, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F43R

S15F44DRNS Get Change Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F44 Python Parse reply
    rcr = sp.sendSecsMsg(15, 43, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:7 RCPID RCPNEWID RMSEGSPEC RMCHGTYPE OPID TIMESTAMP RMREQUESTOR}} {L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}}
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RCPNEWID A:n (always)  the new recipe identifier
        # RMSEGSPEC A:n (always)  The object ID of a distributed recipe namespace segment
        # RMCHGTYPE U4:1 (varies)  type of change for a recipe
        # OPID U4:1 (varies)  operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # RMREQUESTOR TF:1 (always)  True when the initiator of a change request is an attached segment, otherwise false
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 8 or pylist2[0] != "L:7":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPNEWID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RMSEGSPEC = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRMCHGTYPE, lengthRMCHGTYPE) = pylist3[0].split(':')
            RMCHGTYPE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeOPID, lengthOPID) = pylist3[0].split(':')
            OPID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or pylist3[0] != "TF:1":
                ok = False
                break
            RMREQUESTOR = int(pylist3[1])
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for p in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[p])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F45RDRNS Mgr Seg Aprvl Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F45R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 45, secs_receive_S15F45R)

def secs_receive_S15F45R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F45R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID RCPSPEC RCPNEWID RMCHGTYPE
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RCPSPEC A:n (always)  recipe specifier
        # RCPNEWID A:n (always)  the new recipe identifier
        # RMCHGTYPE U4:1 (varies)  type of change for a recipe
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPNEWID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMCHGTYPE, lengthRMCHGTYPE) = pylist1[0].split(':')
        RMCHGTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 46, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F45R

S15F46DRNS Mgr Seg Aprvl Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F46 Python Parse reply
    rcr = sp.sendSecsMsg(15, 45, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 RMCHGTYPE RMGRNT OPID
        # RMCHGTYPE U4:1 (varies)  type of change for a recipe
        # RMGRNT B:1 (always)  grant code, 0 ok
        # OPID U4:1 (varies)  operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRMCHGTYPE, lengthRMCHGTYPE) = pylist1[0].split(':')
        RMCHGTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        RMGRNT = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOPID, lengthOPID) = pylist1[0].split(':')
        OPID = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S15F47RDRNS Mgr Rebuild Req Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F47R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 47, secs_receive_S15F47R)

def secs_receive_S15F47R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F47R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID OBJSPEC RMNSSPEC RMRECSPEC {L:n RMSEGSPEC}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # OBJSPEC A:n (varies)  E39 structured text identifying an object, [object type:object id>]+
        # RMNSSPEC A:n (always)  object id of a recipe namespace
        # RMRECSPEC A:n (always)  object id of a distributed recipe namespace recorder
        # RMSEGSPEC A:n (always)  The object ID of a distributed recipe namespace segment
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJSPEC, lengthOBJSPEC) = pylist1[0].split(':')
        OBJSPEC = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMNSSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMRECSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            RMSEGSPEC = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 48, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F47R

S15F48DRNS Mgr Rebuild Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F48 Python Parse reply
    rcr = sp.sendSecsMsg(15, 47, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RMACK {L:p {L:2 ERRCODE ERRTEXT}}
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S15F49RLarge Recipe Download Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F49R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 49, secs_receive_S15F49R)

def secs_receive_S15F49R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F49R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DSNAME RCPOWCODE
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        # RCPOWCODE TF:1 (always)  recipe overwrite code, true=overwrite ok, false=do not overwrite
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist1[0].split(':')
        DSNAME = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        RCPOWCODE = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 50, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F49R

S15F50Large Recipe Download Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F50 Python Parse reply
    rcr = sp.sendSecsMsg(15, 49, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC15
        # ACKC15 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC15 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S15F51RLarge Recipe Upload Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F51R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 51, secs_receive_S15F51R)

def secs_receive_S15F51R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F51R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DSNAME
        # DSNAME A:50 (varies)  the name of a dataset such as a PPID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDSNAME, lengthDSNAME) = pylist0[0].split(':')
        DSNAME = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 52, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S15F51R

S15F52Large Recipe Upload Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F52 Python Parse reply
    rcr = sp.sendSecsMsg(15, 51, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKC15
        # ACKC15 B:1 (always)  acknowledge code, 0 ok
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        ACKC15 = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S15F53RRecipe Verification Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F53R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 15, 53, secs_receive_S15F53R)

def secs_receive_S15F53R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S15F53R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 RCPSPEC RCPID {L:2 RMACK {L:n {L:2 ERRCODE ERRTEXT}}}
        # RCPSPEC A:n (always)  recipe specifier
        # RCPID A:n (always)  recipe identifier conforming to OBJSPEC
        # RMACK U1:1 (always)  recipe managment completion code
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RCPID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        RMACK = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 15, 54, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S15F53R

S15F54Recipe Verification Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S15F54 Python Parse reply
    rcr = sp.sendSecsMsg(15, 53, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S16F1RProcess Job Data MBI Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 1, secs_receive_S16F1R)

def secs_receive_S16F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID DATALENGTH
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F1R

S16F2PJD MBI Grant Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F2 Python Parse reply
    rcr = sp.sendSecsMsg(16, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S16F3RProcess Job Create Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 3, secs_receive_S16F3R)

def secs_receive_S16F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 DATAID MF {L:n MID} {L:3 PRRECIPEMETHOD RCPSPEC {L:m {L:2 RCPPARNM RCPPARVAL}}} PRPROCESSSTART
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # PRRECIPEMETHOD U1:1 (always)  recipe type
        # RCPSPEC A:n (always)  recipe specifier
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        # PRPROCESSSTART TF:1 (always)  automatic start flag, false implies manual start
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeMID, lengthMID) = pylist2[0].split(':')
            MID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 4 or pylist1[0] != "L:3":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        PRRECIPEMETHOD = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[3])
        if len(pylist2) < 1:
            ok = False
            break
        for m in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[m])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            RCPPARNM = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeRCPPARVAL, lengthRCPPARVAL) = pylist4[0].split(':')
            RCPPARVAL = (pylist4[1] if len(pylist4) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        PRPROCESSSTART = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F3R

S16F4Process Job Create Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F4 Python Parse reply
    rcr = sp.sendSecsMsg(16, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 PRJOBID {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F5RProcess Job Cmd Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 5, secs_receive_S16F5R)

def secs_receive_S16F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID PRJOBID PRCMDNAME {L:n {L:2 CPNAME CPVAL}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # PRJOBID A:n (always)  process job identifier
        # PRCMDNAME A:6 (always)  process job commands, START, STOP, PAUSE, RESUME, ABORT, CANCEL
        # CPNAME A:n (varies)  command parameter name
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRCMDNAME = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPNAME, lengthCPNAME) = pylist3[0].split(':')
            CPNAME = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeCPVAL, lengthCPVAL) = pylist3[0].split(':')
            CPVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F5R

S16F6Process Job Cmd Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F6 Python Parse reply
    rcr = sp.sendSecsMsg(16, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 PRJOBID {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F7[R]Process Job Alert Notify Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F7 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 7, secs_receive_S16F7)

def secs_receive_S16F7(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F7.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TIMESTAMP PRJOBID PRJOBMILESTONE {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # PRJOBID A:n (always)  process job identifier
        # PRJOBMILESTONE U1:1 (varies)  process job status 
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePRJOBMILESTONE, lengthPRJOBMILESTONE) = pylist1[0].split(':')
        PRJOBMILESTONE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S16F7

S16F8Process Job Alert Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F8 Python Parse reply
    rcr = sp.sendSecsMsg(16, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S16F9[R]Process Job Event Notify Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F9 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 9, secs_receive_S16F9)

def secs_receive_S16F9(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F9.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 PREVENTID TIMESTAMP PRJOBID {L:n {L:2 VID V}}
        # PREVENTID U1:1 (varies)  process job event ID
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # PRJOBID A:n (always)  process job identifier
        # VID A:n (varies)  A variable ID
        # V A:n (varies)  variable value, any type including list
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typePREVENTID, lengthPREVENTID) = pylist1[0].split(':')
        PREVENTID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist3[0].split(':')
            VID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeV, lengthV) = pylist3[0].split(':')
            V = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S16F9

S16F10Process Job Event Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F10 Python Parse reply
    rcr = sp.sendSecsMsg(16, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S16F11RPRJobCreateEnh Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 11, secs_receive_S16F11R)

def secs_receive_S16F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:7 DATAID PRJOBID MF {L:n {L:2 CARRIERID {L:j SLOTID}}} {L:3 PRRECIPEMETHOD RCPSPEC {L:m {L:2 RCPPARNM RCPPARVAL}}} PRPROCESSSTART {L:p PRPAUSEEVENTID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # PRJOBID A:n (always)  process job identifier
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # CARRIERID A:n (always)  carrier ID
        # SLOTID U1:1 (always)  slot position within a carrier
        # PRRECIPEMETHOD U1:1 (always)  recipe type
        # RCPSPEC A:n (always)  recipe specifier
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        # PRPROCESSSTART TF:1 (always)  automatic start flag, false implies manual start
        # PRPAUSEEVENTID U4:1 (varies)  an event identifier for which a process job should be paused
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMF, lengthMF) = pylist1[0].split(':')
        MF = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            CARRIERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for j in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[j])
                if len(pylist4) < 1 or pylist4[0] != "U1:1":
                    ok = False
                    break
                SLOTID = int(pylist4[1])
            if not ok: break
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) != 4 or pylist1[0] != "L:3":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        PRRECIPEMETHOD = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        RCPSPEC = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[3])
        if len(pylist2) < 1:
            ok = False
            break
        for m in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[m])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            RCPPARNM = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeRCPPARVAL, lengthRCPPARVAL) = pylist4[0].split(':')
            RCPPARVAL = (pylist4[1] if len(pylist4) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        PRPROCESSSTART = int(pylist1[1])
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) < 1:
                ok = False
                break
            #(typePRPAUSEEVENTID, lengthPRPAUSEEVENTID) = pylist2[0].split(':')
            PRPAUSEEVENTID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F11R

S16F12PRJobCreateEnh Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F12 Python Parse reply
    rcr = sp.sendSecsMsg(16, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 PRJOBID {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F15RPRJobMultiCreate Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 15, secs_receive_S16F15R)

def secs_receive_S16F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 DATAID {L:p {L:6 PRJOBID MF {L:n {L:2 CARRIERID {L:j SLOTID}}} {L:3 PRRECIPEMETHOD RCPSPEC {L:m {L:2 RCPPARNM RCPPARVAL}}} PRPROCESSSTART {L:k PRPAUSEEVENTID}}}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # PRJOBID A:n (always)  process job identifier
        # MF B:1 (varies)  material format code, ASCII indicates generic units, E40 restricts to B:1
        # CARRIERID A:n (always)  carrier ID
        # SLOTID U1:1 (always)  slot position within a carrier
        # PRRECIPEMETHOD U1:1 (always)  recipe type
        # RCPSPEC A:n (always)  recipe specifier
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        # PRPROCESSSTART TF:1 (always)  automatic start flag, false implies manual start
        # PRPAUSEEVENTID U4:1 (varies)  an event identifier for which a process job should be paused
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for p in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[p])
            if len(pylist2) != 7 or pylist2[0] != "L:6":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeMF, lengthMF) = pylist3[0].split(':')
            MF = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            for n in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[n])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1 or not pylist5[0].startswith("A:"):
                    ok = False
                    break
                CARRIERID = (pylist5[1] if len(pylist5) == 2 else "")
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                for j in range(1, len(pylist5)):
                    pylist6 = lsplit(pylist5[j])
                    if len(pylist6) < 1 or pylist6[0] != "U1:1":
                        ok = False
                        break
                    SLOTID = int(pylist6[1])
                if not ok: break
            if not ok: break
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) != 4 or pylist3[0] != "L:3":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1 or pylist4[0] != "U1:1":
                ok = False
                break
            PRRECIPEMETHOD = int(pylist4[1])
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            RCPSPEC = (pylist4[1] if len(pylist4) == 2 else "")
            pylist4 = lsplit(pylist3[3])
            if len(pylist4) < 1:
                ok = False
                break
            for m in range(1, len(pylist4)):
                pylist5 = lsplit(pylist4[m])
                if len(pylist5) != 3 or pylist5[0] != "L:2":
                    ok = False
                    break
                pylist6 = lsplit(pylist5[1])
                if len(pylist6) < 1 or not pylist6[0].startswith("A:"):
                    ok = False
                    break
                RCPPARNM = (pylist6[1] if len(pylist6) == 2 else "")
                pylist6 = lsplit(pylist5[2])
                if len(pylist6) < 1:
                    ok = False
                    break
                #(typeRCPPARVAL, lengthRCPPARVAL) = pylist6[0].split(':')
                RCPPARVAL = (pylist6[1] if len(pylist6) == 2 else None)
            if not ok: break
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or pylist3[0] != "TF:1":
                ok = False
                break
            PRPROCESSSTART = int(pylist3[1])
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1:
                ok = False
                break
            for k in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[k])
                if len(pylist4) < 1:
                    ok = False
                    break
                #(typePRPAUSEEVENTID, lengthPRPAUSEEVENTID) = pylist4[0].split(':')
                PRPAUSEEVENTID = (pylist4[1] if len(pylist4) == 2 else None)
            if not ok: break
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F15R

S16F16PRJobMultiCreate Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F16 Python Parse reply
    rcr = sp.sendSecsMsg(16, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:m PRJOBID} {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F17RPRJobDequeue Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 17, secs_receive_S16F17R)

def secs_receive_S16F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:m PRJOBID
        # PRJOBID A:n (always)  process job identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for m in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[m])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F17R

S16F18PRJobDequeue Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F18 Python Parse reply
    rcr = sp.sendSecsMsg(16, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:m PRJOBID} {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F19RPRJob List Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 19, secs_receive_S16F19R)

def secs_receive_S16F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F19R

S16F20PRJob List Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F20 Python Parse reply
    rcr = sp.sendSecsMsg(16, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:m {L:2 PRJOBID PRSTATE}
        # PRJOBID A:n (always)  process job identifier
        # PRSTATE U1:1 (always)  process job state, E40 definition
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for m in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[m])
            if len(pylist1) != 3 or pylist1[0] != "L:2":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            PRSTATE = int(pylist2[1])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F21RPRJob Create Limit Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 21, secs_receive_S16F21R)

def secs_receive_S16F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F21R

S16F22PRJob Create Limit Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F22 Python Parse reply
    rcr = sp.sendSecsMsg(16, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PRJOBSPACE
        # PRJOBSPACE U2:1 (always)  the number of process jobs that can be created
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U2:1":
            ok = False
            break
        PRJOBSPACE = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S16F23RPRJob Recipe Variable Set Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 23, secs_receive_S16F23R)

def secs_receive_S16F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 PRJOBID {L:m {L:2 RCPPARNM RCPPARVAL}}
        # PRJOBID A:n (always)  process job identifier
        # RCPPARNM A:256 (always)  the name of a recipe variable parameter
        # RCPPARVAL A:80 (varies)  the value of a recipe variable parameter, any scalar format type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RCPPARNM = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPPARVAL, lengthRCPPARVAL) = pylist3[0].split(':')
            RCPPARVAL = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F23R

S16F24PRJob Recipe Variable Ack Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F24 Python Parse reply
    rcr = sp.sendSecsMsg(16, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F25RPRJob Start Method Set Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 25, secs_receive_S16F25R)

def secs_receive_S16F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 {L:m PRJOBID} PRPROCESSSTART
        # PRJOBID A:n (always)  process job identifier
        # PRPROCESSSTART TF:1 (always)  automatic start flag, false implies manual start
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        PRPROCESSSTART = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F25R

S16F26PRJob Start Method Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F26 Python Parse reply
    rcr = sp.sendSecsMsg(16, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:m PRJOBID} {L:2 ACKA {L:n {L:2 ERRCODE ERRTEXT}}}
        # PRJOBID A:n (always)  process job identifier
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            PRJOBID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or pylist2[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist2[1])
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        for n in range(1, len(pylist2)):
            pylist3 = lsplit(pylist2[n])
            if len(pylist3) != 3 or pylist3[0] != "L:2":
                ok = False
                break
            pylist4 = lsplit(pylist3[1])
            if len(pylist4) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist4[0].split(':')
            ERRCODE = (pylist4[1] if len(pylist4) == 2 else None)
            pylist4 = lsplit(pylist3[2])
            if len(pylist4) < 1 or not pylist4[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist4[1] if len(pylist4) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S16F27RControl Job Command Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 27, secs_receive_S16F27R)

def secs_receive_S16F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 CTLJOBID CTLJOBCMD {L:2 CPNAME CPVAL}
        # CTLJOBID A:n (always)  control job ID, an OBJID
        # CTLJOBCMD U1:1 (always)  control job command
        # CPNAME A:n (varies)  command parameter name
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        CTLJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CTLJOBCMD = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeCPNAME, lengthCPNAME) = pylist2[0].split(':')
        CPNAME = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeCPVAL, lengthCPVAL) = pylist2[0].split(':')
        CPVAL = (pylist2[1] if len(pylist2) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F27R

S16F28Control Job Command Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F28 Python Parse reply
    rcr = sp.sendSecsMsg(16, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ACKA {L:2 ERRCODE ERRTEXT}
        # ACKA TF:1 (always)  request success
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) != 3 or pylist1[0] != "L:2":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist2[0].split(':')
        ERRCODE = (pylist2[1] if len(pylist2) == 2 else None)
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        ERRTEXT = (pylist2[1] if len(pylist2) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S16F29PRSetMtrlOrder Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F29 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 16, 29, secs_receive_S16F29)

def secs_receive_S16F29(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S16F29.'''
    ok = True
    while ok:   # break out of loop on error
        # expect PRMTRLORDER
        # PRMTRLORDER U1:1 (always)  ordering method for pending process jobs
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        PRMTRLORDER = int(pylist0[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 16, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S16F29

S16F30PRSetMtrlOrder Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S16F30 Python Parse reply
    rcr = sp.sendSecsMsg(16, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect ACKA
        # ACKA TF:1 (always)  request success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S17F1RData Report Create Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 1, secs_receive_S17F1R)

def secs_receive_S17F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID RPTID DATASRC {L:n VID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # RPTID U4:1 (varies)  report ID
        # DATASRC A:n (always)  identifies a data source, use length 0 to mean the default
        # VID A:n (varies)  A variable ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
        RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        DATASRC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeVID, lengthVID) = pylist2[0].split(':')
            VID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F1R

S17F2Data Report Create Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F2 Python Parse reply
    rcr = sp.sendSecsMsg(17, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 RPTID ERRCODE
        # RPTID U4:1 (varies)  report ID
        # ERRCODE U4:1 (varies)  error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
        RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist1[0].split(':')
        ERRCODE = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S17F3RData Report Delete Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 3, secs_receive_S17F3R)

def secs_receive_S17F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n RPTID
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
            RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F3R

S17F4Data Report Del Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F4 Python Parse reply
    rcr = sp.sendSecsMsg(17, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ACKA {L:m {L:3 RPTID ERRCODE ERRTEXT}}
        # ACKA TF:1 (always)  request success
        # RPTID U4:1 (varies)  report ID
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist3[0].split(':')
            RPTID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S17F5RTrace Create Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 5, secs_receive_S17F5R)

def secs_receive_S17F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 DATAID TRID CEED {L:n RPTID} {L:8* TOTSMP REPGSZ EVNTSRC CEIDSTART EVNTSRC2 CEIDSTOP TRAUTOD RPTOC}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # TRID A:n (varies)  trace request ID
        # CEED TF:1 (always)  collection event or trace enablement, true is enabled
        # RPTID U4:1 (varies)  report ID
        # TOTSMP U4:1 (varies)  total samples to be made, should be an even multiple of REPGSZ
        # REPGSZ U4:1 (varies)  reporting group size, TOTSMP modulo REPGSZ should be 0
        # EVNTSRC A:n (always)  identifies an event source, use length 0 to specify the default
        # CEIDSTART U4:1 (varies)  the CEID of a start event
        # EVNTSRC2 A:n (always)  a second event source EVNTSRC
        # CEIDSTOP U4:1 (varies)  the CEID of a stop event
        # TRAUTOD TF:1 (always)  delete upon completion flag
        # RPTOC TF:1 (always)  send only changed data trace report flag
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        CEED = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist2[0].split(':')
            RPTID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) == 9:   # 8 optional items found
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeTOTSMP, lengthTOTSMP) = pylist2[0].split(':')
            TOTSMP = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeREPGSZ, lengthREPGSZ) = pylist2[0].split(':')
            REPGSZ = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            EVNTSRC = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[4])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCEIDSTART, lengthCEIDSTART) = pylist2[0].split(':')
            CEIDSTART = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[5])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            EVNTSRC2 = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[6])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCEIDSTOP, lengthCEIDSTOP) = pylist2[0].split(':')
            CEIDSTOP = (pylist2[1] if len(pylist2) == 2 else None)
            pylist2 = lsplit(pylist1[7])
            if len(pylist2) < 1 or pylist2[0] != "TF:1":
                ok = False
                break
            TRAUTOD = int(pylist2[1])
            pylist2 = lsplit(pylist1[8])
            if len(pylist2) < 1 or pylist2[0] != "TF:1":
                ok = False
                break
            RPTOC = int(pylist2[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F5R

S17F6Trace Create Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F6 Python Parse reply
    rcr = sp.sendSecsMsg(17, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TRID ERRCODE
        # TRID A:n (varies)  trace request ID
        # ERRCODE U4:1 (varies)  error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeTRID, lengthTRID) = pylist1[0].split(':')
        TRID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist1[0].split(':')
        ERRCODE = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S17F7RTrace Delete Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 7, secs_receive_S17F7R)

def secs_receive_S17F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist1[0].split(':')
            TRID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F7R

S17F8Trace Delete Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F8 Python Parse reply
    rcr = sp.sendSecsMsg(17, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ACKA {L:m {L:3 TRID ERRCODE ERRTEXT}}
        # ACKA TF:1 (always)  request success
        # TRID A:n (varies)  trace request ID
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist3[0].split(':')
            TRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S17F9RCollection Event Link Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 9, secs_receive_S17F9R)

def secs_receive_S17F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 DATAID EVNTSRC CEID {L:n RPTID}
        # DATAID U4:1 (varies)  an identifier to correlate related messages
        # EVNTSRC A:n (always)  identifies an event source, use length 0 to specify the default
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATAID, lengthDATAID) = pylist1[0].split(':')
        DATAID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EVNTSRC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeRPTID, lengthRPTID) = pylist2[0].split(':')
            RPTID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F9R

S17F10Collection Event Link Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F10 Python Parse reply
    rcr = sp.sendSecsMsg(17, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 EVNTSRC CEID ERRCODE
        # EVNTSRC A:n (always)  identifies an event source, use length 0 to specify the default
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # ERRCODE U4:1 (varies)  error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EVNTSRC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist1[0].split(':')
        ERRCODE = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S17F11RCollection Event Unlink Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 11, secs_receive_S17F11R)

def secs_receive_S17F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 EVNTSRC CEID RPTID
        # EVNTSRC A:n (always)  identifies an event source, use length 0 to specify the default
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EVNTSRC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
        RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F11R

S17F12Collection Event Unlink Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F12 Python Parse reply
    rcr = sp.sendSecsMsg(17, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 EVNTSRC CEID RPTID ERRCODE
        # EVNTSRC A:n (always)  identifies an event source, use length 0 to specify the default
        # CEID U4:1 (varies)  collection event identifier, GEM requires type Un
        # RPTID U4:1 (varies)  report ID
        # ERRCODE U4:1 (varies)  error code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EVNTSRC = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCEID, lengthCEID) = pylist1[0].split(':')
        CEID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeRPTID, lengthRPTID) = pylist1[0].split(':')
        RPTID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeERRCODE, lengthERRCODE) = pylist1[0].split(':')
        ERRCODE = (pylist1[1] if len(pylist1) == 2 else None)
        return # finished ok
    # end while(ok)
# end def

S17F13RTrace Reset Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 17, 13, secs_receive_S17F13R)

def secs_receive_S17F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S17F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n TRID
        # TRID A:n (varies)  trace request ID
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist1[0].split(':')
            TRID = (pylist1[1] if len(pylist1) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 17, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S17F13R

S17F14Trace Reset Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S17F14 Python Parse reply
    rcr = sp.sendSecsMsg(17, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ACKA {L:m {L:3 TRID ERRCODE ERRTEXT}}
        # ACKA TF:1 (always)  request success
        # TRID A:n (varies)  trace request ID
        # ERRCODE U4:1 (varies)  error code
        # ERRTEXT A:80 (always)  description of ERRCODE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        ACKA = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeTRID, lengthTRID) = pylist3[0].split(':')
            TRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeERRCODE, lengthERRCODE) = pylist3[0].split(':')
            ERRCODE = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ERRTEXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F1RRead Attribute Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 1, secs_receive_S18F1R)

def secs_receive_S18F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TARGETID {L:n ATTRID}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist2[0].split(':')
            ATTRID = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F1R

S18F2Read Attribute Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F2 Python Parse reply
    rcr = sp.sendSecsMsg(18, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 TARGETID SSACK {L:n ATTRDATA} {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist2[0].split(':')
            ATTRDATA = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F3RWrite Attribute Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 3, secs_receive_S18F3R)

def secs_receive_S18F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TARGETID {L:n {L:2 ATTRID ATTRDATA}}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # ATTRID A:40 (varies)  identifies an attribute type, chars 0x20-0x7e but not >, :, ?, *, or ~.  Does not begin or end with space.
        # ATTRDATA A:n (varies)  a specific attribute value of any data type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRID, lengthATTRID) = pylist3[0].split(':')
            ATTRID = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeATTRDATA, lengthATTRDATA) = pylist3[0].split(':')
            ATTRDATA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F3R

S18F4Write Attribute Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F4 Python Parse reply
    rcr = sp.sendSecsMsg(18, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TARGETID SSACK {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F5RRead Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 5, secs_receive_S18F5R)

def secs_receive_S18F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 TARGETID DATASEG DATALENGTH
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # DATASEG A:n (varies)  identifies data requested, E87 requires text
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATASEG, lengthDATASEG) = pylist1[0].split(':')
        DATASEG = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F5R

S18F6Read Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F6 Python Parse reply
    rcr = sp.sendSecsMsg(18, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 TARGETID SSACK DATA {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # DATA A:n (varies)  unformatted data
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATA, lengthDATA) = pylist1[0].split(':')
        DATA = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F7RWrite Data Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 7, secs_receive_S18F7R)

def secs_receive_S18F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TARGETID DATASEG DATALENGTH DATA
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # DATASEG A:n (varies)  identifies data requested, E87 requires text
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        # DATA A:n (varies)  unformatted data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATASEG, lengthDATASEG) = pylist1[0].split(':')
        DATASEG = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist1[0].split(':')
        DATALENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeDATA, lengthDATA) = pylist1[0].split(':')
        DATA = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F7R

S18F8Write Data Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F8 Python Parse reply
    rcr = sp.sendSecsMsg(18, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TARGETID SSACK {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F9RRead ID Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 9, secs_receive_S18F9R)

def secs_receive_S18F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TARGETID
        # TARGETID A:n (always)  the OBJSPEC for the target object
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F9R

S18F10Read ID Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F10 Python Parse reply
    rcr = sp.sendSecsMsg(18, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:4 TARGETID SSACK MID {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F11RWrite ID Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 11, secs_receive_S18F11R)

def secs_receive_S18F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TARGETID MID
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F11R

S18F12Write ID Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F12 Python Parse reply
    rcr = sp.sendSecsMsg(18, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TARGETID SSACK {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F13RSubsystem Command Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 13, secs_receive_S18F13R)

def secs_receive_S18F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 TARGETID SSCMD {L:n CPVAL}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSCMD A:n (always)  subsystem action command
        # CPVAL A:n (varies)  command parameter value, any scalar type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSCMD = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeCPVAL, lengthCPVAL) = pylist2[0].split(':')
            CPVAL = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F13R

S18F14Subsystem Command Ack Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F14 Python Parse reply
    rcr = sp.sendSecsMsg(18, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TARGETID SSACK {L:s STATUS}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # STATUS A:n (always)  subsystem status data
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S18F15RRead 2D Code Cond Req Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 18, 15, secs_receive_S18F15R)

def secs_receive_S18F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S18F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TARGETID
        # TARGETID A:n (always)  the OBJSPEC for the target object
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 18, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S18F15R

S18F16Read 2D Code Cond Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S18F16 Python Parse reply
    rcr = sp.sendSecsMsg(18, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:5 TARGETID SSACK MID {L:s STATUS} {L:c CONDITION}
        # TARGETID A:n (always)  the OBJSPEC for the target object
        # SSACK A:2 (always)  two character codes for success or failure, NO Normal, EE exec. err, CE comm. err, HE h/w err, TE tag err
        # MID A:16 (varies)  material ID, E40 restricts to A:n
        # STATUS A:n (always)  subsystem status data
        # CONDITION A:n (always)  sub-system condition info tag
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        SSACK = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeMID, lengthMID) = pylist1[0].split(':')
        MID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for s in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[s])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUS = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for c in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[c])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            CONDITION = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F1RRequest Process Definition Element (PDE) Directory Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 1, secs_receive_S19F1R)

def secs_receive_S19F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 {L:m {L:3 PDEATTRIBUTENAME COMPARISONOPERATOR PDEATTRIBUTEVALUE}} {L:n PDEATTRIBUTE}
        # PDEATTRIBUTENAME U1:1 (always)  identifies a PDE attribute type
        # COMPARISONOPERATOR U1:1 (always)  choice of comparison operators.  Interpreted as "target <op> <const>" where <op> is this value and <const> is supplied in the expression
        # PDEATTRIBUTEVALUE A (varies)  contains the value of a PDE Attribute, may be type L, A, TF, U1
        # PDEATTRIBUTE U1:1 (always)  a reportable PDE attribute type, not necessarily useable in a filter expression
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            PDEATTRIBUTENAME = int(pylist3[1])
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COMPARISONOPERATOR = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1:
                ok = False
                break
            #(typePDEATTRIBUTEVALUE, lengthPDEATTRIBUTEVALUE) = pylist3[0].split(':')
            PDEATTRIBUTEVALUE = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            PDEATTRIBUTE = int(pylist2[1])
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F1R

S19F2PDE Directory Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F2 Python Parse reply
    rcr = sp.sendSecsMsg(19, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 DIRRSPSTAT STATUSTXT {L:m {L:2 UID {L:n {L:2 PDEATTRIBUTE PDEATTRIBUTEVALUE}}}}
        # DIRRSPSTAT U1:1 (always)  get dir status response
        # STATUSTXT A:80 (always)  status response description
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # PDEATTRIBUTE U1:1 (always)  a reportable PDE attribute type, not necessarily useable in a filter expression
        # PDEATTRIBUTEVALUE A (varies)  contains the value of a PDE Attribute, may be type L, A, TF, U1
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        DIRRSPSTAT = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        STATUSTXT = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            UID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            for n in range(1, len(pylist3)):
                pylist4 = lsplit(pylist3[n])
                if len(pylist4) != 3 or pylist4[0] != "L:2":
                    ok = False
                    break
                pylist5 = lsplit(pylist4[1])
                if len(pylist5) < 1 or pylist5[0] != "U1:1":
                    ok = False
                    break
                PDEATTRIBUTE = int(pylist5[1])
                pylist5 = lsplit(pylist4[2])
                if len(pylist5) < 1:
                    ok = False
                    break
                #(typePDEATTRIBUTEVALUE, lengthPDEATTRIBUTEVALUE) = pylist5[0].split(':')
                PDEATTRIBUTEVALUE = (pylist5[1] if len(pylist5) == 2 else None)
            if not ok: break
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F3RPDE Delete Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 3, secs_receive_S19F3R)

def secs_receive_S19F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n UID
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            UID = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S19F3R

S19F4PDE Delete Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F4 Python Parse reply
    rcr = sp.sendSecsMsg(19, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:3 UID DELRSPSTAT STATUSTXT}
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # DELRSPSTAT U1:1 (always)  Response code for the PDE deletion request, non-zero means not deleted
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 4 or pylist1[0] != "L:3":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            UID = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            DELRSPSTAT = int(pylist2[1])
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F5RPDE Header Data Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 5, secs_receive_S19F5R)

def secs_receive_S19F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n UID
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            UID = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F5R

S19F6PDE Header Data Reply Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F6 Python Parse reply
    rcr = sp.sendSecsMsg(19, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TCID {L:n {L:3 UID GETRSPSTAT STATUSTXT}}
        # TCID A:36 (always)  The identity of a transfer container specified as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # GETRSPSTAT U1:1 (always)  Response code for PDE queries, non-zero indicates failure
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TCID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            UID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            GETRSPSTAT = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F7Rrequest the transfer of PDEs via Stream 13 Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 7, secs_receive_S19F7R)

def secs_receive_S19F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n UID
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            UID = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F7R

S19F8PDE Transfer Reply Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F8 Python Parse reply
    rcr = sp.sendSecsMsg(19, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 TCID {L:n {L:3 UID GETRSPSTAT STATUSTXT}}
        # TCID A:36 (always)  The identity of a transfer container specified as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # GETRSPSTAT U1:1 (always)  Response code for PDE queries, non-zero indicates failure
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TCID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            UID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            GETRSPSTAT = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F9RRequest to Send PDE Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 9, secs_receive_S19F9R)

def secs_receive_S19F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TCID TRANSFERSIZE
        # TCID A:36 (always)  The identity of a transfer container specified as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens
        # TRANSFERSIZE U8:1 (always)  SIze in bytes of the TransferContainer.   An 8 byte value but HSMS uses 4 byte message lengths!!!
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TCID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U8:1":
            ok = False
            break
        TRANSFERSIZE = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F9R

S19F10Initiate PDE transfer Reply Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F10 Python Parse reply
    rcr = sp.sendSecsMsg(19, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 TCID RTSRSPSTAT STATUSTXT
        # TCID A:36 (always)  The identity of a transfer container specified as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens
        # RTSRSPSTAT U1:1 (always)  PDE transfer request reply code, non-zero means denied
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TCID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RTSRSPSTAT = int(pylist1[1])
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        STATUSTXT = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S19F11RSend PDE Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 11, secs_receive_S19F11R)

def secs_receive_S19F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect TCID
        # TCID A:36 (always)  The identity of a transfer container specified as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        TCID = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F11R

S19F12Send PDE Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F12 Python Parse reply
    rcr = sp.sendSecsMsg(19, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S19F13RTransferContainer Report Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 13, secs_receive_S19F13R)

def secs_receive_S19F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n {L:4 UID SENDRSPSTAT VERIFYRSPSTAT STATUSTXT}
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # SENDRSPSTAT U1:1 (always)  Return codes for the Send PDE request, non-zero means failure
        # VERIFYRSPSTAT U1:1 (always)  PDE verification result, 0 success, 10 none, other error
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 5 or pylist1[0] != "L:4":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            UID = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            SENDRSPSTAT = int(pylist2[1])
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or pylist2[0] != "U1:1":
                ok = False
                break
            VERIFYRSPSTAT = int(pylist2[1])
            pylist2 = lsplit(pylist1[4])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F13R

S19F14TransferContainer Report Ack Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F14 Python Parse reply
    rcr = sp.sendSecsMsg(19, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # no data expected
        return # finished ok
    # end while(ok)
# end def

S19F15RRequest PDE Resolution Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 15, secs_receive_S19F15R)

def secs_receive_S19F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 TARGETPDE {L:n {L:2 PDEREF RESOLUTION}}
        # TARGETPDE A:36 (always)  the UID of the target PDE, a 36 character string with runs of 8,4,4,4, and 12 characters joined by hyphens.
        # PDEREF A:36 (always)  The UID of a PDE or of a PDE group formatted as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens.
        # RESOLUTION A:36 (always)  the UID of a PDE
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETPDE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PDEREF = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RESOLUTION = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S19F15R

S19F16PDE Resolution Data Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F16 Python Parse reply
    rcr = sp.sendSecsMsg(19, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:m {L:2 PDEREF RESOLUTION}} {L:n {L:3 UID RESPDESTAT STATUSTXT}}
        # PDEREF A:36 (always)  The UID of a PDE or of a PDE group formatted as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens.
        # RESOLUTION A:36 (always)  the UID of a PDE
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # RESPDESTAT U1:1 (always)  status codes for PDE resolution
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for m in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[m])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PDEREF = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RESOLUTION = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            UID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            RESPDESTAT = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F17RVerify PDE Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 17, secs_receive_S19F17R)

def secs_receive_S19F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 TARGETPDE {L:n {L:2 PDEREF RESOLUTION}} VERIFYTYPE VERIFYDEPTH
        # TARGETPDE A:36 (always)  the UID of the target PDE, a 36 character string with runs of 8,4,4,4, and 12 characters joined by hyphens.
        # PDEREF A:36 (always)  The UID of a PDE or of a PDE group formatted as a 36 character string with runs of 8, 4, 4, 4, and 12 characters joined by hyphens.
        # RESOLUTION A:36 (always)  the UID of a PDE
        # VERIFYTYPE U1:1 (always)  chooses the type of verification
        # VERIFYDEPTH U1:1 (always)  whether to check only the target, or the target and all referenced PDEs
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        TARGETPDE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 3 or pylist2[0] != "L:2":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            PDEREF = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RESOLUTION = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        VERIFYTYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        VERIFYDEPTH = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S19F17R

S19F18PDE Verification Result Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F18 Python Parse reply
    rcr = sp.sendSecsMsg(19, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 VERIFYSUCCESS {L:n {L:3 UID VERIFYRSPSTAT STATUSTXT}}
        # VERIFYSUCCESS TF:1 (always)  True if no errors were found
        # UID A:36 (always)  See SEMI E139.  A unique identifier for a PDE consisting of a 36 character string with runs of 8, 4, 4, 4, and 12 characters separated by hyphens 
        # VERIFYRSPSTAT U1:1 (always)  PDE verification result, 0 success, 10 none, other error
        # STATUSTXT A:80 (always)  status response description
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "TF:1":
            ok = False
            break
        VERIFYSUCCESS = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            UID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            VERIFYRSPSTAT = int(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            STATUSTXT = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S19F19RS19 Multi-block Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 19, 19, secs_receive_S19F19R)

def secs_receive_S19F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S19F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect DATALENGTH
        # DATALENGTH U4:1 (varies)  total bytes of the message body 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        #(typeDATALENGTH, lengthDATALENGTH) = pylist0[0].split(':')
        DATALENGTH = (pylist0[1] if len(pylist0) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 19, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S19F19R

S19F20S19 Multi-block Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S19F20 Python Parse reply
    rcr = sp.sendSecsMsg(19, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect GRANT
        # GRANT B:1 (always)  multiblock grant code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "B:1":
            ok = False
            break
        GRANT = sp.binToInt(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F1RSetSRO Attributes Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 1, secs_receive_S20F1R)

def secs_receive_S20F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 OBJID OBJTYPE AUTOPOST_DISABLE AUTOCLEAR_DISABLE RETAINRECIPE_DISABLE AUTOCLOSE
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # AUTOPOST_DISABLE U1:1 (always)  Disable automatic posting of recipes to RMS preceeding SRO move to Local state (E171)
        # AUTOCLEAR_DISABLE U1:1 (always)  Disable automatic clear of recipes on SRO transition to Local (E171)
        # RETAINRECIPE_DISABLE U1:1 (always)  Disable automatic retention of recipes on disconnect
        # AUTOCLOSE U2:1 (always)  Interaction timeout for closing operator session, 0 is no limit
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        AUTOPOST_DISABLE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        AUTOCLEAR_DISABLE = int(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RETAINRECIPE_DISABLE = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        AUTOCLOSE = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F1R

S20F2SetSRO Attributes Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F2 Python Parse reply
    rcr = sp.sendSecsMsg(20, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SSAACK
        # SSAACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        SSAACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F3RGetOperationIDList Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 3, secs_receive_S20F3R)

def secs_receive_S20F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:3 OBJID OBJTYPE OPETYPE
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F3R

S20F4GetOperationIDList Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F4 Python Parse reply
    rcr = sp.sendSecsMsg(20, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n OPEID} GOILACK
        # OPEID A:16 (always)  recipe operation identifier
        # GOILACK U1:1 (always)  completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        GOILACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F5ROpenConnectionEvent Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 5, secs_receive_S20F5R)

def secs_receive_S20F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:7 OBJID OBJTYPE OPETYPE RMSUSERID RMSPWD EQUSERID OPEID
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # RMSUSERID A:64 (always)  SRO userID
        # RMSPWD A:64 (always)  password of SRO user 
        # EQUSERID A:64 (always)  Equipment userID for recipe use authentication
        # OPEID A:16 (always)  recipe operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMSUSERID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        RMSPWD = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        EQUSERID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F5R

S20F6OpenConnectionEvent Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F6 Python Parse reply
    rcr = sp.sendSecsMsg(20, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 OPEID OCEACK
        # OPEID A:16 (always)  recipe operation identifier
        # OCEACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OCEACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F7RCloseConnectionEvent Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 7, secs_receive_S20F7R)

def secs_receive_S20F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJID OBJTYPE OPETYPE OPEID
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F7R

S20F8CloseConnectionEvent Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F8 Python Parse reply
    rcr = sp.sendSecsMsg(20, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 OPEID CCEACK
        # OPEID A:16 (always)  recipe operation identifier
        # CCEACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        CCEACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F9RClearOperation Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 9, secs_receive_S20F9R)

def secs_receive_S20F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJID OBJTYPE OPETYPE OPEID
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F9R

S20F10ClearOperation Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F10 Python Parse reply
    rcr = sp.sendSecsMsg(20, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect COACK
        # COACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        COACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F11RGetRecipeXIDList Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F11R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 11, secs_receive_S20F11R)

def secs_receive_S20F11R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F11R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJID OBJTYPE OPETYPE OPEID
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F11R

S20F12GetRecipeXIDList Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F12 Python Parse reply
    rcr = sp.sendSecsMsg(20, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}} GRXLACK
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # GRXLACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        GRXLACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F13RDeleteRecipe Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 13, secs_receive_S20F13R)

def secs_receive_S20F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) != 10 or pylist1[0] != "L:9":
            ok = False
            break
        pylist2 = lsplit(pylist1[1])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        TIMESTAMP = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[2])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[3])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        ASSGNID = int(pylist2[1])
        pylist2 = lsplit(pylist1[4])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        COPYID = int(pylist2[1])
        pylist2 = lsplit(pylist1[5])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        REVID = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[6])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        RecID = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[7])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        VERID = (pylist2[1] if len(pylist2) == 2 else "")
        pylist2 = lsplit(pylist1[8])
        if len(pylist2) < 1 or pylist2[0] != "U1:1":
            ok = False
            break
        TYPEID = int(pylist2[1])
        pylist2 = lsplit(pylist1[9])
        if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
            ok = False
            break
        EQID = (pylist2[1] if len(pylist2) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F13R

S20F14DeleteRecipe Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F14 Python Parse reply
    rcr = sp.sendSecsMsg(20, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect DRRACK
        # DRRACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        DRRACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F15RWriteRecipe Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 15, secs_receive_S20F15R)

def secs_receive_S20F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID {L:n {L:10 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID RCPBODYA}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # RCPBODYA A:n (varies)  user defined recipe body, list allowed
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 11 or pylist2[0] != "L:10":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[10])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPBODYA, lengthRCPBODYA) = pylist3[0].split(':')
            RCPBODYA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F15R

S20F16WriteRecipe Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F16 Python Parse reply
    rcr = sp.sendSecsMsg(20, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect WRACK
        # WRACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        WRACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F17RReadRecipe Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 17, secs_receive_S20F17R)

def secs_receive_S20F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F17R

S20F18ReadRecipe Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F18 Python Parse reply
    rcr = sp.sendSecsMsg(20, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:10 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID RCPBODYA}} RRACK_S20
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # RCPBODYA A:n (varies)  user defined recipe body, list allowed
        # RRACK_S20 U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 11 or pylist2[0] != "L:10":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[10])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPBODYA, lengthRCPBODYA) = pylist3[0].split(':')
            RCPBODYA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        RRACK_S20 = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F19RQueryRecipeXIDList Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 19, secs_receive_S20F19R)

def secs_receive_S20F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 OBJID OBJTYPE OPETYPE OPEID 
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F19R

S20F20QueryRecipeXIDList Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F20 Python Parse reply
    rcr = sp.sendSecsMsg(20, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 OPEID {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}} QRXLEACK
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # QRXLEACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        QRXLEACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F21RQueryRecipe Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F21R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 21, secs_receive_S20F21R)

def secs_receive_S20F21R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F21R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 22, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F21R

S20F22QueryRecipe Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F22 Python Parse reply
    rcr = sp.sendSecsMsg(20, 21, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect QREACK
        # QREACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        QREACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F23RPostRecipe Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F23R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 23, secs_receive_S20F23R)

def secs_receive_S20F23R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F23R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID {L:n {L:10 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID RCPBODYA}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # RCPBODYA A:n (varies)  user defined recipe body, list allowed
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 11 or pylist2[0] != "L:10":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[10])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPBODYA, lengthRCPBODYA) = pylist3[0].split(':')
            RCPBODYA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 24, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F23R

S20F24PostRecipe Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F24 Python Parse reply
    rcr = sp.sendSecsMsg(20, 23, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PREACK
        # PREACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        PREACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F25RSetPRC Attributes Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F25R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 25, secs_receive_S20F25R)

def secs_receive_S20F25R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F25R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE {L:n MAXNUMBER} MAXTIME PRCPREEXECHK
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # MAXNUMBER U2:1 (always)  subspace maximum 
        # MAXTIME U2:1 (always)  maximum minutes for a PEM recipe to be preserved in PRC post use, 0 means NA
        # PRCPREEXECHK U1:1 (always)  Enable Pre-Execution checking
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or pylist2[0] != "U2:1":
                ok = False
                break
            MAXNUMBER = int(pylist2[1])
        if not ok: break
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or pylist1[0] != "U2:1":
            ok = False
            break
        MAXTIME = int(pylist1[1])
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        PRCPREEXECHK = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 26, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F25R

S20F26SetPRC Attributes Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F26 Python Parse reply
    rcr = sp.sendSecsMsg(20, 25, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect SPAACK
        # SPAACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        SPAACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F27RPreSpecifyRecipe Request Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F27R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 27, secs_receive_S20F27R)

def secs_receive_S20F27R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F27R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 OBJID OBJTYPE OPETYPE OPEID PRJOBID {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}}
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # PRJOBID A:n (always)  process job identifier
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 28, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S20F27R

S20F28PreSpecifyRecipe Acknowledge Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F28 Python Parse reply
    rcr = sp.sendSecsMsg(20, 27, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PSRACK
        # PSRACK U1:1 (always)  service completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        PSRACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S20F29RQueryPJRecipeXIDList Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F29R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 29, secs_receive_S20F29R)

def secs_receive_S20F29R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F29R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID PRJOBID 
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # PRJOBID A:n (always)  process job identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 30, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F29R

S20F30QueryPJRecipeXIDList Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F30 Python Parse reply
    rcr = sp.sendSecsMsg(20, 29, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 {L:n {L:9 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID}} QPRKEACK
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # QPRKEACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 10 or pylist2[0] != "L:9":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        QPRKEACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F31RPre-Exe Check Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F31R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 31, secs_receive_S20F31R)

def secs_receive_S20F31R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F31R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:6 OBJID OBJTYPE OPETYPE OPEID PRJOBID CHKINFO
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # PRJOBID A:n (always)  process job identifier
        # CHKINFO A:n (varies)  User defined value, any type
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 7 or pylist0[0] != "L:6":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeCHKINFO, lengthCHKINFO) = pylist1[0].split(':')
        CHKINFO = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 32, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F31R

S20F32Pre-Exe Check Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F32 Python Parse reply
    rcr = sp.sendSecsMsg(20, 31, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 PECRSLT {L:n {L:10 TIMESTAMP OPEID ASSGNID COPYID REVID RecID VERID TYPEID EQID RCPBODYA}} PECEACK
        # PECRSLT U1:1 (always)  RMS result
        # TIMESTAMP A:32 (always)  ECV TimeFormat controls format, 0=A:12 YYMMDDHHMMSS, 1=A:16 YYYYMMDDHHMMSScc,2=YYYY-MM-DDTHH:MM:SS.s[s]*{Z|+hh:mm|-hh:mm}
        # OPEID A:16 (always)  recipe operation identifier
        # ASSGNID U1:1 (always)  Assigner of the RecipeXID Base Part
        # COPYID U1:1 (always)  Recipe copy type
        # REVID A:256 (always)  recipe revision information related to SRO
        # RecID A:n (always)  recipe spec or ppid
        # VERID A:n (always)  composite key with RecipeID to identify a unique recipe
        # TYPEID U1:1 (always)  recipe type
        # EQID A:256 (always)  recipe specification of compatible equipment
        # RCPBODYA A:n (varies)  user defined recipe body, list allowed
        # PECEACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        PECRSLT = int(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 11 or pylist2[0] != "L:10":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            TIMESTAMP = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            OPEID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            ASSGNID = int(pylist3[1])
            pylist3 = lsplit(pylist2[4])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            COPYID = int(pylist3[1])
            pylist3 = lsplit(pylist2[5])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            REVID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[6])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            RecID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[7])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            VERID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[8])
            if len(pylist3) < 1 or pylist3[0] != "U1:1":
                ok = False
                break
            TYPEID = int(pylist3[1])
            pylist3 = lsplit(pylist2[9])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            EQID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[10])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeRCPBODYA, lengthRCPBODYA) = pylist3[0].split(':')
            RCPBODYA = (pylist3[1] if len(pylist3) == 2 else None)
        if not ok: break
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        PECEACK = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S20F33RPreSpecifyRecipe Event Send Sent by Equipment Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F33R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 20, 33, secs_receive_S20F33R)

def secs_receive_S20F33R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S20F33R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 OBJID OBJTYPE OPETYPE OPEID PRJOBID
        # OBJID A:80 (varies)  E39 object identifier 1-80 chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OBJTYPE A:40 (varies)  object class name, chars 0x20-0x7e but not >, ?, *, or ~.  Does not begin or end with space.
        # OPETYPE U1:1 (always)  recipe operation type
        # OPEID A:16 (always)  recipe operation identifier
        # PRJOBID A:n (always)  process job identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJID, lengthOBJID) = pylist1[0].split(':')
        OBJID = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeOBJTYPE, lengthOBJTYPE) = pylist1[0].split(':')
        OBJTYPE = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or pylist1[0] != "U1:1":
            ok = False
            break
        OPETYPE = int(pylist1[1])
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        OPEID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        PRJOBID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 20, 34, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S20F33R

S20F34PreSpecifyRecipe Event Acknowledge Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S20F34 Python Parse reply
    rcr = sp.sendSecsMsg(20, 33, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect PSREACK
        # PSREACK U1:1 (always)  event completion code
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or pylist0[0] != "U1:1":
            ok = False
            break
        PSREACK = int(pylist0[1])
        return # finished ok
    # end while(ok)
# end def

S21F1RItem Load Inquire Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F1R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 1, secs_receive_S21F1R)

def secs_receive_S21F1R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F1R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:4 ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 5 or pylist0[0] != "L:4":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 2, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F1R

S21F2Item Load Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F2 Python Parse reply
    rcr = sp.sendSecsMsg(21, 1, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ITEMACK ITEMERROR
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S21F3RItem Send Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F3R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 3, secs_receive_S21F3R)

def secs_receive_S21F3R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F3R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION {L:n ITEMPART}
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        # ITEMPART A:n (varies)  component part of an item, may be data type A:n or B:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeITEMPART, lengthITEMPART) = pylist2[0].split(':')
            ITEMPART = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 4, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F3R

S21F4Item Send Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F4 Python Parse reply
    rcr = sp.sendSecsMsg(21, 3, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ITEMACK ITEMERROR
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S21F5RItem Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F5R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 5, secs_receive_S21F5R)

def secs_receive_S21F5R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F5R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 ITEMTYPE ITEMID
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 6, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F5R

S21F6Item Data Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F6 Python Parse reply
    rcr = sp.sendSecsMsg(21, 5, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:7 ITEMACK ITEMERROR ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION {L:n ITEMPART}
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        # ITEMPART A:n (varies)  component part of an item, may be data type A:n or B:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1:
                ok = False
                break
            #(typeITEMPART, lengthITEMPART) = pylist2[0].split(':')
            ITEMPART = (pylist2[1] if len(pylist2) == 2 else None)
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S21F7RItem Type List Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F7R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 7, secs_receive_S21F7R)

def secs_receive_S21F7R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F7R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect ITEMTYPE
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1 or not pylist0[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist0[1] if len(pylist0) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 8, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F7R

S21F8Item Type List Results Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F8 Python Parse reply
    rcr = sp.sendSecsMsg(21, 7, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:7 ITEMACK ITEMERROR ITEMTYPE {L:n {L:3 ITEMID ITEMLENGTH ITEMVERSION}}
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ITEMID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1:
                ok = False
                break
            #(typeITEMLENGTH, lengthITEMLENGTH) = pylist3[0].split(':')
            ITEMLENGTH = (pylist3[1] if len(pylist3) == 2 else None)
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ITEMVERSION = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S21F9RSupported Item Type List Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F9R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 9, secs_receive_S21F9R)

def secs_receive_S21F9R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F9R.'''
    ok = True
    while ok:   # break out of loop on error
        # no data expected
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 10, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F9R

S21F10Supported Item Type List Result Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F10 Python Parse reply
    rcr = sp.sendSecsMsg(21, 9, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 ITEMACK ITEMERROR {L:n ITEMTYPE} 
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ITEMTYPE = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S21F11Item Delete Sent by Host Only

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F11 Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 11, secs_receive_S21F11)

def secs_receive_S21F11(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F11.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 ITEMTYPE {L:n ITEMID}
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ITEMID = (pylist2[1] if len(pylist2) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 12, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
    # bad data 
    sp.sendS9( 7, header)
# end recv_S21F11

S21F12Item Delete Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F12 Python Parse reply
    rcr = sp.sendSecsMsg(21, 11, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:3 ITEMACK ITEMTYPE {L:n {L:3 ITEMID ITEMACK ITEMERROR}} 
        # ITEMACK B:1 (always)  item request return code
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 4 or pylist0[0] != "L:3":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        for n in range(1, len(pylist1)):
            pylist2 = lsplit(pylist1[n])
            if len(pylist2) != 4 or pylist2[0] != "L:3":
                ok = False
                break
            pylist3 = lsplit(pylist2[1])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ITEMID = (pylist3[1] if len(pylist3) == 2 else "")
            pylist3 = lsplit(pylist2[2])
            if len(pylist3) < 1 or pylist3[0] != "B:1":
                ok = False
                break
            ITEMACK = sp.binToInt(pylist3[1])
            pylist3 = lsplit(pylist2[3])
            if len(pylist3) < 1 or not pylist3[0].startswith("A:"):
                ok = False
                break
            ITEMERROR = (pylist3[1] if len(pylist3) == 2 else "")
        if not ok: break
        return # finished ok
    # end while(ok)
# end def

S21F13RRequest Permission To Send Item Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F13R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 13, secs_receive_S21F13R)

def secs_receive_S21F13R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F13R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:5 ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION ITEMPARTCOUNT
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        # ITEMPARTCOUNT U4:1 (always)  total number of item parts as split for transfer
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 6 or pylist0[0] != "L:5":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        ITEMPARTCOUNT = int(pylist1[1])
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 14, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F13R

S21F14Grant Permission To Send Item Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F14 Python Parse reply
    rcr = sp.sendSecsMsg(21, 13, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ITEMACK ITEMERROR
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S21F15RItem Request Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F15R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 15, secs_receive_S21F15R)

def secs_receive_S21F15R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F15R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:2 ITEMTYPE ITEMID
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 16, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F15R

S21F16Item Request Grant Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F16 Python Parse reply
    rcr = sp.sendSecsMsg(21, 15, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:7 ITEMACK ITEMERROR ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION ITEMPARTCOUNT
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        # ITEMPARTCOUNT U4:1 (always)  total number of item parts as split for transfer
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 8 or pylist0[0] != "L:7":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        ITEMPARTCOUNT = int(pylist1[1])
        return # finished ok
    # end while(ok)
# end def

S21F17RSend Item Part Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F17R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 17, secs_receive_S21F17R)

def secs_receive_S21F17R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F17R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:8 ITEMTYPE ITEMID ITEMLENGTH ITEMVERSION ITEMINDEX ITEMPARTCOUNT ITEMPARTLENGTH ITEMPART
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMID A:256 (always)  item identifier
        # ITEMLENGTH U4:1 (varies)  sum of item part lengths in bytes, not a message length, type U4 or U8
        # ITEMVERSION A:n (always)  version value, empty for unknown, default is time last modified YYYYMMDDhhmmsscc in the equipment timezone
        # ITEMINDEX U4:1 (always)  1-based index of a component part, 0 means done, 0xFFFFFFFF means abort
        # ITEMPARTCOUNT U4:1 (always)  total number of item parts as split for transfer
        # ITEMPARTLENGTH U4:1 (always)  length of a specific item part presumably in bytes
        # ITEMPART A:n (varies)  component part of an item, may be data type A:n or B:n
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 9 or pylist0[0] != "L:8":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMID = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[3])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMLENGTH, lengthITEMLENGTH) = pylist1[0].split(':')
        ITEMLENGTH = (pylist1[1] if len(pylist1) == 2 else None)
        pylist1 = lsplit(pylist0[4])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMVERSION = (pylist1[1] if len(pylist1) == 2 else "")
        pylist1 = lsplit(pylist0[5])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        ITEMINDEX = int(pylist1[1])
        pylist1 = lsplit(pylist0[6])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        ITEMPARTCOUNT = int(pylist1[1])
        pylist1 = lsplit(pylist0[7])
        if len(pylist1) < 1 or pylist1[0] != "U4:1":
            ok = False
            break
        ITEMPARTLENGTH = int(pylist1[1])
        pylist1 = lsplit(pylist0[8])
        if len(pylist1) < 1:
            ok = False
            break
        #(typeITEMPART, lengthITEMPART) = pylist1[0].split(':')
        ITEMPART = (pylist1[1] if len(pylist1) == 2 else None)
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 18, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F17R

S21F18Send Item Part Acknowledge Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F18 Python Parse reply
    rcr = sp.sendSecsMsg(21, 17, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:2 ITEMACK ITEMERROR
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        pylist0 = lsplit(TSN_data)
        if len(pylist0) != 3 or pylist0[0] != "L:2":
            ok = False
            break
        pylist1 = lsplit(pylist0[1])
        if len(pylist1) < 1 or pylist1[0] != "B:1":
            ok = False
            break
        ITEMACK = sp.binToInt(pylist1[1])
        pylist1 = lsplit(pylist0[2])
        if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
            ok = False
            break
        ITEMERROR = (pylist1[1] if len(pylist1) == 2 else "")
        return # finished ok
    # end while(ok)
# end def

S21F19RItem Type Feature Support Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F19R Python Receive message - add next line to setup
    # sp = your SecsEquip or SecsHost connection object
    sp.messageTypeAdd( 21, 19, secs_receive_S21F19R)

def secs_receive_S21F19R(sp, stream:int, function:int, send_reply:bool, transactionID:int, TSN_data:str, header:str):
    '''Receive SECS Message S21F19R.'''
    ok = True
    while ok:   # break out of loop on error
        # expect L:n ITEMTYPE
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) < 1 or not pylist1[0].startswith("A:"):
                ok = False
                break
            ITEMTYPE = (pylist1[1] if len(pylist1) == 2 else "")
        if not ok: break
        if send_reply:
            # TODO create reply message, use ljoin() to build from parts
            sp.sendReply( 21, 20, transactionID, reply_data)
        return # finished ok
    # here by break from while ok
# end recv_S21F19R

S21F20Item Type Feature Support Results Sent by Host and Equipment

from dmhclient import lindex, ljoin, lsplit, RcResult

    # S21F20 Python Parse reply
    rcr = sp.sendSecsMsg(21, 19, True, sendMsg, True)
    ok = True
    while ok:   # break out of loop on error
        if rcr.rc != 0:  ;# abort, S9, or timeout
            ok = False
            break   # handle failure here and return? 
        TSN_data = rcr.result
        # expect L:n {L:4 ITEMACK ITEMERROR ITEMTYPE ITEMTYPESUPPORT}
        # ITEMACK B:1 (always)  item request return code
        # ITEMERROR A:1024 (always)  error description, empty on success
        # ITEMTYPE A:n (always)  case-sensitve type of an item
        # ITEMTYPESUPPORT U4:1 (always)  bitfield to specify which S21Fx messages accepted 
        pylist0 = lsplit(TSN_data)
        if len(pylist0) < 1:
            ok = False
            break
        for n in range(1, len(pylist0)):
            pylist1 = lsplit(pylist0[n])
            if len(pylist1) != 5 or pylist1[0] != "L:4":
                ok = False
                break
            pylist2 = lsplit(pylist1[1])
            if len(pylist2) < 1 or pylist2[0] != "B:1":
                ok = False
                break
            ITEMACK = sp.binToInt(pylist2[1])
            pylist2 = lsplit(pylist1[2])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ITEMERROR = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[3])
            if len(pylist2) < 1 or not pylist2[0].startswith("A:"):
                ok = False
                break
            ITEMTYPE = (pylist2[1] if len(pylist2) == 2 else "")
            pylist2 = lsplit(pylist1[4])
            if len(pylist2) < 1 or pylist2[0] != "U4:1":
                ok = False
                break
            ITEMTYPESUPPORT = int(pylist2[1])
        if not ok: break
        return # finished ok
    # end while(ok)
# end def