#!/usr/bin/env python

import socket, threading, time, queue, gc, datetime, sys, traceback, logging

opServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
receiveQueue = queue.Queue()
sendQueue = queue.Queue()
ip = ""
port = ""
connected = False
startTimeCommStart = datetime.datetime.now()
endTimeCommStart = datetime.datetime.now()
startTimeSelectJob = datetime.datetime.now()
startTimeSelectPset = datetime.datetime.now()
endTimeSelectJob = datetime.datetime.now()
endTimeSelectPset = datetime.datetime.now()
startTimeJobInfoUnsubscribe = datetime.datetime.now()
endTimeJobInfoUnsubscribe = datetime.datetime.now()
startTimePsetSetSelectedUnsubscribe = datetime.datetime.now()
endTimePsetSetSelectedUnsubscribe = datetime.datetime.now()
startTimePsetSetSelectedSubscribe = datetime.datetime.now()
endTimePsetSetSelectedSubscribe = datetime.datetime.now()
startTimeJobInfoSubscribe = datetime.datetime.now()
endTimeJobInfoSubscribe = datetime.datetime.now()
startTimeKeepAlive = datetime.datetime.now()
endTimeKeepAlive = datetime.datetime.now()
startTimeJobUploadRequest = datetime.datetime.now()
startTimePsetUploadRequest = datetime.datetime.now()
startTimeJobUploadReply = datetime.datetime.now()
endTimeJobUploadReply = datetime.datetime.now()
endTimePsetUploadReply = datetime.datetime.now()
startTimePsetUploadReply = datetime.datetime.now()
endTimePsetUploadReply = datetime.datetime.now()
startTimeToolEnableRequest = datetime.datetime.now()
endTimeToolEnableRequest = datetime.datetime.now()
startTimeToolDisableRequest = datetime.datetime.now()
endTimeToolDisableRequest = datetime.datetime.now()
startTimeAlarmSubscribe = datetime.datetime.now()
endTimeAlarmUnsubscribe = datetime.datetime.now()
startTimeEORSubscribe = datetime.datetime.now()
endTimeEORSubscribe = datetime.datetime.now()
startTimeSocketSubscribe = datetime.datetime.now()
endTimeSocketSubscribe = datetime.datetime.now()
startTimeAlarmSubscribe = datetime.datetime.now()
endTimeAlarmSubscribe = datetime.datetime.now()
startTimeAlarmUnsubscribe = datetime.datetime.now()
endTimeAlarmUnsubscribe = datetime.datetime.now()
startTimeVIN = datetime.datetime.now()
endTimeVIN = datetime.datetime.now()
startTimeGangReset = datetime.datetime.now()
endTimeGangReset = datetime.datetime.now()
startTimePsetUpload = datetime.datetime.now()
endTimePsetUpload = datetime.datetime.now()
startTimeAutoDisable = datetime.datetime.now()
endTimeAutoDisable = datetime.datetime.now()
startTimeJobUpload = datetime.datetime.now()
endTimeJobUpload = datetime.datetime.now()
startTimeJobRestart = datetime.datetime.now()
endTimeJobRestart = datetime.datetime.now()
startTimeJobAbort = datetime.datetime.now()
endTimeJobAbort = datetime.datetime.now()
startTimeSetTime = datetime.datetime.now()
endTimeSetTime= datetime.datetime.now()


keepAliveTimeout = 10
canEnable = True
canDisable = True

class StationComputerClientThread(threading.Thread):
    #constructor for the class
    def __init__(self,ip_in,port_in):
        global ip
        global port
        # initialize the thread and set the member variables
        threading.Thread.__init__(self)
        ip = ip_in
        port = port_in

    #main for the class/thread
    def run(self):
        global opServer
        global receiveQueue
        global sendQueue
        global canKeepAlive
        global canEnable
        global canDisable

        #setup logging
        logging.basicConfig(filename='MES_flooding_messages.log', filemode='w', level=logging.DEBUG, format='%(asctime)s %(message)s')

        
        # setup the worker threads
        #comms threads handles TCP/IP communications
        commSendThread = threading.Thread(target=CommSendWorkerThread)
        commSendThread.setDaemon(True)
        commSendThread.start()

        commRcvThread = threading.Thread(target=CommRcvWorkerThread)
        commRcvThread.setDaemon(True)
        commRcvThread.start()

        heartbeatThread = threading.Thread(target=HeartbeatWorkerThread)
        heartbeatThread.setDaemon(True)
        heartbeatThread.start()

        msgHandlerThread = threading.Thread(target=IncomingMessageHandler)
        msgHandlerThread.setDaemon(True)
        msgHandlerThread.start()
    
        #start the communications
        StartCommunications()
        time.sleep(1)
        #MID0012_PsetUploadRequest()
        MID0010_PsetUpload()
        #time.sleep(1)
        #MID0043_ToolEnableRequest()
        #time.sleep(1)
        MID0018_SelectPset()
        #time.sleep(1)
        MID0060_EORSubscribe()
        #time.sleep(1)
        MID0008_TraceSubscribe()
        time.sleep(1)
        #MID0014_PsetSetSelectedSubscribe()
        #MID0127_JobAbort()
        
        #time.sleep(1)
        #MID0034_JobInfoSubscribe_04()
        #time.sleep(2)
        #MID0020_GangReset()
        #MID0051_VINSbscribe_Rev2()
        #time.sleep(2)
        
        #MID0250_SocketSubscribe()
