Skip to content

Instantly share code, notes, and snippets.

Created October 28, 2019 23:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miguelgrinberg/80973081596f1069057ec6668142be15 to your computer and use it in GitHub Desktop.
Save miguelgrinberg/80973081596f1069057ec6668142be15 to your computer and use it in GitHub Desktop.
Example code from my "MicroPython Heats My Home" presentation.
DHT22_PIN = 4 # D2 pin / GPIO4
LED_PIN = 2 # D4 pin / GPIO2
WIFI_ESSID = 'your-wifi-network-name'
WIFI_PASSWORD = 'your-wifi-password'
INTERVAL = 5 * 60
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.connect(config.WIFI_ESSID, config.WIFI_PASSWORD)
while not sta_if.isconnected():
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(
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]
return d.temperature()
def boosted(now):
"""Returns True if the heating is currently running, or False if it is
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_until = 0
with open('boost.dat', 'rt') as f:
boost_until = float(
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 ='',
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))
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
led = machine.Pin(config.LED_PIN, machine.Pin.OUT)
for i in range(5):
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)
import sys
from heat import wifi_connect, get_current_time, get_temperature, boosted, \
boost, thermostat, show_error, deep_sleep
now = get_current_time()
temp = get_temperature()
print('[{}] Temp = {}C'.format(now, temp))
if not boosted(now) and thermostat(temp, now):
except Exception as exc:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment