# -*- coding:utf-8 -*-
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 = {
                    "CMDS":"#00EF030C","TIME":"221013170133","Radiation1DailyAccumu":"0001","Radiation2DailyAccumu":"0002",\
                    "GroundTem1":"0003","GroundTem2":"0004","GroundTem3":"0005","GroundTem4":"0006","GroundTem5":"0007","AmbientTem":"0008",\
                    "Circumhumidity":"0009","DewPoint":"000A", "Pressure":"000B","Altitude":"000C","WindSpeed":"000D","WindSpeed2MinAverage":"000E" ,\
                    "WindSpeed10MinAverage":"000F","WindDirection":"0010","Radiation1":"0011","Radiation2":"0012","SoilWetness":"0013","BatteryVoltage":"0014",\
                    "DailyAccumulatedRainfall":"0015","visibility":"0016","visibility10MinAverage":"0017","SunshineHourDailyAccumu":"0018","CO2":"0019",\
                    "ElectronicCompass":"0020","END":"GG"\
                   }
"""字段中文名"""
map_name_chg = {
                "CMDS":"报文头","TIME":"时间","Radiation1DailyAccumu":"辐射1 日累计","Radiation2DailyAccumu":"辐射2 日累计",\
                "GroundTem1":"地温1","GroundTem2":"地温2","GroundTem3":"地温3","GroundTem4": "地温4","GroundTem5":"地温5",\
                "AmbientTem":"环温","Circumhumidity": "环湿","DewPoint":  "露点" ,"Pressure":  "气压","Altitude" : "海拨",\
                "WindSpeed":"风速","WindSpeed2MinAverage":"2分钟平均风速" ,"WindSpeed10MinAverage": "10分钟平均风速",\
                "WindDirection" :  "风向","Radiation1" :" 辐射1","Radiation2":"辐射2","SoilWetness": "土湿",\
                "BatteryVoltage" : "电池电压","DailyAccumulatedRainfall": "雨量日累计","visibility" :"能见度",\
                "visibility10MinAverage" : "能见度10分钟平均","SunshineHourDailyAccumu" : "日照时日累计","CO2": "CO2浓度","ElectronicCompass" :  "电子罗盘","END"  :  "END"\
               }

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)

config = configparser.ConfigParser()  # 类实例化
# 定义ini文件路径  这个文件用于存放 天控器当前的报警状态
path = r"acu7m5_hyds.ini"

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对象
print(addr)
TCP_LINK_STATUS = 1  # TCP 连接标志位

def precision0001(key):
      return str(round(int(key,16)* 0.001, 3))
def precison01(key):
    return  str(round((int(key, 16) * 0.1), 1))
def precision1(key):
    return str(int(key, 16))
def downp(key):
    # map_work_status[key]=int("FFFF",16)-int(key,16)+1
    # return  str(-map_work_status[key])
    if(int(key, 16)>0x7fff):
        return '-'+str(int("FFFF",16)-int(key,16)+1)
    else:
        return str((int(key, 16)))
        
def downp001(key):
    if(int(key, 16)>0x7fff):
        return '-'+str((int("FFFF", 16) - int(key, 16) + 1)*0.01)
    else:
        return str((int(key, 16))*0.01)

"""定时读取 map_work_status 发布设备状态报文 间隔200ms"""


def SendStatusHandle():
    global client_socket
    C_MDS= "#00EF030C"
    T_IME = "221013170133"
    cont = 0
    cont_print = 0
    max_cont = 10000
    while 1:
        # print(time.time())
        map_work_status_lock.acquire()  # 上锁
        map_work_status["CMDS"] =C_MDS
        map_work_status["TIME"] = T_IME
        tem_packet_str = ""
        tem_status_str = ""
#完成十六进制到十进制的转化
        #tem_status_str=tem_status_str+map_name_chg[key]+" : "+map_work_status[key]+"\r\n"
        tem_packet_str= tem_packet_str+map_work_status["CMDS"]
        tem_status_str = tem_status_str + map_name_chg["CMDS"] + " : " + tem_packet_str[0:11] + "\r\n"

        tem_packet_str =tem_packet_str  + map_work_status["TIME"]
        tem_status_str = tem_status_str + map_name_chg["TIME"] + " : " + tem_packet_str[12:25] + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Radiation1DailyAccumu"]
        tem_status_str = tem_status_str + map_name_chg["Radiation1DailyAccumu"] + " : " + precision0001(map_work_status["Radiation1DailyAccumu"]) + "MJ/m²"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Radiation2DailyAccumu"] 
        tem_status_str = tem_status_str + map_name_chg["Radiation2DailyAccumu"] + " : " +precision0001(map_work_status["Radiation2DailyAccumu"]) + "MJ/m²" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["GroundTem1"]  
        tem_status_str = tem_status_str + map_name_chg["GroundTem1"] + " : " + precison01( map_work_status["GroundTem1"]  )+ "°C"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["GroundTem2"]  
        tem_status_str = tem_status_str + map_name_chg["GroundTem2"] + " : " + precison01( map_work_status["GroundTem2"]  )+ "°C" + "\r\n"

        tem_packet_str = tem_packet_str +   map_work_status["GroundTem3"]  
        tem_status_str = tem_status_str + map_name_chg["GroundTem3"] + " : " +precison01( map_work_status["GroundTem3"]  )+ "°C" + "\r\n"

        tem_packet_str = tem_packet_str +   map_work_status["GroundTem4"]  
        tem_status_str = tem_status_str + map_name_chg["GroundTem4"] + " : " + precison01( map_work_status["GroundTem4"]  )+ "°C" + "\r\n"

        tem_packet_str = tem_packet_str +   map_work_status["GroundTem5"]  
        tem_status_str = tem_status_str + map_name_chg["GroundTem5"] + " : " + precison01( map_work_status["GroundTem5"]  )+ "°C"+ "\r\n"

        tem_packet_str = tem_packet_str +   map_work_status["AmbientTem"]  
        tem_status_str = tem_status_str + map_name_chg["AmbientTem"] + " : " +precison01( map_work_status["AmbientTem"]  )+ "°C" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Circumhumidity"]  
        tem_status_str = tem_status_str + map_name_chg["Circumhumidity"] + " : " + precison01( map_work_status["Circumhumidity"]  )+ "%RH"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["DewPoint"]  
        tem_status_str = tem_status_str + map_name_chg["DewPoint"] + " : " + downp001( map_work_status["DewPoint"]  ) + "°C"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Pressure"]  
        tem_status_str = tem_status_str + map_name_chg["Pressure"] + " : " +precison01( map_work_status["Pressure"]  ) + "hPa"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Altitude"]  
        tem_status_str = tem_status_str + map_name_chg["Altitude"] + " : " + downp(map_work_status["Altitude"]  ) + "m"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["WindSpeed"]  
        tem_status_str = tem_status_str + map_name_chg["WindSpeed"] + " : " + precison01(map_work_status["WindSpeed"]  ) + "hPa" + "\r\n"

        tem_packet_str = tem_packet_str + map_work_status["WindSpeed2MinAverage"]
        tem_status_str = tem_status_str + map_name_chg["WindSpeed2MinAverage"] + " : " +  precison01(map_work_status["WindSpeed2MinAverage"]) + "m/s" + "\r\n"

        tem_packet_str = tem_packet_str + map_work_status["WindSpeed10MinAverage"]
        tem_status_str = tem_status_str + map_name_chg["WindSpeed10MinAverage"] + " : " + precison01(map_work_status["WindSpeed10MinAverage"]) + "m/s" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["WindDirection"]
        tem_status_str = tem_status_str + map_name_chg["WindDirection"] + " : " + precision1( map_work_status["WindDirection"]) + "°" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Radiation1"]
        tem_status_str = tem_status_str + map_name_chg["Radiation1"] + " : " + precision1( map_work_status["Radiation1"]) + "w/m²" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["Radiation2"]
        tem_status_str = tem_status_str + map_name_chg["Radiation2"] + " : " +precision1(map_work_status["Radiation2"]) + "w/m²" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["SoilWetness"]
        tem_status_str = tem_status_str + map_name_chg["SoilWetness"] + " : " + precison01(map_work_status["SoilWetness"]) + "%m³/m³"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["BatteryVoltage"]
        tem_status_str = tem_status_str + map_name_chg["BatteryVoltage"] + " : " + precison01( map_work_status["BatteryVoltage"]) + "V" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["DailyAccumulatedRainfall"]
        tem_status_str = tem_status_str + map_name_chg["DailyAccumulatedRainfall"] + " : " + precison01(map_work_status["DailyAccumulatedRainfall"]) + "mm"+ "\r\n"

        tem_packet_str = tem_packet_str + map_work_status["visibility"]
        tem_status_str = tem_status_str + map_name_chg["visibility"] + " : " + precision1(map_work_status["visibility"]) + "m" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["visibility10MinAverage"]
        tem_status_str = tem_status_str + map_name_chg["visibility10MinAverage"] + " : " +precision1( map_work_status["visibility10MinAverage"]) + "m" + "\r\n"

        tem_packet_str = tem_packet_str +   map_work_status["SunshineHourDailyAccumu"]
        tem_status_str = tem_status_str + map_name_chg["SunshineHourDailyAccumu"] + " : " + precision1(map_work_status["SunshineHourDailyAccumu"]) + "分钟"+ "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["CO2"]
        tem_status_str = tem_status_str + map_name_chg["CO2"] + " : " + precison01(map_work_status["CO2"]) + "ppm" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["ElectronicCompass"]
        tem_status_str = tem_status_str + map_name_chg["ElectronicCompass"] + " : " +precision1(map_work_status["ElectronicCompass"]) + "°" + "\r\n"

        tem_packet_str = tem_packet_str +  map_work_status["END"]
        tem_status_str = tem_status_str + map_name_chg["END"] + " : " +map_work_status["END"]  + "\r\n"

        if (TCP_LINK_STATUS != 0):
            max_cont = max_cont - 1
            client_socket.send(tem_packet_str.encode("utf-8"))
        # print(tem_packet_str)
        map_work_status_lock.release()  # 解锁
        # print(time.time())
        # cont = cont + 1
        for key in map_work_status:
            # print( map_work_status[key])
            # print(str(hex(cont_print)[2:].zfill(4)))
            if(key != "CMDS" and key != "TIME" and key != "END"):
                map_work_status[key]=str(hex(cont_print)[2:].zfill(4))
        # if (cont > 5 and TCP_LINK_STATUS):
        cont_print = cont_print + 1
        print("=============== 打印当前模拟设备状态 ================= ", cont_print)
        print(tem_status_str)
        time.sleep(1)


def RecvSetCMDHandle():
    print("线程2")
    global TCP_LINK_STATUS
    global client_socket
    while 1:
        data = client_socket.recv(1024)
        rec_str = data.decode()
        if (len(data) > 0):
            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)

""" 一个模拟接收端，收到设置类型的指令后，修改map_work_status。"""

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