Python 环境光传感器

fig.txt

{"cmd":"update_machine","mes":{"sn":"100016813","name":"testlight","type":"切割机","department":"smd","station":"五樓"}}

main_V3_2_2.py

"""
@三色灯採集程序
@功能:通过環境光传感器,采集三色灯各灯的亮灭状态和时间,并上传到MQTT服务器
@by Gansen
@硬件:ESP32采集模块V2版本
@接口:  红灯--> GPIO36
        黄灯--> GPIO35
        绿灯--> GPIO34

@版本:V3.2.2
修改说明:与V2.2.2版本对应,更换esp32硬件为V2版本
修改日期:2022-11-19
"""
import machine, esp32, network, utime, ds1307, ubinascii, ujson, uos, uftp,untp
from umqtt import MQTTClient
from machine import Pin
import _thread


print('ESP32工作頻率爲%dMhz' % int(machine.freq()/1000000)) # 打印當前CPU工作頻率
#machine.freq(240000000) #設置工作頻率240 MHz
wdt = machine.WDT(id=0,timeout=600000)  #看门狗1分钟重启动
feed_flag=False
#串口1配置
uart1=machine.UART(1,tx=16,rx=17)
uart1.init(19200,bits=8,parity=None,stop=1)

#DS1307时钟配置
i2c=machine.I2C(0,scl=machine.Pin(22),sda=machine.Pin(21))
ds=ds1307.DS1307(i2c)
ds.halt(False)
#RTC时钟配置
rtc=machine.RTC()
rtc.datetime(ds.datetime())
#ntp配置
NTP_DELTA = 3155644800  #3155673600 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
ntp_server = '172.16.xxx.xxx'  # 可选,ntp服务器,默认是"pool.ntp.org"
#配置FTP
ftp=uftp.FtpTiny()
ftp.start()

#重启原因日志文件
def write_file(ss):
    file_name = 'reset_log.txt'
    file = open (file_name, 'a')
    file.write(ds.DT() +' -- '+ ss + '\n')
    file.close()
#重启原因保存
print('程序开始执行,重启原因:',end='')
cause = machine.reset_cause()#获取重启原因
if cause==1:
    print('POWER_RESET-上电重启')
    write_file('POWER_RESET-上电重启')
if cause==2:
    print('HARD_RESET-硬重启')
    write_file('HARD_RESET-硬重启')
if cause==3:
    print('WDT_RESET-看门狗定时器重启')
    write_file('WDT_RESET-看门狗定时器重启')
if cause==4:
    print('DEEPSLEEP_RESET-休眠重启')
    write_file('DEEPSLEEP_RESET-休眠重启')
if cause==5:
    print('SOFT_RESET-软重启')
    write_file('SOFT_RESET-软重启')
    
#获取目录文件大小
def print_directory(path,tabs = 0):
    for file in uos.listdir(path):
#        print(file)
        stats = uos.stat(path+'/'+file)
        filesize = stats[6]
        isdir = stats[0] & 0x4000
#        print(isdir)
        
        if filesize < 1024:
            sizestr = str(filesize)+' bytes'
        elif filesize < 1024000:
            sizestr = '%0.1f KB'%(filesize/1024)
        else:
            sizestr = '%0.1f MB'%(filesize/1024000)
        
        prettyprintname = ''
        for i in range(tabs):
            prettyprintname +='   '
        prettyprintname += file
        if isdir:
            prettyprintname+= '/'
        print('{0:<30} Sise: {1:>2}'.format(prettyprintname,sizestr))
        
        if isdir:
            print_directory(path+'/'+file,tabs+1)
            
        if prettyprintname=='reset_log.txt':
            if filesize >10240:
                uos.rmdir('/reset_log.txt')
                print('reset_log remove')
            else: 
                print('filesize;',filesize)
#日志文件>10k删除
print_directory('')

#MQTT配置
ssid     = "wifi"
password = "pass"
mqtt_server = '172.16.xx.xx'  #MQTT服務器IP地址
mqtt_user='xxx'  #MQTT服務器用戶
mqtt_pwd='xxx'  #MQTT服務器密碼
#client_id = ubinascii.hexlify(machine.unique_id())  #ESP模塊uid(mac地址)
client_id = ubinascii.hexlify(machine.unique_id() + utime.time().to_bytes(4,'little',False)) #mqtt client_id
esp32_mac = ubinascii.hexlify(machine.unique_id(),':').upper()  #大寫mac
topic_sub = b'/machine/light/' + esp32_mac+ b'/cmd'  #訂閱命令主旨
topic_pub = b'/machine/light/' + esp32_mac   #數據發布主旨
topic_pub_res = b'/Res/' + esp32_mac  #命令反饋發布主旨
collect_time = 100  #採集傳感器數據時間間隔 單位ms
message_time = 5000  #MQTT消息發送時間間隔 單位ms

#wlan_timeout =10    #wifi连接超时时间 单位s

#设备信息配置
esp32_IP = '0.0.0.0'#ip地址
isopen = True    #刚开始发为true,后续为false
VERsion = 'V2.2.2'   #程序版本号
sn = '100000001'     #资产编号
Name = 'light'       #设备名称
department = 'smd'   #部门
type = 'smd'    #机台类型
station = 'smd' #坐落位置
lamp_event = '' #机台灯事件
machine_state = False #机台警示棒故障标志,正常为true,故障为false

#讀取配置文件
try:
    f = open('fig.txt', 'r')
    config = ujson.loads(f.read())
    f.close()
    sn = config['mes']['sn']
    Name = config['mes']['name']
    type = config['mes']['type']
    department = config['mes']['department']
    station = config['mes']['station']
except Exception as e : #访问异常的错误编号和详细信息
    print("Exception:",e)
    # 若初次运行,则将进入excpet,执行配置文件的创建 
    print('not found file.')

#網絡配置
def do_connect(timeout):
    global  esp32_IP
    at = utime.ticks_ms()
    print('檢測%s熱點AP強度...'%(ssid))
    uart1.write('print kingbright AP...\r\n')
    wlan = network.WLAN(network.STA_IF)
    try:
        wlan.active(True)
    except Exception as e : #访问异常的错误编号和详细信息
        print("Exception:",e)
    wlan.disconnect()
    if wlan.ifconfig()[0] == '0.0.0.0' and len(rtc.memory()) == 0:
        aplist = wlan.scan()
        for one in aplist:
            if one[0] == b'%s'%ssid:
                print(one[0],one[2],one[3])
                uart1.write(b'%s\r\n'%one[3])
#    print('start...')
#    print(wlan.ifconfig())
    if wlan.ifconfig()[0] == '0.0.0.0':
        print('準備連接到',ssid,end='')
        uart1.write('kingbright conneting...\r\n')
        try:
            wlan.connect(ssid,password)
        except Exception as e : #访问异常的错误编号和详细信息
            print("Exception:",e)
            wlan.active(False)
            wlan.active(True)
            wlan.connect(ssid,password)
        start = utime.time() #獲取當前時間節點
        while not wlan.isconnected() and utime.time() - start < timeout:
            pass
        if utime.time() - start < timeout:
            print(wlan.ifconfig())
            esp32_IP = wlan.ifconfig()[0]
            print('已經連接到',ssid)
            rtc.memory(b'\x00\x00')
            uart1.write('kingbright conneted!\r\n')
            print('do_connect time0:',utime.ticks_diff(utime.ticks_ms(),at))
        else:
            print('無法連接到',ssid)
            uart1.write('kingbright connet error!\r\n')
    else:
        print(wlan.ifconfig())
        esp32_IP = wlan.ifconfig()[0]
        print('IP=',esp32_IP)
        print('已經連接到',ssid)
        uart1.write('kingbright conneted!\r\n')
        print('do_connect time1:',utime.ticks_diff(utime.ticks_ms(),at))
    return wlan


#wifi连接
def my_connect(timeout):
    global  esp32_IP
    ast = utime.ticks_ms()
    wlan=network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.disconnect()
    print('wlan.isconnected()-0:',wlan.isconnected())
    if not wlan.isconnected():
        print('准备連接中...')
        wlan.connect('kingbright','28699007')
        start = utime.time() #獲取當前時間節點
        while not wlan.isconnected() and utime.time() - start < timeout:
            pass
        if utime.time() - start < timeout:
            esp32_IP = wlan.ifconfig()[0]
            print('已經連接到kingbright-0')
            print('my_connet time:',utime.ticks_diff(utime.ticks_ms(),ast))
        else:
            print('無法連接到kingbright')
            
    else:
        print('已經連接到kingbright-1')
        esp32_IP = wlan.ifconfig()[0]
    print('wlan.isconnected()-1:',wlan.isconnected())
    return wlan

#訂閱消息中斷
def sub_cb(topic, msg):
    #msg=msg.decode('uft-8')
    print(msg.decode('uft-8'))
    sub_cb_deal(msg)


#連接MQTT並訂閱消息
def connect_and_subscribe():
    global client1
    client_id = ubinascii.hexlify(machine.unique_id() + utime.time().to_bytes(4,'little',False)) #mqtt client_id
    try:
        client1 = MQTTClient(client_id, mqtt_server,user=mqtt_user, password=mqtt_pwd, keepalive=10)
        client1.set_status()#status初始未True,設置為False,MQTT連接成功後再通過ping和check_msg確定當前狀態
        client1.set_callback(sub_cb)
        client1.connect()
        client1.subscribe(topic_sub)
        client1.ping()#設置ping,方便check_msg確定當前狀態
        print('連接到 %s MQTT服務器, 訂閱主旨爲 %s 的消息.' % (mqtt_server, topic_sub))
    except Exception as e :
        print("MQTT服務器連接失敗-",e)
        return False
    return True

#定时发送
def timing_send(self):
    global red_on_time0,yellow_on_time0,green_on_time0
    global red_on_total_time,yellow_on_total_time,green_on_total_time 
    if red_state:
        red_on_time0 = utime.ticks_diff(utime.ticks_ms(),red_on_current_time)#红灯时间差      
        red_on_total_time = red_on_total_time_temp+red_on_time0#红灯时间累计
    
    if yellow_state:
        yellow_on_time0 = utime.ticks_diff(utime.ticks_ms(),yellow_on_current_time)#黄灯时间差
        yellow_on_total_time = yellow_on_total_time_temp + yellow_on_time0#黄灯时间累计

    if green_state:
        green_on_time0 = utime.ticks_diff(utime.ticks_ms(),green_on_current_time)#绿灯时间差
        green_on_total_time=green_on_total_time_temp+green_on_time0#绿灯时间累计
    
    print('*********************')
    uart1.write('******timing******!\r\n')
    str1=jsondata(red_state,yellow_state,green_state,'none')
    send_data(topic_pub, str1) #发布
#    print(str1.decode('uft-8'))
    uart1.write(b'%s\r\n'% str1)



#状态变化发送
def change_send(lamp_event):
    str1 = jsondata(red_state,yellow_state,green_state,lamp_event)
    send_data(topic_pub, str1)
#    print(str1.decode('uft-8'))
    uart1.write(b'%s\r\n'% str1 )
    
#JSON数据
def jsondata(state1,state2,state3,lamp_event):
    global isopen
    data={
        'mac':'',
        'ip':'0.0.0.0',
        'isopen':True,
        'machine_state':False,
        'sn':'',
        'name':'',
        'type':'',
        'department':'',
        'station':'',
        'VER':'',
        'lamp_event':'none',
        'machine_data':{
            'red':{'state':False,'time':0},
            'yellow':{'state':False,'time':0},
            'green':{'state':False,'time':0}},
        'stamp_time':'2021-06-30 13:35:05'}
    #data0={}
    #data = ujson.loads(ujson.dumps(data))
    data['mac'] = esp32_mac #mac地址
    data['ip'] = esp32_IP   #esp32_IP;//ip地址
    data['isopen'] = isopen #刚开始发为true,后续为false
    data['machine_state'] = machine_state #故障为false
    data['sn'] = sn      #资产编号
    data['name'] = Name  #设备名称
    data['type'] = type  #机台类型
    data['department'] = department  #部门
    data['station'] = station        #坐落位置
    data['VER'] = VERsion            #版本号
    data['lamp_event'] = lamp_event  #灯状态事件
    data['stamp_time'] = ds.DT() #实时时间

    data['machine_data']['red']['state']=state1
    data['machine_data']['red']['time']=int(red_on_total_time/1000)
    data['machine_data']['yellow']['state']=state2
    data['machine_data']['yellow']['time']=int(yellow_on_total_time/1000)
    data['machine_data']['green']['state']=state3
    data['machine_data']['green']['time']=int(green_on_total_time/1000)

    isopen = False
    string=ujson.dumps(data)
    return b'%s'%string
    

#三色灯设备状态和时间获取
red_pin = Pin(36, Pin.IN)     # create input pin on GPIO36
yellow_pin = Pin(35, Pin.IN)  # create input pin on GPIO35
green_pin = Pin(34, Pin.IN)   # create input pin on GPIO34

red_state0    = False; 
yellow_state0 = False;
green_state0  = False;

#开始点量时间戳
red_on_current_time=0
yellow_on_current_time=0
green_on_current_time=0

#单次点亮时间
red_on_time=0
yellow_on_time=0
green_on_time=0

#点亮总累计时间
red_on_total_time=0
yellow_on_total_time=0
green_on_total_time=0

#累计时间变量
red_on_total_time_temp = 0
yellow_on_total_time_temp = 0
green_on_total_time_temp = 0

machine_state_false_time = 0#机台状态

#燈狀態和時間變量
light_state = 0
light_state_temp = 0
#各燈狀態
red_state=False
yellow_state=False
green_state=False
#閃爍間隔,ms
red_flicker_time = 300
yellow_flicker_time = 300
green_flicker_time = 300

#燈狀態轉換表
'''
紅黃綠
0 0 0-全滅0
0 0 1-綠1
0 1 0-黃2
0 1 1-黃綠3
1 0 0-紅4
1 0 1-紅綠5
1 1 0-紅黃6
1 1 1-全亮7
'''
#狀態表
#当前状态,下个状态,执行函数
state_table= [
         1,2,6,#绿->黄(綠灭)
         1,2,3,#绿->黃(黄亮)
         1,4,6,#绿->紅(綠灭)
         1,4,1,#绿->红(红亮)
         2,1,4,#黄->绿(黄滅)
         2,1,5,#黄->绿(綠亮)
         2,4,4,#黃->红(黄灭)
         2,4,1,#黄->紅(红亮)
         4,1,2,#红->绿(红灭)
         4,1,5,#红->绿(绿亮)
         4,2,2,#红->黄(红灭)
         4,2,3,#红->黄(黄亮)
         1,0,6,#绿->全灭(绿灭)
         2,0,4,#黄->全灭(黄灭)
         4,0,2,#红->全灭(红灭)
         0,1,5,#全灭->绿(绿亮)
         0,2,3,#全灭->黄(黄亮)
         0,4,1#全灭->红(红亮)
         ]
#状态表转换        
def state_table_trans(state_table,n):
    state0=[0,0,0]
    for i in range(3*n,3*n+3):        
        state0[i-3*n]=state_table[i]
    return state0
 
curr_state = 0#当前状态
next_state = 0#下个状态
#狀態更新
def state_update(next_state):
    global curr_state
    for i in range(0,18):
        if next_state == state_table_trans(state_table,i)[1]:
            if curr_state == state_table_trans(state_table,i)[0]:
#                print('state_update')
                if next_state is not 0 and curr_state is not 0:
                    state_func(state_table_trans(state_table,i)[2])
                    state_func(state_table_trans(state_table,i+1)[2])
                else:
                    state_func(state_table_trans(state_table,i)[2])
                curr_state = next_state

def state_func(n):
    if n==1:
        redtrue()
    if n==2:
        redfalse()
    if n==3:
        yellowtrue()
    if n==4:
        yellowfalse()
    if n==5:
        greentrue()
    if n==6:
        greenfalse()
  
def redtrue():
    print('redtrue')
    change_send("red")#发送
def redfalse():
    global red_on_total_time_temp,red_on_total_time
    print('redfalse:',red_on_time)
    red_on_total_time = red_on_total_time_temp + red_on_time
    red_on_total_time_temp = red_on_total_time 
    change_send("red")#发送
def yellowtrue():
    print('yellowtrue')
    change_send("yellow")#发送
def yellowfalse():
    global yellow_on_total_time_temp,yellow_on_total_time
    print('yellowfalse:',yellow_on_time)
    yellow_on_total_time = yellow_on_total_time_temp + yellow_on_time
    yellow_on_total_time_temp = yellow_on_total_time
    change_send("yellow")#发送
def greentrue():
    print('greentrue')
    change_send("green")#发送
def greenfalse():
    global green_on_total_time_temp,green_on_total_time
    print('greenfalse:',green_on_time)
    green_on_total_time= green_on_total_time_temp + green_on_time
    green_on_total_time_temp = green_on_total_time
#    print("green_on_total_time_temp:",green_on_total_time_temp)
    change_send("green")#发送
    
def get_state():    
    global red_state0,yellow_state0,green_state0,red_state,yellow_state,green_state
    global red_on_current_time,red_on_time,red_on_total_time,red_on_total_time_temp
    global yellow_on_current_time,yellow_on_time,yellow_on_total_time,yellow_on_total_time_temp
    global green_on_current_time,green_on_time,green_on_total_time,green_on_total_time_temp
    global lamp_event,machine_state_false_time,machine_state,light_state,light_state_temp
    #global red_flicker_time,yellow_flicker_time,green_flicker_time
    global tt,rtt,ytt
    #红灯
    if red_pin.value() ==0:
        if red_pin.value() ==0 and not red_state0:
            red_state0=True
            if red_state==False:
                red_on_current_time = utime.ticks_ms()
                red_state=True
#                print('redtrue')
    else:
        if red_pin.value() ==1 and red_state0:
            red_state0=False
            rtt= utime.ticks_ms()  
            red_on_time = utime.ticks_ms()-red_on_current_time
        else:
            if red_state== True and red_state0== False:
                if utime.ticks_diff(utime.ticks_ms(),rtt) < red_flicker_time: 
                    if green_state==True or yellow_state==True:
                        #print('==========redfalsetime:',red_on_time)
                        red_state=False
                if utime.ticks_diff(utime.ticks_ms(),rtt) > 1000:
                    red_state=False

    #黄灯
    if yellow_pin.value()==0:
        if yellow_pin.value()==0 and not yellow_state0:
            yellow_state0=True
            if yellow_state==False:
                yellow_on_current_time = utime.ticks_ms()
                yellow_state=True
                #print('yellowtrue')
    else:
        if yellow_pin.value() ==1 and yellow_state0:
            yellow_state0 = False
            ytt = utime.ticks_ms()
            yellow_on_time = utime.ticks_ms()-yellow_on_current_time
        else:
            if yellow_state== True and yellow_state0== False:
                if utime.ticks_diff(utime.ticks_ms(),ytt) < yellow_flicker_time: 
                    if red_state==True or green_state==True:
                        #print('==========yellowfalsetime:',yellow_on_time)
                        yellow_state=False
                if utime.ticks_diff(utime.ticks_ms(),ytt) > 1000:
                    yellow_state=False
        
    #绿灯
    if green_pin.value()==0:
        if green_pin.value()==0 and not green_state0:
            green_state0=True
            if green_state==False:
                #print('greentrue')
                green_on_current_time = utime.ticks_ms()
                green_state=True
            #print('grtrue',green_on_current_time)
    else:
        if green_pin.value() ==1 and green_state0:
            green_state0=False
            tt= utime.ticks_ms()
            green_on_time = utime.ticks_ms()-green_on_current_time
            #print("greenfalse",utime.ticks_ms())
        else:
            if green_state == True and green_state0== False: 
                if utime.ticks_diff(utime.ticks_ms(),tt) < green_flicker_time: 
                    if red_state==True or yellow_state==True:
#                        print('==========greenfalsetime:',green_on_time)
                        green_state=False
                if utime.ticks_diff(utime.ticks_ms(),tt) > 1000:
                    green_state=False
                      
    light_state = (green_state|yellow_state<<1|red_state<<2)
    if light_state ==1 or light_state ==2 or light_state ==4 or light_state ==0:
        if light_state!= light_state_temp:
            light_state_temp =light_state
            print('****')
            print(light_state)
            state_update(light_state)
 
    #三个灯状态都为灭且持续10S以上则认为警示棒故障 
    if light_state is not 0:
        machine_state_false_time = utime.ticks_ms()
        machine_state = True
    else:
        if utime.ticks_diff(utime.ticks_ms(),machine_state_false_time)> 3000:
            machine_state_false_time = utime.ticks_ms()
            machine_state = False
            print("//the machine lights is all false ")
        

#Ds1307 64位数据存储            
def Write8byte(addr,data):
    buf = bytearray(8)
    buf[7] = ((data >> 56) & 0xFF) 
    buf[6] = ((data >> 48) & 0xFF) 
    buf[5] = ((data >> 40) & 0xFF) 
    buf[4] = ((data >> 32) & 0xFF) 
    buf[3] = ((data >> 24) & 0xFF) 
    buf[2] = ((data >> 16) & 0xFF) 
    buf[1] = ((data >> 8) & 0xFF)
    buf[0] = (data & 0xFF)     
    ds.set_datamem(addr,buf)
    
#Ds1307 64位数据读取    
def Read8byte(addr):
    buff=ds.get_datamem(addr,addr+8)
    Data=buff[0]+(buff[1]<<8)+(buff[2]<<16)+(buff[3]<<24)+(buff[4]<<32)+(buff[5]<<40)+(buff[6]<<48)+(buff[7]<<56)
    return Data

#Ds1307 字节存储
def Writebyte(addr,byte):
    buf = bytearray(1)
    buf[0]=byte & 0xFF
    ds.set_datamem(addr,buf)

#Ds1307 字节读取    
def Readbyte(addr):
    return ord(ds.get_datamem(addr,1))


#DS1307 内存数据清除
def data_clear():
    for i in range(56):
        Writebyte(i,0)
    machine.reset()
    
#数据保存
def data_save(self):
    Write8byte(0,red_on_total_time)#红灯累计时间保存
    Write8byte(8,yellow_on_total_time)#黄灯累计时间保存
    Write8byte(16,green_on_total_time)#绿灯累计时间保存
    
#重启时数据恢复
def data_read():
#    global red_state0,yellow_state0,green_state0
    global red_on_total_time,red_on_total_time_temp,red_on_current_time
    global yellow_on_total_time,yellow_on_total_time_temp,yellow_on_current_time
    global green_on_total_time,green_on_total_time_temp,green_on_current_time
    
    red_on_total_time = Read8byte(0)
    red_on_total_time_temp = red_on_total_time
    yellow_on_total_time = Read8byte(8)
    yellow_on_total_time_temp = yellow_on_total_time
    green_on_total_time = Read8byte(16)
    green_on_total_time_temp = green_on_total_time   
    
    print(red_on_total_time)
    print(yellow_on_total_time)
    print(green_on_total_time)
    
#恢复数据
data_read()

#mqtt订阅消息处理
def sub_cb_deal(string):
    try:
        data = ujson.loads(string)
        if isinstance(data,dict):
          if 'cmd' in data.keys():
            cmd = data['cmd']
            print(cmd)
            #重启
            if cmd == 'restart':
                send_data(topic_pub_res, Res_data(b'reset'))
                uart1.write(b'reset\r\n' )
                utime.sleep(2)
                machine.reset()
            #清空数据
            elif cmd == 'clear':
                send_data(topic_pub_res, Res_data(b'clear'))
                uart1.write(b'clear\r\n' )
                data_clear()
                
            #设备信息配置
            elif cmd == 'update_machine':
                global sn,Name,type,department,station
                sn = data['mes']['sn']
                Name = data['mes']['name']
                type = data['mes']['type']
                department = data['mes']['department']
                station = data['mes']['station']
                #写入配置文件
                file = open ('fig.txt', 'w')
                string = ujson.dumps(data)
                file.write(string)
                file.close()
                print("update_machine")
                uart1.write(b'update_machine\r\n')
                send_data(topic_pub_res, Res_data(b'update_machine'))
            #NTP网络对时
            elif cmd == 'settime':
                global ntp_server
                if 'ntp_server' in data.keys():
                    ntp_server = data['ntp_server']
                if not sync_ntp():
                    send_data(topic_pub_res, Res_data('ntp_server: '+ntp_server+' timeout'))
                else:     
                    uart1.write(b'settime\r\n' )
                    send_data(topic_pub_res, Res_data(b'ntp successed'))
            #反馈IP地址
            elif cmd == 'IP':
                print(esp32_IP)
                uart1.write(b'IP\r\n' )
                send_data(topic_pub_res,Res_data(esp32_IP))
            #反馈DS1307时间
            elif cmd == 'time':
                print(ds.datetime())#读取NTP时间
                send_data(topic_pub_res,Res_data(ds.DT()))
            #反馈wifi信号强度
            elif cmd == 'dbm':
                aplist=wlan.scan()
                for one in aplist:
                    if one[0] == b'%s'%ssid:
                        print(one[0],one[2],one[3])
                        db=b' %s'%one[0]+b' %s'%one[2]+b' %s'%one[3]
                        send_data(topic_pub_res,Res_data(db))    
    except ValueError as e:
        print('不是JSON格式')

#MQTT命令反馈信息
def Res_data(mes):
    Res = {'Res':''}
    Res['Res']= mes
    ss = ujson.dumps(Res)
    return b'%s' % ss
   
