Example code from my "MicroPython Heats My Home" presentation.
import dht [82/128] | |
import machine | |
import network | |
import utime as time | |
import urequests as requests | |
import config | |
def wifi_connect(): | |
"""Connect to the configured Wi-Fi network.""" | |
sta_if = network.WLAN(network.STA_IF) | |
if not sta_if.isconnected(): | |
print('connecting to network...') | |
sta_if.active(True) | |
sta_if.connect(config.WIFI_ESSID, config.WIFI_PASSWORD) | |
while not sta_if.isconnected(): | |
time.sleep(1) | |
print('network config:', sta_if.ifconfig()) | |
def get_current_time(): | |
"""Obtain the current Unix time. | |
Note that because the ESP8266 does not have a clock, I make a call to the | |
World Time API to obtain the current time. | |
""" | |
response = requests.get( | |
'http://worldtimeapi.org/api/timezone/Etc/UTC') | |
if response.status_code != 200: | |
raise RuntimeError('Cannot get current time!') | |
return response.json()['unixtime'] | |
def get_temperature(): | |
"""Obtain the current temperature reading from the DHT22 sensor. | |
The returned temperature is in degrees Celcius. | |
""" | |
d = dht.DHT22(machine.Pin(config.DHT22_PIN)) [43/128] | |
d.measure() | |
return d.temperature() | |
def boosted(now): | |
"""Returns True if the heating is currently running, or False if it is | |
not. | |
The current Unix time must be passed as the now argument. | |
To avoid making frequent calls into the heating controller, each time the | |
heating is boosted, a boost.dat file is written with the end time of the | |
boost. | |
""" | |
boost_until = 0 | |
try: | |
with open('boost.dat', 'rt') as f: | |
boost_until = float(f.read()) | |
except OSError: | |
return False | |
return boost_until > now | |
def boost(now): | |
"""Initiate a 30 minute heating boost. | |
The current Unix time must be passed as the now argument. | |
The end time for this boost is recorded in the boost.dat file. | |
""" | |
# Note that this request must be changed to the proper one for your | |
# heating controller | |
response = requests.post('https://httpbin.org/status/200', | |
json={'foo': 'bar'}) | |
if response.status_code != 200: | |
raise RuntimeError('Could not issue boost!') | |
with open('boost.dat', 'wt') as f: | |
f.write(str(now + 30 * 60)) | |
[4/128] | |
def thermostat(temp, now): | |
"""Returns True if the heating needs to run, or False if not. | |
The current temperature must be passed in the temp argument. | |
The current Unix time must be passed in the now argument. | |
This function uses a simple logic to determine a target temperature for | |
the current time of day. If the current temperature is below the target, | |
then it returns True to indicate that the heating must be started. | |
""" | |
current_hour = int(now % (24 * 60 * 60) / (60 * 60)) | |
target_temp = 19 if 7 <= current_hour < 22 else 17 | |
boost = temp < target_temp | |
print('Target Temp = {}C Boost = {}'.format(target_temp, boost)) | |
return boost | |
def show_error(): | |
"""Blink the ESP8266 LED a few times to indicate that an error has | |
occurred. | |
""" | |
led = machine.Pin(config.LED_PIN, machine.Pin.OUT) | |
for i in range(5): | |
time.sleep(0.5) | |
led.on() | |
time.sleep(0.5) | |
led.off() | |
led.on() | |
def deep_sleep(): | |
"""Put the ESP8266 board into deep sleep mode for the configured length | |
of time. | |
At the end of the deep sleep period the board will reboot. | |
""" | |
rtc = machine.RTC() | |
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP) | |
rtc.alarm(rtc.ALARM0, config.INTERVAL * 1000) | |
machine.deepsleep() |
import sys | |
from heat import wifi_connect, get_current_time, get_temperature, boosted, \ | |
boost, thermostat, show_error, deep_sleep | |
try: | |
wifi_connect() | |
now = get_current_time() | |
temp = get_temperature() | |
print('[{}] Temp = {}C'.format(now, temp)) | |
if not boosted(now) and thermostat(temp, now): | |
boost(now) | |
except Exception as exc: | |
sys.print_exception(exc) | |
show_error() | |
deep_sleep() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment