Я пытаюсь построить систему управления отоплением, в которой в каждой комнате дома установлен датчик температуры DHT22, подключенный к плате с поддержкой Wi-Fi ESP8266, с микро python 1.2 "стабильной".
плата "MakerHawk ESP8266 NodeMCU LUA CP2102 ESP-12F WiFi Inte rnet Плата разработчика Последовательный беспроводной модуль для Arduino IDE / Micro python Новая версия" от Amazon .
Начальная фаза проекта включает в себя платы ESP8266, отображающие температуру через встроенный веб-сервер, и работу на моем файловом сервере Ubuntu, которая запрашивает веб-страницы и помещает результаты в мою локальную базу данных графит . Я выбрал этот подход, потому что таким образом плата ESP8266 не должна иметь надежную временную метку. (Весь приведенный ниже код, касающийся времени, предназначен для передачи точной отладочной информации, а не для фактического сбора данных).
Из моих графанов показаний моей графитовой базы данных у меня есть данные каждые несколько секунд от веб-серверов. Однако один раз в два или три дня одна из плат ESP8266 будет go отключена на несколько часов . Иногда они возвращаются сами по себе, но обычно отключение происходит достаточно долго, и я замечаю, что go и выключение и включение питания неисправной платы.
Платы ESP8266 работают в довольно загруженной среде wifi c wifi с технически подкованных подростков, так что следует ожидать сканирования порта nmap и тому подобное. Мне нужно разобраться с потенциальными ситуациями DOS (учитывая очень ограниченную память на ESP8266) и по-прежнему возвращать температуру каждую минуту или около того.
Код для ESP8266 micro python следует (собран из разных источников на inte rnet);
boot.py:
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
import uos as os
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
gc.collect()
import webrepl
webrepl.start()
main.py:
import machine
import dht
# DHT22 compatible sensor with middle (sensor) pin
d = dht.DHT22(machine.Pin(0))
html = """<!DOCTYPE html>
<html>
<head> <title>ESP8266 Temperature and Humidity</title> </head>
<body> <p>
Temperature %s
Humidity %s
</p> </body>
</html>
"""
access_points = {
'home':'feedfooddeadbeef',
'home2':'feedfooddeadbeef',
'home3':'feedfooddeadbeef',
}
import utime
import network
sta_if = network.WLAN(network.STA_IF)
import ntptime
rtc = machine.RTC()
lifetime = 0
# Connect to list of wifi networks; based on code from https://forum.micropython.org/viewtopic.php?t=2951
def try_connection():
t = 60
while not sta_if.isconnected() and t > 0:
print('.', end='')
utime.sleep_ms(500)
t = t - 1
return sta_if.isconnected()
def try_to_connect():
if sta_if.isconnected():
print('Network connected OK')
else:
print('Network disconnected. Trying to connect ...', end='')
sta_if.active(True)
# Scan for available networks
ap_list = sta_if.scan()
# Sort by signal strength
ap_list.sort(key=lambda ap: ap[3], reverse=True)
# Filter out unknown access points
ap_list = list(filter(lambda ap: ap[0].decode('UTF-8') in access_points.keys(), ap_list))
for ap in ap_list:
essid = ap[0].decode('UTF-8')
if not sta_if.isconnected():
print('Trying to connect to new network %s ...' % essid, end='')
sta_if.connect(essid, access_points[essid])
print(try_connection())
if sta_if.isconnected():
print('network config:', sta_if.ifconfig())
else:
print('Unable to connect.')
def connect():
while True:
try_to_connect()
if sta_if.isconnected():
break
utime.sleep(60)
try:
import usocket as socket
except:
import socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.settimeout(30)
s.bind(addr)
s.listen(5)
print('listening on', addr)
failcount = 1
while True:
lifetime = lifetime + 1
print("Lifetime is", lifetime)
if failcount > 10 or lifetime > 500:
print("Resetting due to old age")
machine.reset()
while True:
try_to_connect()
if sta_if.isconnected():
break
utime.sleep(60)
print("Waiting for connection attempt %d ..." % failcount)
try:
cl, addr = s.accept()
except OSError:
failcount = failcount + 1
continue
failcount = 1
try:
ntptime.settime()
except (OSError, OverflowError):
pass
print('temperature client connected from', addr, 'at ', end='')
print(rtc.datetime())
try:
request=cl.recv(1024)
except OSError:
cl.close()
continue
print('Content of request:', request)
print("Trying to measure ...")
while True:
try:
d.measure()
except OSError:
continue
break
t = d.temperature()
h = d.humidity()
print("Got measurement Temperature %s humidity %s" % (t, h))
response = html % (t, h)
try:
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
except OSError:
pass
try:
cl.send(response)
except OSError:
pass
cl.close()