from pickletools import pyinteger_or_bool
import socket
import sys
import time
import re
import threading
import datetime
import sys
import configparser
config = configparser.ConfigParser() # 类实例化
# 定义ini文件路径  这个文件用于存放 天控器当前的报警状态
path = r'./simulate_device_manager/simulate_devices/acu7m5_hyds.ini'

argv = sys.argv[1:]
tcp_port =int(argv[0])

map_work_status_lock = threading.Lock()#锁的声明
"""数据存放的map 使用锁进行读写访问"""
map_work_status={"Xaxis":"090.00","Yaxis":"090.00","Azimuth":"000.00","ElevationAngle":"090.00","ACUstatus":"P", \
                    "XTrackerSigIntensity":"255","YTrackerSigIntensity":"255","X_STATUS":"255","Y_STATUS":"255","XInitPhase":"012",\
                    "XPolarizationType":"1","SPolarizationType":"0","XTrackerVoltageLimit":"255",\
                    "STrackerVoltageLimit":"255","SUpPolarizationType":"1","XUpPolarizationType":"1",\
                    "TrackingStatus":"0","TrackingBand":"1","X-Bias":"+0.00","Y-Bias":"+0.00" }
"""字段中文名"""
map_name_chg={"Xaxis":"X轴角度","Yaxis":"Y轴角度","Azimuth":"方位轴角度","ElevationAngle":"俯仰轴角度","ACUstatus":"ACU程序状态", \
                    "XTrackerSigIntensity":"X频段信号强度","YTrackerSigIntensity":"y频段信号强度","X_STATUS":"X轴状态","Y_STATUS":"Y轴状态","XInitPhase":"X频段初相位",\
                    "XPolarizationType":"X频段跟踪极化","SPolarizationType":"S频段跟踪极化","XTrackerVoltageLimit":"X频段跟踪门限",\
                    "STrackerVoltageLimit":"S频段跟踪门限","SUpPolarizationType":"S频段上行极化","XUpPolarizationType":"X频段上行极化",\
                    "TrackingStatus":"跟踪方式","TrackingBand":"跟踪频段","X-Bias":"X轴偏置度","Y-Bias":"Y轴偏置度" }


tem_packet_str="$"
for key in map_work_status:
       tem_packet_str=tem_packet_str+","+map_work_status[key]
tem_packet_str=tem_packet_str+"\r\n"
print("初始化数据："+tem_packet_str)
# mesage1="$,111.84,063.28,143.53,56.01,W,200,155,000,008,055,0,1,121,123,1,0,0,0,+1.23,-4.56\r\n"
# print(mesage1)

tcpServer_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #1创建socket对象
tcpServer_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
rc=tcpServer_socket.bind(('0.0.0.0',tcp_port ))#2，需要自己绑定一个ip地址和端口号 
print("开启TCPserver 0.0.0.0 ",tcp_port)
tcpServer_socket.listen(1)   #可以同时监听3个，但是这里只有一个因为没有写多线程
client_socket,addr=tcpServer_socket.accept()   #阻塞 是服务端的socket对象clientServer_socket是接入的客户端socket对象   
TCP_LINK_STATUS = 1 #TCP 连接标志位



""" 处理XY置位指令 回调函数"""
def HY_ACU7M5_PostionSet_CallBack(recv_cmd):
       # print("收到报文"+cmd_str)
       Xaxis = recv_cmd[4:10]
       Yaxis =recv_cmd[11:17]
       # print(Xaxis+"  "+Yaxis)
       map_work_status_lock.acquire()#上锁
       map_work_status["Xaxis"]=Xaxis
       map_work_status["Yaxis"]=Yaxis
       map_work_status_lock.release()#解锁

""" 运动停止指令 回调函数"""
def HY_ACU7M5_MoveStop_CallBack(recv_cmd):
       map_work_status_lock.acquire()#上锁
       map_work_status["ACUstatus"]="W"
       map_work_status_lock.release()#解锁

""" 方位俯仰置位指令  回调函数"""
def HY_ACU7M5_DirectionSet_CallBack(recv_cmd):
       # print("收到报文"+cmd_str)
       Azimuth = recv_cmd[4:10]
       ElevationAngle =recv_cmd[11:17]
       print(Azimuth+"  "+ElevationAngle)
       map_work_status_lock.acquire()#上锁
       map_work_status["Azimuth"]=Azimuth
       map_work_status["ElevationAngle"]=ElevationAngle
       map_work_status_lock.release()#解锁

""" 自跟指令 回调函数"""
def HY_ACU7M5_AutoTrace_CallBack(recv_cmd):
       # print("收到报文"+cmd_str)
       TrackingStatus = recv_cmd[4:5]
       map_work_status_lock.acquire()#上锁
       map_work_status["TrackingStatus"]=TrackingStatus
       map_work_status_lock.release()#解锁

