diff --git a/.github/workflows/ota-update.yml b/.github/workflows/ota-update.yml new file mode 100644 index 0000000..1478615 --- /dev/null +++ b/.github/workflows/ota-update.yml @@ -0,0 +1,46 @@ +name: ESP32 OTA update + +on: + push: + branches: + - 'main' + +jobs: + build: + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Connecting the GitHub workflow to Husarnet VPN network + uses: husarnet/husarnet-action@v2 + with: + join-code: ${{ secrets.HUSARNET_JOINCODE }} + + - name: ESP32 software reset + run: curl -X POST 'http://${{ secrets.HUSARNET_HOSTNAME }}:8080/reset' + + - name: Installing platformio + run: pip3 install -U platformio + + - name: Building a firmware for ESP32 + run: | + export SSID=${{ secrets.WIFI_SSID }} + export PASS=${{ secrets.WIFI_PASS }} + export JOINCODE=${{ secrets.HUSARNET_JOINCODE }} + export HOSTNAME=${{ secrets.HUSARNET_HOSTNAME }} + pio run + + - name: Uploading a firmware to ESP32 + run: > + curl --http0.9 -# -v + -H 'Accept: */*' + -H 'Accept-Encoding: gzip, deflate' + -H 'Connection: keep-alive' + -F "MD5="$(md5sum "${{ github.workspace }}/.pio/build/esp32dev/firmware.bin" | cut -d ' ' -f 1)"" + -F 'firmware=@${{ github.workspace }}/.pio/build/esp32dev/firmware.bin' + 'http://${{ secrets.HUSARNET_HOSTNAME }}:8080/update' + + - name: Stop Husarnet + run: sudo systemctl stop husarnet diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66465ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +src/credentials.h +.vscode/ +firmware.bin +node_modules/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c2f79fa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Husarnet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a6ecdf --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# esp32-internet-ota + +ESP32 + GitHub Actions + Husarnet. + +A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow. + +> **Prerequisites** +> +> Install [Visual Studio Code](https://code.visualstudio.com/) with [PlatformIO extension](https://platformio.org/install/ide?install=vscode). + +## Quick start + +### First setup + +1. Click **[Use this template](https://github.com/husarnet/esp32-internet-ota/generate)** button to create your own copy of this repo. + +2. Clone the repo you have just created and open it in Visual Studio Code. Platformio should automatically install all project dependencies. + +3. Rename `credentials-template.h` to `credentials.h` and type your WiFi an Husarnet credentials there (you will find you Husarnet Join Code at https://app.husarnet.com). + +4. Click "PlatformIO: upload" button to flash your ESP32 board connected to your laptop. You will find the following log in the serial monitor: + + ```bash + ************************************** + GitHub Actions OTA example + ************************************** + + 📻 1. Connecting to: FreeWifi Wi-Fi network .. done + + ⌛ 2. Waiting for Husarnet to be ready ... done + + 🚀 HTTP server started + + Visit: + http://my-esp32:8080/ + + Known hosts: + my-laptop (fc94:a4c1:1f22:ab3b:b04a:1a3b:ba15:84bc) + my-esp32 (fc94:f632:c8d9:d2a6:ad18:ed16:ed7e:9f3f) + ``` + +### Internet OTA with GitHub Actions + +1. Create the folowing GitHub repository secrets (`Settings` > `Secrets` > `New repository secret`): + + | Secret | Sample Value | Desription | + | - | - | - | + | `WIFI_SSID` | FreeWifi | just your WiFi network name | + | `WIFI_PASS` | hardtoguess | ... and password | + | `HUSARNET_HOSTNAME` | my-esp32 | hostname under which you want your ESP32 to be available by other peers | + | `HUSARNET_JOINCODE` | fc94:...:932a/xhfqwPxxxetyCExsSPRPn9 | find your own **secret** Join Code at your user account at https://app/husarnet.com > `choosen network` > `add element` button. Anyone with this Join Code can connect to your Husarnet network | + +2. Push changes to your repo: + + ```bash + git add * + git commit -m "triggering the workflow" + git push + ``` + +3. In ~3 minutes the GitHub workflow should finish its job. Visit: `http://my-esp32:8080` URL with a sample "Hello world" website hosted by your ESP32. + + + Of course your laptop need to be connected to the same Husarnet network - you will find quick start guide showing how to do it here: https://husarnet.com/docs/ + + +## Tips + +### Erasing flash memory of ESP32 + +1. Connect ESP32 to your laptop + +2. Install platformio CLI + + ```bash + pip install -U platformio + ``` + +3. Make flash erase: + + ```bash + pio run --target erase + ``` + +### Monitoring network traffic on `hnet0` interface + +```bash +sudo tcpflow -p -c -i hnet0 +``` + +### Accesing a webserver hosted by ESP32 using a public domain + +Here is a blog post showing how to configure Nginx Proxy Manager to **provide a public access to web servers hosted by Husarnet connected devices**: https://husarnet.com/blog/reverse-proxy-gui + +It can be also used o provide the access to a web server hosted by ESP32 using a nice looking link like: `https://my-awesome-esp32.mydomain.com`. \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..ce01c1f --- /dev/null +++ b/platformio.ini @@ -0,0 +1,29 @@ +[env] +platform = espressif32 +framework = arduino +platform_packages = + framework-arduinoespressif32 @ https://github.com/husarnet/arduino-esp32/releases/download/1.0.4-1/arduino-husarnet-esp32.zip +lib_deps = + ; Until our pull requests are merged you need to use AsyncTCP with our fixes for IPv6 + https://github.com/husarnet/AsyncTCP.git + Husarnet ESP32 + ESP Async WebServer + ayushsharma82/AsyncElegantOTA @ ^2.2.6 + +[env:esp32dev] +board = esp32dev +monitor_speed = 115200 +upload_speed = 921600 + +monitor_filters = esp32_exception_decoder, default + +board_build.partitions = min_spiffs.csv +board_build.embed_txtfiles = + src/index.html + +build_flags = + '-DWIFI_SSID="${sysenv.SSID}"' + '-DWIFI_PASS="${sysenv.PASS}"' + '-DHUSARNET_HOSTNAME="${sysenv.HOSTNAME}"' + '-DHUSARNET_JOINCODE="${sysenv.JOINCODE}"' + diff --git a/src/credentials-template.h b/src/credentials-template.h new file mode 100644 index 0000000..d0404e4 --- /dev/null +++ b/src/credentials-template.h @@ -0,0 +1,8 @@ +// WiFi credentials +const char *ssid = "FreeWifi"; +const char *password = "hardtoguess"; + +// Husarnet credentials +const char *hostName = "my-esp32"; +const char *husarnetJoinCode = "fc94:b01d:1803:8dd8:b293:5c7d:7639:932a/xhfqwPxxxetyCExsSPRPn9"; // find at app.husarnet.com +const char *dashboardURL = "default"; // in you use Husarnet self-hosted Dashboard you can specify URL here. Otherwise keep "default" \ No newline at end of file diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..f2a9435 --- /dev/null +++ b/src/index.html @@ -0,0 +1,9 @@ + + +
+Hello world!
+ + diff --git a/src/simple-webserver.ino b/src/simple-webserver.ino new file mode 100644 index 0000000..20b0f39 --- /dev/null +++ b/src/simple-webserver.ino @@ -0,0 +1,121 @@ +#include