# -*- coding: utf-8 -*-
"""

@author: David S. De Lorenzo

Import file for the DAT65L Programmable Step Attenuator.

"""


import time
import serial


def set(com_port, input_pwr_dBm, desired_rx_pwr_dBm, net_gain_in_rf_path_dB=0):
    #
    # To calculate the receiver RF input power:
    #
    #     receiver RF input power [dBm] = input power to the DAT64L [dBm]
    #                                   - DAT64L attenuation setting [dB]
    #                                   + net gain from DAT64L to rcvr [dB]
    #
    # Rearranging to calculate the attenuation setting:
    #
    #     DAT64L attenuation [dB] = input power to the DAT64L [dBm]
    #                             - desired receiver RF input power [dBm]
    #                             + net gain from DAT64L to receiver [dB]
    #
    atten_dB = input_pwr_dBm - desired_rx_pwr_dBm + net_gain_in_rf_path_dB

    # Enforce attenuation to be in range [0,60] and rounded
    # to the nearest 0.5 dB (the dat64L has 1/2 dB steps)
    if atten_dB < 0:
        atten_dB = 0
    elif atten_dB > 60:
        atten_dB = 63
    else:
        atten_dB = round(atten_dB * 2) / 2

    # Write the attenuation value to HW
    set_attenuation_dB(int(com_port), atten_dB)

    # Calculate the actual receiver RF input power
    actual_rx_pwr_dBm = input_pwr_dBm - atten_dB + net_gain_in_rf_path_dB

    return atten_dB, actual_rx_pwr_dBm


def set_attenuation_dB(com_port, atten_dB):

    try:
        ser = serial.Serial('COM' + str(com_port), 115200, timeout=1)
    except serial.SerialException:
        serial.Serial('COM' + str(com_port), 115200).close()
        print("Close COM" + str(com_port) + ", then open")
        ser = serial.Serial('COM' + str(com_port), 115200, timeout=1)

    # time.sleep(1)
    tmp = 'ATT ' + str(atten_dB) + '\n'
    ser.write(tmp.encode())

    # time.sleep(1)
    ser.close()


def get_attenuation_dB(com_port):

    try:
        ser = serial.Serial('COM' + str(com_port), 115200, timeout=1)
    except serial.SerialException:
        serial.Serial('COM' + str(com_port), 115200).close()
        print("Close COM" + str(com_port) + ", then open")
        ser = serial.Serial('COM' + str(com_port), 115200, timeout=1)

    # time.sleep(1)
    tmp = 'ATT?\n'
    ser.write(tmp.encode())

    # time.sleep(1)
    msg = str(ser.readline().decode())

    # time.sleep(1)
    ser.close()

    return msg


def turn_beep_off(com_port):

    ser = serial.Serial('COM' + str(com_port), 115200, timeout=1)

    time.sleep(1)
    ser.write(b'*BUZZER OFF\n')
