{"id":20559781,"url":"https://github.com/andreabak/esptherm","last_synced_at":"2026-05-08T03:03:56.032Z","repository":{"id":187945828,"uuid":"330418425","full_name":"andreabak/ESPTherm","owner":"andreabak","description":"Smart thermostat and climate monitoring IOT ecosystem, built using ESP8266 devices, MicroPython and Flask","archived":false,"fork":false,"pushed_at":"2021-06-17T23:57:52.000Z","size":1602,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-16T19:01:44.070Z","etag":null,"topics":["climate-control","energy-efficiency","esp8266","flask","iot","python","smarthome"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreabak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-01-17T15:09:30.000Z","updated_at":"2023-06-15T07:41:39.000Z","dependencies_parsed_at":"2023-08-12T22:20:28.401Z","dependency_job_id":null,"html_url":"https://github.com/andreabak/ESPTherm","commit_stats":null,"previous_names":["andreabak/esptherm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreabak%2FESPTherm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreabak%2FESPTherm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreabak%2FESPTherm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreabak%2FESPTherm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreabak","download_url":"https://codeload.github.com/andreabak/ESPTherm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242166177,"owners_count":20082618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["climate-control","energy-efficiency","esp8266","flask","iot","python","smarthome"],"created_at":"2024-11-16T03:52:11.700Z","updated_at":"2026-05-08T03:03:55.980Z","avatar_url":"https://github.com/andreabak.png","language":"Python","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=PCYKW7DB34WQ4\u0026item_name=donate+to+ESPTherm+project+maintainer\u0026currency_code=EUR\u0026source=url"],"categories":[],"sub_categories":[],"readme":"# ESPTherm\n\n![Platform](https://img.shields.io/badge/platform-linux%20%7C%20windows-lightgrey)\n![Python version](https://img.shields.io/badge/python-3.7%20%7C%203.8%20%7C%203.9-informational)\n![Requires.io](https://img.shields.io/requires/github/andreabak/ESPTherm)\n![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/andreabak/esptherm)\n![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/andreabak/ESPTherm)\n![License](https://img.shields.io/github/license/andreabak/ESPTherm)\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)][donation url]\n\n**ESPTherm** is a smart thermostat and climate monitoring ecosystem project, built using _ESP8266_ devices, _MicroPython_ and _Flask_. \\\nThe main motivation behind it was to have better control of the house heating, the original thermostat being located in a non-directly heated area.\n\nIt's comprised of:\n- a central **server** application, that takes care of synchronizing and receiving data from devices.\n- one or more distributed ESP8266 **devices**, such as: \n    - **thermostat** devices, that switch the heating on or off\n    - **tempstation** devices, that monitor temperature (and humidity) of a certain area\n\n## Server\nThe centralized **server** manages synchronization, control and data upload from devices, and serves a simple status page that displays the sensors' data (log) from the known devices:\n\u003cp align=\"center\"\u003e\u003cimg src=\"images/server.png\" height=\"256px\"\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003cimg src=\"images/pinpad_crop.png\" height=\"256px\"\u003e\u003c/p\u003e\nAccess to the status page is password protected, using a simple pinpad.\nThis security approach is by no means robust, it's intended as a minimum solution for unintended access prevention, and it assumes you're running the server only within your local network.\n\n#### Installation\nThe server is implemented in _Python (\u003e=3.7)_, that must be beforehand installed on your system. \\\nBoth _Windows_ and _Linux_ environments are supported. For the latter, the included `install-server.sh` can be used to install the server as a service, in a distro using _systemd_ (and _firewalld_).\n\nIf doing a manual install, the full list of python dependencies is included in `server_requirements.txt` that can be installed using _pip_ or _conda_.\n\nIt listens by default on port `8367` and it should be run as a limited or dedicated user within your OS.\n\n#### Configuration\nThe server configuration file is stored in [`/configs/server.json`](/configs/server.json). There currently are only a few configurable parameters:\n- `ui_secret_code`: the pinpad numeric (max 6 digits) code used for the web UI access.\n- `remote_therm`: this section is dedicated to using the thermostat in remote mode, controlling it with another temperature-sensing device:\n  - `enabled`: set to `true` to enable remote thermostat mode.\n  - `switch_link_id`: the full id (`\u003cdevice_type\u003e/\u003cdevice_id\u003e`) of the linked device from which to get the current temperature and hourly scheduled target temperatures used to remotely switch the thermostat device on or off.\n  - `max_log_age`: the maximum acceptable age in minutes of the last log record received from the linked device. If no records more recent than this are present, the server will instruct the thermostat device to revert to the normal \"schedule\" operating mode.\n\n## Devices\nAll _ESP8266_ devices have been programmed with _MicroPython_, for both code writing speed and versatility, and also given that performance is not an issue for the specific use case.\n\n#### \u003ca name=\"devices_flashing\"\u003e\u003c/a\u003e Flashing\nThe _MicroPython_ firmware used is from unofficial builds over at **[alelec / micropython-ci - GitLab](https://gitlab.com/alelec/micropython_ci)** (see latest jobs artifacts for ESP8266_LFS), due to bad support for the _LittleFSv2_ filesystem in the official ones. This is necessary, given that the devices frequently write to flash to store sensors data and internal operating state, and the default _FAT_ filesystem, lacking wear-leveling and corruption-resistant features, would have lead to faster storage degradation and frequent filesystem corruption, especially in low battery conditions.\n\nTo flash the firmware, follow the official instructions over at **[the MicroPython Documentation for ESP8266](https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html)**. \\\nOnce the firmware is setup and a Python REPL can be accessed over serial, pick your favourite tool for file upload (like [ampy](https://pypi.org/project/adafruit-ampy/)) and proceed.\n\nThe _MicroPython_ source files for devices are contained within the [`/src`](/src) directory of this repo, with code common to all devices in the root of said directory, while device-specific code is in the appropriately-named subdirectories. \\\nSpecifically, all devices need flashing of these common files:\n```\napp_base.mpy\nrequests.mpy\nntc.py\n```\n**For the additional device-specific code files needed, check the appropriate sections below.**\n\nOn the target device, all code files are to be flashed in its root directory. After all files are uploaded, you can do a `uos.listdir()` while in the REPL to check that no subdirectories exist.\n\nN.B. The `.mpy` files are bytecode-compiled _MicroPython_ files required to speed up module import time and circumvent memory limitations of ESP devices, especially for complex code. \\\nBeware that if the original `.py` counterparts of these files are flashed alongside compiled `.mpy` files, the former will be picked by the import mechanism at runtime instead.\n\n#### Configuration\nAll devices require a device-specific config file to be flashed with the name `config.json`, with default ones found at [`/configs/\u003cdevice_type\u003e/_default.json`](/configs) in this repo. This folder is used by the server too, to load device configs and sync them if they're updated.\n\nThe config file has to be tweaked beforehand to set the appropriate values for your setup. This can be also done by creating a device-id specific config file (copying from the default one), stored in the server files like so: `/configs/\u003cdevice_type\u003e/\u003cdevice_id\u003e.json`.\n\nWithin the config file, pay special attention to tweak IP config parameters, including the server address, and the pins and calibration values of the sensors connected (like NTC, DHT, switches, etc.).\n\n#### Initial setup\nOnce flashing of all the appropriate files is complete, resetting the device while connected with a serial interface, will prompt a guided setup, where you'll be requested to input WiFi credentials and a unique device ID.\n\n### Thermostat\nThe thermostat device (`therm`) has one job, that is, as the name implies, controlling the heating.\n\n#### Hardware\nMost homes central heating furnaces usually provide a couple of wires that need either be shorted or disconnected to signal the heating to turn on or off. Check the installation manuals of your heating system, as they can differ a lot. \\\nIf the wiring is such as above, all that's needed to control the heating is a latching SPDT relay, one rated for the maximum voltage your battery can output (eg. 3.0-4.5 V). You can even hijack one from your existing thermostat, if you know how to do it, don't mind hacking it and/or you're your own landlord. \\\nIn my case, I ended up installing the *therm* ESP8266 within the existing thermostat, re-using both its AAA batteries and relay connections. Therefore I didn't implement any kind of display for this device.\n\nThe schematic is more or less as follows:\n\u003cp align=\"center\"\u003e\u003cimg src=\"images/therm_schem.svg\" width=\"80%\"\u003e\u003c/p\u003e\n\n- The `RST` pin of the _ESP8266_ must be connected to `GPIO16` to allow for deepsleep battery saving.\n- The NTC thermistor must create a voltage divider like so `3.3V - NTC - A0 - R2 - GND`, where `A0` is the ADC pin of the ESP8266, and `R2` is the voltage divider resistor, usually of the same value of nominal resistance of the NTC.\n- The heating latching relay must be connected using transistor drivers (I used NPN-PNP), as the ESP8266 GPIOs cannot usually provide enough current to activate the coils. The base and pull-down resistors values should be fine tuned for the specific characteristics of the relay used, finding a good compromise between coil activation time and idle power consumption.\n\nMany of the GPIO and resistor values can be calibrated in the config file.\n\n#### Flashing\nFollow the general instructions [above](#devices_flashing), but also flash these device-specific code files, found under [`/src/therm`](/src/therm):\n```\nmain.py\ntherm_app.mpy\n```\n\n### TempStation\nThe temperature station device(s) (`tempstation`) sense temperature (and humidity) in a specific area of the building, send this information to the server, which in turn can use it to remotely activate the heating. \\\nAlso, if fitted with an OLED display, they can permanently show temperature, humidity, battery and other device's info.\n\u003cp align=\"center\"\u003e\u003cimg src=\"images/tempstation.png\" width=\"50%\"\u003e\u003c/p\u003e\n\n#### Hardware\nThe tempstation device is composed of the _ESP8266_, a _SSD1306_ OLED display (I had the SPI version readily available), a _DHT22_ sensor, a 2x*18650* li-ion battery pack with a USB charging board. \\\nThe battery life is about 7-10 days, with the OLED display always on, a sensor update interval of 1 minute and a sync interval of 5 minutes.\n\nThe schematic is more or less as follows:\n\u003cp align=\"center\"\u003e\u003cimg src=\"images/tempstation_schem.svg\" width=\"80%\"\u003e\u003c/p\u003e\n\n- The `RST` pin of the _ESP8266_ must be connected to `GPIO16` to allow for deepsleep battery saving.\n- The rest of the connections are quite straightforward, with the exception of the _SSD1306_ OLED display `RST` pin. \\\n  To keep the display always on, even when the _ESP8266_ is in deepsleep mode, there's pull-down circuit that prevents spurious voltage spikes the ESP sends on its GPIO pins while resetting or entering deepsleep. There are also some code overrides to the _ssd1306_ library functions to send initialization commands to the display only when first powered up (cold boot). \\\n  The circuit has been implemented using resistors and a NPN driving transistor, although a filtering R-C circuit with a capacitor of the correct value would have probably been just as effective.\n\nMany of the GPIO and DHT values can be calibrated in the config file.\n\n#### Flashing\nFollow the general instructions [above](#devices_flashing), but also flash these device-specific code files, found under [`/src/tempstation`](/src/tempstation):\n```\nmain.py\ntempstation_app.mpy\nwriter_minimal.mpy\nfuturahvbig.mpy\nfuturahvsml.mpy\n```\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\nThe git submodules ([webrepl](https://github.com/Hermann-SW/webrepl) and [micropython-font-to-py](https://github.com/peterhinch/micropython-font-to-py)) are optional for normal operation and can be setup with:\n```bash\ngit submodule init\ngit submodule update\n```\n\n## Licence\n\nReleased under ![GPL-3.0 License](/LICENSE).\n\n## Donations\n\nDonate to the project maintainer:\n\n[![donate with PayPal](https://gist.githubusercontent.com/andreabak/bb1d67a7ffce6ffa830f052361ea0765/raw/f553450f3282bb4fa95dabb4da936e415c270aaa/paypal-donate-button.svg)][donation url]\n\n## Disclaimer\nThis is a personal project, tested and working, but not intended for mission-critical applications. Feel free use it and fork it, according to its license, at your own risk. \\\nStructure, specifications and code are subject to change at any time.\n\n\u003c!--REFERENCES--\u003e\n\n[donation url]: https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=PCYKW7DB34WQ4\u0026item_name=donate+to+ESPTherm+project+maintainer\u0026currency_code=EUR\u0026source=url\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreabak%2Fesptherm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreabak%2Fesptherm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreabak%2Fesptherm/lists"}