#ntp时间同步
def sync_ntp():
    for i in range(5):
        try:
            untp.NTP_DELTA = 3155644800  #3155673600 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
            untp.host = ntp_server  # 可选,ntp服务器,默认是"pool.ntp.org"
            print('ntptime:',end='')
            untp.settime()  #RTC时间同步
            ds.datetime(rtc.datetime()) #DS1307时钟设置
            print(untp.DT())
            return True
        except Exception as e : #访问异常的错误编号和详细信息
            print("Exception:",e)
            utime.sleep(2)
    print('時間服務器'+ ntp_server +'超時')
    return False   

def sync_ntp_timer(self):
    for i in range(5):
        try:
            untp.NTP_DELTA = 3155644800  #3155673600 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
            untp.host = ntp_server  # 可选,ntp服务器,默认是"pool.ntp.org"
            print('ntptime:',end='')
            if abs(untp.time()-ds.time()) > 5:  #ds1307时间误差大于5s
                print('时间误差大')
                untp.settime()  #RTC时间同步
                ds.datetime(rtc.datetime()) #DS1307时钟设置
                print('自动对时完成')
                return True
            else:
                print('时间误差小')
                return True
        except Exception as e : #访问异常的错误编号和详细信息
            print("Exception:",e)
            utime.sleep(1)
    print('時間服務器'+ ntp_server +'超時')
    return False  

mqtt_online = False #MQTT已連接标志
thread_start = False#线程开始标志
#无线网络和MQTT连接线程
def connect_thread(id = 0,interval = 2):
    global mqtt_online,wlan
    global thread_start,reset_count
    thread_start = True
    print('connect_thread start')
    try:
        wlan = my_connect(interval)
    except Exception as e : #访问异常的错误编号和详细信息
        print("wlan error Exception:",e)
        machine.reset()
    if  wlan.isconnected() is True: 
        print('MQTT连接中...')
        client1_status = connect_and_subscribe()
        print("MQTT連接結果:",client1_status)
        if client1_status is True:
            mqtt_online = True
            reset_count = 0
    thread_start = False
    _thread.exit()
    
#MQTT在线才发布数据
def send_data(topic,json_data):
    if mqtt_online is True:
        try:
            if client1.get_status() is True: 
                client1.publish(topic,json_data)
                print('MQTT发布成功',json_data)
            else:
                print("MQTT发布失败")
        except Exception as e:
            print("MQTT发布失败-",e)
    else:
        print('MQTT offline')
    
#發送MQTT消息定時中斷 5秒
tim1 = machine.Timer(1)
tim1.init(period=message_time, mode=machine.Timer.PERIODIC, callback=timing_send)
#数据保存定时中断 1S
tim0 = machine.Timer(0)
tim0.init(period=1000, mode=machine.Timer.PERIODIC, callback=data_save)
#ntp自动对时定時中斷 1小时
tim2 = machine.Timer(2)
tim2.init(period=3600000, mode=machine.Timer.PERIODIC, callback=sync_ntp_timer)


# thread測試,無法創建新thread則看門狗重啟
def thread_check(id = 0,interval = 2):
    global feed_flag
    feed_flag = True
#     print("thread check")
    _thread.exit()
    
reset_count = 0 #一定次数未连接则重启
st = utime.ticks_ms()
while True:
    try:
       #check_msg確定當前MQTT連線狀態
       if mqtt_online is True:
           client1.check_msg()
       #检测MQTT是否在线
       if  utime.ticks_diff(utime.ticks_ms(),st) > 10000 :
           st = utime.ticks_ms()
           #thread異常檢測
           _thread.start_new_thread(thread_check,(1,2))
           try:
               getstatus = client1.get_status()
           except Exception as e : #访问异常的错误编号和详细信息
               print('MQTT状态错误:',e)
               getstatus = False #避免第一次未創建client時client1.get_status()語句出錯
           print("get_status:",getstatus)
           if getstatus is not True:
                mqtt_online = False
                #上個連接線程結束才新建線程
                if not thread_start:
                    reset_count += 1
                    #超过10次仍未连上则重启
                    if reset_count > 10:
                        machine.reset()
                    print('MQTT断开,重新连接---')
                    _thread.start_new_thread(connect_thread,(utime.time(),20))#创建线程
                else:
                    print("connect_thread......")
           else:
                client1.set_status()
                client1.ping()
    except Exception as e : #访问异常的错误编号和详细信息
        print("MQTT連接線程異常:",e)
        machine.reset()
    #线程异常则看门狗重启
    if feed_flag is True:
        wdt.feed()  #喂狗
        print("feed")
        feed_flag = False
    get_state() #状态获取


ds1307.py

"""
MicroPython TinyRTC I2C Module, DS1307 RTC + AT24C32N EEPROM
https://en.wikipedia.org/wiki/Binary-coded_decimal
"""

from micropython import const

DATETIME_REG = const(0) # 0x00-0x06
CHIP_HALT    = const(128)
CONTROL_REG  = const(7) # 0x07
RAM_REG      = const(8) # 0x08-0x3F

class DS1307(object):
    """Driver for the DS1307 RTC."""
    def __init__(self, i2c, addr=0x68):
        self.i2c = i2c
        self.addr = addr
        self.weekday_start = 1
        self._halt = False

    def _dec2bcd(self, value):
        """Convert decimal to binary coded decimal (BCD) format"""
        return (value // 10) << 4 | (value % 10)

    def _bcd2dec(self, value):
        """Convert binary coded decimal (BCD) format to decimal"""
        return ((value >> 4) * 10) + (value & 0x0F)

    def datamem(self, datetime=None):
        if datetime is None:
            return self.i2c.readfrom_mem(self.addr, RAM_REG, 56)
        self.i2c.writeto_mem(self.addr, RAM_REG, datetime)
    def set_datamem(self, addr=0, datetime = None):
        if datetime is None:
            self.i2c.writeto_mem(self.addr, RAM_REG + addr, bytes(56-addr))
            return 56-addr
        else:
            self.i2c.writeto_mem(self.addr, RAM_REG + addr, datetime)
            return len(datetime)
    def get_datamem(self, addr=0, count=56):
            return self.i2c.readfrom_mem(self.addr, RAM_REG + addr, count)
    def datetime(self, datetime=None):
        """Get or set datetime"""
        if datetime is None:
            buf = self.i2c.readfrom_mem(self.addr, DATETIME_REG, 7)
            return (
                self._bcd2dec(buf[6]) + 2000, # year
                self._bcd2dec(buf[5]), # month
                self._bcd2dec(buf[4]), # day
                self._bcd2dec(buf[3] - self.weekday_start), # weekday
                self._bcd2dec(buf[2]), # hour
                self._bcd2dec(buf[1]), # minute
                self._bcd2dec(buf[0] & 0x7F), # second
                0 # subseconds
            )
        buf = bytearray(7)
        buf[0] = self._dec2bcd(datetime[6]) & 0x7F # second, msb = CH, 1=halt, 0=go
        buf[1] = self._dec2bcd(datetime[5]) # minute
        buf[2] = self._dec2bcd(datetime[4]) # hour
        buf[3] = self._dec2bcd(datetime[3] + self.weekday_start) # weekday
        buf[4] = self._dec2bcd(datetime[2]) # day
        buf[5] = self._dec2bcd(datetime[1]) # month
        buf[6] = self._dec2bcd(datetime[0] - 2000) # year
        if (self._halt):
            buf[0] |= (1 << 7)
        self.i2c.writeto_mem(self.addr, DATETIME_REG, buf)

    def halt(self, val=None):
        """Power up, power down or check status"""
        if val is None:
            return self._halt
        reg = self.i2c.readfrom_mem(self.addr, DATETIME_REG, 1)[0]
        if val:
            reg |= CHIP_HALT
        else:
            reg &= ~CHIP_HALT
        self._halt = bool(val)
        self.i2c.writeto_mem(self.addr, DATETIME_REG, bytearray([reg]))
    def DT(self):
        buf = self.datetime()
        return '%4d'%buf[0] + '-%02d'%buf[1]+'-%02d'%buf[2]+' %02d'%buf[4]+':%02d'%buf[5]+':%02d'%buf[6]
    def time(self):
        import utime
        tm = self.datetime()
        return utime.mktime((tm[0], tm[1], tm[2],tm[4], tm[5], tm[6], tm[3]-1,0))
    def square_wave(self, sqw=0, out=0):
        """Output square wave on pin SQ at 1Hz, 4.096kHz, 8.192kHz or 32.768kHz,
        or disable the oscillator and output logic level high/low."""
        rs0 = 1 if sqw == 4 or sqw == 32 else 0
        rs1 = 1 if sqw == 8 or sqw == 32 else 0
        out = 1 if out > 0 else 0
        sqw = 1 if sqw > 0 else 0
        reg = rs0 | rs1 << 1 | sqw << 4 | out << 7
        self.i2c.writeto_mem(self.addr, CONTROL_REG, bytearray([reg]))


uftp.py

# this code is from uftpserver (https://github.com/cpopp/MicroFTPServer/tree/master/uftp).
# there's no license so I used MIT and then...
# packed it into a class, added missing FTP commands, and added the threading
import socket
import network
import os
import _thread
import gc

DATA_PORT = 13333

class FtpTiny:
    '''This class creates a very tiny FTP server in a thread
        x = ftptiny.FtpTiny()
        x.start()
        x.stop()'''
    def __init__(self) :
        self.dorun = True
        self.isrunning = False
        self.cwd = os.getcwd()
        self.ftpsocket = None
        self.datasocket = None
        self.dataclient = None

    def start_listen(self) :
        # the two sockets are the persistant and the pasv sockets
        # so this requires pasv
        self.ftpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.datasocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.ftpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.datasocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.ftpsocket.bind(socket.getaddrinfo("0.0.0.0", 21)[0][4])
        self.datasocket.bind(socket.getaddrinfo("0.0.0.0", DATA_PORT)[0][4])
        self.ftpsocket.listen(1)
        self.datasocket.listen(1)
        self.datasocket.settimeout(10)
        self.lastpayload = ''

    def send_list_data(self, client):
        for file in os.listdir(self.cwd):
            stat = os.stat(self.get_absolute_path(file))
            file_permissions = "drwxr-xr-x" if (stat[0] & 0o170000 == 0o040000) else "-rw-r--r--"
            file_size = stat[6]
            description = "{}    1 owner group {:>13} Jan 1  1980 {}".format(file_permissions, file_size, file)
            self.sendcmdline(client, description)

    def send_file_data(self, path, client):
        with open(path) as file:
            chunk = file.read(128)
            while len(chunk) > 0:
                client.sendall(chunk)
                if len(chunk) == 128:
                    chunk = file.read(128)
                else:
                    chunk = []

    def save_file_data(self, path, client):
        client.settimeout(.5)
        with open(path, "w") as file:
            try:
                chunk = client.recv(128)
                while chunk and len(chunk) > 0:
                    file.write(chunk)
                    if len(chunk) == 128 :
                        chunk = client.recv(128)
                    else :
                        chunk = None # done?
            except Exception as ex:
                pass

    def get_absolute_path(self, payload):
        # if it doesn't start with / consider
        # it a relative path
        rslt = payload
        if not payload.startswith("/"):
            if len(self.cwd) > 1 :
                rslt = self.cwd + "/" + payload
            else :
                rslt = self.cwd + payload
        # and don't leave any trailing /
        if len(rslt) > 1 :
            return rslt.rstrip("/")
        return rslt

    def stop(self):
        self.dorun = False
        self.thread = 0

    def start(self):
        if not self.isrunning :
            self.dorun = True
            tid = _thread.start_new_thread(runserver, (self, ))
            self.thread = tid
        else :
            print("An instance is already running.")

    def sendcmdline(self, cl, txt) :
        cl.sendall(txt)
        cl.sendall("\r\n")

    def closeclient(self) :
        if self.dataclient :
            self.dataclient.close()
            self.dataclient = None

    def client(self, cl) :
        return self.dataclient if self.dataclient else cl

    def _handle_command(self, cl, command, payload) :
        if command == "USER":
            print('usr = '+ payload)
            self.sendcmdline(cl, "230 Logged in.")
            #530 user or pwd error
        elif command == "SYST":
            self.sendcmdline(cl, "215 ESP32 MicroPython")
        elif command == "SYST":
            self.sendcmdline(cl, "502")
        elif command == "PWD":
            self.sendcmdline(cl, '257 "{}"'.format(self.cwd))
        elif command == "CWD":
            path = self.get_absolute_path(payload)
            try:
                os.chdir(path)
                self.sendcmdline(cl, '250 Directory changed successfully')
            except:
                self.sendcmdline(cl, '550 Failed to change directory')
            finally:
                self.cwd = os.getcwd()
        elif command == "EPSV":
            self.sendcmdline(cl, '502')
        elif command == "TYPE":
            # probably should switch between binary and not
            self.sendcmdline(cl, '200 Transfer mode set')
        elif command == "SIZE":
            path = self.get_absolute_path(payload)
            try:
                size = os.stat(path)[6]
                self.sendcmdline(cl, '213 {}'.format(size))
            except:
                self.sendcmdline(cl, '550 Could not get file size')
        elif command == "QUIT":
            self.sendcmdline(cl, '221 Bye.')
        elif command == "PASV":
            addr = network.WLAN().ifconfig()[0]
            self.sendcmdline(cl, '227 Entering Passive Mode ({},{},{}).'.format(addr.replace('.',','), DATA_PORT>>8, DATA_PORT%256))
            self.dataclient, data_addr = self.datasocket.accept()
            print("FTP Data connection from:", data_addr)
        elif command == "LIST":
            try:
                # list folder contents
                self.send_list_data(self.client(cl))
                self.closeclient()
                self.sendcmdline(cl, "150 Here comes the directory listing.")
                self.sendcmdline(cl, "226 Listed.")
            except:
                self.sendcmdline(cl, '550 Failed to list directory')
            finally:
                self.closeclient()
        elif command == "RETR":
            try:
                # send a file to the client
                self.send_file_data(self.get_absolute_path(payload), self.client(cl))
                self.closeclient()
                self.sendcmdline(cl, "150 Opening data connection.")
                self.sendcmdline(cl, "226 Transfer complete.")
            except:
                self.sendcmdline(cl, '550 Failed to send file')
            self.closeclient()
        elif command == "STOR":
            try:
                # receive a file and save to disk
                self.sendcmdline(cl, "150 Ok to send data.")
                self.save_file_data(self.get_absolute_path(payload), self.client(cl))
                self.closeclient()
                print("Finished receiving file")
                self.sendcmdline(cl, "226 Transfer complete.")
            except Exception as ex:
                print("Failed to receive file: " + str(ex))
                self.sendcmdline(cl, '550 Failed to send file')
            finally:
                print("Finally closing dataclient")
                self.closeclient()
        elif command == "DELE":
            try:
                # delete a file
                path = self.get_absolute_path(payload)
                os.remove(path)
                print("Deleted file: " + path)
                self.sendcmdline(cl, "250 File deleted ok.")
            except Exception as ex:
                print("Failed to delete file: " + str(ex))
                self.sendcmdline(cl, '550 Failed to delete file.')
            finally:
                self.closeclient()
        elif command == "MKD":
            try:
                # create a folder
                path = self.get_absolute_path(payload)
                os.mkdir(path)
                print("Create folder: " + path)
                self.sendcmdline(cl, "257 Path created ok.")
            except Exception as ex:
                print("Failed to create folder: " + str(ex))
                self.sendcmdline(cl, '550 Failed to create folder.')
            finally:
                self.closeclient()
        elif command == "RMD":
            try:
                # delete a folder
                path = self.get_absolute_path(payload)
                os.rmdir(path)
                print("Deleted folder: " + path)
                self.sendcmdline(cl, "250 Folder deleted ok.")
            except Exception as ex:
                print("Failed to delete folder: " + str(ex))
                self.sendcmdline(cl, '550 Failed to delete file.')
            finally:
                self.closeclient()
        elif command == "CDUP":
            try:
                # change to parent folder
                if self.cwd and len(self.cwd) > 1 :
                    paths = self.cwd.split('/')
                    xpat = '/' + '/'.join(paths[:-1])
                else :
                    xpat = '/'
                os.chdir(xpat)
                self.cwd = xpat
                print("Go to parent: " + xpat)
                self.sendcmdline(cl, "250 Went to parent folder.")
            except Exception as ex:
                print("Failed to delete folder: " + str(ex))
                self.sendcmdline(cl, '550 Failed to go to parent.')
            finally:
                self.closeclient()
        elif command == "RNFR":
                # rename file start...
                self.lastpayload = payload
                self.sendcmdline(cl, "226 Starting rename.")
        elif command == "RNTO":
            if self.lastpayload :
                try:
                    # rename file end...
                    os.rename(self.lastpayload, payload)
                    self.sendcmdline(cl, "250 Renamed file.")
                except Exception as ex:
                    print("Failed to rename file: " + str(ex))
                    self.sendcmdline(cl, '550 Failed to rename file.')
                finally:
                    self.closeclient()
                    self.lastpayload = None
        else:
            self.sendcmdline(cl, "502 Unsupported command.")
            print("Unsupported command {} with payload {}".format(command, payload))

    # called by the threader
    def dolisten(self):
        self.isrunning = True
        try:
            self.start_listen()
            while self.dorun:
                cl, remote_addr = self.ftpsocket.accept()
                cl.settimeout(300)
                try:
                    print("FTP connection from:", remote_addr)
                    self.sendcmdline(cl, "220 Hello. Welcome to FtpTiny.")
                    # --- here's the command loop
                    # since it's waiting at readline this doesn't end after stop() unless you
                    # send a command
                    while self.dorun:
                        data = cl.readline().decode("utf-8").replace("\r\n", "")
                        if len(data) <= 0:
                            print("Client is gone")
                            break
                        print(data)
                        command, payload = (data.split(" ") + [""])[:2]
                        command = command.upper()

                        print("Command={}, Payload={}".format(command, payload))
                        self._handle_command(cl, command, payload)
                        # we use up memory here, so deal with it
                        gc.collect()
                    # --- end of command loop
                except Exception as ex :
                    print(str(ex))
                finally:
                    print("Closing dataclient socket")
                    cl.close()
        except Exception as ex :
            print("TinyFtp error: "  + str(ex))
        finally:
            self.isrunning = False
            self.closeclient()
            self.datasocket.close()
            self.ftpsocket.close()
            # we use up memory here, so deal with it
            gc.collect()

# our thread calls this which then listens
def runserver(myself):
    myself.dolisten()

umqtt.py

import usocket as socket
import ustruct as struct
from ubinascii import hexlify

class MQTTException(Exception):
    pass

class MQTTClient:

    def __init__(self, client_id, server, port=0, user=None, password=None, keepalive=0,
                 ssl=False, ssl_params={}):
        if port == 0:
            port = 8883 if ssl else 1883
        self.client_id = client_id
        self.sock = None
        self.server = server
        self.port = port
        self.ssl = ssl
        self.ssl_params = ssl_params
        self.pid = 0
        self.cb = None
        self.user = user
        self.pswd = password
        self.keepalive = keepalive
        self.lw_topic = None
        self.lw_msg = None
        self.lw_qos = 0
        self.lw_retain = False
        self.online = True

    def _send_str(self, s):
        self.sock.write(struct.pack("!H", len(s)))
        self.sock.write(s)

    def _recv_len(self):
        n = 0
        sh = 0
        while 1:
            b = self.sock.read(1)[0]
            n |= (b & 0x7f) << sh
            if not b & 0x80:
                return n
            sh += 7

    def set_callback(self, f):
        self.cb = f

    def set_last_will(self, topic, msg, retain=False, qos=0):
        assert 0 <= qos <= 2
        assert topic
        self.lw_topic = topic
        self.lw_msg = msg
        self.lw_qos = qos
        self.lw_retain = retain

    def connect(self, clean_session=True):
        self.sock = socket.socket()
        addr = socket.getaddrinfo(self.server, self.port)[0][-1]
        self.sock.connect(addr)
        if self.ssl:
            import ussl
            self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
        premsg = bytearray(b"\x10\0\0\0\0\0")
        msg = bytearray(b"\x04MQTT\x04\x02\0\0")

        sz = 10 + 2 + len(self.client_id)
        msg[6] = clean_session << 1
        if self.user is not None:
            sz += 2 + len(self.user) + 2 + len(self.pswd)
            msg[6] |= 0xC0
        if self.keepalive:
            assert self.keepalive < 65536
            msg[7] |= self.keepalive >> 8
            msg[8] |= self.keepalive & 0x00FF
        if self.lw_topic:
            sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)
            msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
            msg[6] |= self.lw_retain << 5

        i = 1
        while sz > 0x7f:
            premsg[i] = (sz & 0x7f) | 0x80
            sz >>= 7
            i += 1
        premsg[i] = sz

        self.sock.write(premsg, i + 2)
        self.sock.write(msg)
        #print(hex(len(msg)), hexlify(msg, ":"))
        self._send_str(self.client_id)
        if self.lw_topic:
            self._send_str(self.lw_topic)
            self._send_str(self.lw_msg)
        if self.user is not None:
            self._send_str(self.user)
            self._send_str(self.pswd)
        resp = self.sock.read(4)
        assert resp[0] == 0x20 and resp[1] == 0x02
        if resp[3] != 0:
            raise MQTTException(resp[3])
        return resp[2] & 1

    def disconnect(self):
        self.sock.write(b"\xe0\0")
        self.sock.close()

    def ping(self):
        self.sock.write(b"\xc0\0")

    def publish(self, topic, msg, retain=False, qos=0):
        pkt = bytearray(b"\x30\0\0\0")
        pkt[0] |= qos << 1 | retain
        sz = 2 + len(topic) + len(msg)
        if qos > 0:
            sz += 2
        assert sz < 2097152
        i = 1
        while sz > 0x7f:
            pkt[i] = (sz & 0x7f) | 0x80
            sz >>= 7
            i += 1
        pkt[i] = sz
        #print(hex(len(pkt)), hexlify(pkt, ":"))
        self.sock.write(pkt, i + 1)
        self._send_str(topic)
        if qos > 0:
            self.pid += 1
            pid = self.pid
            struct.pack_into("!H", pkt, 0, pid)
            self.sock.write(pkt, 2)
        self.sock.write(msg)
        if qos == 1:
            while 1:
                op = self.wait_msg()
                if op == 0x40:
                    sz = self.sock.read(1)
                    assert sz == b"\x02"
                    rcv_pid = self.sock.read(2)
                    rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]
                    if pid == rcv_pid:
                        return
        elif qos == 2:
            assert 0

    def subscribe(self, topic, qos=0):
        assert self.cb is not None, "Subscribe callback is not set"
        pkt = bytearray(b"\x82\0\0\0")
        self.pid += 1
        struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid)
        #print(hex(len(pkt)), hexlify(pkt, ":"))
        self.sock.write(pkt)
        self._send_str(topic)
        self.sock.write(qos.to_bytes(1, "little"))
        while 1:
            op = self.wait_msg()
            if op == 0x90:
                resp = self.sock.read(4)
                #print(resp)
                assert resp[1] == pkt[2] and resp[2] == pkt[3]
                if resp[3] == 0x80:
                    raise MQTTException(resp[3])
                return
    def set_status(self):
        self.online = False
    def get_status(self):
        return self.online
    # Wait for a single incoming MQTT message and process it.
    # Subscribed messages are delivered to a callback previously
    # set by .set_callback() method. Other (internal) MQTT
    # messages processed internally.
    def wait_msg(self):
        res = self.sock.read(1)
        self.sock.setblocking(True)
        if res is None:
            return None
        if res == b"":
            print('OSError -1')
            #return None
            raise OSError(-1)
        if res == b"\xd0":  # PINGRESP
            self.online = True
            sz = self.sock.read(1)[0]
            assert sz == 0
            return None
        op = res[0]
        if op & 0xf0 != 0x30:
            return op
        sz = self._recv_len()
        topic_len = self.sock.read(2)
        topic_len = (topic_len[0] << 8) | topic_len[1]
        topic = self.sock.read(topic_len)
        sz -= topic_len + 2
        if op & 6:
            pid = self.sock.read(2)
            pid = pid[0] << 8 | pid[1]
            sz -= 2
        msg = self.sock.read(sz)
        self.cb(topic, msg)
        if op & 6 == 2:
            pkt = bytearray(b"\x40\x02\0\0")
            struct.pack_into("!H", pkt, 2, pid)
            self.sock.write(pkt)
        elif op & 6 == 4:
            assert 0

    # Checks whether a pending message from server is available.
    # If not, returns immediately with None. Otherwise, does
    # the same processing as wait_msg.
    def check_msg(self):
        self.sock.setblocking(False)
        return self.wait_msg()

untp.py

try:
    import usocket as socket
except:
    import socket
try:
    import ustruct as struct
except:
    import struct

# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600

# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org'
host = "pool.ntp.org"


def time():
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48)
    finally:
        s.close()
    val = struct.unpack("!I", msg[40:44])[0]
    return val - NTP_DELTA


# There's currently no timezone support in MicroPython, so
# utime.localtime() will return UTC time (as if it was .gmtime())
def settime():
    t = time()
    import machine
    import utime

    tm = utime.localtime(t)
    machine.RTC().datetime((tm[0], tm[1], tm[2],tm[6]+1, tm[3], tm[4], tm[5],0))
    
     
def datetime():
    t = time()
    import utime
    
    tm = utime.localtime(t)
    return tm
    
def DT():
    buf = datetime()
    return '%4d'%buf[0] + '-%02d'%buf[1]+'-%02d'%buf[2]+' %02d'%buf[3]+':%02d'%buf[4]+':%02d'%buf[5] 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值