from htra_api import *
import numpy as np
###打开设备###
Status = 0          #函数的返回。
Device = c_void_p() #当前设备的内存地址。
DevNum = c_int(0)   #指定设备号。

BootProfile = BootProfile_TypeDef() #启动配置结构体，包括物理接口、供电方式等。
BootInfo = BootInfo_TypeDef()       #启动信息结构体，包括设备信息、USB速率等。

BootProfile.DevicePowerSupply = DevicePowerSupply_TypeDef.USBPortAndPowerPort #使用USB数据端口及独立电源端口双供电
BootProfile.PhysicalInterface = PhysicalInterface_TypeDef.USB                 #使用USB接口进行数据传输。

#使用网口设备配置ETH接口
#BootProfile.PhysicalInterface = PhysicalInterface_TypeDef.ETH #使用网口进行数据传输
#BootProfile.ETH_IPVersion = IPVersion_TypeDef.IPv4
#BootProfile.ETH_RemotePort = 5000
#BootProfile.ETH_ReadTimeOut = 10000
#BootProfile.ETH_IPAddress[0] = 192
#BootProfile.ETH_IPAddress[1] = 168
#BootProfile.ETH_IPAddress[2] = 1
#BootProfile.ETH_IPAddress[3] = 100

Status = dll.Device_Open(pointer(Device),DevNum,pointer(BootProfile),pointer(BootInfo)) #打开设备。
if(Status == 0):
    print("Device is opened successfully")
else:
    print("Return other errors Status = {:d}".format(Status))

###配置下发###
RTA_ProfileIn = RTA_Profile_TypeDef()  #RTA输入配置，包括中心频率、抽取倍数、参考电平等。
RTA_ProfileOut = RTA_Profile_TypeDef() #RTA输出配置。
FrameInfo = RTA_FrameInfo_TypeDef()    #当前配置下的RTA数据相关信息，包括起始频率、终止频率、数据点数等。

dll.RTA_ProfileDeInit(pointer(Device),pointer(RTA_ProfileIn)) #初始化配置RTA模式的相关参数。

RTA_ProfileIn.CenterFreq_Hz = 1e9                           #配置中心频率。
RTA_ProfileIn.RefLevel_dBm = 0                              #配置参考电平。
RTA_ProfileIn.DecimateFactor = 1                            #配置抽取倍数。
RTA_ProfileIn.TriggerSource = RTA_TriggerSource_TypeDef.Bus #配置触发源为内部总线触发。
RTA_ProfileIn.TriggerMode = TriggerMode_TypeDef.FixedPoints
RTA_ProfileIn.TriggerAcqTime = 0.1                          #配置触发后的采样时间为0.1s，仅在FixedPoints模式下生效。

Status = dll.RTA_Configuration(pointer(Device),pointer(RTA_ProfileIn),pointer(RTA_ProfileOut),pointer(FrameInfo)) #下发RTA模式的相关配置。

if(Status == 0):
    print("configuration delievery succeeded")
else:
    print("SWP_Configuration call is incorrect Status = {:d}".format(Status))

###获取数据###
SpectrumTrace = (c_uint8 *FrameInfo.PacketValidPoints)()                      #频谱数组。
SpectrumBitmap = (c_uint16 *(FrameInfo.FrameHeight * FrameInfo.FrameWidth))() #频谱位图数组。
Spectrum = (c_float *FrameInfo.FrameWidth)()                                  #功率的数组
RTA_PlotInfo = RTA_PlotInfo_TypeDef()                                         #绘图信息。
TriggerInfo = RTA_TriggerInfo_TypeDef()                                       #触发信息。
MeasAuxInfo = MeasAuxInfo_TypeDef()                                           #测量数据的辅助信息。

# 尝试导入绘图模块pyplot，绘制RTA模式频谱图
try:
    from plot_module import start_plot
    max = FrameInfo.StopFrequency_Hz
    x_array = np.arange(FrameInfo.StartFrequency_Hz, max, ((FrameInfo.StopFrequency_Hz-FrameInfo.StartFrequency_Hz)/FrameInfo.FrameWidth))
    update_plot = start_plot(Sup_title="Real-time Spectrum", Subplot1_X=x_array, Subplot1_Y=Spectrum, xlabel1="Frequency(Hz)", ylabel1="Spectrum(dBm)",title1=None)

except ImportError:
    print("matplotlib.pyplot not available. Plotting disabled.")
    update_plot = None
    start_plot = None

try:
    while True:
        Status = dll.RTA_BusTriggerStart(pointer(Device))
        for i in range(0,FrameInfo.PacketCount):
            Status = dll.RTA_GetRealTimeSpectrum(Device,SpectrumTrace,SpectrumBitmap,pointer(RTA_PlotInfo),
                                                 pointer(TriggerInfo),pointer(MeasAuxInfo)) #获取RTA数据及触发信息。
            for j in range(0,FrameInfo.FrameWidth):                                             #转换。
                Spectrum[j] = SpectrumTrace[j] * RTA_PlotInfo.ScaleTodBm + RTA_PlotInfo.OffsetTodBm

        if update_plot and not update_plot(): 
            break

except KeyboardInterrupt:
    print("Stopped by user with Ctrl+C")
finally:
    dll.Device_Close(pointer(Device))
    print("Device closed.")