{"id":13849932,"url":"https://github.com/supergreenlab/SuperGreenOSBoilerplate","last_synced_at":"2025-07-12T21:32:34.142Z","repository":{"id":123995559,"uuid":"164238990","full_name":"supergreenlab/SuperGreenOSBoilerplate","owner":"supergreenlab","description":"ESP32 Boilerplate code generator - See README -\u003e","archived":false,"fork":false,"pushed_at":"2020-11-02T11:44:47.000Z","size":12323,"stargazers_count":28,"open_issues_count":2,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-08-04T20:03:30.567Z","etag":null,"topics":["boilerplate","boilerplate-template","esp-idf","esp32","firmware","helper","howto","low-level","ota","ota-update","starter-kit","starter-template","template","tutorial"],"latest_commit_sha":null,"homepage":"https://github.com/supergreenlab/SuperGreenOSBoilerplate/blob/master/README.md","language":"C","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/supergreenlab.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,"roadmap":null,"authors":null}},"created_at":"2019-01-05T18:01:38.000Z","updated_at":"2024-08-04T20:03:30.568Z","dependencies_parsed_at":"2024-01-18T09:57:24.520Z","dependency_job_id":"595fab12-fbb6-485d-86de-4143b724c16c","html_url":"https://github.com/supergreenlab/SuperGreenOSBoilerplate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supergreenlab%2FSuperGreenOSBoilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supergreenlab%2FSuperGreenOSBoilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supergreenlab%2FSuperGreenOSBoilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supergreenlab%2FSuperGreenOSBoilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/supergreenlab","download_url":"https://codeload.github.com/supergreenlab/SuperGreenOSBoilerplate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225839481,"owners_count":17532305,"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":["boilerplate","boilerplate-template","esp-idf","esp32","firmware","helper","howto","low-level","ota","ota-update","starter-kit","starter-template","template","tutorial"],"created_at":"2024-08-04T20:00:53.100Z","updated_at":"2024-11-22T03:30:27.344Z","avatar_url":"https://github.com/supergreenlab.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"![SuperGreenLab](assets/sgl.png?raw=true \"SuperGreenLab\")\n\nTable of Contents\n=================\n\n   * [SuperGreenOSBoilerplate](#supergreenosboilerplate)\n      * [Features](#features)\n      * [TODO](#todo)\n      * [Philosophy](#philosophy)\n   * [How to use](#how-to-use)\n      * [Hardware](#hardware)\n      * [Workstation setup](#workstation-setup)\n   * [Quickstart](#quickstart)\n      * [Creating modules and devices](#creating-modules-and-devices)\n      * [Create sht21 i2c device](#create-sht21-i2c-device)\n         * [I2C device boilerplate](#i2c-device-boilerplate)\n         * [Generated code](#generated-code)\n         * [Driver code](#driver-code)\n      * [Create sht21 keys in config.json](#create-sht21-keys-in-configjson)\n      * [First run](#first-run)\n         * [Tool setup](#tool-setup)\n         * [WIFI AP](#wifi-ap)\n         * [BLE](#ble)\n      * [Create Led module](#create-led-module)\n         * [Boilerplate](#boilerplate)\n         * [Generated code](#generated-code-1)\n         * [Code the led blinking](#code-the-led-blinking)\n      * [WIFI Configuration](#wifi-configuration)\n         * [Through WIFI AP](#through-wifi-ap)\n         * [Through BLE](#through-ble)\n      * [HTTP API](#http-api)\n      * [Cloud, Logs and MQTT](#cloud-logs-and-mqtt)\n         * [How data is sent to MQTT](#how-data-is-sent-to-mqtt)\n         * [Setup MQTT configuration](#setup-mqtt-configuration)\n         * [Monitoring](#monitoring)\n         * [Alert](#alert)\n      * [Over-The-Air (OTA) updates](#over-the-air-ota-updates)\n   * [Keys definition](#keys-definition)\n   * [Troubleshoot](#troubleshoot)\n   * [Contribute](#contribute)\n\n# SuperGreenOSBoilerplate\n\ntl;dr configuring http/ws/ble/whatnot is a pain in the ass, this boilerplate generates C code from cuelang-generated-json through ejs templates to remove the pain and focus on the fun.\n\nSuperGreenOSBoilerplate proposes a way to ease and accelerate esp32 firmware development. By making most widely used features free.\nIt allows to generate most of the code for ble/http/wifi/ota/etc.. from a configuration file.\n\nBuilt around the key/value and modules paradigm, it's quite close to what you'd find in a microservice architecture.\n\nConcretely it means you define modules and key/value pairs in a configuration file, and it will generate:\n\n- getters and setters method\n- http r/w access\n- ble r/w access with notifications\n- an admin interface available over http\n- periodic value update over MQTT\n- save to internal flash\n\nAll these features can be disactivated or tuned (ie read-only access, no persistence etc..).\n\nFrom that all you have left to do is write the module's main loop and work with it's key/values.\n\nThis architecture allows a modular approach, and with modules interacting through there respective key/values.\n\n## Features\n\n- Key-value architecture\n- Over-the-air update\n- Statistic reports\n- Bluetooth LE interface\n- HTTP interface\n- Tiny local file system and http file serving\n- Auto generated admin interface\n- All logs redirected to MQTT\n- Comes with a [cloud backend](http://github.com/supergreenlab/SuperGreenCloud/)\n\n## TODO\n\n- Websocket\n- Mesh network (TODO)\n- Bluetooth (non BLE)\n\n## Philosophy\n\nThe whole point is to end up with a code that is as static as possible, so we can totally eliminate any kind of memory leaks coming from our code itself.\n\nThis is meant to be running 24/24 7/7 for months straight, so better have something as predictable as possible. Full static code makes that more reachable.\n\nBut we don't want to lose the advantages of dynamic code, neither do we want to have to repeat things N times all over the code base. So the proposed solution is to produce static code before compilation.\n\n# How to use\n\n## Hardware\n\nBased on [esp-idf](https://github.com/espressif/esp-idf) from espressif, and FreeRTOS.\n\nOnly runs on esp32.\n\nI've mostly been woking with either:\n\n- [Espressif ESP32 Development Board - Developer Edition](https://www.adafruit.com/product/3269)  \n  Simple, but does not allow to flash other devices.\n- [Espressif ESP32 WROVER KIT - V3](https://www.adafruit.com/product/3384)  \n  this one allows to debug through xtensa-esp32-elf-gdb and to flash other devices.\n\n![ESP32 WROVER KIT](assets/esp32.png?raw=true \"ESP32 WROVER KIT\")\n\n## Workstation setup\n\nFollow the [get-started guide from espressif](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/).\n\nInstall [cuelang getting started](https://cuelang.org/docs/install/)\n\nCue is a tool made to write JSON configurations in a much more efficient manner.\n\nAnd finally, install [ejs-cli](https://github.com/fnobi/ejs-cli).\n\n# Quickstart\n\nAs an example we're just going to stream a temp sensor's values to a cloud, for monitoring and alerts.\nWe'll also blink a led based on said sensor values (the hotter the faster it blinks).\nThe sensor used here is the sht21, I'll pass the detail because it's a weird one, but it's i2c compatible, and I have the code here.\n\nThis will get us through the main features:\n- create a module\n- create an i2c device\n- initialize the key in the system\n\nFirst thing first, clone this repo, and run `make` to see if the whole xtensa/esp-idf setup is working:\n\n```sh\n\n# clone repo\ngit clone git@github.com:supergreenlab/SuperGreenOSBoilerplate.git SuperGreenTemp\ncd SuperGreenTemp\n\n# create config directory\n./init.sh SuperGreenTemp config.json\n\n# generate code and admin app\n./update_template.sh config.json\n./update_htmlapp.sh config.json\n\n# make \u0026 flash\n./write_spiffs.sh \u0026\u0026 make -j4 flash monitor\n\n```\n\nIf it's the first time you launch this command, this is going to ask you a bunch of questions, just press enter to enter the default.\n\nDon't worry if you see a warning about i2c unused variables passing by.\n\nIt should end with something like this:\n\n```sh\n\n...\nGenerating esp32.common.ld\nLD build/firmware.elf\nesptool.py v2.6-beta1\nTo flash all build output, run 'make flash' or:\npython2 /home/korben/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0xd000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/ota_data_initial.bin 0x1000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/bootloader/bootloader.bin 0x10000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/firmware.bin 0x8000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/partitions.bin\n\n```\n\n## Creating modules and devices\n\nNow we're ready to start coding.\nWe'll start by streaming the temperature to the cloud.\n\nFor the 2 first step, we'll be using the script called `templates.sh`, which usage is as follows:\n\n```sh\n\n./templates.sh\n[Usage] ./templates.sh template_name module_name config_file\n\n```\n\n- `template_name` is either `new_module` or `new_i2c_device`.\n- `module_name` is the name of the module of i2c_device we're creating.\n- `config_file` the name of the generated config file\n\n## Create sht21 i2c device\n\nSo first step is to create the i2c device. There's a script for that, we'll call our device sth1x:\n\n### I2C device boilerplate\n\n```sh\n\n./templates.sh new_i2c_device sht21 config.json\n\n```\n\nOutput should look like this:\n\n```sh\n\nCopying files to main/sht21\nCall ejs-cli for templates/new_i2c_device/new_i2c_device.c.template to main/sht21/sht21.c\nCall ejs-cli for templates/new_i2c_device/new_i2c_device.h.template to main/sht21/sht21.h\n===\nDone\n===\nRunning ./update_template.sh....\nProcessing main/component.mk.template: Done\nProcessing main/init.c.template: Done\nProcessing main/core/kv/kv.c.template: Done\nProcessing main/core/kv/kv_helpers_internal.h.template: Done\nProcessing main/core/kv/kv_helpers_internal.c.template: Done\nProcessing main/core/kv/kv_helpers.c.template: Done\nProcessing main/core/kv/keys.h.template: Done\nProcessing main/core/kv/kv.h.template: Done\nProcessing main/core/i2c/i2c.c.template: Done\nProcessing main/core/httpd/httpd_kv_handlers.c.template: Done\nProcessing main/core/ble/ble_db.h.template: Done\nProcessing main/core/ble/ble_db.c.template: Done\nProcessing main/core/include_modules.h.template: Done\nProcessing main/core/stat_dump/stat_dump.c.template: Done\n\n```\n\nRun the `make` command to ensure that the newly created module did not wreck everything:\n\n```sh\nmake\nToolchain path: /home/korben/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc\nToolchain version: crosstool-ng-1.22.0-80-g6c4433a\nCompiler version: 5.2.0\nPython requirements from /home/korben/esp-idf/requirements.txt are satisfied.\nApp \"firmware\" version: 24fcccf-dirty\nCC build/app_update/esp_app_desc.o\nAR build/app_update/libapp_update.a\nCC build/main/init.o\n\n[..... BLAH .....]\n\nCC build/main/sht21/sht21.o      \u003c------ This is our new i2c_device\nAR build/main/libmain.a\nGenerating libapp_update.a.sections_info\nGenerating libmain.a.sections_info\nGenerating esp32.common.ld\nLD build/firmware.elf\nesptool.py v2.6-beta1\nTo flash all build output, run 'make flash' or:\npython2 /home/korben/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0xd000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/ota_data_initial.bin 0x1000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/bootloader/bootloader.bin 0x10000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/firmware.bin 0x8000 /home/korben/SuperGreenLab/SuperGreenOSBoilerplate/build/partitions.bin\n```\n\nGood.\n\n### Generated code\n\nNow we have a new directory under `main/sht21/` containing two files `sht21.c` and `sht21.h`, let's get there and open the files with your favorite code editor.\n\nThey look something like this:\n\nsht21.h\n```c\n/*\n * GPL HEADER\n */\n\n#ifndef SHT21_H_\n#define SHT21_H_\n\nvoid init_sht21(int i2cId);\nvoid loop_sht21(int i2cId);\n\n#endif\n```\n\nsht21.c\n```c\n/*\n * GPL HEADER\n */\n\n#include \u003cstdlib.h\u003e\n#include \"sht21.h\"\n#include \"driver/i2c.h\"\n\n#include \"../core/kv/kv.h\"\n#include \"../core/log/log.h\"\n\n#define SHT21_ADDR 0x42\n\nvoid init_sht21(int i2cId) {\n  ESP_LOGI(SGO_LOG_EVENT, \"@SHT21 Initializing sht21 i2c device\\n\");\n  // TODO: write you setup code here\n}\n\nvoid loop_sht21(int i2cId) {\n  // start_i2c();\n  // TODO: write you i2c device read code here\n  // stop_i2c();\n}\n```\n\nThere are two functions defined, `init_sht21` and `loop_sht21`, `loop_sht21` is called repeatedly every few seconds, depending on how many devices you have (only one i2c device can talk at a time).\nThe `init_sht21` method is called once at the very start of the program.\n\n### Driver code\n\nLet's get this straight, and copy those files in the `main/sht21` directory:\n\n- [sht21.c](https://raw.githubusercontent.com/supergreenlab/SuperGreenOS/master/main/sht21/sht21.c)\n- [sht21.h](https://raw.githubusercontent.com/supergreenlab/SuperGreenOS/master/main/sht21/sht21.h)\n\nConnect the sht21 sensor as follows:\n\n```\n\n- PWR: 3.3v\n- GND: GND\n- SDA: 26\n- SCL: 27\ncf. main/core/i2c/i2c.h (these values can be changed through http)\n\n```\n\n## Create sht21 keys in config.json\n\nOpen `config_gen/config/SuperGreenTemp/sht21.cue`.\nWe'll add a temperature and humidity keys, of type integer, accessible over ble and wifi, but read-only.\nWe'll also add a key to indicate if it's present or not.\nAnd we want it to be automatically backed in the flash store. So the value stays there even after a reboot.\n\nYour `sht21.cue` should look like this:\n\n```json\n\npackage config\n\nmodules sht21: _I2C_MODULE \u0026 {\n  array_len: len(_i2c_conf)\n}\n\nmodules sht21 fields \"\\(k)_present\": _INT8 \u0026 _HTTP \u0026 {\n  default: 0\n} for k, v in _i2c_conf\n\nmodules sht21 fields \"\\(k)_temp\": _INT8 \u0026 _HTTP \u0026 _BLE \u0026 {\n  default: 0\n  temp_sensor: 0x1+k\n  ble uuid: \"{0x91,0xb6,0x64,0x14,0xa9,0xba,0x6a,0x30,0x80,0xc1,0x67,0x62,0x25,0xef,0xe0,0xb2}\"\n  ble notify: true\n  helper: \"SHT21 temperature sensor on sensor port #\\(k)\"\n} for k, v in _i2c_conf\n\nmodules sht21 fields \"\\(k)_humi\": _INT8 \u0026 _HTTP \u0026 _BLE \u0026 {\n  default: 0\n  humi_sensor: 0x1+k\n  ble uuid: \"{0x91,0xb6,0x64,0x14,0xa9,0xba,0x6a,0x30,0x80,0xc1,0x67,0x62,0x25,0xef,0xe0,0xb3}\"\n  ble notify: true\n  helper: \"SHT21 humidity sensor on sensor port #\\(k)\"\n} for k, v in _i2c_conf\n\n```\n\nThe `for k, v in _i2c_conf` code means one key for each available i2c ports, `\\(k)` is replaced by the port index.\n\nThis cue configuration will produce keys named:\n\n```\nSHT21_X_PRESENT\nSHT21_X_TEMP\nSHT21_X_HUMI\n```\n\n`X` being replaced by the i2c port number, starting from 0.\n\nNow run the `update_config.sh config_gen/config/SuperGreenTemp config.json \u0026\u0026 ./update_templates.sh config.json` command.\nAnd then `make` to see that everything's ok.\n\nNow that it's setup, you can access the humidity and temperature from the sensor from any modules with the generated functions `get_sht21_temp` and `get_sht21_humi`.\n\n## First run\n\n### Tool setup\n\nAt that point we want to see our key available over ble and http, right ?\n\nSo plug in your esp32, set the right serial port by doing a `make menuconfig` and under `Serial flasher config -\u003e Default serial port` you'll be able to set the port.\n\nFinding the right port depends on your system, on mine (debian) it's /dev/ttyUSBX, X being 0 for small esp32 boards, and should be 1 when using the esp-wrover-kit.\n\nOn macosx I had to change the python version used too, explicitely set `python2` under `SDK tool configuration -\u003e Python 2 interpreter`\n\nNow let's run:\n\n```sh\n\nmake flash monitor\n\n```\n\nAfter some uploading, you should see all the esp's logs (in green) appearing on your screen.\n\nNow there are two options to do the initial setup, by connecting either to its wifi or ble inteface.\n\n### WIFI AP\n\nIn your wifi list, you'll see that the firmware has started its own wifi AP, it's called `🤖🍁`, and the default password is `multipass`.\n\nOnce connected to it, the firmware is accessible as `supergreenosboilerplate.local`.\n\nTo see by yourself you can direct your browser to `http://supergreenosboilerplate.local/fs/app.html`, which will display the admin interface.\n\nThe HTTP API is further explained [here](https://github.com/supergreenlab/SuperGreenOSBoilerplate#http-api)\n\n### BLE\n\nDownload `LightBlue` on the ios and google stores, and start it.\n\nYou should see a device named `🤖🍁`, select it. Now you're connected.\n\nIn the characteristics list you should see a bunch of characteristics, those are the default ones, and at the very last, there's our temperature characteristic, it's name starts with `b2e0`, select it.\n\nNow you can press the `read` button, and it should display, `0`, which is the default value we provided in the config.json file, under the `default` key, at the very last line.\n\nIf you look in the logs of you esp32, you'll see it react when you press the `read` button.\n\n## Create Led module\n\nWe usually want to do something other than monitoring and alerts, in our case we have a temperature value, so we could control a motor based on that for example.\n\nTo illustrate that, we'll just blink a led, the hotter it gets the faster it blinks.\n\n### Boilerplate\n\nJust like we did with the i2c device, we'll use the `templates.sh` script to generate the base code for our module:\n\n```sh\n\n./templates.sh new_module led\n\n```\n\n(things should go roughly as with the i2c device)\n\nRun a `make` to make sure it's ok.\n\n### Generated code\n\nModule files look like i2c devices' files, except that they run their own freeRTOS task.\n\nOpen the generated files in `main/led`:\n\nled.h\n```c\n\n/*\n * [GPL HEADER]\n */\n\n#ifndef LED_H_\n#define LED_H_\n\nvoid init_led();\n\n#endif\n\n```\n\nled.c\n```c\n\n/*\n * [GPL HEADER]\n */\n\n#include \u003cstdlib.h\u003e\n#include \"led.h\"\n\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/task.h\"\n\n#include \"../core/kv/kv.h\"\n#include \"../core/log/log.h\"\n\nstatic void led_task(void *param);\n\nvoid init_led() {\n  ESP_LOGI(SGO_LOG_EVENT, \"@LED Initializing led module\\n\");\n\n  // TODO: write you setup code here\n\n  xTaskCreate(led_task, \"LED\", 4096, NULL, 10, NULL);\n}\n\nstatic void led_task(void *param) {\n  while (true) {\n\n    // TODO: write your loop code here\n\n    vTaskDelay(5 * 1000 / portTICK_PERIOD_MS);\n  }\n}\n```\n\nWe have two functions, `init_led` and `led_task`, `init_led` is called once on startup, and `led_task` is the code of your task.\n\nIn case you have never used freeRTOS before, you can see them as seperate threads.\n\nIf you have already used arduino, it's like a sketch that can run with other sketches at the same time on the same chip. Only difference with a sketch is that you never exit a task (hence the `while(true)`.\n\n### Code the led blinking\n\nThis part shall be left as an exercise for the reader.\n\nHint: [Espressif has done a great job with their examples](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/gpio)\n\n## WIFI Configuration\n\nNow we're going to configure the wifi, it allows the device to reset its internal clock on reboots, update its firmware automatically, and stream its datas to the cloud.\n\nAnother thing it allows is complete control of all the firmware's parameter, ble has limitations (no more than 64 `keys`, for ex.). Http does not, so it's the preferred method to interact with the firmware.\n\n### Through WIFI AP\n\nWhen no wifi station is configured or if connection repeatedly fails, the firmware will start its own wifi AP, it's called `🤖🍁`, and the default password is `multipass`.\n\nOnce connected you can set the wifi credentials with the following commands:\n\n(Try a few times if it complains about unknown host resolution, the firmware broadcast every 10 seconds.)\n```sh\n\ncurl -X POST http://supergreenosboilerplate.local/s?k=WIFI_SSID\u0026v=[ Insert SSID here ]\ncurl -X POST http://supergreenosboilerplate.local/s?k=WIFI_PASSWORD\u0026v=[ Insert Wifi WPA password here ]\n\n```\n\nOnly `wpa` is supported for now.\n\nYou can check the wifi connection status in the log or by repeatedly calling this command, until it says `3`, which means `CONNECTED`\n\n```sh\n\ncurl http://supergreenosboilerplate.local/i?k=WIFI_STATUS\n\n```\n\n### Through BLE\n\nTo configure the wifi with BLE get back to lightblue, and select the characteristic starting with `372f`, it's the `wifi_status` characteristic, click the `subscribe` button, so you'll have a notification when the value changes.\n\nNow select the characteristic starting by `6ca3`, it's the `wifi_ssid` characteristic, press the `write` button in lightblue, and set your SSID, watch out for android users: the strings are in hex, so you can't type it directly, use a service like [this](https://sites.google.com/site/nathanlexwww/tools/utf8-convert) to do the transformation.\n\nDo the same for the `wifi_password`, it starts with `f7e4`.\n\nNow you should have notifications for the `wifi_status` characteristic changing value. You want it to be equal to `3`.\n\nOnce it's done, your firmware will be available as supergreenosboilerplate.local, for example the url [http://supergreenosboilerplate.local/s?k=DEVICE_NAME](http://supergreenosboilerplate.local/s?k=DEVICE_NAME) will print it's name.\nTry a few times if it complains about unknown host resolution, the firmware broadcast every 10 seconds.\n\n## HTTP API\n\nThe HTTP interface allows read and write on the firmware's keys that have a `write: true` attribute in `config.json`, websocket change subscribing is underway.\n\nThe HTTP interface has 2 routes for now `/i` and `/s`, they correspond to the type of the value, `i` for `integer`, and `s` for `string`.\n\nQuery parameters are as follows:\n\n- GET requests: `k` for the key's `name` to get.\n- POST requests: `k` for the key's `name` to set, and `v` for the value to set.\n\nSo to set a new DEVICE_NAME:\n\n```sh\ncurl -X POST http://supergreenosboilerplate.local/s?k=DEVICE_NAME\u0026v=NewName\n```\n\nAnd to get the DEVICE_NAME back:\n\n```sh\ncurl http://supergreenosboilerplate.local/s?k=DEV_NAME\nNewName\n```\n\nAll right, everything seems to be working, let's move on.\n\n## Cloud, Logs and MQTT\n\nNow monitoring and alerts !\n\n### How data is sent to MQTT\n\nNow we have a way to know if it's too hot or too cold, but this would be even more useful if we could get that data when we're not here, or even better, if it could tell us when the temperature leaves a given range.\n\nActually we'd like to know EVERYTHING that is happening inside the chip, there are also stack RAM monitoring that could be useful, or even re-reading the logs to see what might have lead to a crash.\n\nThe boilerplate comes with an mqtt client, to make it simple, and be sure to never lose anything, the firmware simply catches all logs from the code, and sends it directly to an mqtt server.\n\nMQTT is a publish/subscribe protocol, if you haven't used that before, it's like a big hub, clients connect to it, and can publish (send), or subscribe to messages.\n\nWhich means that once the logs are gone in an mqtt server, it's really easy to plug other things to it, like a redis instance to keep the values of all key/value pairs of the system, or a prometheus server to produce nive graphs and alerts.\n\nYou can even connect a voice assistant like Alexa or others. But that's useless.\n\nCheckout the repo [SuperGreenCloud](https://github.com/supergreenlab/SuperGreenCloud), it's a collection of softwares pre-configured, to let you deploy your own cloud in a matter of minutes.\n\n### Setup MQTT configuration\n\nThere is a key pre-configured to set the mqtt broker url: `BROKER_URL`, it's only accessible through wifi.\nTo change it's value:\n\n```sh\n\ncurl -X POST http://supergreenosboilerplate.local/s?k=BROKER_URL\u0026v=[ Enter your URL here ]\n\n```\n\nRestarting is required for changes to take effect (removing this is on the TODO)\n\nNow you should start seeing logs arriving in prometheus and grafana.\n\n### Monitoring\n\nPlease follow the [SuperGreenCloud Quickstart guide](https://github.com/supergreenlab/SuperGreenCloud#quickstart).\n\nWhich will lead you to something like this:\n\n![Graphs 1](assets/sht21-graphs.png?raw=true \"Graphs 1\")\n![Graphs 2](assets/sht21-graphs2.png?raw=true \"Grahs 2\")\n\nLet me know if you need a complete guide, because that's much more work than just typing text:P\n\n### Alert\n\nTODO\n\n## Over-The-Air (OTA) updates\n\nNow that we have our device setup and installed, we don't really want to have to bet back to it with a usb cord and a laptop.\n\nThat's where OTA updates get handy, we only have to place two files on a server online, tell the firmware how to find them, and it'll check periodically if it needs to update itself.\n\nAgain there are a few keys that you can configure to set this up, and they're only accessible through wifi:\n\n- OTA_SERVER_IP: IP address of the server.\n- OTA_SERVER_HOSTNAME: Hostname to set in the `Host: ` http header.\n- OTA_SERVER_PORT: Server port.\n- OTA_VERSION_FILENAME: The path of the file containing the version information, right now it contains a timestamp, that is compared to the timestamp of the build (set at compile time).\n- OTA_FILENAME: The actual firmware file path.\n\n# Keys definition\n\nWIP\n\n# Troubleshoot\n\nRight now SuperGreenLab does not have an official support hotline.\nBut here's a bunch of places where we'll respond:\n\n- [towelie@supergreenlab.com](mailto:towelie@supergreenlab.com)\n- [r/supergreenlab](https://www.reddit.com/r/supergreenlab)\n- [Discord](https://www.supergreenlab.com/discord)\n- [Github issues](https://github.com/supergreenlab/SuperGreenOSBoilerplate/issues)\n\n# Contribute\n\nActually that's the whole purpose of this repository, so what you'll learn on SuperGreenOS can actually be used for other stuffs:)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupergreenlab%2FSuperGreenOSBoilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsupergreenlab%2FSuperGreenOSBoilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupergreenlab%2FSuperGreenOSBoilerplate/lists"}