In [1]:
import socket 
from datetime import datetime
from config import instruments, instrument_buffer_sizes, saving_parameters

In [2]:
def init_trigger_status():
    
    zero_time = datetime(2000,1,1,0,0,0)
    
    last_trigger = {}
    unsent_trigs = {}
    for inst in instruments:
        last_trigger[inst] = zero_time
        unsent_trigs[inst] = []
    
    trigger_status = {'last_trigger': last_trigger, 'unsent_trigs': unsent_trigs}
    
    return trigger_status

In [3]:
trigger_status = init_trigger_status()


Out[3]:
{'last_trigger': {'adcp': datetime.datetime(2000, 1, 1, 0, 0),
  'blueview': datetime.datetime(2000, 1, 1, 0, 0),
  'camera': datetime.datetime(2000, 1, 1, 0, 0),
  'hydrophones': datetime.datetime(2000, 1, 1, 0, 0),
  'm3': datetime.datetime(2000, 1, 1, 0, 0)},
 'unsent_trigs': {'adcp': [],
  'blueview': [],
  'camera': [],
  'hydrophones': [],
  'm3': []}}

In [8]:
new_trigs = ['m3']

udp_IP = "localhost"
udp_port = 61500 # port to send data over

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
trigs_to_send, trigger_status = is_time_to_send(sock, udp_IP, udp_port, new_trigs, trigger_status)
sock.close()

print('sent triggers:', trigs_to_send)
trigger_status


430.148  seconds since last  m3  detection
510343563.663  seconds since last  m3  trigger sent
sending triggers for  ['m3']
sent triggers: ['m3']
Out[8]:
{'last_trigger': {'adcp': datetime.datetime(2000, 1, 1, 0, 0),
  'blueview': datetime.datetime(2000, 1, 1, 0, 0),
  'camera': datetime.datetime(2000, 1, 1, 0, 0),
  'hydrophones': datetime.datetime(2000, 1, 1, 0, 0),
  'm3': datetime.datetime(2016, 3, 3, 17, 55, 40, 623663)},
 'unsent_trigs': {'adcp': [],
  'blueview': [],
  'camera': [],
  'hydrophones': [],
  'm3': []}}

In [7]:
def is_time_to_send(sock, udp_IP, udp_port, new_trigs, trigger_status):
    """
    Add any new triggers to trigger_status, and determine what, if any save 
    triggers to send to LabView.
    
    inputs:
    socket - socket over which to send triggers to LabView
    udp_IP - IP address over which to send triggers to LabView ("localhost")
    udp_port - port over which to send triggers to LabView (61500)
    new_triggs - new triggers to send (or wait to send)
    trigger_status - dictionary containing unsent triggers and timestamp that 
                    last trigger was sent to each instrument
    
    """
    trigs_to_send = []

    timestamp = datetime.utcnow()

    unsent_trigs = trigger_status['unsent_trigs']
    last_trigger = trigger_status['last_trigger']
    buffer_overlap = saving_parameters['buffer_overlap']
    min_time_between_targets = saving_parameters['min_time_between_targets']
    time_before_target = saving_parameters['time_before_target']

    # add any new triggers to trigger_status list
    for inst in new_trigs: 
        unsent_trigs[inst].append(timestamp)

    # for all triggers that have not been sent yet (unsent_trigs)
    for inst in unsent_trigs:
        if unsent_trigs[inst]:
            # calculate elapsed time since the target was detected
            time_since_detection = delta_t_in_seconds(timestamp, unsent_trigs[inst][0])
            print(time_since_detection, ' seconds since last ', inst, ' detection')

            # calculate elapsed time since the last trigger for this instrument
            time_since_last_trigger = delta_t_in_seconds(timestamp, last_trigger[inst])
            print(time_since_last_trigger, ' seconds since last ', inst, ' trigger sent')

            # Determine if more time than "wait_before_send" (from config) has elapsed
            # since detection.
            if time_since_detection >= instrument_buffer_sizes[inst] - time_before_target:

                # Determine if sufficient time has passed since last trigger was sent to inst to 
                # create an overlap of "buffer_overlap" (from config) in the saved data
                if time_since_last_trigger >= (instrument_buffer_sizes[inst] - buffer_overlap):

                    del unsent_trigs[inst][0]
                    trigs_to_send.append(inst)
                    last_trigger[inst] = timestamp

                    # remove triggers that are within min_time_between_targets (i.e.
                    # already saved by this buffer)
                    for index, unsent_trig in enumerate(unsent_trigs[inst]):
                        time_since_detection = delta_t_in_seconds(last_trigger[inst], unsent_trigs[inst][index])
             
                        if time_since_detection < min_time_between_targets:
                            del unsent_trigs[inst][index]
                        
    # send triggers over socket! 
    if trigs_to_send:   
        print('sending triggers for ', trigs_to_send)
        send_triggers(sock, udp_IP, udp_port, trigs_to_send)

    trigger_status = {'unsent_trigs': unsent_trigs, 'last_trigger': last_trigger}
    
    return trigs_to_send, trigger_status


def delta_t_in_seconds(datetime1, datetime2):
    """
    calculate delta t in seconds between two datetime objects
    """
    delta_t = datetime1 - datetime2
    return delta_t.days*(60*60*24) + delta_t.seconds + delta_t.microseconds/1000

In [5]:
def send_triggers(sock, udp_IP, udp_port, trigs_to_send):
    """
    send triggers to save data to AMP interface.

    Inputs:
    sock - socket over which to send data (create with socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
    udp_IP - IP address to send data over (typically "localhost")
    udp_port - port to send data over (typically 61500)
    new_trigs - list of instruments to send trigger

    Outputs:
    bytes_sent = number of bytes sent, should be 17 for 4 instruments.

    Data is sent in the following format:
        "AAAA 1 1 1 1 1 ZZZZ" where "AAAA" and "ZZZZZ" are always the header and
        footer, and the "1" values are zero or 1 if that instrument should
        offload data (in the order of the instruments list from config)
    """


    msg = "AAAA "

    for instrument in instruments:
        if instrument in trigs_to_send:
            msg += '1 '
        else:
            msg += '0 '

    msg += 'ZZZZ'
    msg = bytes(msg, 'utf-8')

    bytes_sent = sock.sendto(msg, (udp_IP, udp_port))

    return bytes_sent

In [ ]:
test = {'a': 1,'b' : 2,'c': 3}

for key in test:
    print(key)

In [ ]:
test = [1]

In [ ]:
del test[0]
test

In [ ]:
test = []

for index, unsent_trigger in enumerate(test):
    print(index)