diff --git a/CHANGELOG.md b/CHANGELOG.md index 425b42f1..e2589c5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,23 +2,43 @@ All notable changes to this project will be documented in this file. -## [WIP] - Current Main +## [0.5.0] - 2024-05-06 + +Changes the Event Socket System to use a clearer message structure and MessagePack. Brings breaking changes to the `EventSocket.h` API. + +Updated daisyUI to v4. This has changes in the colors and switches to OKLCH. Also button groups and input groups have been depreciated in favor of join. This might require changes to custom parts of the code. Please double check all websites if the still have the desired looks. + +Updates ArduinoJSON from v6 to v7 to increase the available free heap. If you make use of ArduinoJSON, changes might be required. ### Added +- Debug buildflag to switch between MessagePack and JSON for event messages. +- Show SSID of the current WiFi Station as tooltip of the RSSI icon. + ### Changed - Moved MQTT types to models.ts as well. [#49](https://github.com/theelims/ESP32-sveltekit/pull/49) -- Fixed spelling error in models.tsnpm audit +- Updated daisyUI to 4.10.2 [#48](https://github.com/theelims/ESP32-sveltekit/pull/48) +- Fixed spelling error in models.ts +- Changed ArduinoJson from v6 to v7 increasing the free heap by ~40kb +- Split NotificationService out of EventSocket into own class +- Changed API of EventSocket.h. Now uses `void emitEvent(String event, JsonObject &jsonObject, const char *originId = "", bool onlyToSameOrigin = false);`. +- Changed event socket message format to MessagePack ### Fixed - Fixes to WiFi.svelte and models.ts to fix type errors and visibility rights. +- Fixes bug in highlighting the menu when navigating with the browser (back/forward) +- Made WiFi connection routine more robust by using BSSID. Ensures that the STA truly connects to the strongest hotspot, even if several hotspots are in reach. ### Removed - Removed duplicate in ESP32SvelteKit.cpp [#47](https://github.com/theelims/ESP32-sveltekit/pull/47) and WiFi.svelte [#50](https://github.com/theelims/ESP32-sveltekit/pull/50) +### Acknowledgment + +Many thanks to @runeharlyk who contributed significantly to the new event socket system and fixed many smaller issues with the front-end. + ## [0.4.0] - 2024-04-21 This upgrade might require one minor change as `MqttPubSub.h` and its class had been renamed to `MqttEndpoint.h` and `MqttEndoint` respectively. However, it is strongly advised, that you change all existing WebSocketServer endpoints to the new event socket system. diff --git a/LICENSE b/LICENSE index 61238e99..9a14391d 100644 --- a/LICENSE +++ b/LICENSE @@ -5,7 +5,7 @@ under the MIT License. MIT License -Copyright (c) 2023 theelims +Copyright (C) 2023 - 2024 theelims Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/docs/buildprocess.md b/docs/buildprocess.md index a3ed5357..cee2397f 100644 --- a/docs/buildprocess.md +++ b/docs/buildprocess.md @@ -56,12 +56,12 @@ In addition custom features might be added or removed at runtime. See [Custom Fe ## Factory Settings -The framework has built-in factory settings which act as default values for the various configurable services where settings are not saved on the file system. These settings can be overridden using the build flags defined in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini). +The framework has built-in factory settings which act as default values for the various configurable services where settings are not saved on the file system. These settings can be overridden using the build flags defined in [factory_settings.ini](https://github.com/theelims/ESP32-sveltekit/blob/main/factory_settings.ini). All strings entered here must be escaped, especially special characters. Customize the settings as you see fit, for example you might configure your home WiFi network as the factory default: ```ini - -D FACTORY_WIFI_SSID=\"My Awesome WiFi Network\" + -D FACTORY_WIFI_SSID=\"My\ Awesome\ WiFi\ Network\" -D FACTORY_WIFI_PASSWORD=\"secret\" -D FACTORY_WIFI_HOSTNAME=\"awesome_light_controller\" ``` diff --git a/docs/statefulservice.md b/docs/statefulservice.md index 5da1f4a2..600dc2dc 100644 --- a/docs/statefulservice.md +++ b/docs/statefulservice.md @@ -303,14 +303,36 @@ The demo project allows the user to modify the MQTT topics via the UI so they ca Beside RESTful HTTP Endpoints the Event Socket System provides a convenient communication path between the client and the ESP32. It uses a single WebSocket connection to synchronize state and to push realtime data to the client. The client needs to subscribe to the topics he is interested. Only clients who have an active subscription will receive data. Every authenticated client may make use of this system as the security settings are set to `AuthenticationPredicates::IS_AUTHENTICATED`. +### Message Format + +The event messages exchanged between the ESP32 and its clients consists of an "event" head and the "data" payload. For the LightState example a message looks like this in JSON representation: + +```JSON +{ + "event": "led", + "data": { + "led_on": true + } +} +``` + +To save on bandwidth the event message is encoded as binary [MessagePack](https://msgpack.org/) instead of a JSON. + +To subscribe the client has to send the following message (as MessagePack): + +```JSON +{ + "event": "subscribe", + "data": "analytics" +} +``` + ### Emit an Event -The Event Socket provides an overloaded `emit()` function to push data to all subscribed clients. This is used by various esp32sveltekit classes to push real time data to the client. First an event must be registered with the Event Socket by calling `_socket.registerEvent("CustomEvent");`. Only then clients may subscribe to this custom event and you're entitled to emit event data: +The Event Socket provides an `emitEvent()` function to push data to all subscribed clients. This is used by various esp32sveltekit classes to push real time data to the client. First an event must be registered with the Event Socket by calling `_socket.registerEvent("CustomEvent");`. Only then clients may subscribe to this custom event and you're entitled to emit event data: ```cpp -void emit(String event, String payload); -void emit(const char *event, const char *payload); -void emit(const char *event, const char *payload, const char *originId, bool onlyToSameOrigin = false); +void emitEvent(String event, JsonObject &jsonObject, const char *originId = "", bool onlyToSameOrigin = false); ``` The latter function allowing a selection of the recipient. If `onlyToSameOrigin = false` the payload is distributed to all subscribed clients, except the `originId`. If `onlyToSameOrigin = true` only the client with `originId` will receive the payload. This is used by the [EventEndpoint](#event-socket-endpoint) to sync the initial state when a new client subscribes. @@ -331,7 +353,7 @@ _socket.onEvent("CostumEvent",[&](JsonObject &root, int originId) Similarly a callback or lambda function may be registered to get notified when a client subscribes to an event: ```cpp -_socket.onEvent("CostumEvent",[&](const String &originId, bool sync) +_socket.onSubscribe("CostumEvent",[&](const String &originId) { Serial.println("New Client subscribed: " + originId); }); @@ -344,7 +366,7 @@ The boolean parameter provided will always be `true`. It is possibly to send push notifications to all clients by using the Event Socket. These will be displayed as toasts an the client side. Either directly call ```cpp -esp32sveltekit.getSocket()->pushNotification("Pushed a message!", PUSHINFO); +esp32sveltekit.getNotificationService()->pushNotification("Pushed a message!", PUSHINFO); ``` or keep a local pointer to the `EventSocket` instance. It is possible to send `PUSHINFO`, `PUSHWARNING`, `PUSHERROR` and `PUSHSUCCESS` events to all clients. @@ -377,7 +399,7 @@ In case of a websocket connection the JWT token is supplied as a search paramete ## 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: +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. Strings must be properly escaped in the ini-file. The following placeholders are supported: | Placeholder | Substituted value | | ------------ | --------------------------------------------------------------------- | diff --git a/docs/stores.md b/docs/stores.md index 07b7077d..09bd1a53 100644 --- a/docs/stores.md +++ b/docs/stores.md @@ -57,6 +57,7 @@ It exposes the following properties you can subscribe to: | Property | Type | Description | | ---------------------------------- | --------- | ------------------------------------------- | | `$telemetry.rssi.rssi` | `Number` | The RSSI signal strength of the WiFi in dBm | +| `$telemetry.rssi.ssid` | `String` | Name of the connected WiFi station | | `$telemetry.rssi.connected` | `Boolean` | Connection status of the WiFi | | `$telemetry.battery.soc` | `Number` | Battery state of charge | | `$telemetry.battery.charging` | `Boolean` | Is battery connected to charger | diff --git a/docs/structure.md b/docs/structure.md index a6a10c84..8c810446 100644 --- a/docs/structure.md +++ b/docs/structure.md @@ -49,7 +49,6 @@ The menu consists of an array of menu items. These are defined as follows: icon: Control, href: '/demo', feature: $page.data.features.project, - active: false }, ``` @@ -68,7 +67,6 @@ export const load = (async ({ fetch }) => { - `icon` must be an icon component giving the menu items icon. - `href` is the link to the route the menu item refers to. - `feature` takes a bool and should be set to `true`. It is used by the [feature selector](#features) to hide a menu entry of it is not present on the back end. -- `active` takes a bool as well and should be set to `false` by default. It is automatically set to `true` to highlight a menu entry as active. ## Advanced Customizations diff --git a/interface/LICENSE b/interface/LICENSE index 8a47f001..9155cf7c 100644 --- a/interface/LICENSE +++ b/interface/LICENSE @@ -5,7 +5,7 @@ under the MIT License. MIT License -Copyright (c) 2023 theelims +Copyright (C) 2023 - 2024 theelims Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/interface/package-lock.json b/interface/package-lock.json index e0acb2ad..e60017f5 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -10,8 +10,9 @@ "dependencies": { "chart.js": "^4.4.0", "compare-versions": "^6.0.0", - "daisyui": "^3.5.1", + "daisyui": "^4.10.2", "jwt-decode": "^4.0.0", + "msgpack-lite": "^0.1.26", "postcss-remove-classes": "^2.0.0", "svelte-dnd-list": "^0.1.8", "svelte-modals": "^1.3.0" @@ -21,6 +22,7 @@ "@sveltejs/adapter-auto": "^2.1.0", "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.22.4", + "@types/msgpack-lite": "^0.1.11", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "autoprefixer": "^10.4.14", @@ -54,6 +56,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, "engines": { "node": ">=10" }, @@ -746,6 +749,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -758,6 +762,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "engines": { "node": ">= 8" } @@ -766,6 +771,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -889,6 +895,24 @@ "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", "dev": true }, + "node_modules/@types/msgpack-lite": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/msgpack-lite/-/msgpack-lite-0.1.11.tgz", + "integrity": "sha512-cdCZS/gw+jIN22I4SUZUFf1ZZfVv5JM1//Br/MuZcI373sxiy3eSSoiyLu0oz+BPatTbGGGBO5jrcvd0siCdTQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/pug": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.7.tgz", @@ -1153,12 +1177,14 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1170,7 +1196,8 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", @@ -1243,12 +1270,14 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } @@ -1257,6 +1286,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1266,6 +1296,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1382,6 +1413,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1405,6 +1437,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1442,15 +1475,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, "engines": { "node": ">= 6" } @@ -1463,7 +1492,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/confbox": { "version": "0.1.7", @@ -1526,16 +1556,23 @@ "node": ">=4" } }, + "node_modules/culori": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz", + "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/daisyui": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.9.2.tgz", - "integrity": "sha512-yJZ1QjHUaL+r9BkquTdzNHb7KIgAJVFh0zbOXql2Wu0r7zx5qZNLxclhjN0WLoIpY+o2h/8lqXg7ijj8oTigOw==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.2.tgz", + "integrity": "sha512-eCWS1W/JPyxW9IvlgW5m0R6rp9ZhRsBTW37rvEUthckkjsV04u8XipV519OoccSA46ixhSJa3q7XLI1WUFtRCA==", "dependencies": { - "colord": "^2.9", "css-selector-tokenizer": "^0.8", - "postcss": "^8", - "postcss-js": "^4", - "tailwindcss": "^3.1" + "culori": "^3", + "picocolors": "^1", + "postcss-js": "^4" }, "engines": { "node": ">=16.9.0" @@ -1603,7 +1640,8 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true }, "node_modules/dir-glob": { "version": "3.0.1", @@ -1620,7 +1658,8 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true }, "node_modules/doctrine": { "version": "3.0.0", @@ -1905,6 +1944,11 @@ "node": ">=0.10.0" } }, + "node_modules/event-lite": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz", + "integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==" + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -1938,6 +1982,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1953,6 +1998,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1981,6 +2027,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -2001,6 +2048,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2060,12 +2108,14 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -2111,6 +2161,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -2181,6 +2232,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, "engines": { "node": ">= 0.4.0" } @@ -2203,6 +2255,25 @@ "node": ">=16.17.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2251,6 +2322,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2259,12 +2331,19 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/int64-buffer": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", + "integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2276,6 +2355,7 @@ "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -2287,6 +2367,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2295,6 +2376,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2306,6 +2388,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -2339,6 +2422,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2349,6 +2437,7 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", + "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -2438,6 +2527,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, "engines": { "node": ">=10" } @@ -2445,7 +2535,8 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/local-pkg": { "version": "0.5.0", @@ -2532,6 +2623,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -2540,6 +2632,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -2573,6 +2666,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2643,10 +2737,25 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/msgpack-lite": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz", + "integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==", + "dependencies": { + "event-lite": "^0.1.1", + "ieee754": "^1.1.8", + "int64-buffer": "^0.1.9", + "isarray": "^1.0.0" + }, + "bin": { + "msgpack": "bin/msgpack" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -2686,6 +2795,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2730,6 +2840,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2738,6 +2849,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, "engines": { "node": ">= 6" } @@ -2746,6 +2858,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" } @@ -2837,6 +2950,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2853,7 +2967,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -2889,6 +3004,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -2900,6 +3016,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2908,6 +3025,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, "engines": { "node": ">= 6" } @@ -2954,6 +3072,7 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -3017,6 +3136,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.11" }, @@ -3100,7 +3220,8 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -3221,6 +3342,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -3240,6 +3362,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -3248,6 +3371,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -3259,6 +3383,7 @@ "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -3284,6 +3409,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -3324,6 +3450,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -3530,6 +3657,7 @@ "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -3551,6 +3679,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3582,6 +3711,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -3773,6 +3903,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -3809,6 +3940,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^2.1.1" @@ -3837,6 +3969,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "dev": true, "engines": { "node": ">= 14" } @@ -3851,6 +3984,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -3859,6 +3993,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -3880,6 +4015,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -3911,7 +4047,8 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true }, "node_modules/tslib": { "version": "2.6.2", @@ -3974,6 +4111,12 @@ "node": ">=14.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unplugin": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.1.tgz", @@ -4177,7 +4320,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/yallist": { "version": "4.0.0", diff --git a/interface/package.json b/interface/package.json index 8cf9e180..836da6e3 100644 --- a/interface/package.json +++ b/interface/package.json @@ -18,6 +18,7 @@ "@sveltejs/kit": "^1.22.4", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", + "@types/msgpack-lite": "^0.1.11", "autoprefixer": "^10.4.14", "eslint": "^8.46.0", "eslint-config-prettier": "^9.0.0", @@ -39,8 +40,9 @@ "dependencies": { "chart.js": "^4.4.0", "compare-versions": "^6.0.0", - "daisyui": "^3.5.1", + "daisyui": "^4.10.2", "jwt-decode": "^4.0.0", + "msgpack-lite": "^0.1.26", "postcss-remove-classes": "^2.0.0", "svelte-dnd-list": "^0.1.8", "svelte-modals": "^1.3.0" diff --git a/interface/src/lib/DaisyUiHelper.ts b/interface/src/lib/DaisyUiHelper.ts index 273c8553..0c7028a2 100644 --- a/interface/src/lib/DaisyUiHelper.ts +++ b/interface/src/lib/DaisyUiHelper.ts @@ -1,4 +1,4 @@ export function daisyColor(name: string, opacity: number = 100) { const color = getComputedStyle(document.documentElement).getPropertyValue(name); - return 'hsla(' + color + '/ ' + Math.min(Math.max(Math.round(opacity), 0), 100) + '%)'; + return `oklch(${color} / ${Math.min(Math.max(Math.round(opacity), 0), 100)}%)`; } diff --git a/interface/src/lib/components/RSSIIndicator.svelte b/interface/src/lib/components/RSSIIndicator.svelte index 6810bb4f..7feef375 100644 --- a/interface/src/lib/components/RSSIIndicator.svelte +++ b/interface/src/lib/components/RSSIIndicator.svelte @@ -6,30 +6,37 @@ export let showDBm = false; export let rssi_dbm = 0; + export let ssid = ''; + + $: if (ssid === '') { + ssid = 'Unknown'; + }
- {#if showDBm} - - {rssi_dbm} dBm - - {/if} - {#if rssi_dbm >= -55} - - {:else if rssi_dbm >= -75} -
- - -
- {:else if rssi_dbm >= -85} -
- - -
- {:else} -
- - -
- {/if} +
+ {#if showDBm} + + {rssi_dbm} dBm + + {/if} + {#if rssi_dbm >= -55} + + {:else if rssi_dbm >= -75} +
+ + +
+ {:else if rssi_dbm >= -85} +
+ + +
+ {:else} +
+ + +
+ {/if} +
diff --git a/interface/src/lib/stores/socket.ts b/interface/src/lib/stores/socket.ts index e230c25b..fbb7168d 100644 --- a/interface/src/lib/stores/socket.ts +++ b/interface/src/lib/stores/socket.ts @@ -1,4 +1,5 @@ import { writable } from 'svelte/store'; +import msgpack from 'msgpack-lite'; function createWebSocket() { let listeners = new Map void>>(); @@ -9,9 +10,11 @@ function createWebSocket() { let reconnectTimeoutId: number; let ws: WebSocket; let socketUrl: string | URL; + let event_use_json = false; - function init(url: string | URL) { + function init(url: string | URL, use_json: boolean = false) { socketUrl = url; + event_use_json = use_json; connect(); } @@ -26,6 +29,7 @@ function createWebSocket() { function connect() { ws = new WebSocket(socketUrl); + ws.binaryType = 'arraybuffer'; ws.onopen = (ev) => { set(true); clearTimeout(reconnectTimeoutId); @@ -37,22 +41,19 @@ function createWebSocket() { }; ws.onmessage = (message) => { resetUnresponsiveCheck(); - let data = message.data; + let payload = message.data; - if (data instanceof ArrayBuffer) { - listeners.get('binary')?.forEach((listener) => listener(data)); - return; - } - listeners.get('message')?.forEach((listener) => listener(data)); + const binary = payload instanceof ArrayBuffer; + listeners.get(binary ? 'binary' : 'message')?.forEach((listener) => listener(payload)); try { - data = JSON.parse(message.data); + payload = binary ? msgpack.decode(new Uint8Array(payload)) : JSON.parse(payload); } catch (error) { listeners.get('error')?.forEach((listener) => listener(error)); return; } - listeners.get('json')?.forEach((listener) => listener(data)); - const [event, payload] = data; - if (event) listeners.get(event)?.forEach((listener) => listener(payload)); + listeners.get('json')?.forEach((listener) => listener(payload)); + const { event, data } = payload; + if (event) listeners.get(event)?.forEach((listener) => listener(data)); }; ws.onerror = (ev) => disconnect('error', ev); ws.onclose = (ev) => disconnect('close', ev); @@ -79,7 +80,11 @@ function createWebSocket() { function send(msg: unknown) { if (!ws || ws.readyState !== WebSocket.OPEN) return; - ws.send(JSON.stringify(msg)); + if (event_use_json) { + ws.send(JSON.stringify(msg)); + } else { + ws.send(msgpack.encode(msg)); + } } function sendEvent(event: string, data: unknown) { diff --git a/interface/src/lib/stores/telemetry.ts b/interface/src/lib/stores/telemetry.ts index c6eead61..31ee6d59 100644 --- a/interface/src/lib/stores/telemetry.ts +++ b/interface/src/lib/stores/telemetry.ts @@ -1,8 +1,12 @@ import { writable } from 'svelte/store'; +import type { RSSI } from '../types/models'; +import type { Battery } from '../types/models'; +import type { DownloadOTA } from '../types/models'; let telemetry_data = { rssi: { rssi: 0, + ssid: '', disconnected: true }, battery: { @@ -21,28 +25,29 @@ function createTelemetry() { return { subscribe, - setRSSI: (data: string) => { - if (!isNaN(Number(data))) { + setRSSI: (data: RSSI) => { + if (!isNaN(Number(data.rssi))) { update((telemetry_data) => ({ ...telemetry_data, - rssi: { rssi: Number(data), disconnected: false } + rssi: { rssi: Number(data.rssi), ssid: data.ssid, disconnected: false } })); } else { - update((telemetry_data) => ({ ...telemetry_data, rssi: { rssi: 0, disconnected: true } })); + update((telemetry_data) => ({ + ...telemetry_data, + rssi: { rssi: 0, ssid: data.ssid, disconnected: true } + })); } }, - setBattery: (data: string) => { - const content = JSON.parse(data); + setBattery: (data: Battery) => { update((telemetry_data) => ({ ...telemetry_data, - battery: { soc: content.soc, charging: content.charging } + battery: { soc: data.soc, charging: data.charging } })); }, - setDownloadOTA: (data: string) => { - const content = JSON.parse(data); + setDownloadOTA: (data: DownloadOTA) => { update((telemetry_data) => ({ ...telemetry_data, - download_ota: { status: content.status, progress: content.progress, error: content.error } + download_ota: { status: data.status, progress: data.progress, error: data.error } })); } }; diff --git a/interface/src/lib/types/models.ts b/interface/src/lib/types/models.ts index a6b75708..a1f7d516 100644 --- a/interface/src/lib/types/models.ts +++ b/interface/src/lib/types/models.ts @@ -94,6 +94,22 @@ export type Analytics = { uptime: number; }; +export type RSSI = { + rssi: number; + ssid: string; +}; + +export type Battery = { + soc: number; + charging: boolean; +}; + +export type DownloadOTA = { + status: string; + progress: number; + error: string; +}; + export type StaticSystemInformation = { esp_platform: string; firmware_version: string; @@ -127,4 +143,4 @@ export type MQTTSettings = { client_id: string; keep_alive: number; clean_session: boolean; -}; \ No newline at end of file +}; diff --git a/interface/src/routes/+layout.svelte b/interface/src/routes/+layout.svelte index cd578c50..b11606e7 100644 --- a/interface/src/routes/+layout.svelte +++ b/interface/src/routes/+layout.svelte @@ -16,6 +16,9 @@ import Statusbar from './statusbar.svelte'; import Login from './login.svelte'; import type { Analytics } from '$lib/types/models'; + import type { RSSI } from '$lib/types/models'; + import type { Battery } from '$lib/types/models'; + import type { DownloadOTA } from '$lib/types/models'; export let data: LayoutData; @@ -24,7 +27,10 @@ await validateUser($user); } const ws_token = $page.data.features.security ? '?access_token=' + $user.bearer_token : ''; - socket.init(`ws://${window.location.host}/ws/events${ws_token}`); + socket.init( + `ws://${window.location.host}/ws/events${ws_token}`, + $page.data.features.event_use_json + ); addEventListeners(); }); @@ -38,10 +44,7 @@ socket.on('close', handleClose); socket.on('error', handleError); socket.on('rssi', handleNetworkStatus); - socket.on('infoToast', handleInfoToast); - socket.on('successToast', handleSuccessToast); - socket.on('warningToast', handleWarningToast); - socket.on('errorToast', handleErrorToast); + socket.on('notification', handleNotification); if ($page.data.features.analytics) socket.on('analytics', handleAnalytics); if ($page.data.features.battery) socket.on('battery', handleBattery); if ($page.data.features.download_firmware) socket.on('otastatus', handleOAT); @@ -52,10 +55,7 @@ socket.off('open', handleOpen); socket.off('close', handleClose); socket.off('rssi', handleNetworkStatus); - socket.off('infoToast', handleInfoToast); - socket.off('successToast', handleSuccessToast); - socket.off('warningToast', handleWarningToast); - socket.off('errorToast', handleErrorToast); + socket.off('notification', handleNotification); socket.off('battery', handleBattery); socket.off('otastatus', handleOAT); }; @@ -83,23 +83,37 @@ const handleClose = () => { notifications.error('Connection to device lost', 5000); - telemetry.setRSSI('lost'); + telemetry.setRSSI({ rssi: 0, ssid: '' }); }; const handleError = (data: any) => console.error(data); - const handleInfoToast = (data: string) => notifications.info(data, 5000); - const handleWarningToast = (data: string) => notifications.warning(data, 5000); - const handleErrorToast = (data: string) => notifications.error(data, 5000); - const handleSuccessToast = (data: string) => notifications.success(data, 5000); + const handleNotification = (data: any) => { + switch (data.type) { + case 'info': + notifications.info(data.message, 5000); + break; + case 'warning': + notifications.warning(data.message, 5000); + break; + case 'error': + notifications.error(data.message, 5000); + break; + case 'success': + notifications.success(data.message, 5000); + break; + default: + break; + } + }; const handleAnalytics = (data: Analytics) => analytics.addData(data); - const handleNetworkStatus = (data: string) => telemetry.setRSSI(data); + const handleNetworkStatus = (data: RSSI) => telemetry.setRSSI(data); - const handleBattery = (data: string) => telemetry.setBattery(data); + const handleBattery = (data: Battery) => telemetry.setBattery(data); - const handleOAT = (data: string) => telemetry.setDownloadOTA(data); + const handleOAT = (data: DownloadOTA) => telemetry.setDownloadOTA(data); let menuOpen = false; diff --git a/interface/src/routes/menu.svelte b/interface/src/routes/menu.svelte index 169ce948..7c1c3bd1 100644 --- a/interface/src/routes/menu.svelte +++ b/interface/src/routes/menu.svelte @@ -18,7 +18,6 @@ import NTP from '~icons/tabler/clock-check'; import Metrics from '~icons/tabler/report-analytics'; import { page } from '$app/stores'; - import { onMount } from 'svelte'; import { user } from '$lib/stores/user'; import { createEventDispatcher } from 'svelte'; @@ -28,7 +27,7 @@ type menuItem = { title: string; - icon: object; + icon: ConstructorOfATypedSvelteComponent; href?: string; feature: boolean; active?: boolean; @@ -37,7 +36,7 @@ type subMenuItem = { title: string; - icon: object; + icon: ConstructorOfATypedSvelteComponent; href: string; feature: boolean; active: boolean; @@ -49,7 +48,7 @@ icon: Control, href: '/demo', feature: true, - active: false + }, { title: 'Connections', @@ -61,14 +60,14 @@ icon: MQTT, href: '/connections/mqtt', feature: $page.data.features.mqtt, - active: false + }, { title: 'NTP', icon: NTP, href: '/connections/ntp', feature: $page.data.features.ntp, - active: false + } ] }, @@ -82,14 +81,14 @@ icon: Router, href: '/wifi/sta', feature: true, - active: false + }, { title: 'Access Point', icon: AP, href: '/wifi/ap', feature: true, - active: false + } ] }, @@ -98,7 +97,7 @@ icon: Users, href: '/user', feature: $page.data.features.security && $user.admin, - active: false + }, { title: 'System', @@ -110,14 +109,14 @@ icon: Health, href: '/system/status', feature: true, - active: false + }, { title: 'System Metrics', icon: Metrics, href: '/system/metrics', feature: $page.data.features.analytics, - active: false + }, { title: 'Firmware Update', @@ -128,43 +127,25 @@ $page.data.features.upload_firmware || $page.data.features.download_firmware) && (!$page.data.features.security || $user.admin), - active: false } ] } - ]; + ] as menuItem[]; const dispatch = createEventDispatcher(); - function setActiveMenuItem(menuItems: menuItem[], targetTitle: string) { - for (let i = 0; i < menuItems.length; i++) { - const menuItem = menuItems[i]; - - // Clear any previous set active flags - menuItem.active = false; - - // Check if the current menu item's title matches the target title - if (menuItem.title === targetTitle) { - menuItem.active = true; // Set the active property to true - dispatch('menuClicked'); - } - - // Check if the current menu item has a submenu - if (menuItem.submenu && menuItem.submenu.length > 0) { - // Recursively call the function for each submenu item - setActiveMenuItem(menuItem.submenu, targetTitle); - } - } - if (targetTitle == '') { - dispatch('menuClicked'); - } - menuItems = menuItems; + function setActiveMenuItem(targetTitle: string) { + menuItems.forEach(item => { + item.active = item.title === targetTitle; + item.submenu?.forEach(subItem => { + subItem.active = subItem.title === targetTitle; + }); + }); + menuItems = menuItems + dispatch('menuClicked'); } - onMount(() => { - setActiveMenuItem(menuItems, $page.data.title); - menuItems = menuItems; - }); + $: setActiveMenuItem($page.data.title);
@@ -172,7 +153,7 @@ setActiveMenuItem(menuItems, '')} + on:click={() => setActiveMenuItem('')} > Logo

{$page.data.appName}

@@ -180,21 +161,23 @@
@@ -232,6 +214,7 @@ {$user.username} +
{ diff --git a/interface/src/routes/statusbar.svelte b/interface/src/routes/statusbar.svelte index d790507d..006c7ba2 100644 --- a/interface/src/routes/statusbar.svelte +++ b/interface/src/routes/statusbar.svelte @@ -52,7 +52,12 @@ {#if $telemetry.rssi.disconnected} {:else} - + {/if}
diff --git a/interface/src/routes/wifi/ap/Accesspoint.svelte b/interface/src/routes/wifi/ap/Accesspoint.svelte index 6b110897..93ca2839 100644 --- a/interface/src/routes/wifi/ap/Accesspoint.svelte +++ b/interface/src/routes/wifi/ap/Accesspoint.svelte @@ -258,7 +258,7 @@ transition:slide|local={{ duration: 300, easing: cubicOut }} >
-
+
Saved Networks
{#await getWifiSettings()} @@ -609,13 +611,13 @@ > Static IP Config?
- {#if networkEditable.static_ip_config} + {#if static_ip_config}
-
+
diff --git a/lib/framework/APSettingsService.cpp b/lib/framework/APSettingsService.cpp index 9f6b0e55..0478dd71 100644 --- a/lib/framework/APSettingsService.cpp +++ b/lib/framework/APSettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/APSettingsService.h b/lib/framework/APSettingsService.h index 0e342d35..3f91c678 100644 --- a/lib/framework/APSettingsService.h +++ b/lib/framework/APSettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/APStatus.cpp b/lib/framework/APStatus.cpp index d6d65641..cb8b70a2 100644 --- a/lib/framework/APStatus.cpp +++ b/lib/framework/APStatus.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -33,7 +33,7 @@ void APStatus::begin() esp_err_t APStatus::apStatus(PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_AP_STATUS_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); root["status"] = _apSettingsService->getAPNetworkStatus(); diff --git a/lib/framework/APStatus.h b/lib/framework/APStatus.h index 55b2357f..25b62f72 100644 --- a/lib/framework/APStatus.h +++ b/lib/framework/APStatus.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -23,7 +23,6 @@ #include #include -#define MAX_AP_STATUS_SIZE 1024 #define AP_STATUS_SERVICE_PATH "/rest/apStatus" class APStatus diff --git a/lib/framework/AnalyticsService.h b/lib/framework/AnalyticsService.h index 3aaa15e3..f699d3ce 100644 --- a/lib/framework/AnalyticsService.h +++ b/lib/framework/AnalyticsService.h @@ -7,7 +7,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -49,11 +49,9 @@ class AnalyticsService void _loop() { TickType_t xLastWakeTime = xTaskGetTickCount(); - StaticJsonDocument doc; - char message[MAX_ESP_ANALYTICS_SIZE]; + JsonDocument doc; while (1) { - doc.clear(); doc["uptime"] = millis() / 1000; doc["free_heap"] = ESP.getFreeHeap(); doc["total_heap"] = ESP.getHeapSize(); @@ -63,8 +61,8 @@ class AnalyticsService doc["fs_total"] = ESPFS.totalBytes(); doc["core_temp"] = temperatureRead(); - serializeJson(doc, message); - _socket->emit(EVENT_ANALYTICS, message); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_ANALYTICS, jsonObject); vTaskDelayUntil(&xLastWakeTime, ANALYTICS_INTERVAL / portTICK_PERIOD_MS); } diff --git a/lib/framework/ArduinoJsonJWT.cpp b/lib/framework/ArduinoJsonJWT.cpp index 1489ecb9..0a2691d4 100644 --- a/lib/framework/ArduinoJsonJWT.cpp +++ b/lib/framework/ArduinoJsonJWT.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/ArduinoJsonJWT.h b/lib/framework/ArduinoJsonJWT.h index 38abcf20..b6ad8a1b 100644 --- a/lib/framework/ArduinoJsonJWT.h +++ b/lib/framework/ArduinoJsonJWT.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/AuthenticationService.cpp b/lib/framework/AuthenticationService.cpp index c7f808d5..0aa1c8f6 100644 --- a/lib/framework/AuthenticationService.cpp +++ b/lib/framework/AuthenticationService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -27,13 +27,13 @@ void AuthenticationService::begin() _server->on(SIGN_IN_PATH, HTTP_POST, [this](PsychicRequest *request, JsonVariant &json) { if (json.is()) { - String username = json["username"]; - String password = json["password"]; + String username = json["username"]; + String password = json["password"]; Authentication authentication = _securityManager->authenticate(username, password); if (authentication.authenticated) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, 256); - JsonObject root = response.getRoot(); - root["access_token"] = _securityManager->generateJWT(authentication.user); + PsychicJsonResponse response = PsychicJsonResponse(request, false); + JsonObject root = response.getRoot(); + root["access_token"] = _securityManager->generateJWT(authentication.user); return response.send(); } } diff --git a/lib/framework/AuthenticationService.h b/lib/framework/AuthenticationService.h index 1cc02ba5..9308e377 100644 --- a/lib/framework/AuthenticationService.h +++ b/lib/framework/AuthenticationService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,8 +22,6 @@ #define VERIFY_AUTHORIZATION_PATH "/rest/verifyAuthorization" #define SIGN_IN_PATH "/rest/signIn" -#define MAX_AUTHENTICATION_SIZE 256 - #if FT_ENABLED(FT_SECURITY) class AuthenticationService diff --git a/lib/framework/BatteryService.cpp b/lib/framework/BatteryService.cpp index 808bdc51..001f0a1e 100644 --- a/lib/framework/BatteryService.cpp +++ b/lib/framework/BatteryService.cpp @@ -5,7 +5,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -24,10 +24,9 @@ void BatteryService::begin() void BatteryService::batteryEvent() { - StaticJsonDocument<32> doc; - char message[32]; + JsonDocument doc; doc["soc"] = _lastSOC; doc["charging"] = _isCharging; - serializeJson(doc, message); - _socket->emit(EVENT_BATTERY, message); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_BATTERY, jsonObject); } diff --git a/lib/framework/BatteryService.h b/lib/framework/BatteryService.h index 2496a2a1..e785f539 100644 --- a/lib/framework/BatteryService.h +++ b/lib/framework/BatteryService.h @@ -7,7 +7,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/DownloadFirmwareService.cpp b/lib/framework/DownloadFirmwareService.cpp index 07a09ede..acdf98c0 100644 --- a/lib/framework/DownloadFirmwareService.cpp +++ b/lib/framework/DownloadFirmwareService.cpp @@ -5,7 +5,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -17,25 +17,25 @@ extern const uint8_t rootca_crt_bundle_start[] asm("_binary_src_certs_x509_crt_b static EventSocket *_socket = nullptr; static int previousProgress = 0; -StaticJsonDocument<128> doc; +JsonDocument doc; void update_started() { String output; doc["status"] = "preparing"; - serializeJson(doc, output); - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); } void update_progress(int currentBytes, int totalBytes) { - String output; doc["status"] = "progress"; int progress = ((currentBytes * 100) / totalBytes); if (progress > previousProgress) { doc["progress"] = progress; - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); ESP_LOGV("Download OTA", "HTTP update process at %d of %d bytes... (%d %%)", currentBytes, totalBytes, progress); } previousProgress = progress; @@ -43,10 +43,9 @@ void update_progress(int currentBytes, int totalBytes) void update_finished() { - String output; doc["status"] = "finished"; - serializeJson(doc, output); - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); // delay to allow the event to be sent out vTaskDelay(100 / portTICK_PERIOD_MS); @@ -68,6 +67,7 @@ void updateTask(void *param) // httpUpdate.onEnd(update_finished); t_httpUpdate_return ret = httpUpdate.update(client, url.c_str()); + JsonObject jsonObject; switch (ret) { @@ -75,8 +75,8 @@ void updateTask(void *param) doc["status"] = "error"; doc["error"] = httpUpdate.getLastErrorString().c_str(); - serializeJson(doc, output); - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); ESP_LOGE("Download OTA", "HTTP Update failed with error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); #ifdef SERIAL_INFO @@ -87,8 +87,8 @@ void updateTask(void *param) doc["status"] = "error"; doc["error"] = "Update failed, has same firmware version"; - serializeJson(doc, output); - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); ESP_LOGE("Download OTA", "HTTP Update failed, has same firmware version"); #ifdef SERIAL_INFO @@ -143,10 +143,8 @@ esp_err_t DownloadFirmwareService::downloadUpdate(PsychicRequest *request, JsonV doc["progress"] = 0; doc["error"] = ""; - String output; - serializeJson(doc, output); - - _socket->emit(EVENT_DOWNLOAD_OTA, output.c_str()); + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_DOWNLOAD_OTA, jsonObject); if (xTaskCreatePinnedToCore( &updateTask, // Function that should be called diff --git a/lib/framework/DownloadFirmwareService.h b/lib/framework/DownloadFirmwareService.h index e9b6869c..96fcb35f 100644 --- a/lib/framework/DownloadFirmwareService.h +++ b/lib/framework/DownloadFirmwareService.h @@ -8,7 +8,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/ESP32SvelteKit.cpp b/lib/framework/ESP32SvelteKit.cpp index 1648455c..ec8e68dd 100644 --- a/lib/framework/ESP32SvelteKit.cpp +++ b/lib/framework/ESP32SvelteKit.cpp @@ -24,6 +24,7 @@ ESP32SvelteKit::ESP32SvelteKit(PsychicHttpServer *server, unsigned int numberEnd _apSettingsService(server, &ESPFS, &_securitySettingsService), _apStatus(server, &_securitySettingsService, &_apSettingsService), _socket(server, &_securitySettingsService, AuthenticationPredicates::IS_AUTHENTICATED), + _notificationService(&_socket), #if FT_ENABLED(FT_NTP) _ntpSettingsService(server, &ESPFS, &_securitySettingsService), _ntpStatus(server, &_securitySettingsService), @@ -137,6 +138,7 @@ void ESP32SvelteKit::begin() // Start the services _apStatus.begin(); _socket.begin(); + _notificationService.begin(); _apSettingsService.begin(); _factoryResetService.begin(); _featureService.begin(); diff --git a/lib/framework/ESP32SvelteKit.h b/lib/framework/ESP32SvelteKit.h index 6f41932f..6bd02c79 100644 --- a/lib/framework/ESP32SvelteKit.h +++ b/lib/framework/ESP32SvelteKit.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,11 @@ class ESP32SvelteKit return &_apSettingsService; } + NotificationService *getNotificationService() + { + return &_notificationService; + } + #if FT_ENABLED(FT_NTP) StatefulService *getNTPSettingsService() { @@ -171,6 +177,7 @@ class ESP32SvelteKit APSettingsService _apSettingsService; APStatus _apStatus; EventSocket _socket; + NotificationService _notificationService; #if FT_ENABLED(FT_NTP) NTPSettingsService _ntpSettingsService; NTPStatus _ntpStatus; diff --git a/lib/framework/ESPFS.h b/lib/framework/ESPFS.h index 3ec3a6cd..5cb0dd48 100644 --- a/lib/framework/ESPFS.h +++ b/lib/framework/ESPFS.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/EventEndpoint.h b/lib/framework/EventEndpoint.h index c5041675..86ff45cf 100644 --- a/lib/framework/EventEndpoint.h +++ b/lib/framework/EventEndpoint.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -27,13 +27,11 @@ class EventEndpoint EventEndpoint(JsonStateReader stateReader, JsonStateUpdater stateUpdater, StatefulService *statefulService, - EventSocket *socket, const char *event, - size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader), - _stateUpdater(stateUpdater), - _statefulService(statefulService), - _socket(socket), - _bufferSize(bufferSize), - _event(event) + EventSocket *socket, const char *event) : _stateReader(stateReader), + _stateUpdater(stateUpdater), + _statefulService(statefulService), + _socket(socket), + _event(event) { _statefulService->addUpdateHandler([&](const String &originId) { syncState(originId); }, @@ -44,7 +42,8 @@ class EventEndpoint { _socket->registerEvent(_event); _socket->onEvent(_event, std::bind(&EventEndpoint::updateState, this, std::placeholders::_1, std::placeholders::_2)); - _socket->onSubscribe(_event, std::bind(&EventEndpoint::syncState, this, std::placeholders::_1, std::placeholders::_2)); + _socket->onSubscribe(_event, [&](const String &originId) + { syncState(originId, true); }); } private: @@ -53,7 +52,6 @@ class EventEndpoint StatefulService *_statefulService; EventSocket *_socket; const char *_event; - size_t _bufferSize; void updateState(JsonObject &root, int originId) { @@ -62,13 +60,11 @@ class EventEndpoint void syncState(const String &originId, bool sync = false) { - DynamicJsonDocument jsonDocument{_bufferSize}; + JsonDocument jsonDocument; JsonObject root = jsonDocument.to(); - String output; _statefulService->read(root, _stateReader); - serializeJson(root, output); - ESP_LOGV("EventEndpoint", "Syncing state: %s", output.c_str()); - _socket->emit(_event, output.c_str(), originId.c_str(), sync); + JsonObject jsonObject = jsonDocument.as(); + _socket->emitEvent(_event, jsonObject, originId.c_str(), sync); } }; diff --git a/lib/framework/EventSocket.cpp b/lib/framework/EventSocket.cpp index 17c49400..e6be158d 100644 --- a/lib/framework/EventSocket.cpp +++ b/lib/framework/EventSocket.cpp @@ -6,8 +6,7 @@ EventSocket::EventSocket(PsychicHttpServer *server, SecurityManager *securityManager, AuthenticationPredicate authenticationPredicate) : _server(server), _securityManager(securityManager), - _authenticationPredicate(authenticationPredicate), - _bufferSize(1024) + _authenticationPredicate(authenticationPredicate) { } @@ -19,11 +18,6 @@ void EventSocket::begin() _socket.onFrame(std::bind(&EventSocket::onFrame, this, std::placeholders::_1, std::placeholders::_2)); _server->on(EVENT_SERVICE_PATH, &_socket); - registerEvent("errorToast"); - registerEvent("warningToast"); - registerEvent("infoToast"); - registerEvent("successToast"); - ESP_LOGV("EventSocket", "Registered event socket endpoint: %s", EVENT_SERVICE_PATH); } @@ -59,13 +53,22 @@ esp_err_t EventSocket::onFrame(PsychicWebSocketRequest *request, httpd_ws_frame ESP_LOGV("EventSocket", "ws[%s][%u] opcode[%d]", request->client()->remoteIP().toString().c_str(), request->client()->socket(), frame->type); + JsonDocument doc; +#if FT_ENABLED(EVENT_USE_JSON) if (frame->type == HTTPD_WS_TYPE_TEXT) { ESP_LOGV("EventSocket", "ws[%s][%u] request: %s", request->client()->remoteIP().toString().c_str(), request->client()->socket(), (char *)frame->payload); - DynamicJsonDocument doc = DynamicJsonDocument(_bufferSize); DeserializationError error = deserializeJson(doc, (char *)frame->payload, frame->len); +#else + if (frame->type == HTTPD_WS_TYPE_BINARY) + { + ESP_LOGV("EventSocket", "ws[%s][%u] request: %s", request->client()->remoteIP().toString().c_str(), + request->client()->socket(), (char *)frame->payload); + + DeserializationError error = deserializeMsgPack(doc, (char *)frame->payload, frame->len); +#endif if (!error && doc.is()) { @@ -94,21 +97,12 @@ esp_err_t EventSocket::onFrame(PsychicWebSocketRequest *request, httpd_ws_frame } return ESP_OK; } + ESP_LOGW("EventSocket", "Error[%d] parsing JSON: %s", error, (char *)frame->payload); } return ESP_OK; } -void EventSocket::emit(String event, String payload) -{ - emit(event.c_str(), payload.c_str(), ""); -} - -void EventSocket::emit(const char *event, const char *payload) -{ - emit(event, payload, ""); -} - -void EventSocket::emit(const char *event, const char *payload, const char *originId, bool onlyToSameOrigin) +void EventSocket::emitEvent(String event, JsonObject &jsonObject, const char *originId, bool onlyToSameOrigin) { // Only process valid events if (!isEventValid(String(event))) @@ -125,7 +119,27 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi xSemaphoreGive(clientSubscriptionsMutex); return; } - String msg = "[\"" + String(event) + "\"," + String(payload) + "]"; + + JsonDocument doc; + doc["event"] = event; + doc["data"] = jsonObject; + +#if FT_ENABLED(EVENT_USE_JSON) + size_t len = measureJson(doc); +#else + size_t len = measureMsgPack(doc); +#endif + + char *output = new char[len + 1]; + +#if FT_ENABLED(EVENT_USE_JSON) + serializeJson(doc, output, len + 1); +#else + serializeMsgPack(doc, output, len); +#endif + + // null terminate the string + output[len] = '\0'; // if onlyToSameOrigin == true, send the message back to the origin if (onlyToSameOrigin && originSubscriptionId > 0) @@ -133,9 +147,12 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi auto *client = _socket.getClient(originSubscriptionId); if (client) { - ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event, client->remoteIP().toString().c_str(), - msg.c_str()); - client->sendMessage(msg.c_str()); + ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message[%d]: %s", event, client->remoteIP().toString().c_str(), len, output); +#if FT_ENABLED(EVENT_USE_JSON) + client->sendMessage(HTTPD_WS_TYPE_TEXT, output, len); +#else + client->sendMessage(HTTPD_WS_TYPE_BINARY, output, len); +#endif } } else @@ -151,36 +168,17 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi subscriptions.remove(subscription); continue; } - ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event, client->remoteIP().toString().c_str(), - msg.c_str()); - client->sendMessage(msg.c_str()); + ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message[%d]: %s", event, client->remoteIP().toString().c_str(), len, output); +#if FT_ENABLED(EVENT_USE_JSON) + client->sendMessage(HTTPD_WS_TYPE_TEXT, output, len); +#else + client->sendMessage(HTTPD_WS_TYPE_BINARY, output, len); +#endif } } - xSemaphoreGive(clientSubscriptionsMutex); -} -void EventSocket::pushNotification(String message, pushEvent event) -{ - String eventType; - switch (event) - { - case (PUSHERROR): - eventType = "errorToast"; - break; - case (PUSHWARNING): - eventType = "warningToast"; - break; - case (PUSHINFO): - eventType = "infoToast"; - break; - case (PUSHSUCCESS): - eventType = "successToast"; - break; - default: - ESP_LOGW("EventSocket", "Client tried invalid push notification: %s", event); - return; - } - emit(eventType.c_str(), message.c_str()); + delete[] output; + xSemaphoreGive(clientSubscriptionsMutex); } void EventSocket::handleEventCallbacks(String event, JsonObject &jsonObject, int originId) @@ -195,7 +193,7 @@ void EventSocket::handleSubscribeCallbacks(String event, const String &originId) { for (auto &callback : subscribe_callbacks[event]) { - callback(originId, true); + callback(originId); } } diff --git a/lib/framework/EventSocket.h b/lib/framework/EventSocket.h index 84b52c2b..d10f66d2 100644 --- a/lib/framework/EventSocket.h +++ b/lib/framework/EventSocket.h @@ -1,6 +1,20 @@ #ifndef Socket_h #define Socket_h +/** + * ESP32 SvelteKit + * + * A simple, secure and extensible framework for IoT projects for ESP32 platforms + * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. + * https://github.com/theelims/ESP32-sveltekit + * + * Copyright (C) 2018 - 2023 rjwats + * Copyright (C) 2023 - 2024 theelims + * + * All Rights Reserved. This software may be modified and distributed under + * the terms of the LGPL v3 license. See the LICENSE file for details. + **/ + #include #include #include @@ -11,15 +25,7 @@ #define EVENT_SERVICE_PATH "/ws/events" typedef std::function EventCallback; -typedef std::function SubscribeCallback; - -enum pushEvent -{ - PUSHERROR, - PUSHWARNING, - PUSHINFO, - PUSHSUCCESS -}; +typedef std::function SubscribeCallback; class EventSocket { @@ -34,15 +40,9 @@ class EventSocket void onSubscribe(String event, SubscribeCallback callback); - void emit(String event, String payload); - - void emit(const char *event, const char *payload); - - void emit(const char *event, const char *payload, const char *originId, bool onlyToSameOrigin = false); + void emitEvent(String event, JsonObject &jsonObject, const char *originId = "", bool onlyToSameOrigin = false); // if onlyToSameOrigin == true, the message will be sent to the originId only, otherwise it will be broadcasted to all clients except the originId - void pushNotification(String message, pushEvent event); - private: PsychicHttpServer *_server; PsychicWebSocketHandler _socket; @@ -58,7 +58,6 @@ class EventSocket bool isEventValid(String event); - size_t _bufferSize; void onWSOpen(PsychicWebSocketClient *client); void onWSClose(PsychicWebSocketClient *client); esp_err_t onFrame(PsychicWebSocketRequest *request, httpd_ws_frame *frame); diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index a1de7c32..729ce081 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -26,14 +26,12 @@ class FSPersistence JsonStateUpdater stateUpdater, StatefulService *statefulService, FS *fs, - const char *filePath, - size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader), - _stateUpdater(stateUpdater), - _statefulService(statefulService), - _fs(fs), - _filePath(filePath), - _bufferSize(bufferSize), - _updateHandlerId(0) + const char *filePath) : _stateReader(stateReader), + _stateUpdater(stateUpdater), + _statefulService(statefulService), + _fs(fs), + _filePath(filePath), + _updateHandlerId(0) { enableUpdateHandler(); } @@ -44,7 +42,7 @@ class FSPersistence if (settingsFile) { - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; DeserializationError error = deserializeJson(jsonDocument, settingsFile); if (error == DeserializationError::Ok && jsonDocument.is()) { @@ -66,7 +64,7 @@ class FSPersistence bool writeToFS() { // create and populate a new json object - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; JsonObject jsonObject = jsonDocument.to(); _statefulService->read(jsonObject, _stateReader); @@ -112,7 +110,6 @@ class FSPersistence StatefulService *_statefulService; FS *_fs; const char *_filePath; - size_t _bufferSize; update_handler_id_t _updateHandlerId; // We assume we have a _filePath with format "/directory1/directory2/filename" @@ -136,7 +133,7 @@ class FSPersistence // is supplied, this virtual function allows that to be changed. virtual void applyDefaults() { - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; JsonObject jsonObject = jsonDocument.as(); _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater); } diff --git a/lib/framework/FactoryResetService.cpp b/lib/framework/FactoryResetService.cpp index e7bb6448..a16a00e6 100644 --- a/lib/framework/FactoryResetService.cpp +++ b/lib/framework/FactoryResetService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/FactoryResetService.h b/lib/framework/FactoryResetService.h index 9299cb69..71873c25 100644 --- a/lib/framework/FactoryResetService.h +++ b/lib/framework/FactoryResetService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/Features.h b/lib/framework/Features.h index 60957cf4..ce4c5188 100644 --- a/lib/framework/Features.h +++ b/lib/framework/Features.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -57,4 +57,9 @@ #define FT_ANALYTICS 1 #endif +// Use JSON for events. Default, use MessagePack for events +#ifndef EVENT_USE_JSON +#define EVENT_USE_JSON 0 +#endif + #endif diff --git a/lib/framework/FeaturesService.cpp b/lib/framework/FeaturesService.cpp index 2c05ae90..18853fab 100644 --- a/lib/framework/FeaturesService.cpp +++ b/lib/framework/FeaturesService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,7 +22,7 @@ void FeaturesService::begin() { _server->on(FEATURES_SERVICE_PATH, HTTP_GET, [&](PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_FEATURES_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); #if FT_ENABLED(FT_SECURITY) @@ -65,6 +65,13 @@ void FeaturesService::begin() #else root["analytics"] = false; #endif + +#if FT_ENABLED(EVENT_USE_JSON) + root["event_use_json"] = true; +#else + root["event_use_json"] = false; +#endif + root["firmware_version"] = APP_VERSION; root["firmware_name"] = APP_NAME; root["firmware_built_target"] = BUILD_TARGET; diff --git a/lib/framework/FeaturesService.h b/lib/framework/FeaturesService.h index 7f524bd6..f132c900 100644 --- a/lib/framework/FeaturesService.h +++ b/lib/framework/FeaturesService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,7 +22,6 @@ #include #include -#define MAX_FEATURES_SIZE 256 #define FEATURES_SERVICE_PATH "/rest/features" typedef struct diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index 0397a48a..4232c3e4 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -20,7 +20,6 @@ class HttpEndpoint JsonStateReader _stateReader; JsonStateUpdater _stateUpdater; StatefulService *_statefulService; - size_t _bufferSize; SecurityManager *_securityManager; AuthenticationPredicate _authenticationPredicate; PsychicHttpServer *_server; @@ -33,9 +32,13 @@ class HttpEndpoint PsychicHttpServer *server, const char *servicePath, SecurityManager *securityManager, - AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN, - size_t bufferSize = DEFAULT_BUFFER_SIZE) - : _stateReader(stateReader), _stateUpdater(stateUpdater), _statefulService(statefulService), _server(server), _servicePath(servicePath), _securityManager(securityManager), _authenticationPredicate(authenticationPredicate), _bufferSize(bufferSize) + AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN) : _stateReader(stateReader), + _stateUpdater(stateUpdater), + _statefulService(statefulService), + _server(server), + _servicePath(servicePath), + _securityManager(securityManager), + _authenticationPredicate(authenticationPredicate) { } @@ -61,7 +64,7 @@ class HttpEndpoint _securityManager->wrapRequest( [this](PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, _bufferSize); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject jsonObject = response.getRoot(); _statefulService->read(jsonObject, _stateReader); return response.send(); @@ -93,7 +96,7 @@ class HttpEndpoint _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); } - PsychicJsonResponse response = PsychicJsonResponse(request, false, _bufferSize); + PsychicJsonResponse response = PsychicJsonResponse(request, false); jsonObject = response.getRoot(); _statefulService->read(jsonObject, _stateReader); diff --git a/lib/framework/IPUtils.h b/lib/framework/IPUtils.h index c2e548b3..ba69f9dc 100644 --- a/lib/framework/IPUtils.h +++ b/lib/framework/IPUtils.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/JsonUtils.h b/lib/framework/JsonUtils.h index 067adae9..e3f94656 100644 --- a/lib/framework/JsonUtils.h +++ b/lib/framework/JsonUtils.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/MqttEndpoint.h b/lib/framework/MqttEndpoint.h index b97087e7..c8bf64c2 100644 --- a/lib/framework/MqttEndpoint.h +++ b/lib/framework/MqttEndpoint.h @@ -30,15 +30,13 @@ class MqttEndpoint PsychicMqttClient *mqttClient, const String &pubTopic = "", const String &subTopic = "", - bool retain = false, - size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader), - _stateUpdater(stateUpdater), - _statefulService(statefulService), - _mqttClient(mqttClient), - _pubTopic(pubTopic), - _subTopic(subTopic), - _retain(retain), - _bufferSize(bufferSize) + bool retain = false) : _stateReader(stateReader), + _stateUpdater(stateUpdater), + _statefulService(statefulService), + _mqttClient(mqttClient), + _pubTopic(pubTopic), + _subTopic(subTopic), + _retain(retain) { _statefulService->addUpdateHandler([&](const String &originId) @@ -95,7 +93,7 @@ class MqttEndpoint if (_pubTopic.length() > 0 && _mqttClient->connected()) { // serialize to json doc - DynamicJsonDocument json(_bufferSize); + JsonDocument json; JsonObject jsonObject = json.to(); _statefulService->read(jsonObject, _stateReader); @@ -116,7 +114,6 @@ class MqttEndpoint protected: StatefulService *_statefulService; PsychicMqttClient *_mqttClient; - int _bufferSize; JsonStateUpdater _stateUpdater; JsonStateReader _stateReader; String _subTopic; @@ -136,7 +133,7 @@ class MqttEndpoint } // deserialize from string - DynamicJsonDocument json(_bufferSize); + JsonDocument json; DeserializationError error = deserializeJson(json, payload); if (!error && json.is()) { diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 881e2777..97216221 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 8624b874..d45f3199 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/MqttStatus.cpp b/lib/framework/MqttStatus.cpp index 8a56feb8..85235d6f 100644 --- a/lib/framework/MqttStatus.cpp +++ b/lib/framework/MqttStatus.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -34,7 +34,7 @@ void MqttStatus::begin() esp_err_t MqttStatus::mqttStatus(PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_MQTT_STATUS_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); root["enabled"] = _mqttSettingsService->isEnabled(); diff --git a/lib/framework/MqttStatus.h b/lib/framework/MqttStatus.h index 4ec80fef..364b100c 100644 --- a/lib/framework/MqttStatus.h +++ b/lib/framework/MqttStatus.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,7 +22,6 @@ #include #include -#define MAX_MQTT_STATUS_SIZE 1024 #define MQTT_STATUS_SERVICE_PATH "/rest/mqttStatus" class MqttStatus diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index 0e0ffe5d..c5b37efb 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/NTPSettingsService.h b/lib/framework/NTPSettingsService.h index 1b511501..0ec7fa29 100644 --- a/lib/framework/NTPSettingsService.h +++ b/lib/framework/NTPSettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -41,7 +41,6 @@ #define NTP_SETTINGS_FILE "/config/ntpSettings.json" #define NTP_SETTINGS_SERVICE_PATH "/rest/ntpSettings" -#define MAX_TIME_SIZE 256 #define TIME_PATH "/rest/time" class NTPSettings diff --git a/lib/framework/NTPStatus.cpp b/lib/framework/NTPStatus.cpp index 27a9a5c9..90d3b060 100644 --- a/lib/framework/NTPStatus.cpp +++ b/lib/framework/NTPStatus.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -53,7 +53,7 @@ String toLocalTimeString(tm *time) esp_err_t NTPStatus::ntpStatus(PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_NTP_STATUS_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); // grab the current instant in unix seconds diff --git a/lib/framework/NTPStatus.h b/lib/framework/NTPStatus.h index f9baeef3..2ae9d2fd 100644 --- a/lib/framework/NTPStatus.h +++ b/lib/framework/NTPStatus.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -23,7 +23,6 @@ #include #include -#define MAX_NTP_STATUS_SIZE 1024 #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" class NTPStatus diff --git a/lib/framework/NotificationService.cpp b/lib/framework/NotificationService.cpp new file mode 100644 index 00000000..2940cc8c --- /dev/null +++ b/lib/framework/NotificationService.cpp @@ -0,0 +1,22 @@ +#include + +// array translating pushType into strings +const char *pushTypeStrings[] = {"error", "warning", "info", "success"}; + +NotificationService::NotificationService(EventSocket *eventSocket) : _eventSocket(eventSocket) +{ +} + +void NotificationService::begin() +{ + _eventSocket->registerEvent(NOTIFICATION_EVENT); +} + +void NotificationService::pushNotification(String message, pushType event) +{ + JsonDocument doc; + doc["type"] = pushTypeStrings[event]; + doc["message"] = message; + JsonObject jsonObject = doc.as(); + _eventSocket->emitEvent(NOTIFICATION_EVENT, jsonObject); +} diff --git a/lib/framework/NotificationService.h b/lib/framework/NotificationService.h new file mode 100644 index 00000000..aee238c2 --- /dev/null +++ b/lib/framework/NotificationService.h @@ -0,0 +1,43 @@ +#ifndef NotificationService_h +#define NotificationService_h + +/** + * ESP32 SvelteKit + * + * A simple, secure and extensible framework for IoT projects for ESP32 platforms + * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. + * https://github.com/theelims/ESP32-sveltekit + * + * Copyright (C) 2018 - 2023 rjwats + * Copyright (C) 2023 - 2024 theelims + * + * All Rights Reserved. This software may be modified and distributed under + * the terms of the LGPL v3 license. See the LICENSE file for details. + **/ + +#include + +#define NOTIFICATION_EVENT "notification" + +enum pushType +{ + PUSHERROR, + PUSHWARNING, + PUSHINFO, + PUSHSUCCESS +}; + +class NotificationService +{ +public: + NotificationService(EventSocket *eventSocket); + + void begin(); + + void pushNotification(String message, pushType event); + +private: + EventSocket *_eventSocket; +}; + +#endif // NotificationService_h \ No newline at end of file diff --git a/lib/framework/RestartService.cpp b/lib/framework/RestartService.cpp index 6a918148..6e7a5cdc 100644 --- a/lib/framework/RestartService.cpp +++ b/lib/framework/RestartService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/RestartService.h b/lib/framework/RestartService.h index 56f16840..a3b7b893 100644 --- a/lib/framework/RestartService.h +++ b/lib/framework/RestartService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 4224c0e1..5aef1f46 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -26,8 +26,6 @@ #define AUTHORIZATION_HEADER_PREFIX "Bearer " #define AUTHORIZATION_HEADER_PREFIX_LEN 7 -#define MAX_JWT_SIZE 128 - class User { public: diff --git a/lib/framework/SecuritySettingsService.cpp b/lib/framework/SecuritySettingsService.cpp index 4acdbc79..37eb09b5 100644 --- a/lib/framework/SecuritySettingsService.cpp +++ b/lib/framework/SecuritySettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -69,7 +69,7 @@ void SecuritySettingsService::configureJWTHandler() Authentication SecuritySettingsService::authenticateJWT(String &jwt) { - DynamicJsonDocument payloadDocument(MAX_JWT_SIZE); + JsonDocument payloadDocument; _jwtHandler.parseJWT(jwt, payloadDocument); if (payloadDocument.is()) { @@ -106,7 +106,7 @@ inline void populateJWTPayload(JsonObject &payload, User *user) boolean SecuritySettingsService::validatePayload(JsonObject &parsedPayload, User *user) { - DynamicJsonDocument jsonDocument(MAX_JWT_SIZE); + JsonDocument jsonDocument; JsonObject payload = jsonDocument.to(); populateJWTPayload(payload, user); return payload == parsedPayload; @@ -114,7 +114,7 @@ boolean SecuritySettingsService::validatePayload(JsonObject &parsedPayload, User String SecuritySettingsService::generateJWT(User *user) { - DynamicJsonDocument jsonDocument(MAX_JWT_SIZE); + JsonDocument jsonDocument; JsonObject payload = jsonDocument.to(); populateJWTPayload(payload, user); return _jwtHandler.buildJWT(payload); @@ -179,7 +179,7 @@ esp_err_t SecuritySettingsService::generateToken(PsychicRequest *request) { if (_user.username == usernameParam) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, GENERATE_TOKEN_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); root["token"] = generateJWT(&_user); return response.send(); diff --git a/lib/framework/SecuritySettingsService.h b/lib/framework/SecuritySettingsService.h index ce6de701..d68953e6 100644 --- a/lib/framework/SecuritySettingsService.h +++ b/lib/framework/SecuritySettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -44,7 +44,6 @@ #define SECURITY_SETTINGS_FILE "/config/securitySettings.json" #define SECURITY_SETTINGS_PATH "/rest/securitySettings" -#define GENERATE_TOKEN_SIZE 512 #define GENERATE_TOKEN_PATH "/rest/generateToken" #if FT_ENABLED(FT_SECURITY) @@ -61,10 +60,10 @@ class SecuritySettings root["jwt_secret"] = settings.jwtSecret; // users - JsonArray users = root.createNestedArray("users"); + JsonArray users = root["users"].to(); for (User user : settings.users) { - JsonObject userRoot = users.createNestedObject(); + JsonObject userRoot = users.add(); userRoot["username"] = user.username; userRoot["password"] = user.password; userRoot["admin"] = user.admin; diff --git a/lib/framework/SettingValue.cpp b/lib/framework/SettingValue.cpp index 9ebba8e2..8eff5802 100644 --- a/lib/framework/SettingValue.cpp +++ b/lib/framework/SettingValue.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/SettingValue.h b/lib/framework/SettingValue.h index d0aee406..46e79ab9 100644 --- a/lib/framework/SettingValue.h +++ b/lib/framework/SettingValue.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/SleepService.cpp b/lib/framework/SleepService.cpp index 633d675f..15e12b3d 100644 --- a/lib/framework/SleepService.cpp +++ b/lib/framework/SleepService.cpp @@ -5,7 +5,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/SleepService.h b/lib/framework/SleepService.h index 2524e2da..ffa09618 100644 --- a/lib/framework/SleepService.h +++ b/lib/framework/SleepService.h @@ -7,7 +7,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/StatefulService.cpp b/lib/framework/StatefulService.cpp index e3599074..297f74d8 100644 --- a/lib/framework/StatefulService.cpp +++ b/lib/framework/StatefulService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/StatefulService.h b/lib/framework/StatefulService.h index 530ecef6..32893c17 100644 --- a/lib/framework/StatefulService.h +++ b/lib/framework/StatefulService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -23,10 +23,6 @@ #include #include -#ifndef DEFAULT_BUFFER_SIZE -#define DEFAULT_BUFFER_SIZE 1024 -#endif - enum class StateUpdateResult { CHANGED = 0, // The update changed the state and propagation should take place if required diff --git a/lib/framework/SystemStatus.cpp b/lib/framework/SystemStatus.cpp index f41848ed..7e0700f2 100644 --- a/lib/framework/SystemStatus.cpp +++ b/lib/framework/SystemStatus.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -111,7 +111,7 @@ void SystemStatus::begin() esp_err_t SystemStatus::systemStatus(PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_ESP_STATUS_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); root["esp_platform"] = ESP_PLATFORM; diff --git a/lib/framework/SystemStatus.h b/lib/framework/SystemStatus.h index 139d6de2..87367c4a 100644 --- a/lib/framework/SystemStatus.h +++ b/lib/framework/SystemStatus.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,7 +22,6 @@ #include #include -#define MAX_ESP_STATUS_SIZE 1024 #define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" class SystemStatus diff --git a/lib/framework/UploadFirmwareService.cpp b/lib/framework/UploadFirmwareService.cpp index 1466c5c1..bf9f7a51 100644 --- a/lib/framework/UploadFirmwareService.cpp +++ b/lib/framework/UploadFirmwareService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -152,7 +152,7 @@ esp_err_t UploadFirmwareService::uploadComplete(PsychicRequest *request) { if (strlen(md5) == 32) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, 256); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); root["md5"] = md5; return response.send(); diff --git a/lib/framework/UploadFirmwareService.h b/lib/framework/UploadFirmwareService.h index 1e9d4344..0ea5771e 100644 --- a/lib/framework/UploadFirmwareService.h +++ b/lib/framework/UploadFirmwareService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/lib/framework/WebSocketClient.bak b/lib/framework/WebSocketClient.bak index 1d5b9d30..4a88dc4b 100644 --- a/lib/framework/WebSocketClient.bak +++ b/lib/framework/WebSocketClient.bak @@ -6,7 +6,7 @@ * with responsive Sveltekit front-end built with TailwindCSS and DaisyUI. * https://github.com/theelims/ESP32-sveltekit * - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -63,8 +63,7 @@ public: WebSocketClient(JsonStateReader stateReader, JsonStateUpdater stateUpdater, StatefulService *statefulService, - const char *webSocketUri, - size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader), + const char *webSocketUri) : _stateReader(stateReader), _stateUpdater(stateUpdater), _statefulService(statefulService), _bufferSize(bufferSize) @@ -194,7 +193,7 @@ protected: payload[data->data_len] = '\0'; ESP_LOGV(wsTAG, "Payload=%s", payload); - // DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + // JsonDocument jsonDocument; // DeserializationError error = deserializeJson(jsonDocument, payload); // ESP_LOGE(wsTAG, "deserializeJson() status: %s", error.c_str()); @@ -232,7 +231,7 @@ protected: void transmitData(const String &originId) { - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; JsonObject payload = jsonDocument.to(); _statefulService->read(payload, _stateReader); String json_string; diff --git a/lib/framework/WebSocketServer.h b/lib/framework/WebSocketServer.h index 1a325a5b..99f9f536 100644 --- a/lib/framework/WebSocketServer.h +++ b/lib/framework/WebSocketServer.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -19,8 +19,6 @@ #include #include -#define WEB_SOCKET_CLIENT_ID_MSG_SIZE 128 - #define WEB_SOCKET_ORIGIN "wsserver" #define WEB_SOCKET_ORIGIN_CLIENT_ID_PREFIX "wsserver:" @@ -34,15 +32,13 @@ class WebSocketServer PsychicHttpServer *server, const char *webSocketPath, SecurityManager *securityManager, - AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN, - size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader), - _stateUpdater(stateUpdater), - _statefulService(statefulService), - _server(server), - _bufferSize(bufferSize), - _webSocketPath(webSocketPath), - _authenticationPredicate(authenticationPredicate), - _securityManager(securityManager) + AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN) : _stateReader(stateReader), + _stateUpdater(stateUpdater), + _statefulService(statefulService), + _server(server), + _webSocketPath(webSocketPath), + _authenticationPredicate(authenticationPredicate), + _securityManager(securityManager) { _statefulService->addUpdateHandler( [&](const String &originId) @@ -90,7 +86,7 @@ class WebSocketServer { ESP_LOGV("WebSocketServer", "ws[%s][%u] request: %s", request->client()->remoteIP().toString().c_str(), request->client()->socket(), (char *)frame->payload); - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; DeserializationError error = deserializeJson(jsonDocument, (char *)frame->payload, frame->len); if (!error && jsonDocument.is()) @@ -117,11 +113,10 @@ class WebSocketServer PsychicHttpServer *_server; PsychicWebSocketHandler _webSocket; String _webSocketPath; - size_t _bufferSize; void transmitId(PsychicWebSocketClient *client) { - DynamicJsonDocument jsonDocument = DynamicJsonDocument(WEB_SOCKET_CLIENT_ID_MSG_SIZE); + JsonDocument jsonDocument; JsonObject root = jsonDocument.to(); root["type"] = "id"; root["id"] = clientId(client); @@ -141,7 +136,7 @@ class WebSocketServer */ void transmitData(PsychicWebSocketClient *client, const String &originId) { - DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize); + JsonDocument jsonDocument; JsonObject root = jsonDocument.to(); String buffer; diff --git a/lib/framework/WiFiScanner.cpp b/lib/framework/WiFiScanner.cpp index 2f1f8384..39be4a1f 100644 --- a/lib/framework/WiFiScanner.cpp +++ b/lib/framework/WiFiScanner.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -52,12 +52,12 @@ esp_err_t WiFiScanner::listNetworks(PsychicRequest *request) int numNetworks = WiFi.scanComplete(); if (numNetworks > -1) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_WIFI_SCANNER_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); - JsonArray networks = root.createNestedArray("networks"); + JsonArray networks = root["networks"].to(); for (int i = 0; i < numNetworks; i++) { - JsonObject network = networks.createNestedObject(); + JsonObject network = networks.add(); network["rssi"] = WiFi.RSSI(i); network["ssid"] = WiFi.SSID(i); network["bssid"] = WiFi.BSSIDstr(i); diff --git a/lib/framework/WiFiScanner.h b/lib/framework/WiFiScanner.h index e963b67a..a846bf6c 100644 --- a/lib/framework/WiFiScanner.h +++ b/lib/framework/WiFiScanner.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -24,8 +24,6 @@ #define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks" #define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks" -#define MAX_WIFI_SCANNER_SIZE 1024 - class WiFiScanner { public: diff --git a/lib/framework/WiFiSettingsService.cpp b/lib/framework/WiFiSettingsService.cpp index 4c510fce..80626c3f 100644 --- a/lib/framework/WiFiSettingsService.cpp +++ b/lib/framework/WiFiSettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -20,7 +20,7 @@ WiFiSettingsService::WiFiSettingsService(PsychicHttpServer *server, EventSocket *socket) : _server(server), _securityManager(securityManager), _httpEndpoint(WiFiSettings::read, WiFiSettings::update, this, server, WIFI_SETTINGS_SERVICE_PATH, securityManager, - AuthenticationPredicates::IS_ADMIN, WIFI_SETTINGS_BUFFER_SIZE), + AuthenticationPredicates::IS_ADMIN), _fsPersistence(WiFiSettings::read, WiFiSettings::update, this, fs, WIFI_SETTINGS_FILE), _lastConnectionAttempt(0), _socket(socket) { @@ -140,7 +140,7 @@ void WiFiSettingsService::connectToWiFi() int32_t chan_scan; WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan); - ESP_LOGV("WiFiSettingsService", "SSID: %s, RSSI: %d dbm", ssid_scan.c_str(), rssi_scan); + ESP_LOGV("WiFiSettingsService", "SSID: %s, BSSID: " MACSTR ", RSSI: %d dbm, Channel: %d", ssid_scan.c_str(), MAC2STR(BSSID_scan), rssi_scan, chan_scan); for (auto &network : _state.wifiSettings) { @@ -149,12 +149,17 @@ void WiFiSettingsService::connectToWiFi() if (rssi_scan > bestNetworkDb) { // best network bestNetworkDb = rssi_scan; - bestNetwork = &network; + ESP_LOGV("WiFiSettingsService", "--> New best network SSID: %s, BSSID: " MACSTR "", ssid_scan.c_str(), MAC2STR(BSSID_scan)); network.available = true; + network.channel = chan_scan; + memcpy(network.bssid, BSSID_scan, 6); + bestNetwork = &network; } - else if (rssi_scan >= FACTORY_WIFI_RSSI_THRESHOLD) + else if (rssi_scan >= FACTORY_WIFI_RSSI_THRESHOLD && network.available == false) { // available network network.available = true; + network.channel = chan_scan; + memcpy(network.bssid, BSSID_scan, 6); } } break; @@ -176,9 +181,8 @@ void WiFiSettingsService::connectToWiFi() } else if (_state.priorityBySignalStrength == true && bestNetwork) { - ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s", bestNetwork->ssid.c_str()); + ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s, BSSID: " MACSTR " ", bestNetwork->ssid.c_str(), MAC2STR(bestNetwork->bssid)); configureNetwork(*bestNetwork); - WiFi.begin(bestNetwork->ssid.c_str(), bestNetwork->password.c_str()); } else // no suitable network to connect { @@ -205,7 +209,8 @@ void WiFiSettingsService::configureNetwork(wifi_settings_t &network) WiFi.setHostname(_state.hostname.c_str()); // attempt to connect to the network - WiFi.begin(network.ssid.c_str(), network.password.c_str()); + WiFi.begin(network.ssid.c_str(), network.password.c_str(), network.channel, network.bssid); + // WiFi.begin(network.ssid.c_str(), network.password.c_str()); #if CONFIG_IDF_TARGET_ESP32C3 WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi @@ -214,9 +219,11 @@ void WiFiSettingsService::configureNetwork(wifi_settings_t &network) void WiFiSettingsService::updateRSSI() { - char buffer[16]; - snprintf(buffer, sizeof(buffer), WiFi.isConnected() ? "%d" : "disconnected", WiFi.RSSI()); - _socket->emit(EVENT_RSSI, buffer); + JsonDocument doc; + doc["rssi"] = WiFi.RSSI(); + doc["ssid"] = WiFi.isConnected() ? WiFi.SSID() : "disconnected"; + JsonObject jsonObject = doc.as(); + _socket->emitEvent(EVENT_RSSI, jsonObject); } void WiFiSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) diff --git a/lib/framework/WiFiSettingsService.h b/lib/framework/WiFiSettingsService.h index 986ef667..f636857a 100644 --- a/lib/framework/WiFiSettingsService.h +++ b/lib/framework/WiFiSettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -47,9 +47,7 @@ #define WIFI_SETTINGS_SERVICE_PATH "/rest/wifiSettings" #define WIFI_RECONNECTION_DELAY 1000 * 30 -#define RSSI_EVENT_DELAY 200 - -#define WIFI_SETTINGS_BUFFER_SIZE 2048 +#define RSSI_EVENT_DELAY 500 #define EVENT_RSSI "rssi" @@ -57,6 +55,8 @@ typedef struct { String ssid; + uint8_t bssid[6]; + int32_t channel; String password; bool staticIPConfig; IPAddress localIP; @@ -81,13 +81,13 @@ class WiFiSettings root["priority_RSSI"] = settings.priorityBySignalStrength; // create JSON array from root - JsonArray wifiNetworks = root.createNestedArray("wifi_networks"); + JsonArray wifiNetworks = root["wifi_networks"].to(); // iterate over the wifiSettings for (auto &wifi : settings.wifiSettings) { // create JSON object for each wifi network - JsonObject wifiNetwork = wifiNetworks.createNestedObject(); + JsonObject wifiNetwork = wifiNetworks.add(); // add the ssid and password to the JSON object wifiNetwork["ssid"] = wifi.ssid; diff --git a/lib/framework/WiFiStatus.cpp b/lib/framework/WiFiStatus.cpp index 539499dc..41348626 100644 --- a/lib/framework/WiFiStatus.cpp +++ b/lib/framework/WiFiStatus.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -63,7 +63,7 @@ void WiFiStatus::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) esp_err_t WiFiStatus::wifiStatus(PsychicRequest *request) { - PsychicJsonResponse response = PsychicJsonResponse(request, false, MAX_WIFI_STATUS_SIZE); + PsychicJsonResponse response = PsychicJsonResponse(request, false); JsonObject root = response.getRoot(); wl_status_t status = WiFi.status(); root["status"] = (uint8_t)status; diff --git a/lib/framework/WiFiStatus.h b/lib/framework/WiFiStatus.h index 3b761c6d..e7c03ba5 100644 --- a/lib/framework/WiFiStatus.h +++ b/lib/framework/WiFiStatus.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -22,7 +22,6 @@ #include #include -#define MAX_WIFI_STATUS_SIZE 1024 #define WIFI_STATUS_SERVICE_PATH "/rest/wifiStatus" class WiFiStatus diff --git a/platformio.ini b/platformio.ini index 6226862f..81886251 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,21 +24,34 @@ build_flags = ${features.build_flags} -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.4.0\" ; semver compatible version string - ; Uncomment to receive log messages from the ESP Arduino Core - -D CORE_DEBUG_LEVEL=4 + -D APP_VERSION=\"0.5.0\" ; semver compatible version string + ; Move all networking stuff to the protocol core 0 and leave business logic on application core 1 -D ESP32SVELTEKIT_RUNNING_CORE=0 + ; Uncomment EMBED_WWW to embed the WWW data in the firmware binary -D EMBED_WWW + ; Uncomment to configure Cross-Origin Resource Sharing ; -D ENABLE_CORS ; -D CORS_ORIGIN=\"*\" - ; Serve config files from flash - ;-D SERVE_CONFIG_FILES + ; Uncomment to enable informations from ESP32-Sveltekit in Serial Monitor -D SERIAL_INFO + ; D E B U G B U I L D F L A G S + ; =============================== + ; These build flags are only for debugging purposes and should not be used in production + + ; Uncomment to show log messages from the ESP Arduino Core and ESP32-SvelteKit + -D CORE_DEBUG_LEVEL=4 + + ; Serve config files from flash and access at /config/filename.json + ;-D SERVE_CONFIG_FILES + + ; Uncomment to use JSON instead of MessagePack for event messages. Default is MessagePack. + ; -D EVENT_USE_JSON=1 + lib_compat_mode = strict ; Uncomment to include the a Root CA SSL Certificate Bundle for all SSL needs @@ -61,7 +74,7 @@ extra_scripts = pre:scripts/generate_cert_bundle.py scripts/rename_fw.py lib_deps = - ArduinoJson@>=6.0.0,<7.0.0 + ArduinoJson@>=7.0.0 https://github.com/theelims/PsychicMqttClient.git#0.1.1 [env:esp32-c3-devkitm-1] diff --git a/scripts/build_interface.py b/scripts/build_interface.py index af5ce3d4..2229ee94 100644 --- a/scripts/build_interface.py +++ b/scripts/build_interface.py @@ -5,7 +5,7 @@ # https://github.com/theelims/ESP32-sveltekit # # Copyright (C) 2018 - 2023 rjwats -# Copyright (C) 2023 theelims +# Copyright (C) 2023 - 2024 theelims # Copyright (C) 2023 Maxtrium B.V. [ code available under dual license ] # Copyright (C) 2024 runeharlyk # diff --git a/src/LightMqttSettingsService.cpp b/src/LightMqttSettingsService.cpp index 8ff2d04a..82bb2c52 100644 --- a/src/LightMqttSettingsService.cpp +++ b/src/LightMqttSettingsService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/src/LightMqttSettingsService.h b/src/LightMqttSettingsService.h index ec539093..61ff4c63 100644 --- a/src/LightMqttSettingsService.h +++ b/src/LightMqttSettingsService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. diff --git a/src/LightStateService.cpp b/src/LightStateService.cpp index 629888d0..b9f1a9eb 100644 --- a/src/LightStateService.cpp +++ b/src/LightStateService.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -29,8 +29,7 @@ LightStateService::LightStateService(PsychicHttpServer *server, LightState::update, this, socket, - LIGHT_SETTINGS_EVENT, - LIGHT_SETTINGS_MAX_BUFFER_SIZE), + LIGHT_SETTINGS_EVENT), _mqttEndpoint(LightState::homeAssistRead, LightState::homeAssistUpdate, this, @@ -85,7 +84,7 @@ void LightStateService::registerConfig() String subTopic; String pubTopic; - DynamicJsonDocument doc(256); + JsonDocument doc; _lightMqttSettingsService->read([&](LightMqttSettings &settings) { configTopic = settings.mqttPath + "/config"; diff --git a/src/LightStateService.h b/src/LightStateService.h index 15365816..8e08b22e 100644 --- a/src/LightStateService.h +++ b/src/LightStateService.h @@ -9,7 +9,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details. @@ -30,7 +30,6 @@ #define LIGHT_SETTINGS_ENDPOINT_PATH "/rest/lightState" #define LIGHT_SETTINGS_SOCKET_PATH "/ws/lightState" #define LIGHT_SETTINGS_EVENT "led" -#define LIGHT_SETTINGS_MAX_BUFFER_SIZE 256 class LightState { diff --git a/src/main.cpp b/src/main.cpp index f35fa5e7..694885ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ * https://github.com/theelims/ESP32-sveltekit * * Copyright (C) 2018 - 2023 rjwats - * Copyright (C) 2023 theelims + * Copyright (C) 2023 - 2024 theelims * * All Rights Reserved. This software may be modified and distributed under * the terms of the LGPL v3 license. See the LICENSE file for details.