|
|
@@ -0,0 +1,311 @@
|
|
|
+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
|