""" 跟踪极化及跟踪门限设置指令  回调函数"""
def HY_ACU7M5_GZJHMXSetting_CallBack(recv_cmd):
       # print("收到报文"+cmd_str)
       XPolarizationType = recv_cmd[4:5]
       SPolarizationType = recv_cmd[6:7]
       XTrackerVoltageLimit = recv_cmd[8:11]
       STrackerVoltageLimit = recv_cmd[12:15]
       map_work_status_lock.acquire()#上锁
       map_work_status["XPolarizationType"]=XPolarizationType
       map_work_status["SPolarizationType"]=SPolarizationType
       map_work_status["XTrackerVoltageLimit"]=XTrackerVoltageLimit
       map_work_status["STrackerVoltageLimit"]=STrackerVoltageLimit
       map_work_status_lock.release()#解锁

""" 加载轨道数据指令 回调函数"""
def HY_ACU7M5_LoadingTrackData_CallBack(recv_cmd):
       map_work_status_lock.acquire()#上锁
       map_work_status["ACUstatus"]="P"
       map_work_status_lock.release()#解锁

""" 程引偏置指令 回调函数"""
def HY_ACU7M5_BiasCommand_CallBack(recv_cmd):
       # print("收到报文"+recv_cmd)
       X_Bias = recv_cmd[4:9]
       Y_Bias = recv_cmd[10:15]
       map_work_status_lock.acquire()#上锁
       map_work_status["X-Bias"]=X_Bias
       map_work_status["Y-Bias"]=Y_Bias
       map_work_status_lock.release()#解锁

""" 初相位设置指令 回调函数"""
def HY_ACU7M5_InitPhaseSet_CallBack(recv_cmd):
       # print("收到报文"+recv_cmd)
       XInitPhase = recv_cmd[3:6]
       map_work_status_lock.acquire()#上锁
       map_work_status["XInitPhase"]=XInitPhase
       map_work_status_lock.release()#解锁

""" X频段上行极化设置指令 回调函数"""
def HY_ACU7M5_XUpPolarizationTypeSet_CallBack(recv_cmd):
       # print("收到报文"+recv_cmd)
       XUpPolarizationType = recv_cmd[3:4]
       map_work_status_lock.acquire()#上锁
       map_work_status["XUpPolarizationType"]=XUpPolarizationType
       map_work_status_lock.release()#解锁
        
""" S频段上行极化设置指令 回调函数"""
def HY_ACU7M5_SUpPolarizationTypeSet_CallBack(recv_cmd):
       # print("收到报文"+recv_cmd)
       SUpPolarizationType = recv_cmd[3:4]
       map_work_status_lock.acquire()#上锁
       map_work_status["SUpPolarizationType"]=SUpPolarizationType
       map_work_status_lock.release()#解锁

        
""" 跟踪频段指令 回调函数"""
def HY_ACU7M5_TrackingBandSet_CallBack(recv_cmd):
       # print("收到报文"+recv_cmd)
       TrackingBand = recv_cmd[3:4]
       map_work_status_lock.acquire()#上锁
       map_work_status["TrackingBand"]=TrackingBand
       map_work_status_lock.release()#解锁

map_callBackFun={"$XY":HY_ACU7M5_PostionSet_CallBack,\
                 "$WT":HY_ACU7M5_MoveStop_CallBack,\
                 "$AE":HY_ACU7M5_DirectionSet_CallBack,\
                 "$AT":HY_ACU7M5_AutoTrace_CallBack,\
                 "$PL":HY_ACU7M5_GZJHMXSetting_CallBack,\
                 "$SP":HY_ACU7M5_LoadingTrackData_CallBack,\
                 "$RS":HY_ACU7M5_BiasCommand_CallBack,\
                 "$PH":HY_ACU7M5_InitPhaseSet_CallBack,\
                 "$XU":HY_ACU7M5_XUpPolarizationTypeSet_CallBack,\
                 "$SU":HY_ACU7M5_SUpPolarizationTypeSet_CallBack,\
                 "$BD":HY_ACU7M5_TrackingBandSet_CallBack
                }

