generated from husarnet/esp32-internet-ota
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d8d5a07
Showing
8 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.pio | ||
src/credentials.h | ||
.vscode/ | ||
firmware.bin | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}"' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>ESP32 boilerplate</title> | ||
</head> | ||
<body> | ||
<p>Hello world!</p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#include <AsyncElegantOTA.h> | ||
#include <AsyncTCP.h> | ||
#include <ESPAsyncWebServer.h> | ||
#include <Husarnet.h> | ||
#include <WiFi.h> | ||
|
||
#define HTTP_PORT 8080 | ||
|
||
#if __has_include("credentials.h") | ||
|
||
// For local development (rename credenials-template.h and type your WiFi and | ||
// Husarnet credentials there) | ||
#include "credentials.h" | ||
|
||
#else | ||
|
||
// For GitHub Actions OTA deploment | ||
|
||
// WiFi credentials | ||
const char *ssid = WIFI_SSID; | ||
const char *password = WIFI_PASS; | ||
|
||
// Husarnet credentials | ||
const char *hostName = HUSARNET_HOSTNAME; | ||
const char *husarnetJoinCode = HUSARNET_JOINCODE; // find at app.husarnet.com | ||
const char *dashboardURL = "default"; | ||
|
||
#endif | ||
|
||
AsyncWebServer server(HTTP_PORT); | ||
|
||
// index.html available in "index_html" const String | ||
extern const char index_html_start[] asm("_binary_src_index_html_start"); | ||
const String index_html = String((const char*)index_html_start); | ||
|
||
void setup(void) { | ||
// =============================================== | ||
// Wi-Fi, OTA and Husarnet VPN configuration | ||
// =============================================== | ||
|
||
// remap default Serial (used by Husarnet logs) | ||
Serial.begin(115200, SERIAL_8N1, 16, 17); // from P3 & P1 to P16 & P17 | ||
Serial1.begin(115200, SERIAL_8N1, 3, 1); // remap Serial1 from P9 & P10 to P3 & P1 | ||
|
||
Serial1.println("\r\n**************************************"); | ||
Serial1.println("GitHub Actions OTA example"); | ||
Serial1.println("**************************************\r\n"); | ||
|
||
// Init Wi-Fi | ||
Serial1.printf("📻 1. Connecting to: %s Wi-Fi network ", ssid); | ||
|
||
WiFi.mode(WIFI_STA); | ||
WiFi.begin(ssid, password); | ||
while (WiFi.status() != WL_CONNECTED) { | ||
static int cnt = 0; | ||
delay(500); | ||
Serial1.print("."); | ||
cnt++; | ||
if (cnt > 10) { | ||
ESP.restart(); | ||
} | ||
} | ||
|
||
Serial1.println(" done\r\n"); | ||
|
||
// Init Husarnet P2P VPN service | ||
Serial1.printf("⌛ 2. Waiting for Husarnet to be ready "); | ||
|
||
Husarnet.selfHostedSetup(dashboardURL); | ||
Husarnet.join(husarnetJoinCode, hostName); | ||
Husarnet.start(); | ||
|
||
// Before Husarnet is ready peer list contains: | ||
// master (0000:0000:0000:0000:0000:0000:0000:0001) | ||
const uint8_t addr_comp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; | ||
bool husarnetReady = 0; | ||
while (husarnetReady == 0) { | ||
Serial1.print("."); | ||
for (auto const &host : Husarnet.listPeers()) { | ||
if (host.first == addr_comp) { | ||
; | ||
} else { | ||
husarnetReady = 1; | ||
} | ||
} | ||
delay(1000); | ||
} | ||
|
||
Serial1.println(" done\r\n"); | ||
|
||
// define HTTP API for remote reset | ||
server.on("/reset", HTTP_POST, [](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Reseting ESP32 after 1s ..."); | ||
Serial1.println("Software reset on POST request"); | ||
delay(1000); | ||
ESP.restart(); | ||
}); | ||
|
||
// Init OTA webserver (available under /update path) | ||
AsyncElegantOTA.begin(&server); | ||
server.begin(); | ||
|
||
// =============================================== | ||
// PLACE YOUR APPLICATION CODE BELOW | ||
// =============================================== | ||
|
||
// Example webserver hosting table with known Husarnet Hosts | ||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { | ||
request->send(200, "text/html", index_html); | ||
}); | ||
|
||
Serial1.println("🚀 HTTP server started\r\n"); | ||
Serial1.printf("Visit:\r\nhttp://%s:%d/\r\n\r\n", hostName, HTTP_PORT); | ||
|
||
Serial1.printf("Known hosts:\r\n"); | ||
for (auto const &host : Husarnet.listPeers()) { | ||
Serial1.printf("%s (%s)\r\n", host.second.c_str(), host.first.toString().c_str()); | ||
} | ||
} | ||
|
||
void loop(void) { ; } |