mirror of
https://github.com/wled/WLED.git
synced 2025-08-24 01:59:24 +00:00
Compare commits
32 Commits
v0.15.0-b6
...
http-api-r
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cab2f91bc6 | ||
![]() |
e65f6c7bc7 | ||
![]() |
4d0b79f300 | ||
![]() |
e570460cd9 | ||
![]() |
223b97b884 | ||
![]() |
70323b9477 | ||
![]() |
7d0951a08a | ||
![]() |
d98ca9a202 | ||
![]() |
3c2c5bedc5 | ||
![]() |
749d34cd30 | ||
![]() |
1898be2fe1 | ||
![]() |
af34da4160 | ||
![]() |
4588219e31 | ||
![]() |
6e89346f00 | ||
![]() |
2703c9899a | ||
![]() |
4cc2cc4ad4 | ||
![]() |
832599b8c5 | ||
![]() |
c81ef2669e | ||
![]() |
19d837c222 | ||
![]() |
4f48ddfaec | ||
![]() |
2e01fe0b5b | ||
![]() |
7d067d8c30 | ||
![]() |
b3b326738c | ||
![]() |
2bb2caf2d2 | ||
![]() |
2a094883ad | ||
![]() |
6d1126b8aa | ||
![]() |
26a47537f9 | ||
![]() |
01d43c69fb | ||
![]() |
7db1989093 | ||
![]() |
0a97e28aab | ||
![]() |
e9d2182390 | ||
![]() |
44e28f96e0 |
@@ -1,5 +1,14 @@
|
||||
## WLED changelog
|
||||
|
||||
#### Build 2410270
|
||||
- WLED 0.15.0-b7 release
|
||||
- Re-license the WLED project from MIT to EUPL (#4194 by @Aircoookie)
|
||||
- Fix alexa devices invisible/uncontrollable (#4214 by @Svennte)
|
||||
- Add visual expand button on hover (#4172)
|
||||
- Usermod: Audioreactive tuning and performance enhancements (by @softhack007)
|
||||
- `/json/live` (JSON live data/peek) only enabled when WebSockets are disabled
|
||||
- Various bugfixes and optimisations: #4179, #4215, #4219, #4222, #4223, #4224, #4228, #4230
|
||||
|
||||
#### Build 2410140
|
||||
- WLED 0.15.0-b6 release
|
||||
- Added BRT timezone (#4188 by @LuisFadini)
|
||||
|
307
LICENSE
307
LICENSE
@@ -1,21 +1,294 @@
|
||||
MIT License
|
||||
Copyright (c) 2016-present Christian Schwinne and individual WLED contributors
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
|
||||
Copyright (c) 2016 Christian Schwinne
|
||||
EUROPEAN UNION PUBLIC LICENCE v. 1.2
|
||||
EUPL © the European Union 2007, 2016
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This European Union Public Licence (the ‘EUPL’) applies to the Work (as
|
||||
defined below) which is provided under the terms of this Licence. Any use of
|
||||
the Work, other than as authorised under this Licence is prohibited (to the
|
||||
extent such use is covered by a right of the copyright holder of the Work).
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The Work is provided under the terms of this Licence when the Licensor (as
|
||||
defined below) has placed the following notice immediately following the
|
||||
copyright notice for the Work:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Licensed under the EUPL
|
||||
|
||||
or has expressed by any other means his willingness to license under the EUPL.
|
||||
|
||||
1. Definitions
|
||||
|
||||
In this Licence, the following terms have the following meaning:
|
||||
|
||||
- ‘The Licence’: this Licence.
|
||||
|
||||
- ‘The Original Work’: the work or software distributed or communicated by the
|
||||
Licensor under this Licence, available as Source Code and also as Executable
|
||||
Code as the case may be.
|
||||
|
||||
- ‘Derivative Works’: the works or software that could be created by the
|
||||
Licensee, based upon the Original Work or modifications thereof. This
|
||||
Licence does not define the extent of modification or dependence on the
|
||||
Original Work required in order to classify a work as a Derivative Work;
|
||||
this extent is determined by copyright law applicable in the country
|
||||
mentioned in Article 15.
|
||||
|
||||
- ‘The Work’: the Original Work or its Derivative Works.
|
||||
|
||||
- ‘The Source Code’: the human-readable form of the Work which is the most
|
||||
convenient for people to study and modify.
|
||||
|
||||
- ‘The Executable Code’: any code which has generally been compiled and which
|
||||
is meant to be interpreted by a computer as a program.
|
||||
|
||||
- ‘The Licensor’: the natural or legal person that distributes or communicates
|
||||
the Work under the Licence.
|
||||
|
||||
- ‘Contributor(s)’: any natural or legal person who modifies the Work under
|
||||
the Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||
|
||||
- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of
|
||||
the Work under the terms of the Licence.
|
||||
|
||||
- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending,
|
||||
renting, distributing, communicating, transmitting, or otherwise making
|
||||
available, online or offline, copies of the Work or providing access to its
|
||||
essential functionalities at the disposal of any other natural or legal
|
||||
person.
|
||||
|
||||
2. Scope of the rights granted by the Licence
|
||||
|
||||
The Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
sublicensable licence to do the following, for the duration of copyright
|
||||
vested in the Original Work:
|
||||
|
||||
- use the Work in any circumstance and for all usage,
|
||||
- reproduce the Work,
|
||||
- modify the Work, and make Derivative Works based upon the Work,
|
||||
- communicate to the public, including the right to make available or display
|
||||
the Work or copies thereof to the public and perform publicly, as the case
|
||||
may be, the Work,
|
||||
- distribute the Work or copies thereof,
|
||||
- lend and rent the Work or copies thereof,
|
||||
- sublicense rights in the Work or copies thereof.
|
||||
|
||||
Those rights can be exercised on any media, supports and formats, whether now
|
||||
known or later invented, as far as the applicable law permits so.
|
||||
|
||||
In the countries where moral rights apply, the Licensor waives his right to
|
||||
exercise his moral right to the extent allowed by law in order to make
|
||||
effective the licence of the economic rights here above listed.
|
||||
|
||||
The Licensor grants to the Licensee royalty-free, non-exclusive usage rights
|
||||
to any patents held by the Licensor, to the extent necessary to make use of
|
||||
the rights granted on the Work under this Licence.
|
||||
|
||||
3. Communication of the Source Code
|
||||
|
||||
The Licensor may provide the Work either in its Source Code form, or as
|
||||
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||
provides in addition a machine-readable copy of the Source Code of the Work
|
||||
along with each copy of the Work that the Licensor distributes or indicates,
|
||||
in a notice following the copyright notice attached to the Work, a repository
|
||||
where the Source Code is easily and freely accessible for as long as the
|
||||
Licensor continues to distribute or communicate the Work.
|
||||
|
||||
4. Limitations on copyright
|
||||
|
||||
Nothing in this Licence is intended to deprive the Licensee of the benefits
|
||||
from any exception or limitation to the exclusive rights of the rights owners
|
||||
in the Work, of the exhaustion of those rights or of other applicable
|
||||
limitations thereto.
|
||||
|
||||
5. Obligations of the Licensee
|
||||
|
||||
The grant of the rights mentioned above is subject to some restrictions and
|
||||
obligations imposed on the Licensee. Those obligations are the following:
|
||||
|
||||
Attribution right: The Licensee shall keep intact all copyright, patent or
|
||||
trademarks notices and all notices that refer to the Licence and to the
|
||||
disclaimer of warranties. The Licensee must include a copy of such notices and
|
||||
a copy of the Licence with every copy of the Work he/she distributes or
|
||||
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||
notices stating that the Work has been modified and the date of modification.
|
||||
|
||||
Copyleft clause: If the Licensee distributes or communicates copies of the
|
||||
Original Works or Derivative Works, this Distribution or Communication will be
|
||||
done under the terms of this Licence or of a later version of this Licence
|
||||
unless the Original Work is expressly distributed only under this version of
|
||||
the Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee
|
||||
(becoming Licensor) cannot offer or impose any additional terms or conditions
|
||||
on the Work or Derivative Work that alter or restrict the terms of the
|
||||
Licence.
|
||||
|
||||
Compatibility clause: If the Licensee Distributes or Communicates Derivative
|
||||
Works or copies thereof based upon both the Work and another work licensed
|
||||
under a Compatible Licence, this Distribution or Communication can be done
|
||||
under the terms of this Compatible Licence. For the sake of this clause,
|
||||
‘Compatible Licence’ refers to the licences listed in the appendix attached to
|
||||
this Licence. Should the Licensee's obligations under the Compatible Licence
|
||||
conflict with his/her obligations under this Licence, the obligations of the
|
||||
Compatible Licence shall prevail.
|
||||
|
||||
Provision of Source Code: When distributing or communicating copies of the
|
||||
Work, the Licensee will provide a machine-readable copy of the Source Code or
|
||||
indicate a repository where this Source will be easily and freely available
|
||||
for as long as the Licensee continues to distribute or communicate the Work.
|
||||
|
||||
Legal Protection: This Licence does not grant permission to use the trade
|
||||
names, trademarks, service marks, or names of the Licensor, except as required
|
||||
for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the copyright notice.
|
||||
|
||||
6. Chain of Authorship
|
||||
|
||||
The original Licensor warrants that the copyright in the Original Work granted
|
||||
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||
power and authority to grant the Licence.
|
||||
|
||||
Each Contributor warrants that the copyright in the modifications he/she
|
||||
brings to the Work are owned by him/her or licensed to him/her and that he/she
|
||||
has the power and authority to grant the Licence.
|
||||
|
||||
Each time You accept the Licence, the original Licensor and subsequent
|
||||
Contributors grant You a licence to their contributions to the Work, under the
|
||||
terms of this Licence.
|
||||
|
||||
7. Disclaimer of Warranty
|
||||
|
||||
The Work is a work in progress, which is continuously improved by numerous
|
||||
Contributors. It is not a finished work and may therefore contain defects or
|
||||
‘bugs’ inherent to this type of development.
|
||||
|
||||
For the above reason, the Work is provided under the Licence on an ‘as is’
|
||||
basis and without warranties of any kind concerning the Work, including
|
||||
without limitation merchantability, fitness for a particular purpose, absence
|
||||
of defects or errors, accuracy, non-infringement of intellectual property
|
||||
rights other than copyright as stated in Article 6 of this Licence.
|
||||
|
||||
This disclaimer of warranty is an essential part of the Licence and a
|
||||
condition for the grant of any rights to the Work.
|
||||
|
||||
8. Disclaimer of Liability
|
||||
|
||||
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||
material or moral, damages of any kind, arising out of the Licence or of the
|
||||
use of the Work, including without limitation, damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, loss of data or any commercial
|
||||
damage, even if the Licensor has been advised of the possibility of such
|
||||
damage. However, the Licensor will be liable under statutory product liability
|
||||
laws as far such laws apply to the Work.
|
||||
|
||||
9. Additional agreements
|
||||
|
||||
While distributing the Work, You may choose to conclude an additional
|
||||
agreement, defining obligations or services consistent with this Licence.
|
||||
However, if accepting obligations, You may act only on your own behalf and on
|
||||
your sole responsibility, not on behalf of the original Licensor or any other
|
||||
Contributor, and only if You agree to indemnify, defend, and hold each
|
||||
Contributor harmless for any liability incurred by, or claims asserted against
|
||||
such Contributor by the fact You have accepted any warranty or additional
|
||||
liability.
|
||||
|
||||
10. Acceptance of the Licence
|
||||
|
||||
The provisions of this Licence can be accepted by clicking on an icon ‘I
|
||||
agree’ placed under the bottom of a window displaying the text of this Licence
|
||||
or by affirming consent in any other similar way, in accordance with the rules
|
||||
of applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||
acceptance of this Licence and all of its terms and conditions.
|
||||
|
||||
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||
conditions by exercising any rights granted to You by Article 2 of this
|
||||
Licence, such as the use of the Work, the creation by You of a Derivative Work
|
||||
or the Distribution or Communication by You of the Work or copies thereof.
|
||||
|
||||
11. Information to the public
|
||||
|
||||
In case of any Distribution or Communication of the Work by means of
|
||||
electronic communication by You (for example, by offering to download the Work
|
||||
from a remote location) the distribution channel or media (for example, a
|
||||
website) must at least provide to the public the information requested by the
|
||||
applicable law regarding the Licensor, the Licence and the way it may be
|
||||
accessible, concluded, stored and reproduced by the Licensee.
|
||||
|
||||
12. Termination of the Licence
|
||||
|
||||
The Licence and the rights granted hereunder will terminate automatically upon
|
||||
any breach by the Licensee of the terms of the Licence.
|
||||
|
||||
Such a termination will not terminate the licences of any person who has
|
||||
received the Work from the Licensee under the Licence, provided such persons
|
||||
remain in full compliance with the Licence.
|
||||
|
||||
13. Miscellaneous
|
||||
|
||||
Without prejudice of Article 9 above, the Licence represents the complete
|
||||
agreement between the Parties as to the Work.
|
||||
|
||||
If any provision of the Licence is invalid or unenforceable under applicable
|
||||
law, this will not affect the validity or enforceability of the Licence as a
|
||||
whole. Such provision will be construed or reformed so as necessary to make it
|
||||
valid and enforceable.
|
||||
|
||||
The European Commission may publish other linguistic versions or new versions
|
||||
of this Licence or updated versions of the Appendix, so far this is required
|
||||
and reasonable, without reducing the scope of the rights granted by the
|
||||
Licence. New versions of the Licence will be published with a unique version
|
||||
number.
|
||||
|
||||
All linguistic versions of this Licence, approved by the European Commission,
|
||||
have identical value. Parties can take advantage of the linguistic version of
|
||||
their choice.
|
||||
|
||||
14. Jurisdiction
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- any litigation resulting from the interpretation of this License, arising
|
||||
between the European Union institutions, bodies, offices or agencies, as a
|
||||
Licensor, and any Licensee, will be subject to the jurisdiction of the Court
|
||||
of Justice of the European Union, as laid down in article 272 of the Treaty
|
||||
on the Functioning of the European Union,
|
||||
|
||||
- any litigation arising between other parties and resulting from the
|
||||
interpretation of this License, will be subject to the exclusive
|
||||
jurisdiction of the competent court where the Licensor resides or conducts
|
||||
its primary business.
|
||||
|
||||
15. Applicable Law
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- this Licence shall be governed by the law of the European Union Member State
|
||||
where the Licensor has his seat, resides or has his registered office,
|
||||
|
||||
- this licence shall be governed by Belgian law if the Licensor has no seat,
|
||||
residence or registered office inside a European Union Member State.
|
||||
|
||||
Appendix
|
||||
|
||||
‘Compatible Licences’ according to Article 5 EUPL are:
|
||||
|
||||
- GNU General Public License (GPL) v. 2, v. 3
|
||||
- GNU Affero General Public License (AGPL) v. 3
|
||||
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||
- Eclipse Public License (EPL) v. 1.0
|
||||
- CeCILL v. 2.0, v. 2.1
|
||||
- Mozilla Public Licence (MPL) v. 2
|
||||
- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
|
||||
- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for
|
||||
works other than software
|
||||
- European Union Public Licence (EUPL) v. 1.1, v. 1.2
|
||||
- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong
|
||||
Reciprocity (LiLiQ-R+).
|
||||
|
||||
The European Commission may update this Appendix to later versions of the
|
||||
above licences without producing a new version of the EUPL, as long as they
|
||||
provide the rights granted in Article 2 of this Licence and protect the
|
||||
covered Source Code from exclusive appropriation.
|
||||
|
||||
All other changes or additions to this Appendix require the production of a
|
||||
new EUPL version.
|
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b6",
|
||||
"version": "0.15.0-b7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b6",
|
||||
"version": "0.15.0-b7",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"clean-css": "^5.3.3",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b6",
|
||||
"version": "0.15.0-b7",
|
||||
"description": "Tools for WLED project",
|
||||
"main": "tools/cdata.js",
|
||||
"directories": {
|
||||
|
@@ -197,6 +197,7 @@ build_flags =
|
||||
; decrease code cache size and increase IRAM to fit all pixel functions
|
||||
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
|
||||
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown
|
||||
-D NON32XFER_HANDLER ;; ask forgiveness for PROGMEM misuse
|
||||
|
||||
lib_deps =
|
||||
#https://github.com/lorol/LITTLEFS.git
|
||||
@@ -259,7 +260,8 @@ lib_deps =
|
||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||
${env.lib_deps}
|
||||
# additional build flags for audioreactive
|
||||
AR_build_flags = -D USERMOD_AUDIOREACTIVE
|
||||
AR_build_flags = -D USERMOD_AUDIOREACTIVE
|
||||
-D sqrt_internal=sqrtf ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
|
||||
AR_lib_deps = kosme/arduinoFFT @ 2.0.1
|
||||
|
||||
[esp32_idf_V4]
|
||||
@@ -554,6 +556,33 @@ board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = qio
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:esp32S3_wroom2]
|
||||
;; For ESP32-S3 WROOM-2, a.k.a. ESP32-S3 DevKitC-1 v1.1
|
||||
;; with >= 16MB FLASH and >= 8MB PSRAM (memory_type: opi_opi)
|
||||
platform = ${esp32s3.platform}
|
||||
platform_packages = ${esp32s3.platform_packages}
|
||||
board = esp32s3camlcd ;; this is the only standard board with "opi_opi"
|
||||
board_build.arduino.memory_type = opi_opi
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_WROOM-2
|
||||
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
|
||||
;; -D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
||||
-DBOARD_HAS_PSRAM
|
||||
-D LEDPIN=38 -D DATA_PINS=38 ;; buildin WS2812b LED
|
||||
-D BTNPIN=0 -D RLYPIN=16 -D IRPIN=17 -D AUDIOPIN=-1
|
||||
-D WLED_DEBUG
|
||||
${esp32.AR_build_flags}
|
||||
-D SR_DMTYPE=1 -D I2S_SDPIN=13 -D I2S_CKPIN=14 -D I2S_WSPIN=15 -D MCLK_PIN=4 ;; I2S mic
|
||||
lib_deps = ${esp32s3.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
|
||||
board_build.partitions = ${esp32.extreme_partitions}
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.maximum_size = 16777216
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:esp32s3_4M_qspi]
|
||||
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
|
||||
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
|
||||
|
@@ -61,7 +61,7 @@ See [here](https://kno.wled.ge/basics/compatible-hardware)!
|
||||
|
||||
## ✌️ Other
|
||||
|
||||
Licensed under the MIT license
|
||||
Licensed under the EUPL v1.2 license
|
||||
Credits [here](https://kno.wled.ge/about/contributors/)!
|
||||
|
||||
Join the Discord server to discuss everything about WLED!
|
||||
@@ -80,5 +80,5 @@ If WLED really brightens up your day, you can [ {
|
||||
//oappend(SET_F("dd=addDropdown('staircase','selectfield');"));
|
||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
||||
//oappend(SET_F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field
|
||||
//oappend(F("dd=addDropdown('staircase','selectfield');"));
|
||||
//oappend(F("addOption(dd,'1st value',0);"));
|
||||
//oappend(F("addOption(dd,'2nd value',1);"));
|
||||
//oappend(F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
|
||||
|
@@ -767,22 +767,22 @@ void UsermodBME68X::appendConfigData() {
|
||||
// snprintf_P(charbuffer, 127, PSTR("addInfo('%s:%s',1,'*) Set to minus to deactivate (all sensors)');"), UMOD_NAME, _nameTemp); oappend(charbuffer);
|
||||
|
||||
/* Dropdown for Celsius/Fahrenheit*/
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(UMOD_NAME);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_nameTempScale);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'Celsius',0);"));
|
||||
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||
|
||||
/* i²C Address*/
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(UMOD_NAME);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_nameI2CAdr);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'0x76',0x76);"));
|
||||
oappend(SET_F("addOption(dd,'0x77',0x77);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'0x76',0x76);"));
|
||||
oappend(F("addOption(dd,'0x77',0x77);"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -478,29 +478,29 @@ class UsermodBattery : public Usermod
|
||||
void appendConfigData()
|
||||
{
|
||||
// Total: 462 Bytes
|
||||
oappend(SET_F("td=addDropdown('Battery','type');")); // 34 Bytes
|
||||
oappend(SET_F("addOption(td,'Unkown','0');")); // 28 Bytes
|
||||
oappend(SET_F("addOption(td,'LiPo','1');")); // 26 Bytes
|
||||
oappend(SET_F("addOption(td,'LiOn','2');")); // 26 Bytes
|
||||
oappend(SET_F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
||||
oappend(SET_F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
||||
oappend(SET_F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
||||
oappend(F("td=addDropdown('Battery','type');")); // 34 Bytes
|
||||
oappend(F("addOption(td,'Unkown','0');")); // 28 Bytes
|
||||
oappend(F("addOption(td,'LiPo','1');")); // 26 Bytes
|
||||
oappend(F("addOption(td,'LiOn','2');")); // 26 Bytes
|
||||
oappend(F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
||||
oappend(F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
||||
oappend(F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
||||
oappend(F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
||||
oappend(F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
||||
|
||||
// this option list would exeed the oappend() buffer
|
||||
// a list of all presets to select one from
|
||||
// oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||
// the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);"));
|
||||
// oappend(F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||
// the loop generates: oappend(F("addOption(bd, 'preset name', preset id);"));
|
||||
// for(int8_t i=1; i < 42; i++) {
|
||||
// oappend(SET_F("addOption(bd, 'Preset#"));
|
||||
// oappend(F("addOption(bd, 'Preset#"));
|
||||
// oappendi(i);
|
||||
// oappend(SET_F("',"));
|
||||
// oappend(F("',"));
|
||||
// oappendi(i);
|
||||
// oappend(SET_F(");"));
|
||||
// oappend(F(");"));
|
||||
// }
|
||||
}
|
||||
|
||||
|
@@ -287,11 +287,11 @@ class MyExampleUsermod : public Usermod {
|
||||
*/
|
||||
void appendConfigData() override
|
||||
{
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'<i>(this is a great config value)</i>');"));
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');"));
|
||||
oappend(SET_F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F("','testInt');"));
|
||||
oappend(SET_F("addOption(dd,'Nothing',0);"));
|
||||
oappend(SET_F("addOption(dd,'Everything',42);"));
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":great")); oappend(F("',1,'<i>(this is a great config value)</i>');"));
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":testString")); oappend(F("',1,'enter any string you want');"));
|
||||
oappend(F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(F("','testInt');"));
|
||||
oappend(F("addOption(dd,'Nothing',0);"));
|
||||
oappend(F("addOption(dd,'Everything',42);"));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -149,11 +149,11 @@ public:
|
||||
void appendConfigData()
|
||||
{
|
||||
// Display 'ms' next to the 'Loop Interval' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');"));
|
||||
oappend(F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');"));
|
||||
// Display '°C' next to the 'Activation Threshold' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');"));
|
||||
oappend(F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');"));
|
||||
// Display '0 = Disabled' next to the 'Preset To Activate' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');"));
|
||||
oappend(F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');"));
|
||||
}
|
||||
|
||||
bool readFromConfig(JsonObject &root)
|
||||
|
@@ -511,8 +511,8 @@ void PIRsensorSwitch::addToConfig(JsonObject &root)
|
||||
|
||||
void PIRsensorSwitch::appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
|
||||
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
|
||||
char str[128];
|
||||
sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i);
|
||||
|
@@ -377,10 +377,10 @@ class St7789DisplayUsermod : public Usermod {
|
||||
|
||||
|
||||
void appendConfigData() override {
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -435,10 +435,10 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void UsermodTemperature::appendConfigData() {
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
||||
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
||||
oappend(F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||
oappend(F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
float UsermodTemperature::getTemperature() {
|
||||
|
@@ -191,8 +191,8 @@ constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT resul
|
||||
#define LOG_256 5.54517744f // log(256)
|
||||
|
||||
// These are the input and output vectors. Input vectors receive computed results from FFT.
|
||||
static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins
|
||||
static float vImag[samplesFFT] = {0.0f}; // imaginary parts
|
||||
static float* vReal = nullptr; // FFT sample inputs / freq output - these are our raw result bins
|
||||
static float* vImag = nullptr; // imaginary parts
|
||||
|
||||
// Create FFT object
|
||||
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||
@@ -200,14 +200,9 @@ static float vImag[samplesFFT] = {0.0f}; // imaginary parts
|
||||
// #define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc) - not faster on ESP32
|
||||
// #define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - slower on ESP32
|
||||
// Below options are forcing ArduinoFFT to use sqrtf() instead of sqrt()
|
||||
#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32
|
||||
#define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83
|
||||
|
||||
#include <arduinoFFT.h>
|
||||
|
||||
/* Create FFT object with weighing factor storage */
|
||||
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, true);
|
||||
// #define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83 - since v2.0.0 this must be done in build_flags
|
||||
|
||||
#include <arduinoFFT.h> // FFT object is created in FFTcode
|
||||
// Helper functions
|
||||
|
||||
// compute average of several FFT result bins
|
||||
@@ -226,6 +221,18 @@ void FFTcode(void * parameter)
|
||||
{
|
||||
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
|
||||
|
||||
// allocate FFT buffers on first call
|
||||
if (vReal == nullptr) vReal = (float*) calloc(sizeof(float), samplesFFT);
|
||||
if (vImag == nullptr) vImag = (float*) calloc(sizeof(float), samplesFFT);
|
||||
if ((vReal == nullptr) || (vImag == nullptr)) {
|
||||
// something went wrong
|
||||
if (vReal) free(vReal); vReal = nullptr;
|
||||
if (vImag) free(vImag); vImag = nullptr;
|
||||
return;
|
||||
}
|
||||
// Create FFT object with weighing factor storage
|
||||
ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, true);
|
||||
|
||||
// see https://www.freertos.org/vtaskdelayuntil.html
|
||||
const TickType_t xFrequency = FFT_MIN_CYCLE * portTICK_PERIOD_MS;
|
||||
|
||||
@@ -247,6 +254,7 @@ void FFTcode(void * parameter)
|
||||
|
||||
// get a fresh batch of samples from I2S
|
||||
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
|
||||
memset(vImag, 0, samplesFFT * sizeof(float)); // set imaginary parts to 0
|
||||
|
||||
#if defined(WLED_DEBUG) || defined(SR_DEBUG)
|
||||
if (start < esp_timer_get_time()) { // filter out overflows
|
||||
@@ -265,8 +273,6 @@ void FFTcode(void * parameter)
|
||||
// find highest sample in the batch
|
||||
float maxSample = 0.0f; // max sample from FFT batch
|
||||
for (int i=0; i < samplesFFT; i++) {
|
||||
// set imaginary parts to 0
|
||||
vImag[i] = 0;
|
||||
// pick our our current mic sample - we take the max value from all samples that go into FFT
|
||||
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts
|
||||
if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]);
|
||||
@@ -297,7 +303,7 @@ void FFTcode(void * parameter)
|
||||
#endif
|
||||
|
||||
} else { // noise gate closed - only clear results as FFT was skipped. MIC samples are still valid when we do this.
|
||||
memset(vReal, 0, sizeof(vReal));
|
||||
memset(vReal, 0, samplesFFT * sizeof(float));
|
||||
FFT_MajorPeak = 1;
|
||||
FFT_Magnitude = 0.001;
|
||||
}
|
||||
@@ -1879,57 +1885,59 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
void appendConfigData() override
|
||||
void appendConfigData(Print& uiScript) override
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');"));
|
||||
uiScript.print(F("ux='AudioReactive';")); // ux = shortcut for Audioreactive - fingers crossed that "ux" isn't already used as JS var, html post parameter or css style
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
uiScript.print(F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[]
|
||||
uiScript.print(F("dd=addDropdown(ux,'digitalmic:type');"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
oappend(SET_F("addOption(dd,'Generic Analog',0);"));
|
||||
uiScript.print(F("addOption(dd,'Generic Analog',0);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'Generic I2S',1);"));
|
||||
oappend(SET_F("addOption(dd,'ES7243',2);"));
|
||||
oappend(SET_F("addOption(dd,'SPH0654',3);"));
|
||||
oappend(SET_F("addOption(dd,'Generic I2S with Mclk',4);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S',1);"));
|
||||
uiScript.print(F("addOption(dd,'ES7243',2);"));
|
||||
uiScript.print(F("addOption(dd,'SPH0654',3);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S with Mclk',4);"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
oappend(SET_F("addOption(dd,'Generic I2S PDM',5);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S PDM',5);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'ES8388',6);"));
|
||||
uiScript.print(F("addOption(dd,'ES8388',6);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','config:AGC');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
oappend(SET_F("addOption(dd,'Normal',1);"));
|
||||
oappend(SET_F("addOption(dd,'Vivid',2);"));
|
||||
oappend(SET_F("addOption(dd,'Lazy',3);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'config:AGC');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("addOption(dd,'Normal',1);"));
|
||||
uiScript.print(F("addOption(dd,'Vivid',2);"));
|
||||
uiScript.print(F("addOption(dd,'Lazy',3);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','dynamics:limiter');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
oappend(SET_F("addOption(dd,'On',1);"));
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:rise',1,'ms <i>(♪ effects only)</i>');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:fall',1,'ms <i>(♪ effects only)</i>');"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'dynamics:limiter');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("addOption(dd,'On',1);"));
|
||||
uiScript.print(F("addInfo(ux+':dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field
|
||||
uiScript.print(F("addInfo(ux+':dynamics:rise',1,'ms <i>(♪ effects only)</i>');"));
|
||||
uiScript.print(F("addInfo(ux+':dynamics:fall',1,'ms <i>(♪ effects only)</i>');"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','frequency:scale');"));
|
||||
oappend(SET_F("addOption(dd,'None',0);"));
|
||||
oappend(SET_F("addOption(dd,'Linear (Amplitude)',2);"));
|
||||
oappend(SET_F("addOption(dd,'Square Root (Energy)',3);"));
|
||||
oappend(SET_F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'frequency:scale');"));
|
||||
uiScript.print(F("addOption(dd,'None',0);"));
|
||||
uiScript.print(F("addOption(dd,'Linear (Amplitude)',2);"));
|
||||
uiScript.print(F("addOption(dd,'Square Root (Energy)',3);"));
|
||||
uiScript.print(F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||
#endif
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'sync:mode');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("addOption(dd,'Send',1);"));
|
||||
uiScript.print(F("addOption(dd,'Send',1);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'Receive',2);"));
|
||||
uiScript.print(F("addOption(dd,'Receive',2);"));
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',0,'<i>sd/data/dout</i>','I2S SD');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',1,'<i>ws/clk/lrck</i>','I2S WS');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',2,'<i>sck/bclk</i>','I2S SCK');"));
|
||||
uiScript.print(F("addInfo(ux+':digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
||||
uiScript.print(F("addInfo(uxp,0,'<i>sd/data/dout</i>','I2S SD');"));
|
||||
uiScript.print(F("addInfo(uxp,1,'<i>ws/clk/lrck</i>','I2S WS');"));
|
||||
uiScript.print(F("addInfo(uxp,2,'<i>sck/bclk</i>','I2S SCK');"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'<i>only use -1, 0, 1 or 3</i>','I2S MCLK');"));
|
||||
uiScript.print(F("addInfo(uxp,3,'<i>only use -1, 0, 1 or 3</i>','I2S MCLK');"));
|
||||
#else
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'<i>master clock</i>','I2S MCLK');"));
|
||||
uiScript.print(F("addInfo(uxp,3,'<i>master clock</i>','I2S MCLK');"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ There are however plans to create a lightweight audioreactive for the 8266, with
|
||||
### using latest _arduinoFFT_ library version 2.x
|
||||
The latest arduinoFFT release version should be used for audioreactive.
|
||||
|
||||
* `build_flags` = `-D USERMOD_AUDIOREACTIVE`
|
||||
* `build_flags` = `-D USERMOD_AUDIOREACTIVE -D sqrt_internal=sqrtf`
|
||||
* `lib_deps`= `kosme/arduinoFFT @ 2.0.1`
|
||||
|
||||
## Configuration
|
||||
|
@@ -305,14 +305,14 @@ class BobLightUsermod : public Usermod {
|
||||
}
|
||||
|
||||
void appendConfigData() override {
|
||||
//oappend(SET_F("dd=addDropdown('usermod','selectfield');"));
|
||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
||||
oappend(SET_F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||
//oappend(F("dd=addDropdown('usermod','selectfield');"));
|
||||
//oappend(F("addOption(dd,'1st value',0);"));
|
||||
//oappend(F("addOption(dd,'2nd value',1);"));
|
||||
oappend(F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
void addToConfig(JsonObject& root) override {
|
||||
|
@@ -264,7 +264,7 @@ void MultiRelay::handleOffTimer() {
|
||||
void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer
|
||||
DEBUG_PRINTLN(F("Relays: Initialize HTML API"));
|
||||
|
||||
server.on(SET_F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) {
|
||||
server.on(F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) {
|
||||
DEBUG_PRINTLN(F("Relays: HTML API"));
|
||||
String janswer;
|
||||
String error = "";
|
||||
@@ -765,10 +765,10 @@ void MultiRelay::addToConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void MultiRelay::appendConfigData() {
|
||||
oappend(SET_F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(SET_F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
||||
//oappend(SET_F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');"));
|
||||
oappend(SET_F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
oappend(F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
||||
//oappend(F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');"));
|
||||
oappend(F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -387,23 +387,23 @@ class PixelsDiceTrayUsermod : public Usermod {
|
||||
// To work around this, add info text to the end of the preceding item.
|
||||
//
|
||||
// See addInfo in wled00/data/settings_um.htm for details on what this function does.
|
||||
oappend(SET_F(
|
||||
oappend(F(
|
||||
"addInfo('DiceTray:ble_scan_duration',1,'<br><br><i>Set to \"*\" to "
|
||||
"connect to any die.<br>Leave Blank to disable.</i><br><i "
|
||||
"class=\"warn\">Saving will replace \"*\" with die names.</i>','');"));
|
||||
#if USING_TFT_DISPLAY
|
||||
oappend(SET_F("ddr=addDropdown('DiceTray','rotation');"));
|
||||
oappend(SET_F("addOption(ddr,'0 deg',0);"));
|
||||
oappend(SET_F("addOption(ddr,'90 deg',1);"));
|
||||
oappend(SET_F("addOption(ddr,'180 deg',2);"));
|
||||
oappend(SET_F("addOption(ddr,'270 deg',3);"));
|
||||
oappend(SET_F(
|
||||
oappend(F("ddr=addDropdown('DiceTray','rotation');"));
|
||||
oappend(F("addOption(ddr,'0 deg',0);"));
|
||||
oappend(F("addOption(ddr,'90 deg',1);"));
|
||||
oappend(F("addOption(ddr,'180 deg',2);"));
|
||||
oappend(F("addOption(ddr,'270 deg',3);"));
|
||||
oappend(F(
|
||||
"addInfo('DiceTray:rotation',1,'<br><i class=\"warn\">DO NOT CHANGE "
|
||||
"SPI PINS.</i><br><i class=\"warn\">CHANGES ARE IGNORED.</i>','');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
||||
oappend(F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -310,22 +310,22 @@ void ShtUsermod::onMqttConnect(bool sessionPresent) {
|
||||
* @return void
|
||||
*/
|
||||
void ShtUsermod::appendConfigData() {
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(_name);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_shtType);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'SHT30',0);"));
|
||||
oappend(SET_F("addOption(dd,'SHT31',1);"));
|
||||
oappend(SET_F("addOption(dd,'SHT35',2);"));
|
||||
oappend(SET_F("addOption(dd,'SHT85',3);"));
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'SHT30',0);"));
|
||||
oappend(F("addOption(dd,'SHT31',1);"));
|
||||
oappend(F("addOption(dd,'SHT35',2);"));
|
||||
oappend(F("addOption(dd,'SHT85',3);"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(_name);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_unitOfTemp);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'Celsius',0);"));
|
||||
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -96,7 +96,7 @@ void setup() {
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(0); //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
|
@@ -86,7 +86,7 @@ void startWipe()
|
||||
bri = briLast; //turn on
|
||||
transitionDelayTemp = 0; //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
|
@@ -1202,21 +1202,21 @@ void FourLineDisplayUsermod::onUpdateBegin(bool init) {
|
||||
//}
|
||||
|
||||
void FourLineDisplayUsermod::appendConfigData() {
|
||||
oappend(SET_F("dd=addDropdown('4LineDisplay','type');"));
|
||||
oappend(SET_F("addOption(dd,'None',0);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306',1);"));
|
||||
oappend(SET_F("addOption(dd,'SH1106',2);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1305',4);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1309 128x64',9);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("dd=addDropdown('4LineDisplay','type');"));
|
||||
oappend(F("addOption(dd,'None',0);"));
|
||||
oappend(F("addOption(dd,'SSD1306',1);"));
|
||||
oappend(F("addOption(dd,'SH1106',2);"));
|
||||
oappend(F("addOption(dd,'SSD1306 128x64',3);"));
|
||||
oappend(F("addOption(dd,'SSD1305',4);"));
|
||||
oappend(F("addOption(dd,'SSD1305 128x64',5);"));
|
||||
oappend(F("addOption(dd,'SSD1309 128x64',9);"));
|
||||
oappend(F("addOption(dd,'SSD1306 SPI',6);"));
|
||||
oappend(F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||
oappend(F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||
oappend(F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1090,8 +1090,8 @@ void RotaryEncoderUIUsermod::addToConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void RotaryEncoderUIUsermod::appendConfigData() {
|
||||
oappend(SET_F("addInfo('Rotary-Encoder:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(SET_F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
oappend(F("addInfo('Rotary-Encoder:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -433,8 +433,8 @@ class WordClockUsermod : public Usermod
|
||||
|
||||
void appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');"));
|
||||
oappend(SET_F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');"));
|
||||
oappend(F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');"));
|
||||
oappend(F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -54,13 +54,13 @@ class WireguardUsermod : public Usermod {
|
||||
}
|
||||
|
||||
void appendConfigData() {
|
||||
oappend(SET_F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
void addToConfig(JsonObject& root) {
|
||||
|
@@ -2,24 +2,10 @@
|
||||
WS2812FX.cpp contains all effect methods
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
@@ -2520,9 +2506,9 @@ static uint16_t ripple_base() {
|
||||
#endif
|
||||
{
|
||||
int left = rippleorigin - propI -1;
|
||||
int right = rippleorigin + propI +3;
|
||||
int right = rippleorigin + propI +2;
|
||||
for (int v = 0; v < 4; v++) {
|
||||
unsigned mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp);
|
||||
unsigned mag = scale8(cubicwave8((propF>>2) + v * 64), amp);
|
||||
SEGMENT.setPixelColor(left + v, color_blend(SEGMENT.getPixelColor(left + v), col, mag)); // TODO
|
||||
SEGMENT.setPixelColor(right - v, color_blend(SEGMENT.getPixelColor(right - v), col, mag)); // TODO
|
||||
}
|
||||
@@ -7749,7 +7735,7 @@ uint16_t mode_2Doctopus() {
|
||||
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
|
||||
for (int x = 0; x < cols; x++) {
|
||||
for (int y = 0; y < rows; y++) {
|
||||
rMap[XY(x, y)].angle = 40.7436f * atan2f((y - C_Y), (x - C_X)); // avoid 128*atan2()/PI
|
||||
rMap[XY(x, y)].angle = int(40.7436f * atan2f((y - C_Y), (x - C_X))); // avoid 128*atan2()/PI
|
||||
rMap[XY(x, y)].radius = hypotf((x - C_X), (y - C_Y)) * mapp; //thanks Sutaburosu
|
||||
}
|
||||
}
|
||||
|
55
wled00/FX.h
55
wled00/FX.h
@@ -2,24 +2,10 @@
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified for WLED
|
||||
*/
|
||||
@@ -539,12 +525,12 @@ typedef struct Segment {
|
||||
inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||
|
||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
void setCCT(uint16_t k);
|
||||
void setOpacity(uint8_t o);
|
||||
void setOption(uint8_t n, bool val);
|
||||
void setMode(uint8_t fx, bool loadDefaults = false);
|
||||
void setPalette(uint8_t pal);
|
||||
Segment &setColor(uint8_t slot, uint32_t c);
|
||||
Segment &setCCT(uint16_t k);
|
||||
Segment &setOpacity(uint8_t o);
|
||||
Segment &setOption(uint8_t n, bool val);
|
||||
Segment &setMode(uint8_t fx, bool loadDefaults = false);
|
||||
Segment &setPalette(uint8_t pal);
|
||||
uint8_t differs(Segment& b) const;
|
||||
void refreshLightCapabilities();
|
||||
|
||||
@@ -559,7 +545,7 @@ typedef struct Segment {
|
||||
* Call resetIfRequired before calling the next effect function.
|
||||
* Safe to call from interrupts and network requests.
|
||||
*/
|
||||
inline void markForReset() { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
||||
inline Segment &markForReset() { reset = true; return *this; } // setOption(SEG_OPTION_RESET, true)
|
||||
|
||||
// transition functions
|
||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||
@@ -613,9 +599,15 @@ typedef struct Segment {
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
[[gnu::hot]] uint16_t virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
[[gnu::hot]] uint16_t virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
[[gnu::hot]] unsigned virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
[[gnu::hot]] unsigned virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
inline unsigned nrOfVStrips() const { // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
return (is2D() && map1D2D == M12_pBar) ? virtualWidth() : 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
#ifndef WLED_DISABLE_2D
|
||||
[[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment
|
||||
[[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
@@ -792,7 +784,8 @@ class WS2812FX { // 96 bytes
|
||||
setTargetFps(uint8_t fps),
|
||||
setupEffectData(); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void resetTimebase() { timebase = 0UL - millis(); }
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) { seg.markForReset().resetIfRequired(); } }
|
||||
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
@@ -848,10 +841,8 @@ class WS2812FX { // 96 bytes
|
||||
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms)
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase,
|
||||
getPixelColor(uint16_t) const;
|
||||
unsigned long now, timebase;
|
||||
uint32_t getPixelColor(unsigned) const;
|
||||
|
||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
|
||||
|
@@ -1,24 +1,9 @@
|
||||
/*
|
||||
FX_2Dfcn.cpp contains all 2D utility functions
|
||||
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2022 Blaz Kristan (https://blaz.at/home)
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Parts of the code adapted from WLED Sound Reactive
|
||||
*/
|
||||
@@ -171,7 +156,7 @@ uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
||||
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
if (!isActive()) return; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
@@ -266,7 +251,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||
// returns RGBW values of pixel
|
||||
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
||||
if (!isActive()) return 0; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if (reverse ) x = virtualWidth() - x - 1;
|
||||
if (reverse_y) y = virtualHeight() - y - 1;
|
||||
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
||||
|
@@ -2,24 +2,10 @@
|
||||
WS2812FX_fcn.cpp contains all utility functions
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
@@ -523,46 +509,53 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
||||
}
|
||||
|
||||
|
||||
bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed
|
||||
if (slot >= NUM_COLORS || c == colors[slot]) return false;
|
||||
Segment &Segment::setColor(uint8_t slot, uint32_t c) {
|
||||
if (slot >= NUM_COLORS || c == colors[slot]) return *this;
|
||||
if (!_isRGB && !_hasW) {
|
||||
if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black
|
||||
if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black
|
||||
if (slot == 0 && c == BLACK) return *this; // on/off segment cannot have primary color black
|
||||
if (slot == 1 && c != BLACK) return *this; // on/off segment cannot have secondary color non black
|
||||
}
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
colors[slot] = c;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
return true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setCCT(uint16_t k) {
|
||||
Segment &Segment::setCCT(uint16_t k) {
|
||||
if (k > 255) { //kelvin value, convert to 0-255
|
||||
if (k < 1900) k = 1900;
|
||||
if (k > 10091) k = 10091;
|
||||
k = (k - 1900) >> 5;
|
||||
}
|
||||
if (cct == k) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
cct = k;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
if (cct != k) {
|
||||
//DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k);
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
cct = k;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setOpacity(uint8_t o) {
|
||||
if (opacity == o) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
Segment &Segment::setOpacity(uint8_t o) {
|
||||
if (opacity != o) {
|
||||
//DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setOption(uint8_t n, bool val) {
|
||||
Segment &Segment::setOption(uint8_t n, bool val) {
|
||||
bool prevOn = on;
|
||||
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||
if (val) options |= 0x01 << n;
|
||||
else options &= ~(0x01 << n);
|
||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
Segment &Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
// skip reserved
|
||||
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
||||
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
||||
@@ -594,9 +587,10 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
markForReset();
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setPalette(uint8_t pal) {
|
||||
Segment &Segment::setPalette(uint8_t pal) {
|
||||
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes
|
||||
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes
|
||||
if (pal != palette) {
|
||||
@@ -604,37 +598,24 @@ void Segment::setPalette(uint8_t pal) {
|
||||
palette = pal;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
uint16_t IRAM_ATTR Segment::virtualWidth() const {
|
||||
unsigned IRAM_ATTR Segment::virtualWidth() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
||||
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vWidth;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR Segment::virtualHeight() const {
|
||||
unsigned IRAM_ATTR Segment::virtualHeight() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
|
||||
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vHeight;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const {
|
||||
unsigned vLen = 1;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
switch (map1D2D) {
|
||||
case M12_pBar:
|
||||
vLen = virtualWidth();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return vLen;
|
||||
}
|
||||
|
||||
// Constants for mapping mode "Pinwheel"
|
||||
#ifndef WLED_DISABLE_2D
|
||||
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
|
||||
@@ -1201,10 +1182,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
|
||||
//do not call this method from system context (network callback)
|
||||
void WS2812FX::finalizeInit() {
|
||||
//reset segment runtimes
|
||||
for (segment &seg : _segments) {
|
||||
seg.markForReset();
|
||||
seg.resetIfRequired();
|
||||
}
|
||||
restartRuntime();
|
||||
|
||||
// for the lack of better place enumerate ledmaps here
|
||||
// if we do it in json.cpp (serializeInfo()) we are getting flashes on LEDs
|
||||
@@ -1351,7 +1329,7 @@ void WS2812FX::service() {
|
||||
if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
||||
{
|
||||
doShow = true;
|
||||
unsigned delay = FRAMETIME;
|
||||
unsigned frameDelay = FRAMETIME;
|
||||
|
||||
if (!seg.freeze) { //only run effect function if not frozen
|
||||
int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based)
|
||||
@@ -1371,7 +1349,7 @@ void WS2812FX::service() {
|
||||
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
|
||||
// would need to be allocated for each effect and then blended together for each pixel.
|
||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||
frameDelay = (*_mode[seg.mode])(); // run new/current mode
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
Segment::tmpsegd_t _tmpSegData;
|
||||
@@ -1380,16 +1358,16 @@ void WS2812FX::service() {
|
||||
_virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed)
|
||||
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
||||
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
||||
delay = MIN(delay,d2); // use shortest delay
|
||||
frameDelay = min(frameDelay,d2); // use shortest delay
|
||||
Segment::modeBlend(false); // unset semaphore
|
||||
}
|
||||
#endif
|
||||
seg.call++;
|
||||
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||
if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition
|
||||
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||
}
|
||||
|
||||
seg.next_time = nowUp + delay;
|
||||
seg.next_time = nowUp + frameDelay;
|
||||
}
|
||||
_segment_index++;
|
||||
}
|
||||
@@ -1416,7 +1394,7 @@ void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) {
|
||||
BusManager::setPixelColor(i, col);
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) const {
|
||||
uint32_t IRAM_ATTR WS2812FX::getPixelColor(unsigned i) const {
|
||||
i = getMappedPixelIndex(i);
|
||||
if (i >= _length) return 0;
|
||||
return BusManager::getPixelColor(i);
|
||||
|
@@ -215,6 +215,7 @@ void handleAnalog(uint8_t b)
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
} else {
|
||||
if (bri == 0) strip.restartRuntime();
|
||||
bri = aRead;
|
||||
}
|
||||
} else if (macroDoublePress[b] == 249) {
|
||||
|
@@ -53,7 +53,7 @@
|
||||
#else
|
||||
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, 6 LEDC, only has 1 I2S but NPB does not support it ATM
|
||||
#define WLED_MAX_BUSSES 4 // will allow 2 digital & 2 analog RGB
|
||||
#define WLED_MAX_BUSSES 6 // will allow 2 digital & 2 analog RGB or 6 PWM white
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 2
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 6
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||
|
@@ -1040,7 +1040,7 @@ textarea {
|
||||
|
||||
.segname .flr, .pname .flr {
|
||||
transform: rotate(0deg);
|
||||
right: -6px;
|
||||
/*right: -6px;*/
|
||||
}
|
||||
|
||||
/* segment power wrapper */
|
||||
@@ -1335,6 +1335,11 @@ TD .checkmark, TD .radiomark {
|
||||
box-shadow: 0 0 10px 4px var(--c-1);
|
||||
}
|
||||
|
||||
.lstI .flr:hover {
|
||||
background: var(--c-6);
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
#pcont .selected:not([class*="expanded"]) {
|
||||
bottom: 52px;
|
||||
top: 42px;
|
||||
|
@@ -72,7 +72,7 @@
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||
(c) 2016-2024 Christian Schwinne <br>
|
||||
<i>Licensed under the <a href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">MIT license</a></i><br><br>
|
||||
<i>Licensed under the <a href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">EUPL v1.2 license</a></i><br><br>
|
||||
Server message: <span class="sip"> Response error! </span><hr>
|
||||
<div id="toast"></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
|
@@ -169,7 +169,6 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
||||
void setValuesFromSegment(uint8_t s);
|
||||
void setValuesFromMainSeg();
|
||||
void setValuesFromFirstSelectedSeg();
|
||||
void resetTimebase();
|
||||
void toggleOnOff();
|
||||
void applyBri();
|
||||
void applyFinalBri();
|
||||
@@ -236,7 +235,7 @@ void handleRemote(uint8_t *data, size_t len);
|
||||
//set.cpp
|
||||
bool isAsterisksOnly(const char* str, byte maxLen);
|
||||
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage);
|
||||
bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply=true);
|
||||
bool handleHttpApi(const String& req, bool apply=true);
|
||||
|
||||
//udp.cpp
|
||||
void notify(byte callMode, bool followUp=false);
|
||||
@@ -324,6 +323,10 @@ class Usermod {
|
||||
protected:
|
||||
// Shim for oappend(), which used to exist in utils.cpp
|
||||
template<typename T> static inline void oappend(const T& t) { oappend_shim->print(t); };
|
||||
#ifdef ESP8266
|
||||
// Handle print(PSTR()) without crashing by detecting PROGMEM strings
|
||||
static void oappend(const char* c) { if ((intptr_t) c >= 0x40000000) oappend_shim->print(FPSTR(c)); else oappend_shim->print(c); };
|
||||
#endif
|
||||
};
|
||||
|
||||
class UsermodManager {
|
||||
|
@@ -599,16 +599,14 @@ static void decodeIRJson(uint32_t code)
|
||||
}
|
||||
} else {
|
||||
// HTTP API command
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
if (cmdStr.indexOf("~") > 0 || fdo["rpt"]) lastValidCode = code; // repeatable action
|
||||
if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix
|
||||
if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) {
|
||||
char tmp[10];
|
||||
sprintf_P(tmp, PSTR("&SS=%d"), strip.getMainSegmentId());
|
||||
cmdStr += tmp;
|
||||
}
|
||||
fdo.clear(); // clear JSON buffer (it is no longer needed)
|
||||
handleSet(nullptr, cmdStr, false); // no stateUpdated() call here
|
||||
handleHttpApi(cmdStr, false); // no stateUpdated() call here
|
||||
}
|
||||
} else {
|
||||
// command is JSON object (TODO: currently will not handle irApplyToAllSelected correctly)
|
||||
|
@@ -346,7 +346,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
int tr = -1;
|
||||
long tr = -1;
|
||||
if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times
|
||||
tr = root[F("transition")] | -1;
|
||||
if (tr >= 0) {
|
||||
@@ -363,7 +363,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
|
||||
tr = root[F("tb")] | -1;
|
||||
if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis();
|
||||
if (tr >= 0) strip.timebase = (unsigned long)tr - millis();
|
||||
|
||||
JsonObject nl = root["nl"];
|
||||
nightlightActive = getBoolVal(nl["on"], nightlightActive);
|
||||
@@ -449,9 +449,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
// HTTP API commands (must be handled before "ps")
|
||||
const char* httpwin = root["win"];
|
||||
if (httpwin) {
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
apireq += httpwin;
|
||||
handleSet(nullptr, apireq, false); // may set stateChanged
|
||||
handleHttpApi(httpwin, false); // may set stateChanged
|
||||
}
|
||||
|
||||
// Applying preset from JSON API has 2 cases: a) "pd" AKA "preset direct" and b) "ps" AKA "preset select"
|
||||
@@ -462,7 +460,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
if (!root[F("pd")].isNull() && stateChanged) {
|
||||
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
||||
currentPreset = root[F("pd")] | currentPreset;
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise presetCycCurr was set in handleSet() [set.cpp]
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise presetCycCurr was set in handleHttpApi() [set.cpp]
|
||||
presetToRestore = currentPreset; // stateUpdated() will clear the preset, so we need to restore it after
|
||||
DEBUG_PRINTF_P(PSTR("Preset direct: %d\n"), currentPreset);
|
||||
} else if (!root["ps"].isNull()) {
|
||||
|
@@ -47,17 +47,12 @@ void applyValuesToSelectedSegs()
|
||||
}
|
||||
|
||||
|
||||
void resetTimebase()
|
||||
{
|
||||
strip.timebase = 0 - millis();
|
||||
}
|
||||
|
||||
|
||||
void toggleOnOff()
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = briLast;
|
||||
strip.restartRuntime();
|
||||
} else
|
||||
{
|
||||
briLast = bri;
|
||||
@@ -122,7 +117,7 @@ void stateUpdated(byte callMode) {
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
if (briT == 0) {
|
||||
if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
|
||||
if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning
|
||||
}
|
||||
|
||||
if (bri > 0) briLast = bri;
|
||||
|
@@ -107,9 +107,7 @@ static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProp
|
||||
deserializeJson(*pDoc, payloadStr);
|
||||
deserializeState(pDoc->as<JsonObject>());
|
||||
} else { //HTTP API
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
apireq += payloadStr;
|
||||
handleSet(nullptr, apireq);
|
||||
handleHttpApi(payloadStr);
|
||||
}
|
||||
releaseJSONBufferLock();
|
||||
}
|
||||
|
@@ -201,7 +201,12 @@ bool PinManager::isPinOk(byte gpio, bool output)
|
||||
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
|
||||
#endif
|
||||
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
|
||||
if (gpio > 32 && gpio < 38) return !psramFound(); // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM
|
||||
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI // 33-37: never available if using _octal_ Flash (opi_opi)
|
||||
if (gpio > 32 && gpio < 38) return false;
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_MODE_OCT // 33-37: not available if using _octal_ PSRAM (qio_opi), but free to use on _quad_ PSRAM (qio_qspi)
|
||||
if (gpio > 32 && gpio < 38) return !psramFound();
|
||||
#endif
|
||||
// 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board.
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
// strapping pins: 0, 45 & 46
|
||||
|
@@ -143,6 +143,7 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID,
|
||||
|
||||
void handlePresets()
|
||||
{
|
||||
byte presetErrFlag = ERR_NONE;
|
||||
if (presetToSave) {
|
||||
strip.suspend();
|
||||
doSaveState();
|
||||
@@ -166,21 +167,20 @@ void handlePresets()
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
||||
deserializeJson(*pDoc,tmpRAMbuffer);
|
||||
errorFlag = ERR_NONE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||
presetErrFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||
}
|
||||
fdo = pDoc->as<JsonObject>();
|
||||
|
||||
// only reset errorflag if previous error was preset-related
|
||||
if ((errorFlag == ERR_NONE) || (errorFlag == ERR_FS_PLOAD)) errorFlag = presetErrFlag;
|
||||
|
||||
//HTTP API commands
|
||||
const char* httpwin = fdo["win"];
|
||||
if (httpwin) {
|
||||
String apireq = "win"; // reduce flash string usage
|
||||
apireq += F("&IN&"); // internal call
|
||||
apireq += httpwin;
|
||||
handleSet(nullptr, apireq, false); // may call applyPreset() via PL=
|
||||
handleHttpApi(httpwin, false); // may call applyPreset() via PL=
|
||||
setValuesFromFirstSelectedSeg(); // fills legacy values
|
||||
changePreset = true;
|
||||
} else {
|
||||
@@ -205,7 +205,7 @@ void handlePresets()
|
||||
updateInterfaces(tmpMode);
|
||||
}
|
||||
|
||||
//called from handleSet(PS=) [network callback (sObj is empty), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)]
|
||||
//called from handleHttpApi(PS=) [network callback (sObj is empty), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)]
|
||||
void savePreset(byte index, const char* pname, JsonObject sObj)
|
||||
{
|
||||
if (!saveName) saveName = new char[33];
|
||||
|
@@ -153,16 +153,14 @@ static bool remoteJson(int button)
|
||||
}
|
||||
} else {
|
||||
// HTTP API command
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
//if (cmdStr.indexOf("~") || fdo["rpt"]) lastValidCode = code; // repeatable action
|
||||
if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix
|
||||
if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) {
|
||||
char tmp[10];
|
||||
sprintf_P(tmp, PSTR("&SS=%d"), strip.getMainSegmentId());
|
||||
cmdStr += tmp;
|
||||
}
|
||||
fdo.clear(); // clear JSON buffer (it is no longer needed)
|
||||
handleSet(nullptr, cmdStr, false); // no stateUpdated() call here
|
||||
handleHttpApi(cmdStr, false); // no stateUpdated() call here
|
||||
stateUpdated(CALL_MODE_BUTTON);
|
||||
parsed = true;
|
||||
}
|
||||
|
105
wled00/set.cpp
105
wled00/set.cpp
@@ -803,16 +803,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
|
||||
//HTTP API request parser
|
||||
bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
bool handleHttpApi(const String& req, bool apply)
|
||||
{
|
||||
if (!(req.indexOf("win") >= 0)) return false;
|
||||
|
||||
int pos = 0;
|
||||
DEBUG_PRINTF_P(PSTR("API req: %s\n"), req.c_str());
|
||||
|
||||
//segment select (sets main segment)
|
||||
pos = req.indexOf(F("SM="));
|
||||
if (pos > 0 && !realtimeMode) {
|
||||
if (pos >= 0 && !realtimeMode) {
|
||||
strip.setMainSegmentId(getNumVal(&req, pos));
|
||||
}
|
||||
|
||||
@@ -821,7 +819,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
bool singleSegment = false;
|
||||
|
||||
pos = req.indexOf(F("SS="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
unsigned t = getNumVal(&req, pos);
|
||||
if (t < strip.getSegmentsNum()) {
|
||||
selectedSeg = t;
|
||||
@@ -831,7 +829,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
Segment& selseg = strip.getSegment(selectedSeg);
|
||||
pos = req.indexOf(F("SV=")); //segment selected
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
unsigned t = getNumVal(&req, pos);
|
||||
if (t == 2) for (unsigned i = 0; i < strip.getSegmentsNum(); i++) strip.getSegment(i).selected = false; // unselect other segments
|
||||
selseg.selected = t;
|
||||
@@ -859,31 +857,31 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
uint8_t grpI = selseg.grouping;
|
||||
uint16_t spcI = selseg.spacing;
|
||||
pos = req.indexOf(F("&S=")); //segment start
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
startI = std::abs(getNumVal(&req, pos));
|
||||
}
|
||||
pos = req.indexOf(F("S2=")); //segment stop
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
stopI = std::abs(getNumVal(&req, pos));
|
||||
}
|
||||
pos = req.indexOf(F("GP=")); //segment grouping
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
grpI = std::max(1,getNumVal(&req, pos));
|
||||
}
|
||||
pos = req.indexOf(F("SP=")); //segment spacing
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
spcI = std::max(0,getNumVal(&req, pos));
|
||||
}
|
||||
strip.setSegment(selectedSeg, startI, stopI, grpI, spcI, UINT16_MAX, startY, stopY);
|
||||
|
||||
pos = req.indexOf(F("RV=")); //Segment reverse
|
||||
if (pos > 0) selseg.reverse = req.charAt(pos+3) != '0';
|
||||
if (pos >= 0) selseg.reverse = req.charAt(pos+3) != '0';
|
||||
|
||||
pos = req.indexOf(F("MI=")); //Segment mirror
|
||||
if (pos > 0) selseg.mirror = req.charAt(pos+3) != '0';
|
||||
if (pos >= 0) selseg.mirror = req.charAt(pos+3) != '0';
|
||||
|
||||
pos = req.indexOf(F("SB=")); //Segment brightness/opacity
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
byte segbri = getNumVal(&req, pos);
|
||||
selseg.setOption(SEG_OPTION_ON, segbri); // use transition
|
||||
if (segbri) {
|
||||
@@ -892,7 +890,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("SW=")); //segment power
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
switch (getNumVal(&req, pos)) {
|
||||
case 0: selseg.setOption(SEG_OPTION_ON, false); break; // use transition
|
||||
case 1: selseg.setOption(SEG_OPTION_ON, true); break; // use transition
|
||||
@@ -901,13 +899,13 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("PS=")); //saves current in preset
|
||||
if (pos > 0) savePreset(getNumVal(&req, pos));
|
||||
if (pos >= 0) savePreset(getNumVal(&req, pos));
|
||||
|
||||
pos = req.indexOf(F("P1=")); //sets first preset for cycle
|
||||
if (pos > 0) presetCycMin = getNumVal(&req, pos);
|
||||
if (pos >= 0) presetCycMin = getNumVal(&req, pos);
|
||||
|
||||
pos = req.indexOf(F("P2=")); //sets last preset for cycle
|
||||
if (pos > 0) presetCycMax = getNumVal(&req, pos);
|
||||
if (pos >= 0) presetCycMax = getNumVal(&req, pos);
|
||||
|
||||
//apply preset
|
||||
if (updateVal(req.c_str(), "PL=", &presetCycCurr, presetCycMin, presetCycMax)) {
|
||||
@@ -915,7 +913,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("NP")); //advances to next preset in a playlist
|
||||
if (pos > 0) doAdvancePlaylist = true;
|
||||
if (pos >= 0) doAdvancePlaylist = true;
|
||||
|
||||
//set brightness
|
||||
updateVal(req.c_str(), "&A=", &bri);
|
||||
@@ -935,7 +933,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
#ifdef WLED_ENABLE_LOXONE
|
||||
//lox parser
|
||||
pos = req.indexOf(F("LX=")); // Lox primary color
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
int lxValue = getNumVal(&req, pos);
|
||||
if (parseLx(lxValue, colIn)) {
|
||||
bri = 255;
|
||||
@@ -944,7 +942,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
}
|
||||
pos = req.indexOf(F("LY=")); // Lox secondary color
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
int lxValue = getNumVal(&req, pos);
|
||||
if(parseLx(lxValue, colInSec)) {
|
||||
bri = 255;
|
||||
@@ -956,11 +954,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//set hue
|
||||
pos = req.indexOf(F("HU="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
uint16_t temphue = getNumVal(&req, pos);
|
||||
byte tempsat = 255;
|
||||
pos = req.indexOf(F("SA="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
tempsat = getNumVal(&req, pos);
|
||||
}
|
||||
byte sec = req.indexOf(F("H2"));
|
||||
@@ -970,7 +968,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//set white spectrum (kelvin)
|
||||
pos = req.indexOf(F("&K="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
byte sec = req.indexOf(F("K2"));
|
||||
colorKtoRGB(getNumVal(&req, pos), (sec>0) ? colInSec : colIn);
|
||||
col0Changed |= (!sec); col1Changed |= sec;
|
||||
@@ -979,17 +977,17 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
//set color from HEX or 32bit DEC
|
||||
byte tmpCol[4];
|
||||
pos = req.indexOf(F("CL="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
colorFromDecOrHexString(colIn, (char*)req.substring(pos + 3).c_str());
|
||||
col0Changed = true;
|
||||
}
|
||||
pos = req.indexOf(F("C2="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
colorFromDecOrHexString(colInSec, (char*)req.substring(pos + 3).c_str());
|
||||
col1Changed = true;
|
||||
}
|
||||
pos = req.indexOf(F("C3="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str());
|
||||
uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
|
||||
selseg.setColor(2, col2); // defined above (SS= or main)
|
||||
@@ -998,7 +996,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//set to random hue SR=0->1st SR=1->2nd
|
||||
pos = req.indexOf(F("SR"));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
byte sec = getNumVal(&req, pos);
|
||||
setRandomColor(sec? colInSec : colIn);
|
||||
col0Changed |= (!sec); col1Changed |= sec;
|
||||
@@ -1006,7 +1004,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//swap 2nd & 1st
|
||||
pos = req.indexOf(F("SC"));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
byte temp;
|
||||
for (unsigned i=0; i<4; i++) {
|
||||
temp = colIn[i];
|
||||
@@ -1032,10 +1030,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
bool fxModeChanged = false, speedChanged = false, intensityChanged = false, paletteChanged = false;
|
||||
bool custom1Changed = false, custom2Changed = false, custom3Changed = false, check1Changed = false, check2Changed = false, check3Changed = false;
|
||||
// set effect parameters
|
||||
if (updateVal(req.c_str(), "FX=", &effectIn, 0, strip.getModeCount()-1)) {
|
||||
if (request != nullptr) unloadPlaylist(); // unload playlist if changing FX using web request
|
||||
fxModeChanged = true;
|
||||
}
|
||||
fxModeChanged = updateVal(req.c_str(), "FX=", &effectIn, 0, strip.getModeCount()-1);
|
||||
speedChanged = updateVal(req.c_str(), "SX=", &speedIn);
|
||||
intensityChanged = updateVal(req.c_str(), "IX=", &intensityIn);
|
||||
paletteChanged = updateVal(req.c_str(), "FP=", &paletteIn, 0, strip.getPaletteCount()-1);
|
||||
@@ -1066,31 +1061,31 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//set advanced overlay
|
||||
pos = req.indexOf(F("OL="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
overlayCurrent = getNumVal(&req, pos);
|
||||
}
|
||||
|
||||
//apply macro (deprecated, added for compatibility with pre-0.11 automations)
|
||||
pos = req.indexOf(F("&M="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
applyPreset(getNumVal(&req, pos) + 16);
|
||||
}
|
||||
|
||||
//toggle send UDP direct notifications
|
||||
pos = req.indexOf(F("SN="));
|
||||
if (pos > 0) notifyDirect = (req.charAt(pos+3) != '0');
|
||||
if (pos >= 0) notifyDirect = (req.charAt(pos+3) != '0');
|
||||
|
||||
//toggle receive UDP direct notifications
|
||||
pos = req.indexOf(F("RN="));
|
||||
if (pos > 0) receiveGroups = (req.charAt(pos+3) != '0') ? receiveGroups | 1 : receiveGroups & 0xFE;
|
||||
if (pos >= 0) receiveGroups = (req.charAt(pos+3) != '0') ? receiveGroups | 1 : receiveGroups & 0xFE;
|
||||
|
||||
//receive live data via UDP/Hyperion
|
||||
pos = req.indexOf(F("RD="));
|
||||
if (pos > 0) receiveDirect = (req.charAt(pos+3) != '0');
|
||||
if (pos >= 0) receiveDirect = (req.charAt(pos+3) != '0');
|
||||
|
||||
//main toggle on/off (parse before nightlight, #1214)
|
||||
pos = req.indexOf(F("&T="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
nightlightActive = false; //always disable nightlight when toggling
|
||||
switch (getNumVal(&req, pos))
|
||||
{
|
||||
@@ -1102,9 +1097,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//toggle nightlight mode
|
||||
bool aNlDef = false;
|
||||
if (req.indexOf(F("&ND")) > 0) aNlDef = true;
|
||||
if (req.indexOf(F("&ND")) >= 0) aNlDef = true;
|
||||
pos = req.indexOf(F("NL="));
|
||||
if (pos > 0)
|
||||
if (pos >= 0)
|
||||
{
|
||||
if (req.charAt(pos+3) == '0')
|
||||
{
|
||||
@@ -1124,14 +1119,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
//set nightlight target brightness
|
||||
pos = req.indexOf(F("NT="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
nightlightTargetBri = getNumVal(&req, pos);
|
||||
nightlightActiveOld = false; //re-init
|
||||
}
|
||||
|
||||
//toggle nightlight fade
|
||||
pos = req.indexOf(F("NF="));
|
||||
if (pos > 0)
|
||||
if (pos >= 0)
|
||||
{
|
||||
nightlightMode = getNumVal(&req, pos);
|
||||
|
||||
@@ -1140,24 +1135,24 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (nightlightMode > NL_MODE_SUN) nightlightMode = NL_MODE_SUN;
|
||||
|
||||
pos = req.indexOf(F("TT="));
|
||||
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
||||
if (pos >= 0) transitionDelay = getNumVal(&req, pos);
|
||||
if (fadeTransition) strip.setTransition(transitionDelay);
|
||||
|
||||
//set time (unix timestamp)
|
||||
pos = req.indexOf(F("ST="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
setTimeFromAPI(getNumVal(&req, pos));
|
||||
}
|
||||
|
||||
//set countdown goal (unix timestamp)
|
||||
pos = req.indexOf(F("CT="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
countdownTime = getNumVal(&req, pos);
|
||||
if (countdownTime - toki.second() > 0) countdownOverTriggered = false;
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("LO="));
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
realtimeOverride = getNumVal(&req, pos);
|
||||
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
|
||||
if (realtimeMode && useMainSegmentOnly) {
|
||||
@@ -1166,19 +1161,19 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("RB"));
|
||||
if (pos > 0) doReboot = true;
|
||||
if (pos >= 0) doReboot = true;
|
||||
|
||||
// clock mode, 0: normal, 1: countdown
|
||||
pos = req.indexOf(F("NM="));
|
||||
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
|
||||
if (pos >= 0) countdownMode = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf(F("U0=")); //user var 0
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
userVar0 = getNumVal(&req, pos);
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("U1=")); //user var 1
|
||||
if (pos > 0) {
|
||||
if (pos >= 0) {
|
||||
userVar1 = getNumVal(&req, pos);
|
||||
}
|
||||
// you can add more if you need
|
||||
@@ -1187,15 +1182,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (!apply) return true; // when called by JSON API, do not call colorUpdated() here
|
||||
|
||||
pos = req.indexOf(F("&NN")); //do not send UDP notifications this time
|
||||
stateUpdated((pos > 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE);
|
||||
|
||||
// internal call, does not send XML response
|
||||
pos = req.indexOf(F("IN"));
|
||||
if (pos < 1) {
|
||||
auto response = request->beginResponseStream("text/xml");
|
||||
XML_response(*response);
|
||||
request->send(response);
|
||||
}
|
||||
stateUpdated((pos >= 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -120,10 +120,8 @@ private:
|
||||
|
||||
void encodeLightId(uint8_t idx, char* out)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
|
||||
sprintf_P(out, PSTR("%02X:%02X:%02X:%02X:%02X:%02X:00:11-%02X"), mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], idx);
|
||||
String mymac = WiFi.macAddress();
|
||||
sprintf_P(out, PSTR("%02X:%s:AB-%02X"), idx, mymac.c_str(), idx);
|
||||
}
|
||||
|
||||
// construct 'globally unique' Json dict key fitting into signed int
|
||||
|
@@ -681,9 +681,7 @@ void handleNotifications()
|
||||
|
||||
if (requestJSONBufferLock(18)) {
|
||||
if (udpIn[0] >= 'A' && udpIn[0] <= 'Z') { //HTTP API
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
apireq += (char*)udpIn;
|
||||
handleSet(nullptr, apireq);
|
||||
handleHttpApi((char*)udpIn);
|
||||
} else if (udpIn[0] == '{') { //JSON API
|
||||
DeserializationError error = deserializeJson(*pDoc, udpIn);
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
|
@@ -380,6 +380,12 @@ void WLED::setup()
|
||||
case FM_QOUT: DEBUG_PRINT(F("(QOUT)"));break;
|
||||
case FM_DIO: DEBUG_PRINT(F("(DIO)")); break;
|
||||
case FM_DOUT: DEBUG_PRINT(F("(DOUT)"));break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) && CONFIG_ESPTOOLPY_FLASHMODE_OPI
|
||||
case FM_FAST_READ: DEBUG_PRINT(F("(OPI)")); break;
|
||||
#else
|
||||
case FM_FAST_READ: DEBUG_PRINT(F("(fast_read)")); break;
|
||||
#endif
|
||||
case FM_SLOW_READ: DEBUG_PRINT(F("(slow_read)")); break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
|
@@ -3,12 +3,12 @@
|
||||
/*
|
||||
Main sketch, global variable declarations
|
||||
@title WLED project sketch
|
||||
@version 0.15.0-b6
|
||||
@version 0.15.0-b7
|
||||
@author Christian Schwinne
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2410140
|
||||
#define VERSION 2410270
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@@ -36,12 +36,13 @@
|
||||
#undef WLED_ENABLE_ADALIGHT // disable has priority over enable
|
||||
#endif
|
||||
//#define WLED_ENABLE_DMX // uses 3.5kb
|
||||
//#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled)
|
||||
#ifndef WLED_DISABLE_LOXONE
|
||||
#define WLED_ENABLE_LOXONE // uses 1.2kb
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_WEBSOCKETS
|
||||
#define WLED_ENABLE_WEBSOCKETS
|
||||
#else
|
||||
#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled)
|
||||
#endif
|
||||
|
||||
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
||||
|
@@ -193,12 +193,12 @@ void createEditHandler(bool enable) {
|
||||
editHandler = &server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
|
||||
#endif
|
||||
#else
|
||||
editHandler = &server.on(SET_F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
editHandler = &server.on(F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 501, FPSTR(s_notimplemented), F("The FS editor is disabled in this build."), 254);
|
||||
});
|
||||
#endif
|
||||
} else {
|
||||
editHandler = &server.on(SET_F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
editHandler = &server.on(F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_cfg), 254);
|
||||
});
|
||||
}
|
||||
@@ -427,11 +427,11 @@ void initServer()
|
||||
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send_P(200, FPSTR(CONTENT_TYPE_HTML), PAGE_dmxmap , dmxProcessor);
|
||||
});
|
||||
#else
|
||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 501, FPSTR(s_notimplemented), F("DMX support is not enabled in this build."), 254);
|
||||
});
|
||||
#endif
|
||||
@@ -482,7 +482,17 @@ void initServer()
|
||||
return;
|
||||
}
|
||||
|
||||
if(handleSet(request, request->url())) return;
|
||||
if (request->url().indexOf("win") == 0) {
|
||||
if (handleHttpApi(request->url().substring(3))) {
|
||||
if (request->url().indexOf(F("&FX=")) > 0) {
|
||||
unloadPlaylist(); // Setting an FX via HTTP disables any active playlist.
|
||||
}
|
||||
auto response = request->beginResponseStream(CONTENT_TYPE_XML);
|
||||
XML_response(*response);
|
||||
request->send(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if(espalexa.handleAlexaApiCall(request)) return;
|
||||
#endif
|
||||
|
@@ -227,7 +227,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||
if (Network.isEthernet()) strcat_P(s ,SET_F(" (Ethernet)"));
|
||||
if (Network.isEthernet()) strcat_P(s ,PSTR(" (Ethernet)"));
|
||||
#endif
|
||||
printSetClassElementHTML(settingsScript,PSTR("sip"),0,s);
|
||||
} else
|
||||
@@ -501,7 +501,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
#endif
|
||||
printSetFormValue(settingsScript,PSTR("BD"),serialBaud);
|
||||
#ifndef WLED_ENABLE_ADALIGHT
|
||||
settingsScript.print(F("toggle('Serial);"));
|
||||
settingsScript.print(F("toggle('Serial');"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user