utils.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. from time import sleep
  2. import ujson
  3. from machine import Pin,reset
  4. import time
  5. import network
  6. from config import getConfig,saveConfig
  7. from umqtt.simple import MQTTClient
  8. import _thread
  9. from dispatcher import Dispatcher
  10. import urequests
  11. import os
  12. import device
  13. led = Pin(8, Pin.OUT)
  14. led.value(1)
  15. tasks = Dispatcher()
  16. def changeLed():
  17. """
  18. 改变led
  19. :param t:
  20. :return:
  21. """
  22. if led.value() == 1:
  23. led.value(0)
  24. else:
  25. led.value(1)
  26. def onFlickerLed(period):
  27. """
  28. 闪烁led
  29. :param period: 周期 毫秒
  30. :return:
  31. """
  32. offFlickerLed()
  33. tasks.add_work(changeLed, period)
  34. def offFlickerLed():
  35. """
  36. 关闭闪烁
  37. :return:
  38. """
  39. tasks.del_work(changeLed)
  40. def onLed():
  41. offFlickerLed()
  42. led.value(0)
  43. def offLed():
  44. offFlickerLed()
  45. led.value(1)
  46. def getLed():
  47. return led.value()
  48. ap = None
  49. # 开启热点
  50. def openAp():
  51. global ap
  52. if not getConfig().openAp:
  53. ssid = getConfig().ap.ssid + '-' + getConfig().model + '-' + getConfig().id
  54. ap = network.WLAN(network.AP_IF) # 创捷一个AP热点接口
  55. ap.ifconfig(('192.168.5.1', '255.255.255.0', '192.168.5.1', '114.114.114.114'))
  56. ap.active(True) # 激活接口
  57. ap.config(essid=ssid, authmode=network.AUTH_WPA_WPA2_PSK, password=getConfig().ap.pwd) # 设置AP的ESSID名称
  58. getConfig().openAp = True
  59. print('热点已开启', ssid, getConfig().ap.pwd)
  60. def closeAp():
  61. if getConfig().openAp:
  62. ap.active(False)
  63. getConfig().openAp = False
  64. print('关闭热点')
  65. # 创建 WIFI 连接对象
  66. wlan = network.WLAN(network.STA_IF)
  67. wlan.active(False)#先进行wlan的清除
  68. wlan.active(True)#再激活
  69. def scanWifi():
  70. """扫描WiFi"""
  71. wifis = wlan.scan()
  72. print("扫描WiFi结果:", wifis)
  73. return wifis
  74. def getStatus():
  75. """获取WiFi连接状态"""
  76. return wlan.isconnected()
  77. def getWifiConnectInfo():
  78. """获取已连接的WiFi信息"""
  79. return wlan.ifconfig()
  80. def disconnectWifi():
  81. """断开当前连接的无线网络"""
  82. wlan.disconnect()
  83. def connectWifi(ssid, pwd):
  84. """
  85. 连接wifi
  86. :param ssid:
  87. :param pwd:
  88. :return:
  89. """
  90. print("开始连接", ssid, pwd)
  91. onFlickerLed(200)
  92. wlan.disconnect()
  93. getConfig().connectWifi.ssid = None
  94. getConfig().connectWifi.pwd = None
  95. wlan.connect(ssid, pwd)
  96. timeout = 0
  97. while not wlan.isconnected() and timeout < 10:
  98. timeout += 1
  99. time.sleep(1)
  100. offFlickerLed()
  101. if wlan.isconnected():
  102. print('WiFi已连接', wlan.ifconfig())
  103. getConfig().connectWifi.ssid = ssid
  104. getConfig().connectWifi.ip = wlan.ifconfig()[0]
  105. return True
  106. print('连接'+ssid+' 失败!')
  107. return False
  108. def autoConnectWifi():
  109. """
  110. 连接附近WiFi
  111. :return:
  112. """
  113. for item in scanWifi():
  114. try:
  115. ssid = str(item[0].decode('utf-8'))
  116. if ssid in getConfig().wifi:
  117. pwd = getConfig().wifi[ssid]
  118. print('连接WiFi:', ssid, pwd)
  119. if connectWifi(ssid, pwd):
  120. return True
  121. except:
  122. pass
  123. print('连接附近WiFi失败')
  124. return False
  125. client = None
  126. def send_ping():
  127. try:
  128. client.ping()
  129. except Exception as e:
  130. print(e)
  131. getConfig().mqttStatus = False
  132. def connectMQTT(keepalive):
  133. """
  134. 连接MQTT
  135. :return:
  136. """
  137. global client
  138. onFlickerLed(1000)
  139. try:
  140. client.disconnect()
  141. except Exception as e:
  142. pass
  143. try:
  144. client = None
  145. except:
  146. pass
  147. topic = getConfig().id
  148. client = MQTTClient(getConfig().id, getConfig().mqtt.host, getConfig().mqtt.port, 'esp', 'Mqtt.158747928', keepalive=keepalive)
  149. client.set_callback(mqCallback)
  150. try:
  151. print('连接mqtt中......')
  152. client.connect()
  153. print('mqtt连接成功')
  154. client.subscribe(topic, 1)
  155. sleep(1)
  156. onLed()
  157. except Exception as e:
  158. print('MQTT连接失败:', getConfig().id, getConfig().mqtt.host, getConfig().mqtt.port, topic)
  159. print(e)
  160. return False
  161. getConfig().mqtt.subTopic = topic
  162. getConfig().mqttStatus = True
  163. # 启动定时任务定时ping
  164. # tasks.add_work(send_ping, 30000)
  165. # 启动多线程检查待处理消息
  166. _thread.start_new_thread(checkMsg, ())
  167. # 上报状态
  168. reportConfig()
  169. print("已连接到MQTT:", topic)
  170. return True
  171. def checkMsg():
  172. """
  173. 检查服务器是否有待处理的消息
  174. :return:
  175. """
  176. while getConfig().mqttStatus:
  177. try:
  178. client.check_msg()
  179. except Exception as e:
  180. print(e)
  181. print('MQTT断开')
  182. getConfig().mqttStatus = False
  183. break
  184. heartbeat = 1
  185. def mqCallback(topic, msg):
  186. print(topic, msg)
  187. msg = msg.decode('utf-8').split("@")
  188. com = msg[0]
  189. logId = msg[1] if len(msg) > 1 else None
  190. # 执行命令
  191. if not sysCom(com):
  192. device.command(com)
  193. # 执行完命令上报状态
  194. reportLog(logId)
  195. def sysCom(com):
  196. """
  197. 判断是不是系统命令,如果不是就调用模块去执行
  198. """
  199. if com == 'updateSystem':
  200. checkUpdate()
  201. return True
  202. elif com == 'heartbeat':
  203. return True
  204. return False
  205. def sendMqtt(msg):
  206. """
  207. 发送mqtt消息
  208. :param msg:
  209. :return:
  210. """
  211. client.publish(getConfig().mqtt.sendTopic, msg, False)
  212. def reportHeartbeat():
  213. sendMqtt('heartbeat')
  214. def reportConfig():
  215. data = getConfig().toJson()
  216. data['report'] = 'reportConfig'
  217. sendMqtt(ujson.dumps(data))
  218. print('reportConfig')
  219. def reportLog(logId):
  220. """
  221. 上报状态
  222. """
  223. data = {'device': device.status()}
  224. data['logId'] = logId
  225. data['report'] = 'reportLog'
  226. sendMqtt(ujson.dumps(data))
  227. print('reportLog')
  228. # 读取文件内容
  229. def openFile(path):
  230. file=open(path, 'r')
  231. text = file.read()
  232. file.close()
  233. return text
  234. # 写文件
  235. def writeFile(path, content):
  236. # 判断是否在文件夹下
  237. index = path.rfind('/')
  238. if index != -1:
  239. try:
  240. os.mkdir(path[:index])
  241. except OSError as e:
  242. pass
  243. file=open(path, 'w')
  244. text = file.write(content)
  245. file.close()
  246. return True
  247. def checkUpdate():
  248. """
  249. 检查系统更新
  250. """
  251. try:
  252. version = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/version.json").text
  253. print(version)
  254. if version is not None and version != '':
  255. v = ujson.loads(version)
  256. isSave = False
  257. if v["system"] > getConfig().version.system:
  258. if updateSystem(str(v["system"]), 'system'):
  259. getConfig().version.system = v["system"]
  260. isSave = True
  261. if v[getConfig().model] > getConfig().version.model:
  262. if updateSystem(str(v[getConfig().model]), getConfig().model):
  263. getConfig().version.model = v[getConfig().model]
  264. isSave = True
  265. if isSave:
  266. saveConfig()
  267. reset()
  268. except Exception as e:
  269. print(e)
  270. def updateSystem(version, name):
  271. print('更新', name, version)
  272. try:
  273. # 获取要更新的文件列表
  274. files = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/"+name+"/v"+version+"/fileList.json").text
  275. files = ujson.loads(files)
  276. for file in files:
  277. print(file)
  278. text = urequests.get("http://v-kun.com:3000/hk/smart-home-version-release/raw/master/" + name + "/v" + version + "/"+file).text
  279. writeFile(file, text)
  280. return True
  281. except Exception as e:
  282. print(e)
  283. return False