"""定时读取 map_work_status 发布设备状态报文 间隔200ms"""
def SendStatusHandle():
       global client_socket
       X_STATUS ="000"
       Y_STATUS ="000"
       cont =0
       while 1:
              # print(time.time())
              map_work_status_lock.acquire()#上锁
              map_work_status["X_STATUS"]=X_STATUS
              map_work_status["Y_STATUS"]=Y_STATUS
              
              x_axis = float(map_work_status["Xaxis"])
              y_axis = float(map_work_status["Yaxis"])
              # x_axis = (x_axis + 1) % 181
              # y_axis = (y_axis + 1) % 181
              map_work_status["Xaxis"] = "{:03d}.{:02d}".format(int(x_axis), int((x_axis % 1) * 100))
              map_work_status["Yaxis"] = "{:03d}.{:02d}".format(int(y_axis), int((y_axis % 1) * 100))

              tem_packet_str="$"
              tem_status_str = ""
              for key in map_work_status:
                     tem_packet_str=tem_packet_str+","+map_work_status[key]
                     tem_status_str=tem_status_str+map_name_chg[key]+" : "+map_work_status[key]+"\r\n"
              tem_packet_str=tem_packet_str+"\r\n"
              if (TCP_LINK_STATUS != 0):
                     client_socket.send(tem_packet_str.encode("utf-8"))
              # print(tem_packet_str)
              map_work_status_lock.release()#解锁
              # print(time.time())
              cont= cont+1
              if(cont>5 and TCP_LINK_STATUS):
                     print("=============== 打印当前模拟设备状态 =================")
                     print(tem_status_str)
                     config.read(path)
                     XaxisAlarm = config['alarm_status']['XaxisAlarm']
                     XaxisServoStatus = config['alarm_status']['XaxisServoStatus']
                     EasternLimit = config['alarm_status']['EasternLimit']
                     WestLimit = config['alarm_status']['WestLimit']
                     YaxisAlarm = config['alarm_status']['YaxisAlarm']
                     YaxisServoStatus = config['alarm_status']['YaxisServoStatus']
                     SouthrLimit = config['alarm_status']['SouthrLimit']
                     NorthLimit = config['alarm_status']['NorthLimit']
                     X_STATUS =str(240+ int(XaxisAlarm)*8+ int(XaxisServoStatus)*4+ int(EasternLimit)*2+ int(WestLimit)*1)
                     Y_STATUS =str(240+ int(YaxisAlarm)*8+ int(YaxisServoStatus)*4+ int(SouthrLimit)*2+ int(NorthLimit)*1)
                     cont =0
                     # print("X_STATUS ======= ",X_STATUS)
                     # print("Y_STATUS ======= ",Y_STATUS)                     
                     # print("==================== 结束打印 =======================\r\n")
              
              time.sleep(1)


""" 一个模拟接收端，收到设置类型的指令后，修改map_work_status。"""
def RecvSetCMDHandle():
       global TCP_LINK_STATUS 
       global client_socket
       while 1:
              data = client_socket.recv(1024)   # 一次接收1024字节
              rec_str =data.decode()
              if(len(data)>0): 
                     cmd =rec_str[0:3]
                     # print("cmd = "+cmd)
                     if(cmd in map_callBackFun):
                            map_callBackFun[cmd](rec_str)
                     else:
                            print("收到未知报文 : "+rec_str)
              else:
                     TCP_LINK_STATUS =0
                     print("连接断开，等待接入")
                     client_socket.close()
                     client_socket,addr=tcpServer_socket.accept()   #s是服务端的socket对象clientServer_socket是接入的客户端socket对象
                     TCP_LINK_STATUS =1
                     print(addr)
                     cont = 0
                     time.sleep(0.1)
              # time.sleep(1)

""" 
初始化TCP SERVER
起两个线程
一个模拟设备定时读取 map_work_status 发布设备状态报文 间隔200ms
一个模拟接收端，收到设置类型的指令后，修改map_work_status。
"""
if __name__ == '__main__':
       tr1 =threading.Thread(target=SendStatusHandle)
       tr2 =threading.Thread(target=RecvSetCMDHandle)
       tr1.start()
       tr2.start()


"""数据格式: 
$,xxx.xx,yyy.yy,aaa.aa,ee.ee,p,lsx,lsy,lx,ly,ph,psx,pss,gx,gs,us,ux,at,bd,fffff,ggggg\r\n 
解释:
xxx.xx:X轴角度数据,范围:000.00~180.00,单位:度;
yyy.yy:俯仰角度数据,范围:000.00~180.00,单位:度;
aaa.aa:方位轴角度数据,范围:000.00~360.00,单位:度;
ee.ee:俯仰轴角度数据,范围:00.00~90.00,单位:度;
p:程序状态,W待机,M手动,P程引,A自跟,ZW置位;
lsx: X频段信号强度,范围0-512;
lsy; S频段信号强度,范围0-512;
lx: X轴状态数据,详见举例说明 ;
ly: Y轴状态数据,详见举例说明;
ph: X频段初相位,范围0-255;
psx: X频段跟踪极化,范围0-1,0左旋,1右旋;
pss: S频段跟踪极化,范围0-1,0左旋,1右旋;
gx: X频段跟踪门限,范围0-512;
gs: S频段跟踪门限,范围0-512;
us: S频段上行极化,范围0-1,0左旋,1右旋;
ux: X频段上行极化,范围0-1,0左旋,1右旋;
at:跟踪方式,1 表示启动了自动进入跟踪。0 表示未启动。 
Bd:跟踪频段,1为X频段,0为S频段。
fffff:X轴偏置角;
ggggg:y轴偏置角;
举例: 
$,111.84,063.28,143.53,56.01,W,200,155,000,008,055,0,1,121,123,1,0,0,0,+1.23,-4.56\r\n
"XaxisAlarm":"0", "XaxisServoStatus":"1","EasternLimit":"0","WestLimit":"0","YaxisAlarm":"0","YaxisServoStatus":"0","SouthrLimit":"0","NorthLimit":"0",
"XaxisAlarm":"X轴报警","XaxisServoStatus":"X轴伺服状态","EasternLimit":"东限位","WestLimit":"西限位","YaxisAlarm":"Y轴报警","YaxisServoStatus":"Y轴伺服","SouthrLimit":"南限位","NorthLimit":"北限位",
 """