from pickletools import pyinteger_or_bool
import socket
import sys
import time
import re
import threading
import datetime
import sys
import configparser
import signal



# 定义回调函数
def myHandler(signum, frame):
    print("接收信号为：", signum)
    exit(0)
# 等待接收 signal.SIGTERM命令
signal.signal(signal.SIGTERM, myHandler)

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

map_work_status_lock = threading.Lock()  # 锁的声明
"""字典 数据存放的map 使用锁进行读写访问"""

map_work_status = {"Pow1": "ON",
                "Pow2": "ON",
                "Pow3": "ON",
                "Pow4": "ON",
                "Pow5": "ON",
                "Pow6": "ON",
                "Pow7": "ON",
                "Pow8": "ON",
                "Pow9": "ON",
                "Pow10": "ON",
                "Pow11": "ON",
                "Pow12": "ON",
                "Pow13": "ON",
                "Pow14": "ON",
                "Pow15": "ON",
                "Pow16": "ON"
                }
"""字段中文名"""
map_name_chg = {"Pow1": "电源输出端口1",
                "Pow2": "电源输出端口2",
                "Pow3": "电源输出端口3",
                "Pow4": "电源输出端口4",
                "Pow5": "电源输出端口5",
                "Pow6": "电源输出端口6",
                "Pow7": "电源输出端口7",
                "Pow8": "电源输出端口8",
                "Pow9": "电源输出端口9",
                "Pow10": "电源输出端口10",
                "Pow11": "电源输出端口11",
                "Pow12": "电源输出端口12",
                "Pow13": "电源输出端口13",
                "Pow14": "电源输出端口14",
                "Pow15": "电源输出端口15",
                "Pow16": "电源输出端口16"
                }
packet_head = \
"************************************************************\r\n\
*                                                          *\r\n\
*                                                          *\r\n\
*     Power Outlet Port Parameters and Status              *\r\n\
*                                                          *\r\n\
*                                                          *\r\n\
************************************************************\r\n\
>\r\n\
>\r\n\
\r\n\
Port |       Name | status | Reserved By |   Timer   | AutoPing \r\n\
-----+------------+--------+-------------+-----------|---------\r\n\
"
tem_packet_str=""

def packet_string(tem_packet_str):
    packet_info=""
    status_str=""
    for num in range(1,17):  
        key = "Pow"+str(num)
        if(num<10):
            str1="  "+ str(num).zfill(2)+" |   Outlet "+str(num)+" |"
        else:
            str1="  "+ str(num).zfill(2)+" |  Outlet "+str(num).zfill(2)+" |"
        if(map_work_status[key] == "ON"):
            status_str="     "+map_work_status[key] +" "
        else:
            status_str="    "+map_work_status[key] +" "
        str3="|        Open |       OFF |    OFF\r\n"
        packet_info=packet_info+str1+status_str+str3
    tem_packet_str=packet_head +packet_info+"\r\n> "
    # print("11111111111122222222222222222: ",tem_packet_str)
    return tem_packet_str

tem_packet_str = packet_string(tem_packet_str)

print("初始化数据：\r\n" + tem_packet_str)


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



""" 状态查询指令 回调函数 """
def HY_NP16EHPDU_PShow_CallBack(recv_cmd):
    print("NP16EHPDU_PShow_CallBack")
    map_work_status_lock.acquire()  # 上锁
    tem_packet_str=""
    tem_packet_str = packet_string(tem_packet_str)
    if (TCP_LINK_STATUS != 0):
        # client_socket.send("".encode("utf-8"))
        print("send")
        client_socket.send(tem_packet_str.encode("utf-8"))
    map_work_status_lock.release()  # 解锁
    

""" 控制开关指令 回调函数"""
def HY_NP16EHPDU_SetOutPort_CallBack(recv_cmd):
    print(recv_cmd)
    if(len(recv_cmd)==10):
        key = "Pow"+recv_cmd[5]
        value = recv_cmd[7]
    else:
        key = "Pow"+recv_cmd[5:7]
        value = recv_cmd[8]
    print("key = ",key," value = ",value)
    map_work_status_lock.acquire()  # 上锁
    if (int(value) == 1):
        map_work_status[key] = "ON"
    elif (int(value) == 0):
        map_work_status[key] = "OFF"
    map_work_status_lock.release()  # 解锁


map_calBackFun = {"pset": HY_NP16EHPDU_SetOutPort_CallBack,
                "pshow":HY_NP16EHPDU_PShow_CallBack
}


"""定时读取 map_work_status 发布设备状态报文 间隔200ms"""
def SendStatusHandle():
    print("线程1")
    global client_socket
    cont = 0
    cont_print = 0
    max_cont = 10000
    while max_cont:
        map_work_status_lock.acquire()
        # tem_packet_str =""
        # tem_packet_str = packet_string(tem_packet_str)
        # if (TCP_LINK_STATUS != 0):
        #     max_cont = max_cont - 1
        #     client_socket.send(tem_packet_str.encode("utf-8"))
        tem_status_str=""
        for num in range(1,17):  
            key = "Pow"+str(num)
            tem_status_str =tem_status_str+map_name_chg[key]+" : "+map_work_status[key]+"\r\n"
        map_work_status_lock.release()

        cont = cont + 1
        if (cont > 2 and TCP_LINK_STATUS):
            cont_print = cont_print + 1
            print("=============== 打印当前模拟设备状态 ================= ", cont_print)
            print(tem_status_str)
            cont = 0
        time.sleep(1)


""" 一个模拟接收端，收到设置类型的指令后，修改 map_work_status。"""
def RecvSetCMDHandle():
    print("线程2")
    global TCP_LINK_STATUS
    global client_socket
    while 1:
        data = client_socket.recv(1024)
        rec_str = data.decode()
        cmd=""
        if (len(data) > 0):
            if(len(data)==7):
                cmd = rec_str[0:5]
                print("1111111",cmd)#查询指令
            elif(len(data)==10 or len(data)==11):
                cmd = rec_str[0:4]
                print("1111111",cmd)#设置指令
            if (cmd in map_calBackFun):
                map_calBackFun[cmd](rec_str)
                # SendMessage(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(1)


def SendMessage(recv_cmd):
    global client_socket
    send_str = ""
    map_work_status_lock.acquire()
    if recv_cmd[0] == "C":
        send_str = "<" + recv_cmd
    elif recv_cmd[0] == "B":
        send_str = "<" + recv_cmd
    elif recv_cmd[0] == "?":
        send_str = "<CF_" + map_work_status["InputFrequency"] + ",BD_" + map_banwith_status[map_work_status["Bandwidth"]] + "\r\n"
    client_socket.send(send_str.encode("utf-8"))
    map_work_status_lock.release()


if __name__ == '__main__':
    tr1 = threading.Thread(target=SendStatusHandle)
    tr2 = threading.Thread(target=RecvSetCMDHandle)
    tr1.start()
    tr2.start()

"""数据格式：
CF_xxxx.xxx\r\n
解释：
xxxx.xxx:输入频率,范围:2200.000~3000.000,单位:MHz;
BD_x\r\n
解释：
x:带宽,范围:1,2,3 1:50KHz  2:1MHz  3:2MHz   默认 1
"""
