Created
April 4, 2021 17:09
-
-
Save russhughes/428ecd42fbb89db9da9640a748e6022d to your computer and use it in GitHub Desktop.
Quick and dirty web temp and light sensor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Quick and dirty web based temp and light sensor using ebay 8266 board. | |
described in this review https://blog.squix.org/2015/01/esp8266-test-board-review.html | |
Based on project from https://RandomNerdTutorials.com | |
""" | |
try: | |
import usocket as socket | |
except: | |
import socket | |
from machine import Pin, PWM, ADC | |
from time import sleep | |
import onewire, ds18x20 | |
import network | |
import ure | |
import esp | |
esp.osdebug(None) | |
import gc | |
gc.collect() | |
# connect to access point | |
SSID = 'SSID' | |
PASSWORD = 'PASSWORD' | |
station = network.WLAN(network.STA_IF) | |
station.active(True) | |
station.connect(SSID, PASSWORD) | |
# wait until connected | |
while station.isconnected() == False: | |
pass | |
# set static ip address | |
station.ifconfig(('10.10.0.22','255.255.255.0','10.10.0.1','10.10.0.1')) | |
print('Connection successful', station.ifconfig()) | |
# initalize onewire temp sensor | |
ds_sensor = ds18x20.DS18X20(onewire.OneWire(Pin(4))) | |
# initalize adc for light sensor | |
adc = ADC(0) | |
# initialize PWM pins on RGB led | |
red = PWM(Pin(13), 0, 0) | |
green = PWM(Pin(12), 0, 0) | |
blue = PWM(Pin(15), 0, 0) | |
# regular expression to get numbers for RGB pwm ( /r=255,255,255 = White) | |
regex = ure.compile("GET /r=(\d+),(\d+),(\d+).*") | |
# read temp sensor | |
def read_ds_sensor(): | |
roms = ds_sensor.scan() | |
ds_sensor.convert_temp() | |
for rom in roms: | |
temp = ds_sensor.read_temp(rom) | |
if isinstance(temp, float): | |
msg = round(temp, 2) | |
print(temp, end=' ') | |
print('Valid temperature') | |
return msg | |
return b'0.0' | |
# read light sensor | |
def lights(): | |
if adc.read() > 30: | |
return "Off" | |
else: | |
return "On" | |
# create webpage with temp in 'c and 'f plus light sensor status | |
def web_page(): | |
temp = read_ds_sensor() | |
return """<!DOCTYPE HTML> | |
<html><head><meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> | |
<style> html { font-family: Arial; display: inline-block; margin: 0px auto; text-align: center; } | |
h2 { font-size: 1.5rem; } p { font-size: 1.5rem; } .units { font-size: 1.2rem; } | |
.ds-labels{ font-size: 1.5rem; vertical-align:middle; padding-bottom: 15px; } | |
table { margin-left: auto; margin-right: auto; } | |
td { font-size: 1.5rem; vertical-align:middle; padding: 15px; } | |
.data { text-align: right; } | |
} | |
</style></head><body><h2>Location: Router Room</h2> | |
<table> | |
<tr> | |
<td><i class="fas fa-thermometer-half" style="color:#059e8a;"></i></td> | |
<td>Temperature</td> | |
<td class="data">""" + str(temp) + """</td> | |
<td><sup class="units">°C</sup></td> | |
</tr> | |
<tr> | |
<td><i class="fas fa-thermometer-half" style="color:#059e8a;"></i></td> | |
<td>Temperature</td> | |
<td class="data">""" + str(round(temp * (9/5) + 32.0, 2)) + """</td> | |
<td><sup class="units">°F</sup></td> | |
</tr> | |
<tr> | |
<td><i class="fas fa-lightbulb" style="color:#059e8a;"></i></td> | |
<td>Lights</td> | |
<td class="data">""" + str(adc.read()) + """</td> | |
<td class="data">""" + lights() + """</td> | |
</tr> | |
</table> | |
</body></html>""" | |
# handle web request "GET /?c" | |
def api_c(): | |
temp = read_ds_sensor() | |
return str(temp) | |
# handle web request "GET /?f" | |
def api_f(): | |
temp = read_ds_sensor() | |
return str(round(temp * (9/5) + 32.0, 2)) | |
# handle web request "GET /?l" | |
def api_l(): | |
return str(adc.read()) | |
# get initial temp sensor, the first one is usually wrong | |
read_ds_sensor() | |
# create socket to listen for connections on port 80 | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
s.bind(('', 80)) | |
s.listen(5) | |
# main look waiting for a web request | |
while True: | |
try: | |
if gc.mem_free() < 102000: | |
gc.collect() | |
conn, addr = s.accept() | |
conn.settimeout(3.0) | |
request = str(conn.recv(1024)) | |
conn.settimeout(None) | |
# received a request | |
print("Request: ", request) | |
# use regular expression to grab request text | |
parms = ure.search("GET (.*?) HTTP\/1\.1", request) | |
if parms: | |
print ("parms: ", parms) | |
if request.find('GET /?c') !=-1: | |
response = api_c() | |
elif request.find('GET /?f') !=-1: | |
response = api_f() | |
elif request.find('GET /?l') !=-1: | |
response = api_l() | |
elif request.find('GET /r=') != -1: | |
match = regex.match(request) | |
print("match: ", match) | |
if match: | |
red.PWM(int(match[1])) | |
green.PWM(int(match[2])) | |
blue.PWM(int(match[3])) | |
response = "ok" | |
else: | |
response = "error" | |
else: | |
response = web_page() | |
# send response back | |
conn.send('HTTP/1.1 200 OK\n') | |
conn.send('Content-Type: text/html\n') | |
conn.send('Connection: close\n\n') | |
conn.sendall(response) | |
conn.close() | |
except OSError as e: | |
conn.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment