from time import sleep import ujson from machine import Pin,reset import time import network from config import getConfig,saveConfig from umqtt.simple import MQTTClient import _thread from dispatcher import Dispatcher import urequests import os import device led = Pin(8, Pin.OUT) led.value(1) tasks = Dispatcher() def changeLed(): """ 改变led :param t: :return: """ if led.value() == 1: led.value(0) else: led.value(1) def onFlickerLed(period): """ 闪烁led :param period: 周期 毫秒 :return: """ offFlickerLed() tasks.add_work(changeLed, period) def offFlickerLed(): """ 关闭闪烁 :return: """ tasks.del_work(changeLed) def onLed(): offFlickerLed() led.value(0) def offLed(): offFlickerLed() led.value(1) def getLed(): return led.value() ap = None # 开启热点 def openAp(): global ap if not getConfig().openAp: ssid = getConfig().ap.ssid + '-' + getConfig().model + '-' + getConfig().id ap = network.WLAN(network.AP_IF) # 创捷一个AP热点接口 ap.ifconfig(('192.168.5.1', '255.255.255.0', '192.168.5.1', '114.114.114.114')) ap.active(True) # 激活接口 ap.config(essid=ssid, authmode=network.AUTH_WPA_WPA2_PSK, password=getConfig().ap.pwd) # 设置AP的ESSID名称 getConfig().openAp = True print('热点已开启', ssid, getConfig().ap.pwd) def closeAp(): if getConfig().openAp: ap.active(False) getConfig().openAp = False print('关闭热点') # 创建 WIFI 连接对象 wlan = network.WLAN(network.STA_IF) wlan.active(False)#先进行wlan的清除 wlan.active(True)#再激活 def scanWifi(): """扫描WiFi""" wifis = wlan.scan() print("扫描WiFi结果:", wifis) return wifis def getStatus(): """获取WiFi连接状态""" return wlan.isconnected() def getWifiConnectInfo(): """获取已连接的WiFi信息""" return wlan.ifconfig() def disconnectWifi(): """断开当前连接的无线网络""" wlan.disconnect() def connectWifi(ssid, pwd): """ 连接wifi :param ssid: :param pwd: :return: """ print("开始连接", ssid, pwd) onFlickerLed(200) wlan.disconnect() getConfig().connectWifi.ssid = None getConfig().connectWifi.pwd = None wlan.connect(ssid, pwd) timeout = 0 while not wlan.isconnected() and timeout < 10: timeout += 1 time.sleep(1) offFlickerLed() if wlan.isconnected(): print('WiFi已连接', wlan.ifconfig()) getConfig().connectWifi.ssid = ssid getConfig().connectWifi.ip = wlan.ifconfig()[0] return True print('连接'+ssid+' 失败!') return False def autoConnectWifi(): """ 连接附近WiFi :return: """ for item in scanWifi(): try: ssid = str(item[0].decode('utf-8')) if ssid in getConfig().wifi: pwd = getConfig().wifi[ssid] print('连接WiFi:', ssid, pwd) if connectWifi(ssid, pwd): return True except: pass print('连接附近WiFi失败') return False client = None def send_ping(): try: client.ping() except Exception as e: print(e) getConfig().mqttStatus = False def connectMQTT(keepalive): """ 连接MQTT :return: """ global client onFlickerLed(1000) try: client.disconnect() except Exception as e: pass try: client = None except: pass topic = getConfig().id client = MQTTClient(getConfig().id, getConfig().mqtt.host, getConfig().mqtt.port, 'esp', 'Mqtt.158747928', keepalive=keepalive) client.set_callback(mqCallback) try: print('连接mqtt中......') client.connect() print('mqtt连接成功') client.subscribe(topic, 1) sleep(1) onLed() except Exception as e: print('MQTT连接失败:', getConfig().id, getConfig().mqtt.host, getConfig().mqtt.port, topic) print(e) return False getConfig().mqtt.subTopic = topic getConfig().mqttStatus = True # 启动定时任务定时ping # tasks.add_work(send_ping, 30000) # 启动多线程检查待处理消息 _thread.start_new_thread(checkMsg, ()) # 上报状态 reportConfig() print("已连接到MQTT:", topic) return True def checkMsg(): """ 检查服务器是否有待处理的消息 :return: """ while getConfig().mqttStatus: try: client.check_msg() except Exception as e: print(e) print('MQTT断开') getConfig().mqttStatus = False break heartbeat = 1 def mqCallback(topic, msg): print(topic, msg) msg = msg.decode('utf-8').split("@") com = msg[0] logId = msg[1] if len(msg) > 1 else None # 执行命令 if not sysCom(com): device.command(com) # 执行完命令上报状态 reportLog(logId) def sysCom(com): """ 判断是不是系统命令,如果不是就调用模块去执行 """ if com == 'updateSystem': checkUpdate() return True elif com == 'heartbeat': return True return False def sendMqtt(msg): """ 发送mqtt消息 :param msg: :return: """ client.publish(getConfig().mqtt.sendTopic, msg, False) def reportHeartbeat(): sendMqtt('heartbeat') def reportConfig(): data = getConfig().toJson() data['report'] = 'reportConfig' sendMqtt(ujson.dumps(data)) print('reportConfig') def reportLog(logId): """ 上报状态 """ data = {'device': device.status()} data['logId'] = logId data['report'] = 'reportLog' sendMqtt(ujson.dumps(data)) print('reportLog') # 读取文件内容 def openFile(path): file=open(path, 'r') text = file.read() file.close() return text # 写文件 def writeFile(path, content): # 判断是否在文件夹下 index = path.rfind('/') if index != -1: try: os.mkdir(path[:index]) except OSError as e: pass file=open(path, 'w') text = file.write(content) file.close() return True def checkUpdate(): """ 检查系统更新 """ try: version = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/version.json").text print(version) if version is not None and version != '': v = ujson.loads(version) isSave = False if v["system"] > getConfig().version.system: if updateSystem(str(v["system"]), 'system'): getConfig().version.system = v["system"] isSave = True if v[getConfig().model] > getConfig().version.model: if updateSystem(str(v[getConfig().model]), getConfig().model): getConfig().version.model = v[getConfig().model] isSave = True if isSave: saveConfig() reset() except Exception as e: print(e) def updateSystem(version, name): print('更新', name, version) try: # 获取要更新的文件列表 files = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/"+name+"/v"+version+"/fileList.json").text files = ujson.loads(files) for file in files: print(file) text = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/" + name + "/v" + version + "/"+file).text writeFile(file, text) return True except Exception as e: print(e) return False