'''
        while True:
            
            MID0010_PsetUpload()
            MID0051_VINSbscribe_Rev2()
            MID0043_ToolEnableRequest()
            #MID0018_SelectPset()
            MID0014_PsetSetSelectedSubscribe()
            MID0060_EORSubscribe()
            MID0039_JobRestart_Rev2()
            #MID0050_VIN1()
            MID0064_OldEORSubscribe()
            #MID0018_SelectPset()
            MID0020_GangReset()
            MID0070_AlarmSubscribe()
            MID0073_AlarmUnsubscribe()
            MID0250_SocketSubscribe()
            MID0410_AutoDisable()
            MID0030_JobUpload()
            #MID0039_JobRestart_Rev1()
            #MID0039_JobAbort()
            MID0032_JobData_01()
            MID0032_JobData_02()
            MID0032_JobData_01()
            MID0034_JobInfoSubscribe_04()
            MID0038_SelectJob()
            MID0030_JobUpload()

#'''
      
def ResetKeepAlive():
    global keepAliveTimeout

    keepAliveTimeout = 10

def StartCommunications():
    global startTimeCommStart

    startTimeCommStart = datetime.datetime.now()
    print("{0} : Start Communications".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('Start Communications')
    buf = '00200001001000000000\0';
    sendQueue.put(buf)

    logging.info('')

def MID0038_SelectJob():
    global startTimeSelectJob

    print("{0} : Select Job".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('Select Job')
    buf = '0022003800100000000004\0';
    startTimeSelectJob = datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')

def MID0039_JobRestart_Rev1():
    global startTimeJobRestart

    print("{0} : JobRestart_Rev1".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('JobRestart_Rev1')
    buf = '0022003900100000000003\0';
    startTimeJobRestart= datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')

def MID0039_JobRestart_Rev2():
    global startTimeJobRestart

    print("{0} : JobRestart_Rev2".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('JobRestart_Rev2')
    buf = '002400390020000000000002\0';
    startTimeJobRestart = datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')

def MID0127_JobAbort():
    global startTimeJobAbort

    print("{0} : JobAbort".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('JobAbort')
    buf = '00200127001000000000\0';
    startTimeJobAbort = datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')
def MID0030_JobUpload():
    global startTimeJobUpload

    print("{0} :  Job Upload".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('Job Upload')
    buf = '002000300010000000\0';
    startTimeJobUpload = datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')

def MID0034_JobInfoSubscribe():
    global startTimeJobInfoSubscribe
    logging.info('Subscribe Job Info MID 0034')
    buf = '00200034001000000000\0';
    startTimeJobInfoSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID00037_JobInfoUnsubscibe():
    global startTimeJobInfoUnsubscribe
    logging.info('Unsubscribe Job Info MID 0037')
    buf = '00200037001000000000\0';
    startTimeJobInfoUnsubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0032_JobUploadRequest():
    global startTimeJobUploadRequest
    logging.info('Sending Job Upload Request MID 0032')
    buf = '0022003200100000000001\0'
    startTimeJobUploadRequest = datetime.datetime.now()
    sendQueue.put(buf)

def MID0018_SelectPset():
    global startTimeSelectPset
    print("{0} : Select Pset".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    logging.info('Select Pset')
    buf = '00230018001000000000001\0';
    startTimeSelectPset = datetime.datetime.now()
    sendQueue.put(buf)

    logging.info('')

def MID0014_PsetSetSelectedSubscribe():
    global startTimePsetSetSelectedSubscribe
    logging.info('Subscribe Pset Set Selected MID 0014')
    buf = '00200014001000000000\0';
    startTimePsetSetSelectedSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0017_PsetSetSelectedUnsubscribe():
    global startTimePsetSetSelectedUnsubscribe
    logging.info('Unsubscribe Pset Set Selected MID 0017')
    buf = '00200017001000000000\0';
    startTimePsetSetSelectedSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0012_PsetUploadRequest():
    global startTimePsetUploadRequest
    logging.info('Sending Pset Upload Request MID 0012')
    buf = '00230012001000000000002\0';
    startTimePsetSetSelectedSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0043_ToolEnableRequest():
    global startTimeToolEnableRequest
    logging.info('Sending Tool Enable request MID 0043')
    buf = '00200043001000000000\0';
    startTimeToolEnableRequest = datetime.datetime.now()
    sendQueue.put(buf)

def MID0042_ToolDisableRequest():
    global startTimeToolDisableRequest
    logging.info('Sending Tool Disable request MID 0042')
    buf = '00200042001000000000\0';
    startTimeToolDisableRequest = datetime.datetime.now()
    sendQueue.put(buf)

def MID0060_EORSubscribe():
    global startTimeEORSubscribe
    logging.info("Sending EOR data subscribe MID 0060")
    buf = '00200060001000000000\0';
    startTimeEORSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0064_OldEORSubscribe():
    global startTimeEORSubscribe
    logging.info("Sending Old EOR data subscribe MID 0064")
    buf = '003000640060000000000000000002\0';
    startTimeEORSubscribe = datetime.datetime.now()
    sendQueue.put(buf)
    
def MID0250_SocketSubscribe():
    global startTimeSocketSubscribe
    logging.info("Sending socket data subscribe MID 0250")
    buf = '00200250001000000000\0';
    startTimeSocketSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0051_VINSbscribe_Rev1():
    global startTimeVINSubscribe
    logging.info("Sending VIN data subscribe MID 0250 rev 1")
    buf = '00200051001000000000\0';
    startTimeVINSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0051_VINSbscribe_Rev2():
    global startTimeVINSubscribe
    logging.info("Sending VIN data subscribe MID 0250 rev 2")
    buf = '00200051002000000000\0';
    startTimeVINSubscribe = datetime.datetime.now()
    sendQueue.put(buf)
    
def MID0070_AlarmSubscribe():
    global startTimeSocketSubscribe
    logging.info("Sending Alarm data subscribe MID 0070")
    buf = '00200070000010000000\0';
    startTimeSocketSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0073_AlarmUnsubscribe():
    global startTimeAlarmUnsubscribe
    logging.info("Sending Alarm unsubscribe MID 0073")
    buf = '00200073001000000000\0';
    startTimeAlarmUnsubscribe = datetime.datetime.now()
    sendQueue.put(buf)
    

def MID0050_VIN1(barcode):
    global startTimeVIN
    logging.info("Sending VIN 1 MID 0050")
    buf = '00450050001000000000MYBarcodeSabiullahh'+str(barcode)+'  \0';
    startTimeSocketSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0050_VIN2():
    global startTimeVIN
    logging.info("Sending VIN 2 MID 0050")
    buf = '00450050001000000000VINSECOND2222222222224444\0';
    startTimeSocketSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0050_VIN3():
    global startTimeVIN
    logging.info("Sending VIN 3 MID 0050")
    buf = '00450050001000000000VINThird33333333333333333\0';
    startTimeSocketSubscribe = datetime.datetime.now()
    sendQueue.put(buf)

def MID0020_GangReset():
    global startTimeGangReset
    logging.info("Sending gang reset MID 0020")
    buf = '00230020001000000000003\0';
    startTimeGangReset = datetime.datetime.now()
    sendQueue.put(buf)

def MID0010_PsetUpload():
    global startTimePsetUpload
    logging.info("Sending pset upload MID 0010")
    buf = '00200010001000000000\0';
    startTimePsetUpload = datetime.datetime.now()
    sendQueue.put(buf)

def MID0410_AutoDisable():
    global startTimeAutoDisable
    logging.info("Sending Auto disable MID 0410")
    buf = '00200410000010000000\0';
    startTimeAutoDisable = datetime.datetime.now()
    sendQueue.put(buf)

def MID0080_ReadTime():
    global startTimeReadTime
    logging.info("Sending Read Time MID 0080")
    buf = '00200080001000000000\0';
    startTimeReadTime = datetime.datetime.now()
    sendQueue.put(buf)

def MID0082_SetTime():
    global startTimeSetTime
    logging.info("Sending Set Time MID 0082")
    buf = '003900820010000000002017-11-27:12:13:45\0';
    startTimeReadTime = datetime.datetime.now()
    sendQueue.put(buf)

def MID0032_JobData_01():
    logging.info("Sending job data request MID 0032 revision 1")
    buf = '0022003200100000000004\0';
    sendQueue.put(buf)

def MID0032_JobData_02():
    logging.info("Sending job data request MID 0032 revision 1")
    buf = '002400320020000000000004\0';
    sendQueue.put(buf)    

def MID0032_JobData_03():
    logging.info("Sending job data request MID 0032 revision 1")
    buf = '002400320030000000000004\0';
    sendQueue.put(buf) 

def MID0034_JobInfoSubscribe_01():
    logging.info("Sending job data request MID 0034 revision ")
    buf = '00200034001000000000\0';
    sendQueue.put(buf)

def MID0034_JobInfoSubscribe_02():
    logging.info("Sending job data request MID 0034 revision 2")
    buf = '00200034002000000000\0';
    sendQueue.put(buf)

def MID0034_JobInfoSubscribe_03():
    logging.info("Sending job data request MID 0034 revision 3")
    buf = '00200034003000000000\0';
    sendQueue.put(buf)

def MID0034_JobInfoSubscribe_04():
    logging.info("Sending job data request MID 0034 revision 4")
    buf = '00200034004100000000\0';
    sendQueue.put(buf)

def MID0034_JobInfoSubscribe_05():
    logging.info("Sending job data request MID 0034 revision 5")
    buf = '00200034005000000000\0';
    sendQueue.put(buf)
    
def MID0037_JobInfoUnSubscribe_01():
    logging.info("Sending job data unsusbscribe MID 0037 revision 1")
    buf = '00200037001000000000\0';
    sendQueue.put(buf)

def MID0037_JobInfoUnSubscribe_02():
    logging.info("Sending job data unsusbscribe MID 0037 revision 2")
    buf = '00200037002000000000\0';
    sendQueue.put(buf)

def MID0037_JobInfoUnSubscribe_03():
    logging.info("Sending job data unsusbscribe MID 0037 revision 3")
    buf = '00200037003000000000\0';
    sendQueue.put(buf)

def MID0037_JobInfoUnSubscribe_04():
    logging.info("Sending job data unsusbscribe MID 0037 revision 4")
    buf = '00200037004000000000\0';
    sendQueue.put(buf)

def MID0008_TraceSubscribe():
    logging.info("Sending trace data subscribe MID 0900 revision 1 ")
    buf = '00700008001         0900001350                             03001002003\0';
    sendQueue.put(buf)

def HeartbeatWorkerThread():
    global sendQueue
    global connected
    global keepAliveTimeout
    global startTimeKeepAlive

    # loop forever
    while True:
        # sleep 10 seconds before sending the next heartbeat
        time.sleep(1)

        keepAliveTimeout = keepAliveTimeout - 1

        if connected and (keepAliveTimeout <= 0):
            # generate a keep alive message
            print('{0} : Sending a keep alive'.format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
            logging.info('Sending keep alive')
            buf = '00209999000000000000\0';
            startTimeKeepAlive = datetime.datetime.now()
            ResetKeepAlive()
            sendQueue.put(buf)

def CommSendWorkerThread():
    global opServer
    global ip
    global port
    global connected
    global sendQueue

    # attempt to connect to the controller
    while not connected:
        try:
            # connect to the controller
            logging.info('Connect to the socket on ip:' + ip)
            opServer.connect((ip, port))
            opServer.settimeout(15.0)

            logging.info('')
            connected = True
        except:
            logging.info('Could not connect to the socket on ip:' + ip)

    while connected:
        while not sendQueue.empty():
            msgOut = sendQueue.get()
            logging.info('Message Sent : ' + msgOut)
            opServer.send(msgOut.encode('utf-8'))
            sendQueue.task_done()

            ResetKeepAlive()

        # explicit garbage collection
        gc.collect()

def CommRcvWorkerThread():
    global opServer
    global connected
    global receiveQueue

    while True:
        try:
            if connected:
                # try with a no wait
                incomingMsg = opServer.recv(8192)
                logging.info('Message Received : ' + str(incomingMsg))
                receiveQueue.put(incomingMsg)
                ResetKeepAlive()
        except:
            #a fault probably indicates the connection was dropped on the controller side
            connected = False
            # a fault was detected
            print("{0} : Fault in CommRcvWorkerThread".format(
                datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))


def IncomingMessageHandler():
    global receiveQueue

    while True:
        while receiveQueue.empty():
            datetime.datetime.now()

        incomingMessage = receiveQueue.get()
        msgID = incomingMessage[4:8]
        print("{0} : Message ID Received : {1}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msgID))
        logging.info('Message Processing for MSG ID : ' + str(msgID))
        print (" Message received {0}".format(incomingMessage))


        if msgID == b'0002':
            # communications start acknowledge
            ProcessCommStartAck(incomingMessage)
        elif msgID == b'0003':
            #communications stop message
            ProcessCommStop(incomingMessage)
        elif msgID == b'0004':
            #command error message
            ProcessCommandError(incomingMessage)
        elif msgID == b'0005':
            #communications stop message
            ProcessCommandedAccepted(incomingMessage)
        elif msgID == b'0035':
            #Job Info
            ProcessJobInfo(incomingMessage)
        elif msgID == b'0033':
            #Job Data Upload Reply
            JobDataUploadReply(incomingMessage)
        elif msgID == b'0013':
            #Pset Data Upload Reply
            PsetDataUploadReply(incomingMessage)
        elif msgID == b'9999':
            #keep alive ack
            ProcessKeepAliveAck(incomingMessage)
        elif msgID == b'0015':
            # parameter set selected
            ProcessParameterSetSelected(incomingMessage)
        elif msgID == b'0061':
            #EOR data received
            ProcessEORdataRecieve(incomingMessage)
        elif msgID == b'0251':
            #Socket data received
            ProcessSocketdataRecieve(incomingMessage)
        elif msgID == b'0052':
            #VIN data received
            ProcessVINdataRecieve(incomingMessage)
            
        elif msgID == b'0071':
            #Alarm data received
            ProcessAlarmdataRecieve(incomingMessage)
        elif msgID == b'0076':
            #Previous alarm data received
            ProcessPreviousAlarmdataRecieve(incomingMessage)
        elif msgID == b'0074':
            #Previous alarm data received
            ProcessAckAlarmdataRecieve(incomingMessage)
        elif msgID == b'0010':
            #Pset upload  received
            ProcessAckPsetUpload(incomingMessage)
        elif msgID == b'0035':
            #job data info received
            ProcessJobInfo(incomingMessage)
            

        receiveQueue.task_done()

#MID 0002 Communication start ACK
def ProcessCommStartAck(msg):
    global startTimeCommStart
    global endTimeCommStart

    print("{0} : Communications Comm Start ACK Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    endTimeCommStart = datetime.datetime.now()
    delta = endTimeCommStart - startTimeCommStart
    inSec = delta.seconds + (delta.microseconds / 1000000.0)
    logging.info('Time to ACK Comm Start: ' + str(inSec) + ' seconds')
    logging.info('')

def ProcessCommStop(msg):
    print("{0} : Communications Stop Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))

#MID 0004 Command Error
def ProcessCommandError(msg):
    global startTimeSelectJob
    global startTimeSelectPset
    global endTimeSelectJob
    global endTimeSelectPset
    global startTimeJobInfoUnsubscribe
    global startTimeJobInfoUnsubscribe
    global startTimeJobInfoSubscribe
    global endTimeJobInfoSubscribe
    global endTimePsetSetSelectedSubscribe
    global endTimePsetSetSelectedUnsubscribe
    global startTimePsetSetSelectedSubscribe
    global startTimePsetSetSelectedUnsubscribe
    global startTimeToolEnableRequest
    global startTimeToolDisableRequest
    global startTimeEORSubscribe
    global endTimeEORSubscribe
    global startTimeSocketSubscribe
    global endTimeSocketSubscribe
    global startTimeAlarmSubscribe
    global endTimeAlarmSubscribe
    global startTimeAlarmUnsubscribe
    global endTimeAlarmUnsubscribe
    global startTimeJobUpload
    global endTimeJobUpload
    global canEnable
    global canDisable
    global endTimeVIN
    global startTimeVIN
    global startTimeJobRestart
    global endTimeJobRestart
    global startTimeJobAbort
    global endTimeJobAbort
    global startTimeVINSubscribe
    global endTimeVINSubscribe
    global startTimeSetTime
    global endTimeSetTime 


    print("{0} : Command Error Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))

    msgId = msg[20:24]
    if msgId == b'0038':
        # Select Job
        endTimeSelectJob = datetime.datetime.now()
        delta = endTimeSelectJob - startTimeSelectJob
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 38: ' + str(inSec) + ' seconds')
        logging.info('')

    if msgId == b'0030':
        # Select Job
        endTimeSelectJob = datetime.datetime.now()
        delta = endTimeSelectJob - startTimeSelectJob
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 30: ' + str(inSec) + ' seconds')
        logging.info('')
    if msgId == b'0018':
        # Select Job
        endTimeSelectPset = datetime.datetime.now()
        delta = endTimeSelectPset - startTimeSelectPset
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 18: ' + str(inSec) + ' seconds')
        logging.info('')
    elif msgId == b'0037':
        # Unsubscribe Job Info
        endTimeJobInfoUnsubscribe = datetime.datetime.now()
        delta = endTimeJobInfoUnsubscribe - startTimeJobInfoUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 37: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    elif msgId == b'0034':
        #Subscribe Job Info
        endTimeJobInfoSubscribe = datetime.datetime.now()
        delta = endTimeJobInfoSubscribe - startTimeJobInfoSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 34: ' + str(inSec) + ' seconds')
        logging.info('')
        canEnable = True
    elif msgId == b'0014':
        #Subscribe Pset Set Selected
        endTimePsetSetSelectedSubscribe = datetime.datetime.now()
        delta = endTimePsetSetSelectedSubscribe - startTimePsetSetSelectedSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 14: ' + str(inSec) + ' seconds')
        logging.info('')
        canEnable = True
    elif msgId == b'0017':
        # Unsubscribe Pset Set Selected
        endTimePsetSetSelectedUnsubscribe = datetime.datetime.now()
        delta = endTimePsetSetSelectedUnsubscribe - startTimePsetSetSelectedUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 17: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    elif msgId == b'0042':
        # Disable the tool
        endTimeToolDisableRequest = datetime.datetime.now()
        delta = endTimeToolDisableRequest - startTimeToolDisableRequest
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0042: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0043':
        # Enable the tool
        endTimeToolEnableRequest = datetime.datetime.now()
        delta = endTimeToolEnableRequest - startTimeToolEnableRequest
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0043: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0060':
        #Subscribe to EOR
        endTimeEORSubscribe = datetime.datetime.now()
        delta = endTimeEORSubscribe - startTimeEORSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0060: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0250':
        #Subscribe to socket data
        endTimeSocketSubscribe = datetime.datetime.now()
        delta = endTimeSocketSubscribe - startTimeSocketSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0250: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0051':
        #Subscribe to VIN data
        endTimeVINSubscribe = datetime.datetime.now()
        delta = endTimeVINSubscribe - startTimeVINSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0051: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
        
    elif msgId == b'0070':
        #Subscribe to alarm
        endTimeAlarmSubscribe = datetime.datetime.now()
        delta = endTimeAlarmSubscribe - startTimeAlarmSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0070: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0050':
        #VIN data
        endTimeVIN = datetime.datetime.now()
        delta = endTimeVIN - startTimeVIN
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0070: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0020':
        #Gang reset data
        endTimeGangReset = datetime.datetime.now()
        delta = endTimeGangReset - startTimeGangReset
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0020: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0073':
        #Alarm unsubscribe  data
        endTimeAlarmUnsubscribe = datetime.datetime.now()
        delta = endTimeAlarmUnsubscribe - startTimeAlarmUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0073: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True


    elif msgId == b'0010':
        #Pset upload  data
        endTimePsetUpload = datetime.datetime.now()
        delta = endTimePsetUpload - startTimePsetUpload
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0073: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0039':
        #Job Reset
        endTimeJobRestart = datetime.datetime.now()
        delta = endTimeJobRestart- startTimeJobRestart
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0039: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0127':
        #Job Abort
        endTimeJobAbort = datetime.datetime.now()
        delta = endTimeJobAbort- startTimeJobAbort
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0127: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0082':
        #time Set
        endTimeSetTime = datetime.datetime.now()
        delta = endTimeSetTime- startTimeSetTime
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0082: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0900':
        #time Set
        endTimeSetTime = datetime.datetime.now()
        delta = endTimeSetTime- startTimeSetTime
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK : ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    else:
        logging.info('NACK Unexpected Message: ' + str(msgId))
        logging.info('')

    logging.info('')

#MID 0005 Command Accepted
def ProcessCommandedAccepted(msg):
    global startTimeSelectJob
    global endTimeSelectPset
    global startTimeSelectPset
    global endTimeSelectJob
    global startTimeJobInfoUnsubscribe
    global endTimePsetSetSelectedSubscribe
    global endTimePsetSetSelectedUnsubscribe
    global startTimePsetSetSelectedSubscribe
    global startTimePsetSetSelectedUnsubscribe
    global startTimeJobInfoUnsubscribe
    global startTimeJobInfoSubscribe
    global endTimeJobInfoSubscribe
    global startTimeToolEnableRequest
    global startTimeToolDisableRequest
    global startTimeEORSubscribe
    global endTimeEORSubscribe
    global startTimeSocketSubscribe
    global endTimeSocketSubscribe
    global startTimeAlarmSubscribe
    global endTimeAlarmSubscribe
    global startTimeAlarmUnsubscribe
    global endTimeAlarmUnsubscribe
    global startTimeJobUpload
    global endTimeJobUpload
    global canEnable
    global canDisable
    global startTimeVIN
    global endTimeVIN
    global startTimeJobRestart
    global endTimeJobRestart 
    global startTimeJobAbort
    global endTimeJobAbort
    global startTimeVINSubscribe
    global endTimeVINSubscribe
    global startTimeSetTime
    global endTimeSetTime    
    #print("{0} : Command ACK Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    msgId = msg[20:24]
    if msgId == b'0038':
        # Select Job
        endTimeSelectJob = datetime.datetime.now()
        delta = endTimeSelectJob - startTimeSelectJob
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0038: ' + str(inSec) + ' seconds')
        logging.info('')

    if msgId == b'0030':
        # Select Job
        endTimeSelectJob = datetime.datetime.now()
        delta = endTimeSelectJob - startTimeSelectJob
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0030: ' + str(inSec) + ' seconds')
        logging.info('')

    if msgId == b'0018':
        # Select Job
        endTimeSelectPset = datetime.datetime.now()
        delta = endTimeSelectPset - startTimeSelectPset
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0018: ' + str(inSec) + ' seconds')
        logging.info('')
    elif msgId == b'0037':
        # Job Info Unsubsc
        endTimeJobInfoUnsubscribe = datetime.datetime.now()
        delta = endTimeJobInfoUnsubscribe - startTimeJobInfoUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0037: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    elif msgId == b'0034':
        #Job Info Subscribe
        endTimeJobInfoSubscribe = datetime.datetime.now()
        delta = endTimeJobInfoSubscribe - startTimeJobInfoSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0034: ' + str(inSec) + ' seconds')
        logging.info('')
        canEnable = True
    elif msgId == b'0017':
        # Pset Set Selected Unsubsc
        endTimePsetSetSelectedUnsubscribe = datetime.datetime.now()
        delta = endTimePsetSetSelectedUnsubscribe - startTimePsetSetSelectedUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0017: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    elif msgId == b'0014':
        #Pset Set Selected Subscribe
        endTimePsetSetSelectedSubscribe = datetime.datetime.now()
        delta = endTimePsetSetSelectedSubscribe - startTimePsetSetSelectedSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK 0014: ' + str(inSec) + ' seconds')
        logging.info('')
        canEnable = True
        
    elif msgId == b'0042':
        # Disable the tool
        endTimeToolDisableRequest = datetime.datetime.now()
        delta = endTimeToolDisableRequest - startTimeToolDisableRequest
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0042: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0043':
        # Enable the tool
        endTimeToolEnableRequest = datetime.datetime.now()
        delta = endTimeToolEnableRequest - startTimeToolEnableRequest
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0043: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True


    elif msgId == b'0060':
        #Subscribe to EOR
        endTimeEORSubscribe = datetime.datetime.now()
        delta = endTimeEORSubscribe - startTimeEORSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0060: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0250':
        #Subscribe to EOR
        endTimeSocketSubscribe = datetime.datetime.now()
        delta = endTimeSocketSubscribe - startTimeSocketSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0250: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0050':
        #VIN data
        endTimeVIN = datetime.datetime.now()
        delta = endTimeVIN - startTimeVIN
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0050: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0070':
        #Subscribe to EOR
        endTimeAlarmSubscribe = datetime.datetime.now()
        delta = endTimeAlarmSubscribe - startTimeAlarmSubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0070: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True


    elif msgId == b'0050':
        #VIN data
        endTimeVIN = datetime.datetime.now()
        delta = endTimeVIN - startTimeVIN
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0070: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True


    elif msgId == b'0020':
        #Gang reset data
        endTimeGangReset = datetime.datetime.now()
        delta = endTimeGangReset - startTimeGangReset
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0020: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True  

    elif msgId == b'0073':
        #Gang reset data
        endTimeAlarmUnsubscribe = datetime.datetime.now()
        delta = endTimeAlarmUnsubscribe - startTimeAlarmUnsubscribe
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0073: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0039':
        #Job reset
        endTimeJobRestart = datetime.datetime.now()
        delta = endTimeJobRestart- startTimeJobRestart
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0039: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True


    elif msgId == b'0127':
        #Job Abort
        endTimeJobAbort = datetime.datetime.now()
        delta = endTimeJobAbort- startTimeJobAbort
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to ACK MID 0127: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True

    elif msgId == b'0082':
        #time Set
        endTimeSetTime = datetime.datetime.now()
        delta = endTimeSetTime- startTimeSetTime
        inSec = delta.seconds + (delta.microseconds / 1000000.0)
        logging.info('Time to NACK MID 0082: ' + str(inSec) + ' seconds')
        logging.info('')
        canDisable = True
    else:
        logging.info('ACK Unexpected Message: ' + str(msgId))
        logging.info('')

#MID 0035 Job Info
def ProcessJobInfo(msg):
    global sendQueue
    print("{0} : MID 0035 (Job Info) Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('MID 0035 (Job Info) Message Received - Generate ACK MID 0036')
    logging.info('')
    #time.sleep(20)
    buf = '00200036001000000000\0';
    sendQueue.put(buf)

#MID 9999  Keep Alive Ack 
def ProcessKeepAliveAck(msg):
    global startTimeKeepAlive
    global endTimeKeepAlive
    print("{0} : Keep Alive ACK Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    endTimeKeepAlive = datetime.datetime.now()
    delta = endTimeKeepAlive - startTimeKeepAlive
    inSec = delta.seconds + (delta.microseconds / 1000000.0)
    logging.info('Time to ACK Keep Alive: ' + str(inSec) + ' seconds')
    logging.info('')

#MID 0033 Job Data Upload Reply 
def JobDataUploadReply(msg):
    global startTimeJobUploadReply
    global endTimeJobUploadReply
    print("{0}: MID 0033 (Job Upload Reply) received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    endTimeJobUploadReply = datetime.datetime.now()
    delta = endTimeJobUploadReply - startTimeJobUploadReply
    inSec = delta.seconds + (delta.microseconds / 1000000.0)
    logging.info('Time to receive MID 0033: ' + str(inSec) + ' seconds')
    logging.info('')

#MID 0013 Job Data Upload Reply 
def PsetDataUploadReply(msg):
    global startTimePsetUploadReply
    global endTimePsetUploadReply
    print("{0}: MID 0013 (Pset Upload Reply) received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    endTimePsetUploadReply = datetime.datetime.now()
    delta = endTimePsetUploadReply - startTimePsetUploadReply
    inSec = delta.seconds + (delta.microseconds / 1000000.0)
    logging.info('Time to receive MID 0013: ' + str(inSec) + ' seconds')
    logging.info('')

#MID 0015
def ProcessParameterSetSelected(msg):
    global sendQueue
    print("{0} : Pset Selected Message Received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Pset Selected Message Received - Generate ACK')
    logging.info('')
    buf = '00200016001000000000\0';
    sendQueue.put(buf)

#MID 0061
def ProcessEORdataRecieve(msg):
    global sendQueue
    print("{0} : EOR data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('EOR data - Generate ACK')
    logging.info('')
    buf = '00200062001000000000\0';
    sendQueue.put(buf)

#MID 0251
def ProcessSocketdataRecieve(msg):
    global sendQueue
    print("{0} : Socket data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Socket data - Generate ACK')
    logging.info('')
    buf = '00200252001000000000\0';
    sendQueue.put(buf)

#MID 0052
def ProcessVINdataRecieve(msg):
    global sendQueue
    print("{0} : VIN data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('VIN data - Generate ACK')
    logging.info('')
    buf = '00200053002000000000\0';
    sendQueue.put(buf)


#MID 0071
def ProcessAlarmdataRecieve(msg):
    global sendQueue
    print("{0} : Socket data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Socket data - Generate ACK')
    logging.info('')
    buf = '00200072002000000000\0';
    sendQueue.put(buf)   

#MID 0076
def ProcessPreviousAlarmdataRecieve(msg):
    global sendQueue
    print("{0} : Alarm data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Alarm data - Generate ACK')
    logging.info('')
    buf = '00200077001000000000\0';
    sendQueue.put(buf)

#MID 0075
def ProcessAckAlarmdataRecieve(msg):
    global sendQueue
    print("{0} : Alarm ack data received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Alarm data - Generate ACK')
    logging.info('')
    buf = '00200075001000000000\0';
    sendQueue.put(buf)   

#MID 0035
def ProcessAckJobInfo(msg):
    global sendQueue
    print("{0} : Job info received".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")))
    #generate response message
    logging.info('Job Info - Generate ACK')
    logging.info('')
    buf = '00200036001000000000\0';
    sendQueue.put(buf)   
