diff --git a/.gitignore b/.gitignore index 2e8aa0a1..817f7418 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ .gcc-flags.json *Thumbs.db /data/www -/lib/framework/WWWData.h /interface/build /interface/node_modules /interface/.eslintcache @@ -12,4 +11,8 @@ node_modules /releases /src/certs /temp - +/build/firmware +/lib/framework/WWWData.h +*WWWData.h +lib/framework/WWWData.h +ssl_certs/cacert.pem diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bdde00e..4807de4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,114 @@ All notable changes to this project will be documented in this file. -## [0.2.2] +## [0.3.0] - 2023-02-05 + +> [!CAUTION] +> This update has breaking changes! + +This is a major change getting rid of all ESPAsyncTCP and ESPAsyncWebserver dependencies. Despite their popularity they are plagued with countless bugs, since years unmaintained, not SSL capable and simply not suitable for a production build. Although several attempts exist to fix the most pressing bugs even these libraries lead to frequent crashes. This new version replaces them with ESP-IDF based components. [PsychicHttp](https://github.com/hoeken/PsychicHttp) and [PsychicMqttClient](https://github.com/theelims/PsychicMqttClient) both wrap the ESP-IDF components in a familiar wrapper for easy porting of the code base. However, this will break existing code and will require some effort on your codebase. In return the stability is improved greatly and the RAM usage more friendly. Now e.g. running Bluetooth in parallel becomes possible. + +### Added + +- Added postscript to platform.io build process to copy, rename and calculate MD5 checksum of \*.bin file. These files are ready for uploading to the Github Release page. +- Added more information to SystemStatus API +- Added generateToken API for security settings +- Added Multi-WiFi capability. Add up to five WiFi configurations and connect to either strongest network (default), or by priority. +- Added InfoDialog as a simpler version of the ConfirmDialog for a simple notification modal. +- Added Adafruit certificate repository as the default choice for the X509 certificate bundle. + +### Changed + +- Better route protection for user page with deep link. +- Changed build_interface.py script to check for modified files in the interface sources before re-building the interface. Saves some time on the compilation process. +- Upload firmware binary allows uploading of MD5 checksum file in advance to verify downloaded firmware package. +- GithubFirmwareManager checks against PIO build_target in filename to support Github OTA for binaries build for various targets. You should rename your old release \*.bin files on the Github release pages for backward compatibility. +- Changed MQTT Client to an ESP-IDF backed one which supports SSL/TLS X509 root CA bundles and transport over WS. +- Changed the `PROGMEM_WWW` flag to `EMBED_WWW` as there is technically speaking no PROGMEM on ESP32's. +- Updated dependencies to the latest version. Except SvelteKit. + +### Fixed + +- Fixed reactivity of System Status page. + +### Removed + +- Removed support for Arduino ESP OTA. +- HttpEndpoints and Websocket Server without a securityManager are no longer possible. + +### Migrate from ESPAsyncWebServer to PsychicHttp + +#### Migrate `main.cpp` + +Change the server and ESPSvelteKit instances to PsychicHttpServer and give the ESP32SvelteKit constructor the number of http endpoints of your project. + +``` +PsychicHttpServer server; +ESP32SvelteKit esp32sveltekit(&server, 120); +``` + +Remove `server.begin();` in `void setup()`. This is handled by ESP32SvelteKit now. + +#### Migrate `platformio.ini` + +Remove the following `build_flags`: + +```ini + ; Increase queue size of SSE and WS + -D SSE_MAX_QUEUED_MESSAGES=64 + -D WS_MAX_QUEUED_MESSAGES=64 + -D CONFIG_ASYNC_TCP_RUNNING_CORE=0 + -D NO_GLOBAL_ARDUINOOTA + -D PROGMEM_WWW +``` + +Add the following `build_flags` and adjust to your app, if needed: + +```ini + -D BUILD_TARGET=\"$PIOENV\" + -D APP_NAME=\"ESP32-Sveltekit\" ; Must only contain characters from [a-zA-Z0-9-_] as this is converted into a filename + -D APP_VERSION=\"0.3.0\" ; semver compatible version string + -D EMBED_WWW +``` + +Remove the lib dependency `esphome/AsyncTCP-esphome @ ^2.0.0` and add `https://github.com/theelims/PsychicMqttClient.git` + +Consider adjusting `board_ssl_cert_source = adafruit`, so that the new MQTT client has universal SSL/TLS support with a wide range of CA root certificates. + +#### Migrate `factory_settings.ini` + +The new MQTT client has slightly renamed factory settings: + +```ini + ; MQTT settings + -D FACTORY_MQTT_ENABLED=false + -D FACTORY_MQTT_URI=\"mqtts://mqtt.eclipseprojects.io:8883\" + -D FACTORY_MQTT_USERNAME=\"\" ; supports placeholders + -D FACTORY_MQTT_PASSWORD=\"\" + -D FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\" ; supports placeholders + -D FACTORY_MQTT_KEEP_ALIVE=120 + -D FACTORY_MQTT_CLEAN_SESSION=true +``` + +Max Topic Length is no longer needed. + +#### Custom Stateful Services + +Adapt the class constructor (`(PsychicHttpServer *server, ...`) to PsychicHttpServer. + +Due to the loading sequence HttpEndoint and WebsocketServer both have gotten a `begin()` function to register their http endpoints with the server. This must be called in your stateful services' own `begin()` function: + +```cpp +void LightStateService::begin() +{ + _httpEndpoint.begin(); + _webSocketServer.begin(); + _state.ledOn = DEFAULT_LED_STATE; + onConfigUpdated(); +} +``` + +## [0.2.2] - 2023-10-08 ### Added @@ -53,7 +160,7 @@ All notable changes to this project will be documented in this file. - Compiler flag on which core ESP32-sveltekit tasks should run - Renamed WebSocketRxTx.h to WebSocketServer.h to create a distinction between WS Client and WS Server interfaces - Made code of LightStateExample slightly more verbose -- getServer() returning a pointer to the AsnycWebServer instance. +- getServer() returning a pointer to the AsyncWebServer instance. - Updated frontend dependencies and packages to newest version. ### Depreciated diff --git a/ESP32-sveltekit.code-workspace b/ESP32-sveltekit.code-workspace index 47c4d4bb..d2bc1285 100644 --- a/ESP32-sveltekit.code-workspace +++ b/ESP32-sveltekit.code-workspace @@ -9,7 +9,56 @@ "*.tcc": "cpp", "algorithm": "cpp", "esp32-hal-misc.c": "cpp", - "esp_crt_bundle.h": "c" + "esp_crt_bundle.h": "c", + "functional": "cpp", + "array": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "regex": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "unordered_set": "cpp", + "iomanip": "cpp" } } } diff --git a/README.md b/README.md index f0dedb11..0f5c3f5c 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,11 @@ Manage different user of your app with two authorization levels. An administrato ### :airplane: OTA Upgrade Service -The framework can provide three different channels for Over-the-Air updates. Either an ArduinoOTA port for updates directly from the IDE, by uploading a \*.bin file from the web interface. Or by pulling a firmware image from an update server. This is implemented with the github release page as an example. +The framework can provide two different channels for Over-the-Air updates. Either by uploading a \*.bin file from the web interface. Or by pulling a firmware image from an update server. This is implemented with the github release page as an example. It is even possible to have different build environments at the same time and the Github OTA process pulls the correct binary. ### :building_construction: Automated Build Chain -The automated build chain takes out the pain and tears of getting all the bits and pieces play nice together. The repository contains a PlatformIO project at its heart. A SvelteKit project for the frontend code and a mkdocs project for the documentation go alongside. The PlatformIO build tools not only build the SvelteKit frontend with Vite, but also ensure that the build results are gzipped and find their way into the flash memory of the ESP32. You have two choices to serve the frontend either from the flash partition, or embedded into the firmware binary from PROGMEM. The latter is much more friendly if your frontend code should be distributed OTA as well, leaving all configuration files intact. +The automated build chain takes out the pain and tears of getting all the bits and pieces play nice together. The repository contains a PlatformIO project at its heart. A SvelteKit project for the frontend code and a mkdocs project for the documentation go alongside. The PlatformIO build tools not only build the SvelteKit frontend with Vite, but also ensure that the build results are gzipped and find their way into the flash memory of the ESP32. You have two choices to serve the frontend either from the flash partition, or embedded into the firmware binary. The latter is much more friendly if your frontend code should be distributed OTA as well, leaving all configuration files intact. ### :icecream: Compatible with all ESP32 Flavours @@ -57,9 +57,10 @@ The code runs on many variants of the ESP32 chip family. From the plain old ESP3 - [tabler ICONS](https://tabler-icons.io/) - [unplugin-icons](https://github.com/antfu/unplugin-icons) - [svelte-modals](https://svelte-modals.mattjennings.io/) +- [svelte-dnd-list](https://github.com/tarb/svelte-dnd-list) - [ArduinoJson](https://github.com/bblanchon/ArduinoJson) -- [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) -- [AsyncMqttClient](https://github.com/marvinroger/async-mqtt-client) +- [PsychicHttp](https://github.com/hoeken/PsychicHttp) +- [PsychicMqttClient](https://github.com/theelims/PsychicMqttClient) ## Licensing diff --git a/docs/buildprocess.md b/docs/buildprocess.md index 889b428f..aca855b1 100644 --- a/docs/buildprocess.md +++ b/docs/buildprocess.md @@ -1,22 +1,22 @@ # Build Process -The build process is controlled by [platformio.ini](https://github.com/theelims/ESP32-sveltekit/platformio.ini) and automates the build of the front end website with Vite as well as the binary compilation for the ESP32 firmware. Whenever PlatformIO is triggered with the `upload` command this process will call the python script [build_interface.py](https://github.com/theelims/ESP32-sveltekit/scripts/build_interface.py) to action. It will start the Vite build and gzip the resulting files either to the `data/` directory or embed them into a header file. If necessary a file system image for the flash is created for the default build environment and upload to the ESP32 prior to compiling the firmware binary. +The build process is controlled by [platformio.ini](https://github.com/theelims/ESP32-sveltekit/platformio.ini) and automates the build of the front end website with Vite as well as the binary compilation for the ESP32 firmware. Whenever PlatformIO is building a new binary it will call the python script [build_interface.py](https://github.com/theelims/ESP32-sveltekit/scripts/build_interface.py) to action. It will check the frontend files for changes. If necessary it will start the Vite build and gzip the resulting files either to the `data/` directory or embed them into a header file. In case the WWW files go into a LITTLEFS partition a file system image for the flash is created for the default build environment and upload to the ESP32. -## Serving from Flash or PROGMEM +## Serving from Flash or Embedding into the Binary -The front end website can be served either from the SPIFFS partition of the flash, or embedded into the firmware binary from PROGMEM (default). Later has the advantage that only one binary needs to be distributed easing the OTA process. Further more this is desirable if you like to preserve the settings stored in the SPIFFS partition, or have other files there that need to survive a firmware update. To serve from the SPIFFS partition instead please comment the following build flag out: +The front end website can be served either from the LITTLEFS partition of the flash, or embedded into the firmware binary (default). Later has the advantage that only one binary needs to be distributed easing the OTA process. Further more this is desirable if you like to preserve the settings stored in the LITTLEFS partition, or have other files there that need to survive a firmware update. To serve from the LITTLEFS partition instead please comment the following build flag out: ```ini build_flags = ... - -D PROGMEM_WWW + -D EMBED_WWW ``` ### Partitioning -If you choose to serve the frontend from PROGMEM (default) it becomes part of the firmware binary. As many ESP32 modules only come with 4MB built-in flash this results in the binary being too large for the reserved flash. Therefor a partition scheme with a larger section for the executable code is selected. However, this limits the SPIFFS partition to 200kb. There are a great number of [default partition tables](https://github.com/espressif/arduino-esp32/tree/master/tools/partitions) for Arduino-ESP32 to choose from. If you have 8MB or 16MB flash this would be your first choice. If you don't need OTA you can choose a partition scheme without OTA. +If you choose to embed the frontend it becomes part of the firmware binary (default). As many ESP32 modules only come with 4MB built-in flash this results in the binary being too large for the reserved flash. Therefor a partition scheme with a larger section for the executable code is selected. However, this limits the LITTLEFS partition to 200kb. There are a great number of [default partition tables](https://github.com/espressif/arduino-esp32/tree/master/tools/partitions) for Arduino-ESP32 to choose from. If you have 8MB or 16MB flash this would be your first choice. If you don't need OTA you can choose a partition scheme without OTA. -Should you want to deploy the frontend from the flash's SPIFFS partition on a 4MB chip you need to comment out the following two lines. Otherwise the 200kb will not be large enough to host the front end code. +Should you want to deploy the frontend from the flash's LITTLEFS partition on a 4MB chip you need to comment out the following two lines. Otherwise the 200kb will not be large enough to host the front end code. ```ini board_build.partitions = min_spiffs.csv @@ -32,7 +32,6 @@ Customize the settings as you see fit. A value of 0 will disable the specified f -D FT_SECURITY=1 -D FT_MQTT=1 -D FT_NTP=1 - -D FT_OTA=1 -D FT_UPLOAD_FIRMWARE=1 -D FT_DOWNLOAD_FIRMWARE=1 -D FT_SLEEP=1 @@ -44,7 +43,6 @@ Customize the settings as you see fit. A value of 0 will disable the specified f | FT_SECURITY | Controls whether the [security features](statefulservice.md#security-features) are enabled. Disabling this means you won't need to authenticate to access the device and all authentication predicates will be bypassed. | | FT_MQTT | Controls whether the MQTT features are enabled. Disable this if your project does not require MQTT support. | | FT_NTP | Controls whether network time protocol synchronization features are enabled. Disable this if your project does not require accurate time. | -| FT_OTA | Controls whether ArduinoOTA update support is enabled. Disable this if you won't be using the remote update feature. | | FT_UPLOAD_FIRMWARE | Controls whether the manual upload firmware feature is enabled. Disable this if you won't be manually uploading firmware. | | FT_DOWNLOAD_FIRMWARE | Controls whether the firmware download feature is enabled. Disable this if you won't firmware pulled from a server. | | FT_SLEEP | Controls whether the deep sleep feature is enabled. Disable this if your device is not battery operated or you don't need to place it in deep sleep to save energy. | @@ -80,7 +78,7 @@ By default, the factory settings configure two user accounts with the following | admin | admin | | guest | guest | -It is recommended that you change the user credentials from their defaults better protect your device. You can do this in the user interface, or by modifying [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini) as mentioned above. +It is recommended that you change the user credentials from their defaults to better protect your device. You can do this in the user interface, or by modifying [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini) as mentioned above. ### Customizing the factory time zone setting @@ -127,7 +125,17 @@ build_flags = -DCORE_DEBUG_LEVEL=5 ``` -It accepts values from 1 (Verbose) to 5 (Errors) for different information depths to be logged on the serial terminal. +It accepts values from 5 (Verbose) to 1 (Errors) for different information depths to be logged on the serial terminal. If commented out there won't be debug messages from the core libraries. For a production build you should comment this out. + +### Serve Config Files + +By enabling this build flag the ESP32 will serve all config files stored on the LittleFS flash partition under `http:\\[IP]\config\[filename].json`. This can be helpful to troubleshoot problems. However, it is strongly advised to disable this for production builds. + +```ini +build_flags = +... + -D SERVE_CONFIG_FILES +``` ### Serve Config Files @@ -141,16 +149,16 @@ build_flags = ## SSL Root Certificate Store -Some features like firmware download require a SSL connection. For that the SSL Root CA certificate must be known to the ESP32. The build system contains a python script derived from Espressif ESP-IDF building a certificate store containing one or more certificates. In order to create the store you must uncomment the three lines below in `platformio.ini`. +Some features like firmware download or the MQTT client require a SSL connection. For that the SSL Root CA certificate must be known to the ESP32. The build system contains a python script derived from Espressif ESP-IDF building a certificate store containing one or more certificates. In order to create the store you must uncomment the three lines below in `platformio.ini`. ```ini extra_scripts = pre:scripts/generate_cert_bundle.py board_build.embed_files = src/certs/x509_crt_bundle.bin -board_ssl_cert_source = folder +board_ssl_cert_source = adafruit ``` -The script will download a public certificate store from Mozilla, builds a binary containing all certs and embeds this into the firmware. This will add ~65kb to the firmware image. Should you only need a few known certificates you can place their `*.pem` or `*.der` files in the [ssl_certs](https://github.com/theelims/ESP32-sveltekit/blob/main/ssl_certs) folder and change `board_ssl_cert_source = folder`. Then only these certificates will be included in the store. This is especially useful, if you only need to connect to know servers and need to shave some kb off the firmware image: +The script will download a public certificate store from Mozilla (`board_ssl_cert_source = mozilla`) or a repository curated by Adafruit (`board_ssl_cert_source = adafruit`), builds a binary containing all certs and embeds this into the firmware. This will add ~65kb to the firmware image. Should you only need a few known certificates you can place their `*.pem` or `*.der` files in the [ssl_certs](https://github.com/theelims/ESP32-sveltekit/blob/main/ssl_certs) folder and change `board_ssl_cert_source = folder`. Then only these certificates will be included in the store. This is especially useful, if you only need to connect to know servers and need to shave some kb off the firmware image: !!! info diff --git a/docs/components.md b/docs/components.md index 46b129ec..bd745bd5 100644 --- a/docs/components.md +++ b/docs/components.md @@ -81,7 +81,7 @@ Three slots are available. Besides the main slot for the content there is a name The component exports two properties to determine its behavior. `collapsible` is a boolean describing wether the component should behave like a collapsible in the first place. `open` is a boolean as well and if set true shows the full content of the body on mount. -## Spinner (OBSOLETE) +## Spinner A small component showing an animated spinner which can be used while waiting for data. @@ -117,3 +117,41 @@ This is a modal showing the update progress, possible error messages and makes a ## Update Indicator The update indicator is a small widget shown in the upper right corner of the status bar. It indicates the availability of a newer stable firmware release then the current one. Upon pressing the icon it will automatically update the firmware to the latest stable release. By default this works through the Github Latest Release API. This must be customized should you use a different update server. Have a look at the [source file](https://github.com/theelims/ESP32-sveltekit/blob/main/interface/src/lib/components/GithubUpdateDialog.svelte) to see what portions to update. + +## Info Dialog + +Shows a modal on the UI which must be deliberately dismissed. It features a `title` and a `message` property. The dismiss button can be customized via the `dismiss` property with a label and an icon. `onDismiss` call back must close the modal and can be used to do something when closing the info dialog. + +```ts +import InfoDialog from "$lib/components/InfoDialog.svelte"; + +openModal(InfoDialog, { + title: 'You have a new Info', + message: + 'Something really important happened that justifies showing you a modal which must be clicked away.', + dismiss: { label: 'OK', icon: Check }, + onDismiss: () => closeModal(); +}); +``` + +This modal is based on [svelte-modals](https://svelte-modals.mattjennings.io/) where you can find further information. + +## Confirm Dialog + +Shows a confirm modal on the UI which must be confirmed to proceed, or can be canceled. It features a `title` and a `message` property. The `confirm` and `cancel` buttons can be customized via the `labels` property with a label and an icon. `onConfirm` call back must close the modal and can be used to do proceed. + +```ts +import ConfirmDialog from "$lib/components/ConfirmDialog.svelte"; + +openModal(ConfirmDialog, { + title: "Confirm what you are doing", + message: "Are you sure you want to proceed? This could break stuff!", + labels: { + cancel: { label: "Abort", icon: Cancel }, + confirm: { label: "Confirm", icon: Check }, + }, + onConfirm: () => closeModal(), +}); +``` + +This modal is based on [svelte-modals](https://svelte-modals.mattjennings.io/) where you can find further information. diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index b7d74c68..3feca409 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -78,7 +78,7 @@ If your board is not listed in the platformio.ini you may look in the [official !!! info "Default setup is for an ESP32-S3-DevKitC/M board" - The projects platformio.ini defaults for an ESP32-S3-DevKitC/M board by Espressif connected to the UART USB port. If you use an other board and the projects shows undesired a behavior it is likely that some parts do not match with pin definitions. + The projects platformio.ini defaults for an ESP32-S3-DevKitC/M board by Espressif connected to the UART USB port. If you use an other board and the projects shows an undesired behavior it is likely that some parts do not match with pin definitions. ### Build & Upload Process @@ -86,7 +86,7 @@ After you've changed [platformio.ini](https://github.com/theelims/ESP32-svelteki ![PIO Build](media/PIO-upload.png) -The first build process will take a while. After a couple of minutes you can see the ESP32 outputting information on the terminal. +The first build process will take a while. After a couple of minutes you can see the ESP32 outputting information on the terminal. Some of the python scripts might need to install additional packages. In that case the first build process will fail. Just run it a second time. !!! tip "Use several terminals in parallel" @@ -119,10 +119,6 @@ proxy: { You must restart the development server for changes of the proxy location to come into effect. -!!! tip - - You can (optionally) speed up the build by commenting out the call to build_interface.py under "extra scripts" during local development. This will prevent the npm process from building the production release every time the firmware is compiled significantly decreasing the build time. - ### Development Server The interface comes with Vite as a development server. It allows hot module reloading reflecting code changes to the front end instantly in your browser. Open a new terminal session and execute the following commands: diff --git a/docs/index.md b/docs/index.md index ef573501..5c855a7d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -43,11 +43,11 @@ Manage different user of your app with two authorization levels. An administrato ### :airplane: OTA Upgrade Service -The framework can provide three different channels for Over-the-Air updates. Either an ArduinoOTA port for updates directly from the IDE, by uploading a \*.bin file from the web interface. Or by pulling a firmware image from an update server. This is implemented with the github release page as an example. +The framework can provide two different channels for Over-the-Air updates. Either by uploading a \*.bin file from the web interface. Or by pulling a firmware image from an update server. This is implemented with the github release page as an example. It is even possible to have different build environments at the same time and the Github OTA process pulls the correct binary. ### :construction_site: Automated Build Chain -The automated build chain takes out the pain and tears of getting all the bits and pieces play nice together. The repository contains a PlatformIO project at its heart. A SvelteKit project for the frontend code and a mkdocs project for the documentation go alongside. The PlatformIO build tools not only build the SvelteKit frontend with Vite, but also ensure that the build results are gzipped and find their way into the flash memory of the ESP32. You have two choices to serve the frontend either from the flash partition, or embedded into the firmware binary from PROGMEM. The latter is much more friendly if your frontend code should be distributed OTA as well, leaving all configuration files intact. +The automated build chain takes out the pain and tears of getting all the bits and pieces play nice together. The repository contains a PlatformIO project at its heart. A SvelteKit project for the frontend code and a mkdocs project for the documentation go alongside. The PlatformIO build tools not only build the SvelteKit frontend with Vite, but also ensure that the build results are gzipped and find their way into the flash memory of the ESP32. You have two choices to serve the frontend either from the flash partition, or embedded into the firmware binary. The latter is much more friendly if your frontend code should be distributed OTA as well, leaving all configuration files intact. ### :fontawesome-solid-microchip: Compatible with all ESP32 Flavours diff --git a/docs/restfulapi.md b/docs/restfulapi.md index b60cbd22..b4deb869 100644 --- a/docs/restfulapi.md +++ b/docs/restfulapi.md @@ -2,32 +2,31 @@ The back end exposes a number of API endpoints which are referenced in the table below. -| Method | Request URL | Authentication | POST JSON Body | Info | -| ------ | ------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -| GET | /rest/features | `NONE_REQUIRED` | none | Tells the client which features of the UI should be use | -| GET | /rest/otaSettings | `IS_ADMIN` | none | Retriev current OTA settings | -| POST | /rest/otaSettings | `IS_ADMIN` | `{"enabled": true,"port": 8266,"password": "esp-sveltekit"}` | Update OTA settings | -| GET | /rest/mqttStatus | `IS_AUTHENTICATED` | none | Current MQTT connection status | -| GET | /rest/mqttSettings | `IS_ADMIN` | none | Currently used MQTT settings | -| POST | /rest/mqttSettings | `IS_ADMIN` | `{"enabled":false,"host":"test.mosquitto.org","port":1883,"username":"","password":"","client_id":"esp32-e89f6d20372c","keep_alive":60,"clean_session":true,"max_topic_length":128}` | Update MQTT settings with new parameters | -| GET | /rest/ntpStatus | `IS_AUTHENTICATED` | none | Current NTP connection status | -| GET | /rest/ntpSettings | `IS_ADMIN` | none | Current NTP settings | -| POST | /rest/ntpSettings | `IS_ADMIN` | `{"enabled": true,"server": "time.google.com","tz_label": "Europe/London","tz_format": "GMT0BST,M3.5.0/1,M10.5.0"}` | Update the NTP settings | -| GET | /rest/apStatus | `IS_AUTHENTICATED` | none | Current AP status and client information | -| GET | /rest/apSettings | `IS_ADMIN` | none | Current AP settings | -| POST | /rest/apSettings | `IS_ADMIN` | `{"provision_mode": 1,"ssid": "ESP32-SvelteKit-e89f6d20372c","password": "esp-sveltekit","channel": 1,"ssid_hidden": false,"max_clients": 4,"local_ip": "192.168.4.1","gateway_ip": "192.168.4.1","subnet_mask": "255.255.255.0"}` | Update AP settings | -| GET | /rest/wifiStatus | `IS_AUTHENTICATED` | none | Current status of the wifi client connection | -| GET | /rest/scanNetworks | `IS_ADMIN` | none | Async Scan for Networks in Range | -| GET | /rest/listNetworks | `IS_ADMIN` | none | List networks in range after succesfull scanning. Otherwise triggers scanning. | -| GET | /rest/wifiSettings | `IS_ADMIN` | none | Current WiFi settings | -| POST | /rest/wifiSettings | `IS_ADMIN` | `{"ssid":"YourSSID","password":"YourPassword","hostname":"esp32-sveltekit","static_ip_config":false}` | Udate WiFi settings and credentials | -| GET | /rest/systemStatus | `IS_AUTHENTICATED` | none | Get system informations about the ESP. | -| POST | /rest/restart | `IS_ADMIN` | none | Restart the ESP32 | -| POST | /rest/factoryReset | `IS_ADMIN` | none | Reset the ESP32 and all settings to their default values | -| POST | /rest/uploadFirmware | `IS_ADMIN` | none | File upload of firmware.bin | -| POST | /rest/signIn | `NONE_REQUIRED` | `{"password": "admin","username": "admin"}` | Signs a user in and returns access token | -| GET | /rest/securitySettings | `IS_ADMIN` | none | retrieves all user information and roles | -| POST | /rest/securitySettings | `IS_ADMIN` | `{"jwt_secret": "734cb5bb-5597b722", "users": [{"username": "admin", "password": "admin", "admin": true}, {"username": "guest", "password": "guest", "admin": false, }]` | retrieves all user information and roles | -| GET | /rest/verifyAuthorization | `NONE_REQUIRED` | none | Verifies the content of the auth bearer token | -| POST | /rest/sleep | `IS_AUTHENTICATED` | none | Puts the device in deep sleep mode | -| POST | /rest/downloadUpdate | `IS_ADMIN` | `{"download_url": "https://github.com/theelims/ESP32-sveltekit/releases/download/v0.1.0/firmware_esp32s3.bin"}` | Download link for OTA | +| Method | Request URL | Authentication | POST JSON Body | Info | +| ------ | --------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| GET | /rest/features | `NONE_REQUIRED` | none | Tells the client which features of the UI should be use | +| GET | /rest/mqttStatus | `IS_AUTHENTICATED` | none | Current MQTT connection status | +| GET | /rest/mqttSettings | `IS_ADMIN` | none | Currently used MQTT settings | +| POST | /rest/mqttSettings | `IS_ADMIN` | `{"enabled":false,"uri":"mqtt://192.168.1.12:1883","username":"","password":"","client_id":"esp32-f412fa4495f8","keep_alive":120,"clean_session":true}` | Update MQTT settings with new parameters | +| GET | /rest/ntpStatus | `IS_AUTHENTICATED` | none | Current NTP connection status | +| GET | /rest/ntpSettings | `IS_ADMIN` | none | Current NTP settings | +| POST | /rest/ntpSettings | `IS_ADMIN` | `{"enabled": true,"server": "time.google.com","tz_label": "Europe/London","tz_format": "GMT0BST,M3.5.0/1,M10.5.0"}` | Update the NTP settings | +| GET | /rest/apStatus | `IS_AUTHENTICATED` | none | Current AP status and client information | +| GET | /rest/apSettings | `IS_ADMIN` | none | Current AP settings | +| POST | /rest/apSettings | `IS_ADMIN` | `{"provision_mode": 1,"ssid": "ESP32-SvelteKit-e89f6d20372c","password": "esp-sveltekit","channel": 1,"ssid_hidden": false,"max_clients": 4,"local_ip": "192.168.4.1","gateway_ip": "192.168.4.1","subnet_mask": "255.255.255.0"}` | Update AP settings | +| GET | /rest/wifiStatus | `IS_AUTHENTICATED` | none | Current status of the wifi client connection | +| GET | /rest/scanNetworks | `IS_ADMIN` | none | Async Scan for Networks in Range | +| GET | /rest/listNetworks | `IS_ADMIN` | none | List networks in range after successful scanning. Otherwise triggers scanning. | +| GET | /rest/wifiSettings | `IS_ADMIN` | none | Current WiFi settings | +| POST | /rest/wifiSettings | `IS_ADMIN` | `{"hostname":"esp32-f412fa4495f8","priority_RSSI":true,"wifi_networks":[{"ssid":"YourSSID","password":"YourPassword","static_ip_config":false}]}` | Update WiFi settings and credentials | +| GET | /rest/systemStatus | `IS_AUTHENTICATED` | none | Get system information about the ESP. | +| POST | /rest/restart | `IS_ADMIN` | none | Restart the ESP32 | +| POST | /rest/factoryReset | `IS_ADMIN` | none | Reset the ESP32 and all settings to their default values | +| POST | /rest/uploadFirmware | `IS_ADMIN` | none | File upload of firmware.bin | +| POST | /rest/signIn | `NONE_REQUIRED` | `{"password": "admin","username": "admin"}` | Signs a user in and returns access token | +| GET | /rest/securitySettings | `IS_ADMIN` | none | retrieves all user information and roles | +| POST | /rest/securitySettings | `IS_ADMIN` | `{"jwt_secret": "734cb5bb-5597b722", "users": [{"username": "admin", "password": "admin", "admin": true}, {"username": "guest", "password": "guest", "admin": false, }]}` | retrieves all user information and roles | +| GET | /rest/verifyAuthorization | `NONE_REQUIRED` | none | Verifies the content of the auth bearer token | +| GET | /rest/generateToken?username={username} | `IS_ADMIN` | `{"token": "734cb5bb-5597b722"}` | Generates a new JWT token for the user from username | +| POST | /rest/sleep | `IS_AUTHENTICATED` | none | Puts the device in deep sleep mode | +| POST | /rest/downloadUpdate | `IS_ADMIN` | `{"download_url": "https://github.com/theelims/ESP32-sveltekit/releases/download/v0.1.0/firmware_esp32s3.bin"}` | Download link for OTA. This requires a valid SSL certificate and will follow redirects. | diff --git a/docs/statefulservice.md b/docs/statefulservice.md index f0b00aac..1b7a9f92 100644 --- a/docs/statefulservice.md +++ b/docs/statefulservice.md @@ -1,20 +1,22 @@ # Developing with the Framework -The back end is a set of REST endpoints hosted by a [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) instance. The ['lib/framework'](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework) directory contains the majority of the back end code. The framework contains a number of useful utility classes which you can use when extending it. The project also comes with a demo project to give you some help getting started. +The back end is a set of REST endpoints hosted by a [PsychicHttp](https://github.com/hoeken/PsychicHttp) instance. The ['lib/framework'](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework) directory contains the majority of the back end code. The framework contains a number of useful utility classes which you can use when extending it. The project also comes with a demo project to give you some help getting started. The framework's source is split up by feature, for example [WiFiScanner.h](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework/WiFiScanner.h) implements the end points for scanning for available networks where as [WiFiSettingsService.h](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework/WiFiSettingsService.h) handles configuring the WiFi settings and managing the WiFi connection. ## Initializing the framework -The ['src/main.cpp'](https://github.com/theelims/ESP32-sveltekit/blob/main/src/main.cpp) file constructs the webserver and initializes the framework. You can add endpoints to the server here to support your IoT project. The main loop is also accessible so you can run your own code easily. +The ['src/main.cpp'](https://github.com/theelims/ESP32-sveltekit/blob/main/src/main.cpp) file constructs the web server and initializes the framework. You can add endpoints to the server here to support your IoT project. The main loop is also accessible so you can run your own code easily. The following code creates the web server and esp32sveltekit framework: ```cpp -AsyncWebServer server(80); -ESP32SvelteKit esp32sveltekit(&server); +PsychicHttpServer server; +ESP32SvelteKit esp32sveltekit(&server, 120); ``` +ESP32SvelteKit is instantiated with a reference to the server and a number of HTTP endpoints. The underlying ESP-IDF HTTP Server statically allocates memory for each endpoint and needs to know how many there are. Best is to inspect your WWWData.h file for the number of Endpoints from SvelteKit (currently 60), the framework itself has 37 endpoints, and Lighstate Demo has 7 endpoints. Each `_server.on()` counts as an endpoint. Don't forget to add a couple of spare, just in case. Each HttpEndpoint adds 2 endpoints, if CORS is enabled it adds an other endpoint for the CORS preflight request. + Now in the `setup()` function the initialization is performed: ```cpp @@ -23,14 +25,12 @@ void setup() { Serial.begin(SERIAL_BAUD_RATE); // start the framework and demo project - esp32sveltekit.setMDNSAppName("ESP32 SvelteKit Demo App"); esp32sveltekit.begin(); - - // start the server - server.begin(); } ``` +`server.begin()` is called by ESP32-SvelteKit, as the start-up sequence is crucial. + ## Stateful Service The framework promotes a modular design and exposes features you may re-use to speed up the development of your project. Where possible it is recommended that you use the features the frameworks supplies. These are documented in this section and a comprehensive example is provided by the demo project. @@ -155,13 +155,17 @@ lightStateService->update(jsonObject, LightState::update, "timer"); The framework provides an [HttpEndpoint.h](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework/HttpEndpoint.h) class which may be used to register GET and POST handlers to read and update the state over HTTP. You may construct an HttpEndpoint as a part of the StatefulService or separately if you prefer. -The code below demonstrates how to extend the LightStateService class to provide an unsecured endpoint: +The code below demonstrates how to extend the LightStateService class to provide an endpoint: ```cpp class LightStateService : public StatefulService { public: - LightStateService(AsyncWebServer* server) : - _httpEndpoint(LightState::read, LightState::update, this, server, "/rest/lightState") { + LightStateService(PsychicHttpServer* server, SecurityManager *securityManager) : + _httpEndpoint(LightState::read, LightState::update, this, server, "/rest/lightState", securityManager,AuthenticationPredicates::IS_AUTHENTICATED) { + } + + void begin(); { + _httpEndpoint.begin(); } private: @@ -169,7 +173,9 @@ class LightStateService : public StatefulService { }; ``` -Endpoint security is provided by authentication predicates which are [documented below](#security-features). The SecurityManager and authentication predicate may be provided if a secure endpoint is required. The placeholder project shows how endpoints can be secured. +Endpoint security is provided by authentication predicates which are [documented below](#security-features). The SecurityManager and authentication predicate must be provided, even if no secure endpoint is required. The placeholder project shows how endpoints can be secured. + +To register the HTTP endpoints with the web server the function `_httpEndpoint.begin()` must be called in the custom StatefulService Class' own `void begin()` function. ### Persistence @@ -193,21 +199,27 @@ class LightStateService : public StatefulService { [WebSocketTxRx.h](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework/WebSocketTxRx.h) allows you to read and update state over a WebSocket connection. WebSocketTxRx automatically pushes changes to all connected clients when state is updated. -The code below demonstrates how to extend the LightStateService class to provide an unsecured WebSocket: +The code below demonstrates how to extend the LightStateService class to provide an WebSocket: ```cpp class LightStateService : public StatefulService { public: - LightStateService(AsyncWebServer* server) : - _webSocket(LightState::read, LightState::update, this, server, "/ws/lightState"), { + LightStateService(PsychicHttpServer* server, SecurityManager *securityManager) : + _webSocket(LightState::read, LightState::update, this, server, "/ws/lightState", securityManager, AuthenticationPredicates::IS_AUTHENTICATED), { + } + + void begin() { + _webSocketServer.begin(); } private: - WebSocketTxRx _webSocket; + WebSocketServer _webSocketServer; }; ``` -WebSocket security is provided by authentication predicates which are [documented below](#security-features). The SecurityManager and authentication predicate may be provided if a secure WebSocket is required. The placeholder project shows how WebSockets can be secured. +WebSocket security is provided by authentication predicates which are [documented below](#security-features). The SecurityManager and authentication predicate must be provided, even if no secure endpoint is required. The placeholder project shows how endpoints can be secured. + +To register the WS endpoint with the web server the function `_webSocketServer.begin()` must be called in the custom StatefulService Class' own `void begin()` function. ### MQTT @@ -263,6 +275,12 @@ server->on("/rest/someService", HTTP_GET, ); ``` +In case of a websocket connection the JWT token is supplied as a search parameter in the URL when establishing the connection: + +``` +/ws/lightState?access_token={JWT Token} +``` + ## Placeholder substitution Various settings support placeholder substitution, indicated by comments in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini). This can be particularly useful where settings need to be unique, such as the Access Point SSID or MQTT client id. The following placeholders are supported: @@ -288,20 +306,19 @@ You may use SettingValue::format in your own code if you require the use of thes The framework supplies access to various features via getter functions: -| SettingsService | Description | -| ---------------------------- | ------------------------------------------------------ | -| getFS() | The filesystem used by the framework | -| getSecurityManager() | The security manager - detailed above | -| getSecuritySettingsService() | Configures the users and other security settings | -| getWiFiSettingsService() | Configures and manages the WiFi network connection | -| getAPSettingsService() | Configures and manages the Access Point | -| getNTPSettingsService() | Configures and manages the network time | -| getOTASettingsService() | Configures and manages the Over-The-Air update feature | -| getMqttSettingsService() | Configures and manages the MQTT connection | -| getMqttClient() | Provides direct access to the MQTT client instance | -| getNotificationEvents() | Lets you send push notifications to all clients | -| getSleepService() | Send the ESP32 into deep sleep | -| getBatteryService() | Update battery information on the client | +| SettingsService | Description | +| ---------------------------- | -------------------------------------------------- | +| getFS() | The filesystem used by the framework | +| getSecurityManager() | The security manager - detailed above | +| getSecuritySettingsService() | Configures the users and other security settings | +| getWiFiSettingsService() | Configures and manages the WiFi network connection | +| getAPSettingsService() | Configures and manages the Access Point | +| getNTPSettingsService() | Configures and manages the network time | +| getMqttSettingsService() | Configures and manages the MQTT connection | +| getMqttClient() | Provides direct access to the MQTT client instance | +| getNotificationEvents() | Lets you send push notifications to all clients | +| getSleepService() | Send the ESP32 into deep sleep | +| getBatteryService() | Update battery information on the client | The core features use the [StatefulService.h](https://github.com/theelims/ESP32-sveltekit/blob/main/lib/framework/StatefulService.h) class and can therefore you can change settings or observe changes to settings through the read/update API. @@ -371,10 +388,10 @@ will force a start of the AP regardless of the AP settings. It will not change t It is possibly to send push notifications to all clients by using Server Side Events. These will be displayed as toasts an the client side. Either directly call ```cpp -esp32sveltekit.getNotificationEvents()->pushNotification("Pushed a message!", INFO, millis()); +esp32sveltekit.getNotificationEvents()->pushNotification("Pushed a message!", PUSHINFO, millis()); ``` -or keep a local pointer to the `NotificationEvents` instance. It is possible to send `INFO`, `WARNING`, `ERROR` and `SUCCESS` events to all clients. The HTTP endpoint for this service is at `/events/notifications`. +or keep a local pointer to the `NotificationEvents` instance. It is possible to send `PUSHINFO`, `PUSHWARNING`, `PUSHERROR` and `PUSHSUCCESS` events to all clients. The HTTP endpoint for this service is at `/events/notifications`. In addition the raw `send()` function is mapped out as well: @@ -419,7 +436,7 @@ esp32sveltekit.getBatteryService()->setCharging(boolean isCharging); // notify t ### Custom Features -You may use the compile time feature service also to enable or disable custom features at runtime and thus control the frontend. A custom feature can only be added during initializing the ESP32 and ESP32-SvelteKit. A feature can't be updated on runtime once it is set once. +You may use the compile time feature service also to enable or disable custom features at runtime and thus control the frontend. A custom feature can only be added during initializing the ESP32 and ESP32-SvelteKit. A feature can't be updated on runtime once it is set. ```cpp esp32sveltekit.getFeatureService()->addFeature("custom_feature", true); // or false to disable it @@ -427,19 +444,7 @@ esp32sveltekit.getFeatureService()->addFeature("custom_feature", true); // or fa ## OTA Firmware Updates -ESP32-SvelteKit offers three different ways to roll out firmware updates to field devices. Except for ArduinoOTA all other OTA possibilities cannot update the file system. If the frontend should be updated as well it is necessary to serve it from PROGMEM by activating `-D PROGMEM_WWW`. - -### ArduinoOTA - -Using the ArduinoOTA firmware update service can be enabled by setting `FT_OTA=1` in [features.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/features.ini). It creates an update server and advertises it's service through mDNS. This can then be used by the Arduino IDE or Platform.io to flash new firmware directly from the IDE. -The defaults are defined in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini), but can be changed at any time through the frontend. - -```ini - ; OTA settings - -D FACTORY_OTA_PORT=8266 - -D FACTORY_OTA_PASSWORD=\"esp-sveltekit\" - -D FACTORY_OTA_ENABLED=true -``` +ESP32-SvelteKit offers two different ways to roll out firmware updates to field devices. If the frontend should be updated as well it is necessary to embed it into the firmware binary by activating `-D EMBED_WWW`. ### Firmware Upload @@ -447,13 +452,15 @@ Enabling `FT_UPLOAD_FIRMWARE=1` in [features.ini](https://github.com/theelims/ES ### Firmware Download from Update Server -By enabling `FT_DOWNLOAD_FIRMWARE=1` in [features.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/features.ini) one can POST a link to a firmware binary which is downloaded for the OTA process. This feature requires SSL and is thus dependent on `FT_NTP=1`. The Frontend contains an implementation which uses GitHub's Releases section as teh update server. By specifying a firmware version in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini) one can make use of semantic versioning to determine the correct firmware: +By enabling `FT_DOWNLOAD_FIRMWARE=1` in [features.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/features.ini) one can POST a link to a firmware binary which is downloaded for the OTA process. This feature requires SSL and is thus dependent on `FT_NTP=1`. The Frontend contains an implementation which uses GitHub's Releases section as the update server. By specifying a firmware version in [platformio.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/platformio.ini) one can make use of semantic versioning to determine the correct firmware: ```ini - -D FIRMWARE_VERSION=\"0.2.0\" + -D BUILD_TARGET="$PIOENV" + -D APP_NAME=\"ESP32-Sveltekit\" ; Must only contain characters from [a-zA-Z0-9-_] as this is converted into a filename + -D APP_VERSION=\"0.3.0\" ; semver compatible version string ``` -Attaching the firmware binary from `.pio/build/{env}/firmware.bin` to the right version tag on GitHub allows anyone to easily upgrade to the latest version. +A build script copies the firmware binary files for all build environment to `build/firmware`. It renames them into `{APP_NAME}_{$PIOENV}_{APP_VERSION}.bin`. It also creates a MD5 checksum file for verification during the OTA process. These files can be used as attachment on the GitHub release pages. !!! info diff --git a/docs/structure.md b/docs/structure.md index 2e3a6f42..153a7c93 100644 --- a/docs/structure.md +++ b/docs/structure.md @@ -93,9 +93,17 @@ On the root level there are two more files which you can customize to your needs ## Github Firmware Update -If the feature `FT_DOWNLOAD_FIRMWARE` is enabled, ESP32 SvelteKit pulls the Github Release section through the Github API for firmware updates (stable only) once per hour. Also the firmware update menu shows all available firmware releases allowing the user to up- and downgrade has he pleases. If you're using the Github releases section you must first tell the frontend your correct path to your github repository as described [here](sveltekit.md#changing-the-app-name). +If the feature `FT_DOWNLOAD_FIRMWARE` is enabled, ESP32 SvelteKit pulls the Github Release section through the Github API for firmware updates (stable only) once per hour. Also the firmware update menu shows all available firmware releases allowing the user to up- and downgrade has they please. If you're using the Github releases section you must first tell the frontend your correct path to your github repository as described [here](sveltekit.md#changing-the-app-name). -Also you must make use of the '-D FIRMWARE_VERSION=' flag in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini) and give it the same semantic version number as the release tag on Github. On Github create a new release with the matching tag name. Attach the firmware binary file found under `.pio/build/{env}/firmware.bin`. The frontend searches for the first attachment found and uses this as the update link. If you upload further attachments the binary must be the first element, otherwise the update will fail. +Also you must make use of couple build flags in [platformio.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/platformio.ini): + +```ini + -D BUILD_TARGET=\"$PIOENV\" + -D APP_NAME=\"ESP32-Sveltekit\" ; Must only contain characters from [a-zA-Z0-9-_] as this is converted into a filename + -D APP_VERSION=\"0.3.0\" ; semver compatible version string +``` + +Out of these flags the [rename_fw.py](https://github.com/theelims/ESP32-sveltekit/blob/main/scripts/rename_fw.py) script will copy and rename the firmware binary to `/build/firmware/{APP_NAME}_{$PIOENV}_{APP_VERSION}.bin`. In addition it will also create a corresponding MD5 checksum file. These files are ready to be uploaded to the Github release page without any further changes. The frontend searches for the a firmware binary which matches the build environment and uses this as the update link. This allows you to serve different build targets from the same release page. ### Custom Update Server diff --git a/factory_settings.ini b/factory_settings.ini index 1afb46fc..af679744 100644 --- a/factory_settings.ini +++ b/factory_settings.ini @@ -6,13 +6,11 @@ [factory_settings] build_flags = - ; Global Settings - -D FIRMWARE_VERSION=\"0.2.2\" - ; WiFi settings -D FACTORY_WIFI_SSID=\"\" -D FACTORY_WIFI_PASSWORD=\"\" -D FACTORY_WIFI_HOSTNAME=\"#{platform}-#{unique_id}\" ; supports placeholders + -D FACTORY_WIFI_RSSI_THRESHOLD=-80 ; dBm, -80 is a good value for most applications ; Access point settings -D FACTORY_AP_PROVISION_MODE=AP_MODE_DISCONNECTED @@ -37,21 +35,14 @@ build_flags = -D FACTORY_NTP_TIME_ZONE_FORMAT=\"GMT0BST,M3.5.0/1,M10.5.0\" -D FACTORY_NTP_SERVER=\"time.google.com\" - ; OTA settings - -D FACTORY_OTA_PORT=8266 - -D FACTORY_OTA_PASSWORD=\"esp-sveltekit\" - -D FACTORY_OTA_ENABLED=true - ; MQTT settings -D FACTORY_MQTT_ENABLED=false - -D FACTORY_MQTT_HOST=\"test.mosquitto.org\" - -D FACTORY_MQTT_PORT=1883 + -D FACTORY_MQTT_URI=\"mqtts://mqtt.eclipseprojects.io:8883\" -D FACTORY_MQTT_USERNAME=\"\" ; supports placeholders -D FACTORY_MQTT_PASSWORD=\"\" -D FACTORY_MQTT_CLIENT_ID=\"#{platform}-#{unique_id}\" ; supports placeholders - -D FACTORY_MQTT_KEEP_ALIVE=60 + -D FACTORY_MQTT_KEEP_ALIVE=120 -D FACTORY_MQTT_CLEAN_SESSION=true - -D FACTORY_MQTT_MAX_TOPIC_LENGTH=128 ; JWT Secret -D FACTORY_JWT_SECRET=\"#{random}-#{random}\" ; supports placeholders diff --git a/features.ini b/features.ini index 6b6e7f48..782d9b8b 100644 --- a/features.ini +++ b/features.ini @@ -3,7 +3,6 @@ build_flags = -D FT_SECURITY=1 -D FT_MQTT=1 -D FT_NTP=1 - -D FT_OTA=0 ; Not recommended, will be deprectiated in an upcomming release -D FT_UPLOAD_FIRMWARE=1 -D FT_DOWNLOAD_FIRMWARE=1 ; requires FT_NTP=1 -D FT_SLEEP=0 diff --git a/interface/package-lock.json b/interface/package-lock.json index ea41596f..21889513 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -12,6 +12,7 @@ "compare-versions": "^6.0.0", "daisyui": "^3.5.1", "jwt-decode": "^3.1.2", + "svelte-dnd-list": "^0.1.8", "svelte-modals": "^1.3.0" }, "devDependencies": { @@ -502,9 +503,9 @@ } }, "node_modules/@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", "dev": true, "engines": { "node": ">=14" @@ -680,25 +681,25 @@ } }, "node_modules/@sveltejs/kit": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.25.1.tgz", - "integrity": "sha512-pD8XsvNJNgTNkFngNlM60my/X8dXWPKVzN5RghEQr0NjGZmuCjy49AfFu2cGbZjNf5pBcqd2RCNMW912P5fkhA==", + "version": "1.30.3", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.3.tgz", + "integrity": "sha512-0DzVXfU4h+tChFvoc8C61IqErCyskD4ydSIDjpKS2lYlEzIYrtYrY7juSqACFxqcvZAnOEXvSY+zZ8br0+ZMMg==", "dev": true, "hasInstallScript": true, "dependencies": { - "@sveltejs/vite-plugin-svelte": "^2.4.1", + "@sveltejs/vite-plugin-svelte": "^2.5.0", "@types/cookie": "^0.5.1", "cookie": "^0.5.0", "devalue": "^4.3.1", "esm-env": "^1.0.0", "kleur": "^4.1.5", "magic-string": "^0.30.0", - "mime": "^3.0.0", + "mrmime": "^1.0.1", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^2.0.2", "tiny-glob": "^0.2.9", - "undici": "~5.25.0" + "undici": "~5.26.2" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -707,14 +708,14 @@ "node": "^16.14 || >=18" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0-next.0", + "svelte": "^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.6.tgz", - "integrity": "sha512-zO79p0+DZnXPnF0ltIigWDx/ux7Ni+HRaFOw720Qeivc1azFUrJxTl0OryXVibYNx1hCboGia1NRV3x8RNv4cA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz", + "integrity": "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==", "dev": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", @@ -729,7 +730,7 @@ "node": "^14.18.0 || >= 16" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0", + "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, @@ -2411,18 +2412,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -3441,6 +3430,11 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0" } }, + "node_modules/svelte-dnd-list": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/svelte-dnd-list/-/svelte-dnd-list-0.1.8.tgz", + "integrity": "sha512-81Nt/niux7kf59lql0lxTAH0z8xwAxHdHC9dZT7MbfE32T6hgeLsLZ7RIBNAihQ040Io1KghqqPXD+k2viiKeA==" + }, "node_modules/svelte-eslint-parser": { "version": "0.33.1", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", @@ -3759,9 +3753,9 @@ } }, "node_modules/undici": { - "version": "5.25.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz", - "integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==", + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", + "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", "dev": true, "dependencies": { "@fastify/busboy": "^2.0.0" @@ -3869,9 +3863,9 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vite": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", - "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -3924,12 +3918,12 @@ } }, "node_modules/vitefu": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", - "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", "dev": true, "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0" + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { "vite": { diff --git a/interface/package.json b/interface/package.json index e61f3fd0..b1099e96 100644 --- a/interface/package.json +++ b/interface/package.json @@ -41,6 +41,7 @@ "compare-versions": "^6.0.0", "daisyui": "^3.5.1", "jwt-decode": "^3.1.2", + "svelte-dnd-list": "^0.1.8", "svelte-modals": "^1.3.0" } } diff --git a/interface/src/lib/components/InfoDialog.svelte b/interface/src/lib/components/InfoDialog.svelte new file mode 100644 index 00000000..651fdb46 --- /dev/null +++ b/interface/src/lib/components/InfoDialog.svelte @@ -0,0 +1,42 @@ + + +{#if isOpen} + @@ -231,17 +206,17 @@ Enable MQTT