mirror of https://github.com/arendst/Tasmota.git
Merge remote-tracking branch 'upstream/development' into development
Merge all recent changes into my branch
This commit is contained in:
commit
f0dde50f39
|
@ -0,0 +1,86 @@
|
||||||
|
## Sonoff-Tasmota template information
|
||||||
|
Sonoff-Tasmota uses Device or Module information to control peripherals connected to GPIOs. This information is stored in the ``sonoff_template.h`` file as a device specific template. The template contains information about what GPIO should be connected to what peripheral and what GPIO may be configured online using the ``GPIO`` command or GUI Configure Module menu. In addition a device may need specific coding to process the data from these peripherals. The module number as provided by the ``Modules`` command is used to select this coding.
|
||||||
|
|
||||||
|
Starting with version 6.4.1.16 Sonoff-Tasmota Modules can be extended by users online using a template. To provide easy processing by Sonoff-Tasmota a user template is written as JSON text and could look like this:
|
||||||
|
|
||||||
|
{"NAME":"UserModule1","GPIO":[17,148,29,149,7,255,255,255,138,255,139,255,255],"FLAG":0,"BASE":18}
|
||||||
|
|
||||||
|
The four properties with UPPERCASE property names have the following functionality:
|
||||||
|
|
||||||
|
Property name | Property value description
|
||||||
|
--------------|-------------------------------------------------------------------------------------------------------------------
|
||||||
|
NAME | Up to 14 characters for the Module name
|
||||||
|
GPIO | Up to 13 decimal numbers from 0 to 255 representing GPIO0 to GPIO5, GPIO09, GPIO10 and GPIO12 to GPIO16
|
||||||
|
FLAG | 8 bit mask flag register
|
||||||
|
BASE | Module number of a hard-coded device to be used when device specific functionality is needed
|
||||||
|
|
||||||
|
The above example, based on the Generic Module does not allow ADC0 input.
|
||||||
|
|
||||||
|
## GPIO functionality
|
||||||
|
The GPIO functionality numbers are the same is shown by command ``GPIOs``. In addition code 255 is added to select a GPIO as user configurable via the GUI Configure Module menu.
|
||||||
|
|
||||||
|
## FLAG functionality
|
||||||
|
The FLAG value is an 8-bit mask where each bit controls a features. Add FLAG values to set multiple bits.
|
||||||
|
|
||||||
|
FLAG | Mask | Feature description
|
||||||
|
-----|----------|------------------------------
|
||||||
|
1 | xxxxxxx1 | Allowing to use Analog0 (ADC0) as input if define USE_ADC_VCC in ``my_user_config.h`` is disabled
|
||||||
|
2 | xxxxxx1x | Enable GUI pull-up control message
|
||||||
|
4 | xxxxx1xx | Not used
|
||||||
|
8 | xxxx1xxx | Not used
|
||||||
|
16 | xxx1xxxx | Not used
|
||||||
|
32 | xx1xxxxx | Not used
|
||||||
|
64 | x1xxxxxx | Not used
|
||||||
|
128 | 1xxxxxxx | Not used
|
||||||
|
|
||||||
|
## BASE functionality
|
||||||
|
The following table lists hard-coded device specific functionality. Notice that not all device modules need special handling.
|
||||||
|
|
||||||
|
BASE | Module | Description
|
||||||
|
-----|----------------|----------------------------------------------
|
||||||
|
4 | Sonoff Dual | Process relay and button via hardware serial interface using GPIO01 and GPIO03. Change baudrate to 19200 bps. Process buttons as single press only
|
||||||
|
9 | Sonoff Touch | Invert ledstate 1 functionality
|
||||||
|
10 | Sonoff LED | Set light type to 2 PWM channels disregarding SetOption15. Fix device specific LED instabilities by disabling GPIO04, GPIO5 and GPIO14
|
||||||
|
12 | 4 Channel | See 4
|
||||||
|
13 | Motor C/AC | Force all relays ON at Power On and disable command ``PowerOnState``
|
||||||
|
15 | EXS Relay(s) | Enable pulse latching using even/odd numbered relay pairs
|
||||||
|
18 | Generic | Show Wemos specific pin information in GUI
|
||||||
|
19 | H801 | Change hardware UART Tx from GPIO01 to GPIO02
|
||||||
|
20 | Sonoff SC | Enable and Process data via hardware serial interface using GPIO01 and GPIO03. Change baudrate to 19200 bps
|
||||||
|
21 | Sonoff BN-SZ | Set light type to 1 PWM channel disregarding SetOption15
|
||||||
|
22 | Sonoff 4CH Pro | Button handling disregarding SetOption13 only allowing single press to enable RF learning while holding the button
|
||||||
|
24 | Sonoff Bridge | Enable and Process data via hardware serial interface using GPIO01 and GPIO03. Change baudrate to 19200 bps. Process 16 buttons in web GUI. Enable EFM8BB1 firmware upload
|
||||||
|
25 | Sonoff B1 | Set light type to RGBWC using MY92x1
|
||||||
|
26 | AiLight | Set light type to RGBW using MY92x1
|
||||||
|
27 | Sonoff T1 1CH | See 9
|
||||||
|
28 | Sonoff T1 2CH | See 9
|
||||||
|
29 | Sonoff T1 3CH | See 9
|
||||||
|
38 | Sonoff Dual R2 | Process buttons as single press only
|
||||||
|
43 | Sonoff iFan02 | Enable command ``Fanspeed``. Disable Interlock and PulseTime. Tune status information, MQTT data and GUI. Sync with microcontroller. Process Domoticz Fan state
|
||||||
|
47 | Xiaomi Philips | Process Color Temperature using PWM2 and Intensity using PWM1
|
||||||
|
53 | Tuya Dimmer | Enable and Process data via software or hardware serial interface using GPIO 148 and 149 or forced GPIO01 and GPIO03. Change baudrate to 9600 bps. Process all Buttons
|
||||||
|
55 | ARMTR Dimmer | Enable and Process data via software or hardware serial interface using GPIO 148 and 149. Change baudrate to 115200 bps.
|
||||||
|
57 | PS-16-DZ | Enable and Process data via software or hardware serial interface using GPIO 148 and 149. Change baudrate to 19200 bps.
|
||||||
|
61 | YTF IR Bridge | Disable serial interface to stop loopback
|
||||||
|
65 | Mi Desk Lamp | Process rotary and Button1 data specific to this device
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
A user provided template can be stored in Sonoff-Tasmota using the ``Template`` command. It has the following options.
|
||||||
|
|
||||||
|
Command | Payload | Description
|
||||||
|
---------|----------|---------------------------------------
|
||||||
|
Template | | Show current user template
|
||||||
|
Template | 0 | Copy active module template to user template
|
||||||
|
Template | 1 .. 69 | Copy hard-coded module template to user template
|
||||||
|
|
||||||
|
The following command will store a complete template based on the Generic module
|
||||||
|
``Template {"NAME":"UserModule1","GPIO":[17,148,29,149,7,255,255,255,138,255,139,255,255],"FLAG":0,"BASE":18}``
|
||||||
|
|
||||||
|
The following command will update the name of a stored template
|
||||||
|
``Template {"NAME":"UserModule2"}``
|
||||||
|
|
||||||
|
The following command will update the flag of a stored template
|
||||||
|
``Template {"FLAG":1}``
|
||||||
|
|
||||||
|
The following command will update the base of a stored template to Generic
|
||||||
|
``Template {"BASE":0}``
|
File diff suppressed because it is too large
Load Diff
|
@ -1,156 +0,0 @@
|
||||||
|
|
||||||
# ESP8266 platform
|
|
||||||
# ------------------------------
|
|
||||||
|
|
||||||
# For more info:
|
|
||||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
|
||||||
|
|
||||||
name=ESP8266 Boards (2.5.0-beta2)
|
|
||||||
version=2.5.0-beta2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
runtime.tools.signing={runtime.platform.path}/tools/signing.py
|
|
||||||
|
|
||||||
compiler.warning_flags=-w
|
|
||||||
compiler.warning_flags.none=-w
|
|
||||||
compiler.warning_flags.default=
|
|
||||||
compiler.warning_flags.more=-Wall
|
|
||||||
compiler.warning_flags.all=-Wall -Wextra
|
|
||||||
|
|
||||||
build.lwip_lib=-llwip_gcc
|
|
||||||
build.lwip_include=lwip/include
|
|
||||||
build.lwip_flags=-DLWIP_OPEN_SRC
|
|
||||||
|
|
||||||
build.vtable_flags=-DVTABLES_IN_FLASH
|
|
||||||
|
|
||||||
#build.exception_flags=-fexceptions
|
|
||||||
build.exception_flags=-fno-exceptions
|
|
||||||
#build.stdcpp_lib=-lstdc++
|
|
||||||
build.stdcpp_lib=-lstdc++-nox
|
|
||||||
|
|
||||||
#build.float=-u _printf_float -u _scanf_float
|
|
||||||
build.float=
|
|
||||||
build.led=
|
|
||||||
|
|
||||||
compiler.path={runtime.tools.xtensa-lx106-elf-gcc.path}/bin/
|
|
||||||
compiler.sdk.path={runtime.platform.path}/tools/sdk
|
|
||||||
compiler.libc.path={runtime.platform.path}/tools/sdk/libc/xtensa-lx106-elf
|
|
||||||
compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" "-I{compiler.sdk.path}/{build.lwip_include}" "-I{compiler.libc.path}/include" "-I{build.path}/core"
|
|
||||||
|
|
||||||
compiler.c.cmd=xtensa-lx106-elf-gcc
|
|
||||||
compiler.c.flags=-c {compiler.warning_flags} -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=gnu99 {build.exception_flags} -ffunction-sections -fdata-sections {build.exception_flags}
|
|
||||||
|
|
||||||
compiler.S.cmd=xtensa-lx106-elf-gcc
|
|
||||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD -mlongcalls
|
|
||||||
|
|
||||||
compiler.c.elf.flags=-g {compiler.warning_flags} -Os -nostdlib -Wl,--no-check-sections -u app_entry {build.float} -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-L{compiler.libc.path}/lib" "-T{build.flash_ld}" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read
|
|
||||||
|
|
||||||
compiler.c.elf.cmd=xtensa-lx106-elf-gcc
|
|
||||||
compiler.c.elf.libs=-lhal -lphy -lpp -lnet80211 {build.lwip_lib} -lwpa -lcrypto -lmain -lwps -lbearssl -laxtls -lespnow -lsmartconfig -lairkiss -lwpa2 {build.stdcpp_lib} -lm -lc -lgcc
|
|
||||||
|
|
||||||
compiler.cpp.cmd=xtensa-lx106-elf-g++
|
|
||||||
compiler.cpp.flags=-c {compiler.warning_flags} -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=c++11 -MMD -ffunction-sections -fdata-sections {build.exception_flags}
|
|
||||||
|
|
||||||
compiler.as.cmd=xtensa-lx106-elf-as
|
|
||||||
|
|
||||||
compiler.ar.cmd=xtensa-lx106-elf-ar
|
|
||||||
compiler.ar.flags=cru
|
|
||||||
|
|
||||||
compiler.elf2hex.cmd=esptool
|
|
||||||
compiler.elf2hex.flags=
|
|
||||||
|
|
||||||
compiler.size.cmd=xtensa-lx106-elf-size
|
|
||||||
|
|
||||||
compiler.esptool.cmd=esptool
|
|
||||||
compiler.esptool.cmd.windows=esptool.exe
|
|
||||||
|
|
||||||
# This can be overriden in boards.txt
|
|
||||||
build.extra_flags=-DESP8266
|
|
||||||
|
|
||||||
# These can be overridden in platform.local.txt
|
|
||||||
compiler.c.extra_flags=
|
|
||||||
compiler.c.elf.extra_flags=
|
|
||||||
compiler.S.extra_flags=
|
|
||||||
compiler.cpp.extra_flags=
|
|
||||||
compiler.ar.extra_flags=
|
|
||||||
compiler.objcopy.eep.extra_flags=
|
|
||||||
compiler.elf2hex.extra_flags=
|
|
||||||
|
|
||||||
## generate file with git version number
|
|
||||||
## needs bash, git, and echo
|
|
||||||
recipe.hooks.core.prebuild.1.pattern=python "{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## windows-compatible version without git
|
|
||||||
recipe.hooks.core.prebuild.1.pattern.windows=cmd.exe /c rem cannot sign on windows
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Build the app.ld linker file
|
|
||||||
recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld"
|
|
||||||
|
|
||||||
## Compile c files
|
|
||||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.c.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Compile c++ files
|
|
||||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Compile S files
|
|
||||||
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.S.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {build.led} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
|
|
||||||
|
|
||||||
## Create archives
|
|
||||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
|
||||||
|
|
||||||
## Combine gc-sections, archives, and objects
|
|
||||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} -Wl,--end-group "-L{build.path}"
|
|
||||||
|
|
||||||
## Create eeprom
|
|
||||||
recipe.objcopy.eep.pattern=
|
|
||||||
|
|
||||||
## Create hex
|
|
||||||
#recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
|
|
||||||
|
|
||||||
recipe.objcopy.hex.1.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{runtime.platform.path}/bootloaders/eboot/eboot.elf" -bo "{build.path}/{build.project_name}.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bp 4096 -ec -eo "{build.path}/{build.project_name}.elf" -bs .irom0.text -bs .text -bs .data -bs .rodata -bc -ec
|
|
||||||
recipe.objcopy.hex.2.pattern=python "{runtime.tools.signing}" --mode sign --privatekey "{build.source.path}/private.key" --bin "{build.path}/{build.project_name}.bin" --out "{build.path}/{build.project_name}.bin.signed"
|
|
||||||
|
|
||||||
# No signing on Windows
|
|
||||||
recipe.objcopy.hex.1.pattern.windows="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{runtime.platform.path}/bootloaders/eboot/eboot.elf" -bo "{build.path}/{build.project_name}.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bp 4096 -ec -eo "{build.path}/{build.project_name}.elf" -bs .irom0.text -bs .text -bs .data -bs .rodata -bc -ec
|
|
||||||
recipe.objcopy.hex.2.pattern.windows=
|
|
||||||
|
|
||||||
## Save hex
|
|
||||||
recipe.output.tmp_file={build.project_name}.bin
|
|
||||||
recipe.output.save_file={build.project_name}.{build.variant}.bin
|
|
||||||
|
|
||||||
## Compute size
|
|
||||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
|
||||||
recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|)\s+([0-9]+).*
|
|
||||||
recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).*
|
|
||||||
#recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*
|
|
||||||
|
|
||||||
# ------------------------------
|
|
||||||
|
|
||||||
tools.esptool.cmd=esptool
|
|
||||||
tools.esptool.cmd.windows=esptool.exe
|
|
||||||
tools.esptool.path={runtime.tools.esptool.path}
|
|
||||||
tools.esptool.network_cmd=python
|
|
||||||
tools.esptool.network_cmd.windows=python.exe
|
|
||||||
|
|
||||||
tools.esptool.upload.protocol=esp
|
|
||||||
tools.esptool.upload.params.verbose=-vv
|
|
||||||
tools.esptool.upload.params.quiet=
|
|
||||||
tools.esptool.upload.pattern="{path}/{cmd}" {upload.verbose} -cd {upload.resetmethod} -cb {upload.speed} -cp "{serial.port}" {upload.erase_cmd} -ca 0x00000 -cf "{build.path}/{build.project_name}.bin"
|
|
||||||
tools.esptool.upload.network_pattern="{network_cmd}" "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"
|
|
||||||
|
|
||||||
tools.mkspiffs.cmd=mkspiffs
|
|
||||||
tools.mkspiffs.cmd.windows=mkspiffs.exe
|
|
||||||
tools.mkspiffs.path={runtime.tools.mkspiffs.path}
|
|
||||||
|
|
||||||
tools.espupload.cmd=python
|
|
||||||
tools.espupload.cmd.windows=python.exe
|
|
||||||
tools.espupload.path={runtime.platform.path}/tools
|
|
||||||
tools.espupload.upload.protocol=espupload
|
|
||||||
tools.espupload.upload.params.verbose=
|
|
||||||
tools.espupload.upload.params.quiet=
|
|
||||||
tools.espupload.upload.pattern="{cmd}" "{path}/espupload.py" -f "{build.path}/{build.project_name}.bin"
|
|
|
@ -1330,8 +1330,8 @@ cw01.upload.resetmethod=nodemcu
|
||||||
cw01.menu.CrystalFreq.26=26 MHz
|
cw01.menu.CrystalFreq.26=26 MHz
|
||||||
cw01.menu.CrystalFreq.40=40 MHz
|
cw01.menu.CrystalFreq.40=40 MHz
|
||||||
cw01.menu.CrystalFreq.40.build.extra_flags=-DF_CRYSTAL=40000000 -DESP8266
|
cw01.menu.CrystalFreq.40.build.extra_flags=-DF_CRYSTAL=40000000 -DESP8266
|
||||||
cw01.build.flash_mode=qio
|
cw01.build.flash_mode=dio
|
||||||
cw01.build.flash_flags=-DFLASHMODE_QIO
|
cw01.build.flash_flags=-DFLASHMODE_DIO
|
||||||
cw01.build.flash_freq=40
|
cw01.build.flash_freq=40
|
||||||
cw01.menu.eesz.4M=4M (no SPIFFS)
|
cw01.menu.eesz.4M=4M (no SPIFFS)
|
||||||
cw01.menu.eesz.4M.build.flash_size=4M
|
cw01.menu.eesz.4M.build.flash_size=4M
|
||||||
|
@ -6119,4 +6119,3 @@ espectro.menu.baud.512000.windows=512000
|
||||||
espectro.menu.baud.512000.upload.speed=512000
|
espectro.menu.baud.512000.upload.speed=512000
|
||||||
espectro.menu.baud.921600=921600
|
espectro.menu.baud.921600=921600
|
||||||
espectro.menu.baud.921600.upload.speed=921600
|
espectro.menu.baud.921600.upload.speed=921600
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
# For more info:
|
# For more info:
|
||||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||||
|
|
||||||
name=ESP8266 Boards (2.5.0-beta3)
|
name=ESP8266 Boards (2.5.0)
|
||||||
version=2.5.0-beta3
|
version=2.5.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
runtime.tools.xtensa-lx106-elf-gcc.path={runtime.platform.path}/tools/xtensa-lx106-elf
|
||||||
|
runtime.tools.esptool.path={runtime.platform.path}/tools/esptool
|
||||||
runtime.tools.signing={runtime.platform.path}/tools/signing.py
|
runtime.tools.signing={runtime.platform.path}/tools/signing.py
|
||||||
|
|
||||||
compiler.warning_flags=-w
|
compiler.warning_flags=-w
|
||||||
|
@ -78,13 +78,13 @@ compiler.elf2hex.extra_flags=
|
||||||
## generate file with git version number
|
## generate file with git version number
|
||||||
## needs bash, git, and echo
|
## needs bash, git, and echo
|
||||||
recipe.hooks.core.prebuild.1.pattern=python "{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
|
recipe.hooks.core.prebuild.1.pattern=python "{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
|
||||||
|
recipe.hooks.core.prebuild.2.pattern=bash -c "mkdir -p {build.path}/core && echo \#define ARDUINO_ESP8266_GIT_VER 0x`git --git-dir {runtime.platform.path}/.git rev-parse --short=8 HEAD 2>/dev/null || echo ffffffff` >{build.path}/core/core_version.h"
|
||||||
|
recipe.hooks.core.prebuild.3.pattern=bash -c "mkdir -p {build.path}/core && echo \#define ARDUINO_ESP8266_GIT_DESC `cd "{runtime.platform.path}"; git describe --tags 2>/dev/null || echo unix-{version}` >>{build.path}/core/core_version.h"
|
||||||
|
|
||||||
## windows-compatible version without git
|
## windows-compatible version without git
|
||||||
recipe.hooks.core.prebuild.1.pattern.windows=cmd.exe /c rem cannot sign on windows
|
recipe.hooks.core.prebuild.1.pattern.windows=cmd.exe /c rem cannot sign on windows
|
||||||
|
recipe.hooks.core.prebuild.2.pattern.windows=cmd.exe /c mkdir {build.path}\core & (echo #define ARDUINO_ESP8266_GIT_VER 0x00000000 & echo #define ARDUINO_ESP8266_GIT_DESC win-{version} ) > {build.path}\core\core_version.h
|
||||||
|
recipe.hooks.core.prebuild.3.pattern.windows=cmd.exe /c if exist {build.source.path}\public.key echo #error Cannot automatically build signed binaries on Windows > {build.path}\core\Updater_Signing.h
|
||||||
|
|
||||||
## Build the app.ld linker file
|
## Build the app.ld linker file
|
||||||
recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld"
|
recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld"
|
||||||
|
@ -152,3 +152,4 @@ tools.espupload.upload.protocol=espupload
|
||||||
tools.espupload.upload.params.verbose=
|
tools.espupload.upload.params.verbose=
|
||||||
tools.espupload.upload.params.quiet=
|
tools.espupload.upload.params.quiet=
|
||||||
tools.espupload.upload.pattern="{cmd}" "{path}/espupload.py" -f "{build.path}/{build.project_name}.bin"
|
tools.espupload.upload.pattern="{cmd}" "{path}/espupload.py" -f "{build.path}/{build.project_name}.bin"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Ivan Seidel
|
||||||
|
|
||||||
|
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.
|
|
@ -0,0 +1,325 @@
|
||||||
|
/*
|
||||||
|
LinkedList.h - V1.1 - Generic LinkedList implementation
|
||||||
|
Works better with FIFO, because LIFO will need to
|
||||||
|
search the entire List to find the last one;
|
||||||
|
|
||||||
|
For instructions, go to https://github.com/ivanseidel/LinkedList
|
||||||
|
|
||||||
|
Created by Ivan Seidel Gomes, March, 2013.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LinkedList_h
|
||||||
|
#define LinkedList_h
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct ListNode
|
||||||
|
{
|
||||||
|
T data;
|
||||||
|
ListNode<T> *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LinkedList{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _size;
|
||||||
|
ListNode<T> *root;
|
||||||
|
ListNode<T> *last;
|
||||||
|
|
||||||
|
// Helps "get" method, by saving last position
|
||||||
|
ListNode<T> *lastNodeGot;
|
||||||
|
int lastIndexGot;
|
||||||
|
// isCached should be set to FALSE
|
||||||
|
// everytime the list suffer changes
|
||||||
|
bool isCached;
|
||||||
|
|
||||||
|
ListNode<T>* getNode(int index);
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinkedList();
|
||||||
|
~LinkedList();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns current size of LinkedList
|
||||||
|
*/
|
||||||
|
virtual int size();
|
||||||
|
/*
|
||||||
|
Adds a T object in the specified index;
|
||||||
|
Unlink and link the LinkedList correcly;
|
||||||
|
Increment _size
|
||||||
|
*/
|
||||||
|
virtual bool add(int index, T);
|
||||||
|
/*
|
||||||
|
Adds a T object in the end of the LinkedList;
|
||||||
|
Increment _size;
|
||||||
|
*/
|
||||||
|
virtual bool add(T);
|
||||||
|
/*
|
||||||
|
Adds a T object in the start of the LinkedList;
|
||||||
|
Increment _size;
|
||||||
|
*/
|
||||||
|
virtual bool unshift(T);
|
||||||
|
/*
|
||||||
|
Set the object at index, with T;
|
||||||
|
Increment _size;
|
||||||
|
*/
|
||||||
|
virtual bool set(int index, T);
|
||||||
|
/*
|
||||||
|
Remove object at index;
|
||||||
|
If index is not reachable, returns false;
|
||||||
|
else, decrement _size
|
||||||
|
*/
|
||||||
|
virtual T remove(int index);
|
||||||
|
/*
|
||||||
|
Remove last object;
|
||||||
|
*/
|
||||||
|
virtual T pop();
|
||||||
|
/*
|
||||||
|
Remove first object;
|
||||||
|
*/
|
||||||
|
virtual T shift();
|
||||||
|
/*
|
||||||
|
Get the index'th element on the list;
|
||||||
|
Return Element if accessible,
|
||||||
|
else, return false;
|
||||||
|
*/
|
||||||
|
virtual T get(int index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Clear the entire array
|
||||||
|
*/
|
||||||
|
virtual void clear();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize LinkedList with false values
|
||||||
|
template<typename T>
|
||||||
|
LinkedList<T>::LinkedList()
|
||||||
|
{
|
||||||
|
root=NULL;
|
||||||
|
last=NULL;
|
||||||
|
_size=0;
|
||||||
|
|
||||||
|
lastNodeGot = root;
|
||||||
|
lastIndexGot = 0;
|
||||||
|
isCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear Nodes and free Memory
|
||||||
|
template<typename T>
|
||||||
|
LinkedList<T>::~LinkedList()
|
||||||
|
{
|
||||||
|
ListNode<T>* tmp;
|
||||||
|
while(root!=NULL)
|
||||||
|
{
|
||||||
|
tmp=root;
|
||||||
|
root=root->next;
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
last = NULL;
|
||||||
|
_size=0;
|
||||||
|
isCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Actualy "logic" coding
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ListNode<T>* LinkedList<T>::getNode(int index){
|
||||||
|
|
||||||
|
int _pos = 0;
|
||||||
|
ListNode<T>* current = root;
|
||||||
|
|
||||||
|
// Check if the node trying to get is
|
||||||
|
// immediatly AFTER the previous got one
|
||||||
|
if(isCached && lastIndexGot <= index){
|
||||||
|
_pos = lastIndexGot;
|
||||||
|
current = lastNodeGot;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(_pos < index && current){
|
||||||
|
current = current->next;
|
||||||
|
|
||||||
|
_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the object index got is the same as the required
|
||||||
|
if(_pos == index){
|
||||||
|
isCached = true;
|
||||||
|
lastIndexGot = index;
|
||||||
|
lastNodeGot = current;
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int LinkedList<T>::size(){
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::add(int index, T _t){
|
||||||
|
|
||||||
|
if(index >= _size)
|
||||||
|
return add(_t);
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
return unshift(_t);
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>(),
|
||||||
|
*_prev = getNode(index-1);
|
||||||
|
tmp->data = _t;
|
||||||
|
tmp->next = _prev->next;
|
||||||
|
_prev->next = tmp;
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::add(T _t){
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>();
|
||||||
|
tmp->data = _t;
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
if(root){
|
||||||
|
// Already have elements inserted
|
||||||
|
last->next = tmp;
|
||||||
|
last = tmp;
|
||||||
|
}else{
|
||||||
|
// First element being inserted
|
||||||
|
root = tmp;
|
||||||
|
last = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::unshift(T _t){
|
||||||
|
|
||||||
|
if(_size == 0)
|
||||||
|
return add(_t);
|
||||||
|
|
||||||
|
ListNode<T> *tmp = new ListNode<T>();
|
||||||
|
tmp->next = root;
|
||||||
|
tmp->data = _t;
|
||||||
|
root = tmp;
|
||||||
|
|
||||||
|
_size++;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool LinkedList<T>::set(int index, T _t){
|
||||||
|
// Check if index position is in bounds
|
||||||
|
if(index < 0 || index >= _size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
getNode(index)->data = _t;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::pop(){
|
||||||
|
if(_size <= 0)
|
||||||
|
return T();
|
||||||
|
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
if(_size >= 2){
|
||||||
|
ListNode<T> *tmp = getNode(_size - 2);
|
||||||
|
T ret = tmp->next->data;
|
||||||
|
delete(tmp->next);
|
||||||
|
tmp->next = NULL;
|
||||||
|
last = tmp;
|
||||||
|
_size--;
|
||||||
|
return ret;
|
||||||
|
}else{
|
||||||
|
// Only one element left on the list
|
||||||
|
T ret = root->data;
|
||||||
|
delete(root);
|
||||||
|
root = NULL;
|
||||||
|
last = NULL;
|
||||||
|
_size = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::shift(){
|
||||||
|
if(_size <= 0)
|
||||||
|
return T();
|
||||||
|
|
||||||
|
if(_size > 1){
|
||||||
|
ListNode<T> *_next = root->next;
|
||||||
|
T ret = root->data;
|
||||||
|
delete(root);
|
||||||
|
root = _next;
|
||||||
|
_size --;
|
||||||
|
isCached = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}else{
|
||||||
|
// Only one left, then pop()
|
||||||
|
return pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::remove(int index){
|
||||||
|
if (index < 0 || index >= _size)
|
||||||
|
{
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
return shift();
|
||||||
|
|
||||||
|
if (index == _size-1)
|
||||||
|
{
|
||||||
|
return pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode<T> *tmp = getNode(index - 1);
|
||||||
|
ListNode<T> *toDelete = tmp->next;
|
||||||
|
T ret = toDelete->data;
|
||||||
|
tmp->next = tmp->next->next;
|
||||||
|
delete(toDelete);
|
||||||
|
_size--;
|
||||||
|
isCached = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T LinkedList<T>::get(int index){
|
||||||
|
ListNode<T> *tmp = getNode(index);
|
||||||
|
|
||||||
|
return (tmp ? tmp->data : T());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void LinkedList<T>::clear(){
|
||||||
|
while(size() > 0)
|
||||||
|
shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,171 @@
|
||||||
|
# LinkedList
|
||||||
|
|
||||||
|
This library was developed targeting **`Arduino`** applications. However, works just great with any C++.
|
||||||
|
|
||||||
|
Implementing a buffer for objects takes time. If we are not in the mood, we just create an `array[1000]` with enough size.
|
||||||
|
|
||||||
|
The objective of this library is to create a pattern for projects.
|
||||||
|
If you need to use a List of: `int`, `float`, `objects`, `Lists` or `Wales`. **This is what you are looking for.**
|
||||||
|
|
||||||
|
With a simple but powerful caching algorithm, you can get subsequent objects much faster than usual. Tested without any problems with Lists bigger than 2000 members.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. [Download](https://github.com/ivanseidel/LinkedList/archive/master.zip) the Latest release from gitHub.
|
||||||
|
2. Unzip and modify the Folder name to "LinkedList" (Remove the '-version')
|
||||||
|
3. Paste the modified folder on your Library folder (On your `Libraries` folder inside Sketchbooks or Arduino software).
|
||||||
|
4. Reopen the Arduino software.
|
||||||
|
|
||||||
|
**If you are here, because another Library requires this class, just don't waste time reading bellow. Install and ready.**
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
### The `LinkedList` class
|
||||||
|
|
||||||
|
In case you don't know what a LinkedList is and what it's used for, take a quick look at [Wikipedia::LinkedList](https://en.wikipedia.org/wiki/Linked_list) before continuing.
|
||||||
|
|
||||||
|
#### To declare a LinkedList object
|
||||||
|
```c++
|
||||||
|
// Instantiate a LinkedList that will hold 'integer'
|
||||||
|
LinkedList<int> myLinkedList = LinkedList<int>();
|
||||||
|
|
||||||
|
// Or just this
|
||||||
|
LinkedList<int> myLinkedList;
|
||||||
|
|
||||||
|
// But if you are instantiating a pointer LinkedList...
|
||||||
|
LinkedList<int> *myLinkedList = new LinkedList<int>();
|
||||||
|
|
||||||
|
// If you want a LinkedList with any other type such as 'MyClass'
|
||||||
|
// Make sure you call delete(MyClass) when you remove!
|
||||||
|
LinkedList<MyClass> *myLinkedList = new LinkedList<MyClass>();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Getting the size of the linked list
|
||||||
|
```c++
|
||||||
|
// To get the size of a linked list, make use of the size() method
|
||||||
|
int theSize = myList.size();
|
||||||
|
|
||||||
|
// Notice that if it's pointer to the linked list, you should use -> instead
|
||||||
|
int theSize = myList->size();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Adding elements
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// add(obj) method will insert at the END of the list
|
||||||
|
myList.add(myObject);
|
||||||
|
|
||||||
|
// add(index, obj) method will try to insert the object at the specified index
|
||||||
|
myList.add(0, myObject); // Add at the beginning
|
||||||
|
myList.add(3, myObject); // Add at index 3
|
||||||
|
|
||||||
|
// unshift(obj) method will insert the object at the beginning
|
||||||
|
myList.unshift(myObject);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Getting elements
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// get(index) will return the element at index
|
||||||
|
// (notice that the start element is 0, not 1)
|
||||||
|
|
||||||
|
// Get the FIRST element
|
||||||
|
myObject = myList.get(0);
|
||||||
|
|
||||||
|
// Get the third element
|
||||||
|
myObject = myList.get(2);
|
||||||
|
|
||||||
|
// Get the LAST element
|
||||||
|
myObject = myList.get(myList.size() - 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Changing elements
|
||||||
|
```c++
|
||||||
|
// set(index, obj) method will change the object at index to obj
|
||||||
|
|
||||||
|
// Change the first element to myObject
|
||||||
|
myList.set(0, myObject);
|
||||||
|
|
||||||
|
// Change the third element to myObject
|
||||||
|
myList.set(2, myObject);
|
||||||
|
|
||||||
|
// Change the LAST element of the list
|
||||||
|
myList.set(myList.size() - 1, myObject);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Removing elements
|
||||||
|
```c++
|
||||||
|
// remove(index) will remove and return the element at index
|
||||||
|
|
||||||
|
// Remove the first object
|
||||||
|
myList.remove(0);
|
||||||
|
|
||||||
|
// Get and Delete the third element
|
||||||
|
myDeletedObject = myList.remove(2);
|
||||||
|
|
||||||
|
// pop() will remove and return the LAST element
|
||||||
|
myDeletedObject = myList.pop();
|
||||||
|
|
||||||
|
// shift() will remove and return the FIRST element
|
||||||
|
myDeletedObject = myList.shift();
|
||||||
|
|
||||||
|
// clear() will erase the entire list, leaving it with 0 elements
|
||||||
|
// NOTE: Clear wont DELETE/FREE memory from Pointers, if you
|
||||||
|
// are using Classes/Poiners, manualy delete and free those.
|
||||||
|
myList.clear();
|
||||||
|
```
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
## Library Reference
|
||||||
|
|
||||||
|
### `ListNode` struct
|
||||||
|
|
||||||
|
- `T` `ListNode::data` - The object data
|
||||||
|
|
||||||
|
- `ListNode<T>` `*next` - Pointer to the next Node
|
||||||
|
|
||||||
|
### `LinkedList` class
|
||||||
|
|
||||||
|
**`boolean` methods returns if succeeded**
|
||||||
|
|
||||||
|
- `LinkedList<T>::LinkedList()` - Constructor.
|
||||||
|
|
||||||
|
- `LinkedList<T>::~LinkedList()` - Destructor. Clear Nodes to minimize memory. Does not free pointer memory.
|
||||||
|
|
||||||
|
- `int` `LinkedList<T>::size()` - Returns the current size of the list.
|
||||||
|
|
||||||
|
- `bool` `LinkedList<T>::add(T)` - Add element T at the END of the list.
|
||||||
|
|
||||||
|
- `bool` `LinkedList<T>::add(int index, T)` - Add element T at `index` of the list.
|
||||||
|
|
||||||
|
- `bool` `LinkedList<T>::unshift(T)` - Add element T at the BEGINNING of the list.
|
||||||
|
|
||||||
|
- `bool` `LinkedList<T>::set(int index, T)` - Set the element at `index` to T.
|
||||||
|
|
||||||
|
- `T` `LinkedList<T>::remove(int index)` - Remove element at `index`. Return the removed element. Does not free pointer memory
|
||||||
|
|
||||||
|
- `T` `LinkedList<T>::pop()` - Remove the LAST element. Return the removed element.
|
||||||
|
|
||||||
|
- `T` `LinkedList<T>::shift()` - Remove the FIRST element. Return the removed element.
|
||||||
|
|
||||||
|
- `T` `LinkedList<T>::get(int index)` - Return the element at `index`.
|
||||||
|
|
||||||
|
- `void` `LinkedList<T>::clear()` - Removes all elements. Does not free pointer memory.
|
||||||
|
|
||||||
|
- **protected** `int` `LinkedList<T>::_size` - Holds the cached size of the list.
|
||||||
|
|
||||||
|
- **protected** `ListNode<T>` `LinkedList<T>::*root` - Holds the root node of the list.
|
||||||
|
|
||||||
|
- **protected** `ListNode<T>` `LinkedList<T>::*last` - Holds the last node of the list.
|
||||||
|
|
||||||
|
- **protected** `ListNode<T>*` `LinkedList<T>::getNode(int index)` - Returns the `index` node of the list.
|
||||||
|
|
||||||
|
### Version History
|
||||||
|
|
||||||
|
* `1.1 (2013-07-20)`: Cache implemented. Getting subsequent objects is now O(N). Before, O(N^2).
|
||||||
|
* `1.0 (2013-07-20)`: Original release
|
||||||
|
|
||||||
|
![LinkedList](https://d2weczhvl823v0.cloudfront.net/ivanseidel/LinkedList/trend.png)
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
LinkedList Example
|
||||||
|
Link: http://github.com/ivanseidel/LinkedList
|
||||||
|
|
||||||
|
Example Created by
|
||||||
|
Tom Stewart, github.com/tastewar
|
||||||
|
|
||||||
|
Edited by:
|
||||||
|
Ivan Seidel, github.com/ivanseidel
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LinkedList.h>
|
||||||
|
|
||||||
|
// Let's define a new class
|
||||||
|
class Animal {
|
||||||
|
public:
|
||||||
|
char *name;
|
||||||
|
bool isMammal;
|
||||||
|
};
|
||||||
|
|
||||||
|
char catname[]="kitty";
|
||||||
|
char dogname[]="doggie";
|
||||||
|
char emuname[]="emu";
|
||||||
|
|
||||||
|
LinkedList<Animal*> myAnimalList = LinkedList<Animal*>();
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println("Hello!" );
|
||||||
|
|
||||||
|
// Create a Cat
|
||||||
|
Animal *cat = new Animal();
|
||||||
|
cat->name = catname;
|
||||||
|
cat->isMammal = true;
|
||||||
|
|
||||||
|
// Create a dog
|
||||||
|
Animal *dog = new Animal();
|
||||||
|
dog->name = dogname;
|
||||||
|
dog->isMammal = true;
|
||||||
|
|
||||||
|
// Create a emu
|
||||||
|
Animal *emu = new Animal();
|
||||||
|
emu->name = emuname;
|
||||||
|
emu->isMammal = false; // just an example; no offense to pig lovers
|
||||||
|
|
||||||
|
// Add animals to list
|
||||||
|
myAnimalList.add(cat);
|
||||||
|
myAnimalList.add(emu);
|
||||||
|
myAnimalList.add(dog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
Serial.print("There are ");
|
||||||
|
Serial.print(myAnimalList.size());
|
||||||
|
Serial.print(" animals in the list. The mammals are: ");
|
||||||
|
|
||||||
|
int current = 0;
|
||||||
|
Animal *animal;
|
||||||
|
for(int i = 0; i < myAnimalList.size(); i++){
|
||||||
|
|
||||||
|
// Get animal from list
|
||||||
|
animal = myAnimalList.get(i);
|
||||||
|
|
||||||
|
// If its a mammal, then print it's name
|
||||||
|
if(animal->isMammal){
|
||||||
|
|
||||||
|
// Avoid printing spacer on the first element
|
||||||
|
if(current++)
|
||||||
|
Serial.print(", ");
|
||||||
|
|
||||||
|
// Print animal name
|
||||||
|
Serial.print(animal->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println(".");
|
||||||
|
|
||||||
|
while (true); // nothing else to do, loop forever
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
LinkedList Example
|
||||||
|
Link: http://github.com/ivanseidel/LinkedList
|
||||||
|
|
||||||
|
Example Created by
|
||||||
|
Tom Stewart, github.com/tastewar
|
||||||
|
|
||||||
|
Edited by:
|
||||||
|
Ivan Seidel, github.com/ivanseidel
|
||||||
|
*/
|
||||||
|
#include <LinkedList.h>
|
||||||
|
|
||||||
|
LinkedList<int> myList = LinkedList<int>();
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println("Hello!");
|
||||||
|
|
||||||
|
// Add some stuff to the list
|
||||||
|
int k = -240,
|
||||||
|
l = 123,
|
||||||
|
m = -2,
|
||||||
|
n = 222;
|
||||||
|
myList.add(n);
|
||||||
|
myList.add(0);
|
||||||
|
myList.add(l);
|
||||||
|
myList.add(17);
|
||||||
|
myList.add(k);
|
||||||
|
myList.add(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
int listSize = myList.size();
|
||||||
|
|
||||||
|
Serial.print("There are ");
|
||||||
|
Serial.print(listSize);
|
||||||
|
Serial.print(" integers in the list. The negative ones are: ");
|
||||||
|
|
||||||
|
// Print Negative numbers
|
||||||
|
for (int h = 0; h < listSize; h++) {
|
||||||
|
|
||||||
|
// Get value from list
|
||||||
|
int val = myList.get(h);
|
||||||
|
|
||||||
|
// If the value is negative, print it
|
||||||
|
if (val < 0) {
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true); // nothing else to do, loop forever
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#######################################
|
||||||
|
# Syntax Coloring
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
LinkedList KEYWORD1
|
||||||
|
ListNode KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
size KEYWORD2
|
||||||
|
add KEYWORD2
|
||||||
|
unshift KEYWORD2
|
||||||
|
set KEYWORD2
|
||||||
|
remove KEYWORD2
|
||||||
|
pop KEYWORD2
|
||||||
|
shift KEYWORD2
|
||||||
|
get KEYWORD2
|
||||||
|
clear KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "LinkedList",
|
||||||
|
"keywords": "pattern",
|
||||||
|
"description": "A fully implemented LinkedList (int, float, objects, Lists or Wales) made to work with Arduino projects",
|
||||||
|
"repository":
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ivanseidel/LinkedList.git"
|
||||||
|
},
|
||||||
|
"frameworks": "arduino",
|
||||||
|
"platforms": "*"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
name=LinkedList
|
||||||
|
version=1.2.3
|
||||||
|
author=Ivan Seidel <ivanseidel@gmail.com>
|
||||||
|
maintainer=Ivan Seidel <ivanseidel@gmail.com>
|
||||||
|
sentence=A fully implemented LinkedList made to work with Arduino projects
|
||||||
|
paragraph=The objective of this library is to create a pattern for projects. If you need to use a List of: int, float, objects, Lists or Wales. This is what you are looking for.
|
||||||
|
category=Data Processing
|
||||||
|
url=https://github.com/ivanseidel/LinkedList
|
||||||
|
architectures=*
|
|
@ -65,8 +65,8 @@ build_flags = ${esp82xx_defaults.build_flags}
|
||||||
-DVTABLES_IN_FLASH
|
-DVTABLES_IN_FLASH
|
||||||
|
|
||||||
[core_2_5_0]
|
[core_2_5_0]
|
||||||
; *** Esp8266 core for Arduino version 2.5.0 release (still not available via platformio)
|
; *** Esp8266 core for Arduino version 2.5.0
|
||||||
platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota
|
platform = espressif8266@2.0.0
|
||||||
build_flags = ${esp82xx_defaults.build_flags}
|
build_flags = ${esp82xx_defaults.build_flags}
|
||||||
-Wl,-Teagle.flash.1m.ld
|
-Wl,-Teagle.flash.1m.ld
|
||||||
; lwIP 1.4 (Default)
|
; lwIP 1.4 (Default)
|
||||||
|
|
|
@ -1,5 +1,26 @@
|
||||||
/* 6.4.1.16 20190211
|
/* 6.4.1.18 20191221
|
||||||
* Initial support for online template change using command Template (#5177)
|
* Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215)
|
||||||
|
* Fix some exceptions and watchdogs due to lack of stack space - part 2
|
||||||
|
* Add command SetOption62 0/1 to disable retain on Button or Swith hold messages (#5299)
|
||||||
|
* Add option WifiConfig 7 to allow reset of device in AP mode without admin password (#5297)
|
||||||
|
* Fix command WebSend when using a port number as regression from 6.4.1.17 (#5304)
|
||||||
|
*
|
||||||
|
* 6.4.1.17 20190214
|
||||||
|
* Change template update by removing possibility to add user module config keeping template as defined (#5222)
|
||||||
|
* Fix regression from 6.4.1.16 where GPIO9 and GPIO10 connected devices did not work (#5197)
|
||||||
|
* Fix GUI wifi password acception starting with asteriks (*) (#5231, #5242)
|
||||||
|
* Add rule expression enabled by define USE_EXPRESSION in my_user_config.h (#5210)
|
||||||
|
* Add Configure Template menu option to GUI (#5222)
|
||||||
|
* Remove command SetOption62 as it's functionality is replaced by user changing the device template (#5255)
|
||||||
|
* Add property LinkCount to state and status 11 message representing number of Wifi Link re-connections
|
||||||
|
* Add property MqttCount to status 6 message representing number of Mqtt re-connections
|
||||||
|
* Add property Downtime to state and status 11 message representing the duration of wifi connection loss
|
||||||
|
* Fix command WebSend intermittent results (#5273)
|
||||||
|
*
|
||||||
|
* 6.4.1.16 20190211
|
||||||
|
* Initial support for online template change using command Template or GUI Configure Other (#5177)
|
||||||
|
* Add parameter CFG_HOLDER to status 1 message (#5206)
|
||||||
|
* Update GUI
|
||||||
*
|
*
|
||||||
* 6.4.1.15 20190208
|
* 6.4.1.15 20190208
|
||||||
* Change image name BE_MINIMAL to FIRMWARE_MINIMAL (#5106)
|
* Change image name BE_MINIMAL to FIRMWARE_MINIMAL (#5106)
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#define D_JSON_CHANNEL "Channel"
|
#define D_JSON_CHANNEL "Channel"
|
||||||
#define D_JSON_CO2 "CarbonDioxide"
|
#define D_JSON_CO2 "CarbonDioxide"
|
||||||
#define D_JSON_COMMAND "Command"
|
#define D_JSON_COMMAND "Command"
|
||||||
|
#define D_JSON_CONFIG_HOLDER "CfgHolder"
|
||||||
#define D_JSON_CONNECT_FAILED "Connect failed"
|
#define D_JSON_CONNECT_FAILED "Connect failed"
|
||||||
#define D_JSON_COREVERSION "Core"
|
#define D_JSON_COREVERSION "Core"
|
||||||
#define D_JSON_COUNT "Count"
|
#define D_JSON_COUNT "Count"
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#define D_JSON_DISTANCE "Distance"
|
#define D_JSON_DISTANCE "Distance"
|
||||||
#define D_JSON_DNSSERVER "DNSServer"
|
#define D_JSON_DNSSERVER "DNSServer"
|
||||||
#define D_JSON_DONE "Done"
|
#define D_JSON_DONE "Done"
|
||||||
|
#define D_JSON_DOWNTIME "Downtime"
|
||||||
#define D_JSON_ECO2 "eCO2"
|
#define D_JSON_ECO2 "eCO2"
|
||||||
#define D_JSON_EMPTY "Empty"
|
#define D_JSON_EMPTY "Empty"
|
||||||
#define D_JSON_ENDDST "EndDST" // End Daylight Savings Time
|
#define D_JSON_ENDDST "EndDST" // End Daylight Savings Time
|
||||||
|
@ -88,12 +90,14 @@
|
||||||
#define D_JSON_INFRARED "Infrared"
|
#define D_JSON_INFRARED "Infrared"
|
||||||
#define D_JSON_UNKNOWN "Unknown"
|
#define D_JSON_UNKNOWN "Unknown"
|
||||||
#define D_JSON_LIGHT "Light"
|
#define D_JSON_LIGHT "Light"
|
||||||
|
#define D_JSON_LINK_COUNT "LinkCount"
|
||||||
#define D_JSON_LOCAL_TIME "Local"
|
#define D_JSON_LOCAL_TIME "Local"
|
||||||
#define D_JSON_LOW "Low"
|
#define D_JSON_LOW "Low"
|
||||||
#define D_JSON_MAC "Mac"
|
#define D_JSON_MAC "Mac"
|
||||||
#define D_JSON_MASK "Mask"
|
#define D_JSON_MASK "Mask"
|
||||||
#define D_JSON_MINIMAL "minimal"
|
#define D_JSON_MINIMAL "minimal"
|
||||||
#define D_JSON_MODEL "Model"
|
#define D_JSON_MODEL "Model"
|
||||||
|
#define D_JSON_MQTT_COUNT "MqttCount"
|
||||||
#define D_JSON_NO "No"
|
#define D_JSON_NO "No"
|
||||||
#define D_JSON_NOISE "Noise"
|
#define D_JSON_NOISE "Noise"
|
||||||
#define D_JSON_NONE "None"
|
#define D_JSON_NONE "None"
|
||||||
|
@ -244,6 +248,7 @@
|
||||||
#define D_WCFG_4_RETRY "Retry"
|
#define D_WCFG_4_RETRY "Retry"
|
||||||
#define D_WCFG_5_WAIT "Wait"
|
#define D_WCFG_5_WAIT "Wait"
|
||||||
#define D_WCFG_6_SERIAL "Serial"
|
#define D_WCFG_6_SERIAL "Serial"
|
||||||
|
#define D_WCFG_7_WIFIMANAGER_RESET_ONLY "ManagerRst"
|
||||||
#define D_CMND_FRIENDLYNAME "FriendlyName"
|
#define D_CMND_FRIENDLYNAME "FriendlyName"
|
||||||
#define D_CMND_SWITCHMODE "SwitchMode"
|
#define D_CMND_SWITCHMODE "SwitchMode"
|
||||||
#define D_CMND_INTERLOCK "Interlock"
|
#define D_CMND_INTERLOCK "Interlock"
|
||||||
|
@ -418,6 +423,7 @@
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
#define D_ASTERIX "********"
|
#define D_ASTERIX "********"
|
||||||
|
#define D_ASTERISK_PWD "****"
|
||||||
|
|
||||||
#ifndef MY_LANGUAGE
|
#ifndef MY_LANGUAGE
|
||||||
#include "language/en-GB.h"
|
#include "language/en-GB.h"
|
||||||
|
@ -535,7 +541,8 @@ const char kWifiConfig[MAX_WIFI_OPTION][WCFG_MAX_STRING_LENGTH] PROGMEM = {
|
||||||
D_WCFG_3_WPSCONFIG,
|
D_WCFG_3_WPSCONFIG,
|
||||||
D_WCFG_4_RETRY,
|
D_WCFG_4_RETRY,
|
||||||
D_WCFG_5_WAIT,
|
D_WCFG_5_WAIT,
|
||||||
D_WCFG_6_SERIAL };
|
D_WCFG_6_SERIAL,
|
||||||
|
D_WCFG_7_WIFIMANAGER_RESET_ONLY };
|
||||||
const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
|
const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
|
||||||
D_CMND,
|
D_CMND,
|
||||||
D_STAT,
|
D_STAT,
|
||||||
|
@ -567,6 +574,7 @@ const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_M
|
||||||
|
|
||||||
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
||||||
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
|
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
|
||||||
|
const char S_CONFIGURE_TEMPLATE[] PROGMEM = D_CONFIGURE_TEMPLATE;
|
||||||
const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE;
|
const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE;
|
||||||
const char S_CONFIGURE_WIFI[] PROGMEM = D_CONFIGURE_WIFI;
|
const char S_CONFIGURE_WIFI[] PROGMEM = D_CONFIGURE_WIFI;
|
||||||
const char S_NO_NETWORKS_FOUND[] PROGMEM = D_NO_NETWORKS_FOUND;
|
const char S_NO_NETWORKS_FOUND[] PROGMEM = D_NO_NETWORKS_FOUND;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||||
* Use online command Prefix to translate cmnd, stat and tele.
|
* Use online command Prefix to translate cmnd, stat and tele.
|
||||||
*
|
*
|
||||||
* Updated until v6.4.0.1
|
* Updated until v6.4.1.17 (up to commit 590c883b)
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
|
|
||||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||||
|
@ -253,7 +253,7 @@
|
||||||
|
|
||||||
#define D_MODULE_PARAMETERS "Параметри на модула"
|
#define D_MODULE_PARAMETERS "Параметри на модула"
|
||||||
#define D_MODULE_TYPE "Тип на модула"
|
#define D_MODULE_TYPE "Тип на модула"
|
||||||
#define D_PULLUP_ENABLE "No Button/Switch pull-up"
|
#define D_PULLUP_ENABLE "Без pull-up за бутон/ключ"
|
||||||
#define D_GPIO "GPIO"
|
#define D_GPIO "GPIO"
|
||||||
#define D_SERIAL_IN "Сериен вход"
|
#define D_SERIAL_IN "Сериен вход"
|
||||||
#define D_SERIAL_OUT "Сериен изход"
|
#define D_SERIAL_OUT "Сериен изход"
|
||||||
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Период на телеметрия"
|
#define D_TELEMETRY_PERIOD "Период на телеметрия"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Други параметри"
|
#define D_OTHER_PARAMETERS "Други параметри"
|
||||||
|
#define D_TEMPLATE "Модел"
|
||||||
|
#define D_ACTIVATE "Активирай"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора"
|
#define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора"
|
||||||
#define D_MQTT_ENABLE "Активиране на MQTT"
|
#define D_MQTT_ENABLE "Активиране на MQTT"
|
||||||
#define D_FRIENDLY_NAME "Приятелско име"
|
#define D_FRIENDLY_NAME "Приятелско име"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "Единично"
|
#define D_SINGLE_DEVICE "Единично"
|
||||||
#define D_MULTI_DEVICE "Мулти"
|
#define D_MULTI_DEVICE "Мулти"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Конфигуриране на модел"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Параметри на модел"
|
||||||
|
#define D_TEMPLATE_NAME "Име"
|
||||||
|
#define D_BASE_TYPE "Базиран на"
|
||||||
|
#define D_TEMPLATE_FLAGS "Флагове"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 вход"
|
||||||
|
#define D_ALLOW_PULLUP "Потребителски избор на pull-up"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
|
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
|
||||||
#define D_CONFIGURATION_SAVED "Конфигурацията е запазена"
|
#define D_CONFIGURATION_SAVED "Конфигурацията е запазена"
|
||||||
#define D_CONFIGURATION_RESET "Конфигурацията е изчистена"
|
#define D_CONFIGURATION_RESET "Конфигурацията е изчистена"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Няма"
|
#define D_SENSOR_NONE "Няма"
|
||||||
|
#define D_SENSOR_USER "Потребит."
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Interval telemetrie"
|
#define D_TELEMETRY_PERIOD "Interval telemetrie"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Další nastavení"
|
#define D_OTHER_PARAMETERS "Další nastavení"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora"
|
#define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora"
|
||||||
#define D_MQTT_ENABLE "MQTT aktivní"
|
#define D_MQTT_ENABLE "MQTT aktivní"
|
||||||
#define D_FRIENDLY_NAME "Friendly Name"
|
#define D_FRIENDLY_NAME "Friendly Name"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "single device"
|
#define D_SINGLE_DEVICE "single device"
|
||||||
#define D_MULTI_DEVICE "multi device"
|
#define D_MULTI_DEVICE "multi device"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ulož nastavení"
|
#define D_SAVE_CONFIGURATION "Ulož nastavení"
|
||||||
#define D_CONFIGURATION_SAVED "Nastavení uloženo"
|
#define D_CONFIGURATION_SAVED "Nastavení uloženo"
|
||||||
#define D_CONFIGURATION_RESET "Nastavení resetováno"
|
#define D_CONFIGURATION_RESET "Nastavení resetováno"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Není"
|
#define D_SENSOR_NONE "Není"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||||
* Use online command Prefix to translate cmnd, stat and tele.
|
* Use online command Prefix to translate cmnd, stat and tele.
|
||||||
*
|
*
|
||||||
* Updated until v6.3.0.17
|
* Updated until v6.4.1.17
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
|
|
||||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||||
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetrieperiode"
|
#define D_TELEMETRY_PERIOD "Telemetrieperiode"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Sonstige Einstellungen"
|
#define D_OTHER_PARAMETERS "Sonstige Einstellungen"
|
||||||
|
#define D_TEMPLATE "Vorlage"
|
||||||
|
#define D_ACTIVATE "Aktivieren"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Passwort für Web Oberfläche"
|
#define D_WEB_ADMIN_PASSWORD "Passwort für Web Oberfläche"
|
||||||
#define D_MQTT_ENABLE "MQTT aktivieren"
|
#define D_MQTT_ENABLE "MQTT aktivieren"
|
||||||
#define D_FRIENDLY_NAME "Name [friendly name]"
|
#define D_FRIENDLY_NAME "Name [friendly name]"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "Einzelnes Gerät"
|
#define D_SINGLE_DEVICE "Einzelnes Gerät"
|
||||||
#define D_MULTI_DEVICE "Mehrfachgerät"
|
#define D_MULTI_DEVICE "Mehrfachgerät"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Vorlage konfigurieren"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Vorlage Parameter"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "basiert auf"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "Nutzer pull-up Auswahl"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Konfiguration speichern"
|
#define D_SAVE_CONFIGURATION "Konfiguration speichern"
|
||||||
#define D_CONFIGURATION_SAVED "Konfiguration gespeichert"
|
#define D_CONFIGURATION_SAVED "Konfiguration gespeichert"
|
||||||
#define D_CONFIGURATION_RESET "Konfiguration zurücksetzen"
|
#define D_CONFIGURATION_RESET "Konfiguration zurücksetzen"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Περίοδος τηλεμετρίας"
|
#define D_TELEMETRY_PERIOD "Περίοδος τηλεμετρίας"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Άλλες παράμετροι"
|
#define D_OTHER_PARAMETERS "Άλλες παράμετροι"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Κωδικός διαχειριστή"
|
#define D_WEB_ADMIN_PASSWORD "Κωδικός διαχειριστή"
|
||||||
#define D_MQTT_ENABLE "Ενεργοποίηση MQTT"
|
#define D_MQTT_ENABLE "Ενεργοποίηση MQTT"
|
||||||
#define D_FRIENDLY_NAME "Φιλική ονομασία"
|
#define D_FRIENDLY_NAME "Φιλική ονομασία"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "μονή συσκευή"
|
#define D_SINGLE_DEVICE "μονή συσκευή"
|
||||||
#define D_MULTI_DEVICE "πολλαπλές συσκευές"
|
#define D_MULTI_DEVICE "πολλαπλές συσκευές"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Αποθήκευση ρυθμίσεων"
|
#define D_SAVE_CONFIGURATION "Αποθήκευση ρυθμίσεων"
|
||||||
#define D_CONFIGURATION_SAVED "Οι ρυθμίσεις αποθηκεύτηκαν"
|
#define D_CONFIGURATION_SAVED "Οι ρυθμίσεις αποθηκεύτηκαν"
|
||||||
#define D_CONFIGURATION_RESET "Επαναφορά ρυθμίσεων"
|
#define D_CONFIGURATION_RESET "Επαναφορά ρυθμίσεων"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Κανένα"
|
#define D_SENSOR_NONE "Κανένα"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetry period"
|
#define D_TELEMETRY_PERIOD "Telemetry period"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Other parameters"
|
#define D_OTHER_PARAMETERS "Other parameters"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Web Admin Password"
|
#define D_WEB_ADMIN_PASSWORD "Web Admin Password"
|
||||||
#define D_MQTT_ENABLE "MQTT enable"
|
#define D_MQTT_ENABLE "MQTT enable"
|
||||||
#define D_FRIENDLY_NAME "Friendly Name"
|
#define D_FRIENDLY_NAME "Friendly Name"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "single device"
|
#define D_SINGLE_DEVICE "single device"
|
||||||
#define D_MULTI_DEVICE "multi device"
|
#define D_MULTI_DEVICE "multi device"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Save configuration"
|
#define D_SAVE_CONFIGURATION "Save configuration"
|
||||||
#define D_CONFIGURATION_SAVED "Configuration saved"
|
#define D_CONFIGURATION_SAVED "Configuration saved"
|
||||||
#define D_CONFIGURATION_RESET "Configuration reset"
|
#define D_CONFIGURATION_RESET "Configuration reset"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Otros parámetros"
|
#define D_OTHER_PARAMETERS "Otros parámetros"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Clave Administrador Web"
|
#define D_WEB_ADMIN_PASSWORD "Clave Administrador Web"
|
||||||
#define D_MQTT_ENABLE "Habilitar MQTT"
|
#define D_MQTT_ENABLE "Habilitar MQTT"
|
||||||
#define D_FRIENDLY_NAME "Nombre Amigable"
|
#define D_FRIENDLY_NAME "Nombre Amigable"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "dispositivo simple"
|
#define D_SINGLE_DEVICE "dispositivo simple"
|
||||||
#define D_MULTI_DEVICE "dispositivo múltiple"
|
#define D_MULTI_DEVICE "dispositivo múltiple"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Grabar configuración"
|
#define D_SAVE_CONFIGURATION "Grabar configuración"
|
||||||
#define D_CONFIGURATION_SAVED "Configuración grabada"
|
#define D_CONFIGURATION_SAVED "Configuración grabada"
|
||||||
#define D_CONFIGURATION_RESET "Configuración restablecida"
|
#define D_CONFIGURATION_RESET "Configuración restablecida"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Ninguno"
|
#define D_SENSOR_NONE "Ninguno"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||||
* Use online command Prefix to translate cmnd, stat and tele.
|
* Use online command Prefix to translate cmnd, stat and tele.
|
||||||
*
|
*
|
||||||
* Updated until v6.3.0.17
|
* Updated until v6.4.1.17
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
|
|
||||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||||
|
@ -98,8 +98,8 @@
|
||||||
#define D_GAS "Gaz"
|
#define D_GAS "Gaz"
|
||||||
#define D_GATEWAY "Passerelle"
|
#define D_GATEWAY "Passerelle"
|
||||||
#define D_GROUP "Groupe"
|
#define D_GROUP "Groupe"
|
||||||
#define D_HOST "Host"
|
#define D_HOST "Hôte"
|
||||||
#define D_HOSTNAME "Hostname"
|
#define D_HOSTNAME "Nom d'Hôte"
|
||||||
#define D_HUMIDITY "Humidité"
|
#define D_HUMIDITY "Humidité"
|
||||||
#define D_ILLUMINANCE "Éclairement"
|
#define D_ILLUMINANCE "Éclairement"
|
||||||
#define D_IMMEDIATE "immédiat" // Button immediate
|
#define D_IMMEDIATE "immédiat" // Button immediate
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
#define D_RESTARTING "Redémarre"
|
#define D_RESTARTING "Redémarre"
|
||||||
#define D_RESTART_REASON "Raison du redémarrage"
|
#define D_RESTART_REASON "Raison du redémarrage"
|
||||||
#define D_RESTORE "restaurer"
|
#define D_RESTORE "restaurer"
|
||||||
#define D_RETAINED "retenu"
|
#define D_RETAINED "persistant" // MQTT
|
||||||
#define D_RULE "Règle"
|
#define D_RULE "Règle"
|
||||||
#define D_SAVE "Enregistrer"
|
#define D_SAVE "Enregistrer"
|
||||||
#define D_SENSOR "Capteur"
|
#define D_SENSOR "Capteur"
|
||||||
|
@ -184,7 +184,7 @@
|
||||||
#define D_LEVEL_10 "level 1-0"
|
#define D_LEVEL_10 "level 1-0"
|
||||||
#define D_LEVEL_01 "level 0-1"
|
#define D_LEVEL_01 "level 0-1"
|
||||||
#define D_SERIAL_LOGGING_DISABLED "Journalisation série désactivée"
|
#define D_SERIAL_LOGGING_DISABLED "Journalisation série désactivée"
|
||||||
#define D_SYSLOG_LOGGING_REENABLED "Jounalisation syslog réactivée"
|
#define D_SYSLOG_LOGGING_REENABLED "Jounalisation SysLog réactivée"
|
||||||
|
|
||||||
#define D_SET_BAUDRATE_TO "Définir le débit à"
|
#define D_SET_BAUDRATE_TO "Définir le débit à"
|
||||||
#define D_RECEIVED_TOPIC "Topic reçu" // Terme MQTT
|
#define D_RECEIVED_TOPIC "Topic reçu" // Terme MQTT
|
||||||
|
@ -209,7 +209,7 @@
|
||||||
#define D_QUERY_DONE "Requête terminée. Services MQTT trouvés"
|
#define D_QUERY_DONE "Requête terminée. Services MQTT trouvés"
|
||||||
#define D_MQTT_SERVICE_FOUND "Service MQTT trouvé sur"
|
#define D_MQTT_SERVICE_FOUND "Service MQTT trouvé sur"
|
||||||
#define D_FOUND_AT "trouvé à"
|
#define D_FOUND_AT "trouvé à"
|
||||||
#define D_SYSLOG_HOST_NOT_FOUND "Host syslog introuvable"
|
#define D_SYSLOG_HOST_NOT_FOUND "Hôte SysLog introuvable"
|
||||||
|
|
||||||
// settings.ino
|
// settings.ino
|
||||||
#define D_SAVED_TO_FLASH_AT "Enregistré en flash à"
|
#define D_SAVED_TO_FLASH_AT "Enregistré en flash à"
|
||||||
|
@ -253,7 +253,7 @@
|
||||||
|
|
||||||
#define D_MODULE_PARAMETERS "Paramètres module"
|
#define D_MODULE_PARAMETERS "Paramètres module"
|
||||||
#define D_MODULE_TYPE "Type de module"
|
#define D_MODULE_TYPE "Type de module"
|
||||||
#define D_PULLUP_ENABLE "No Button/Switch pull-up"
|
#define D_PULLUP_ENABLE "Inter. sans pull-up"
|
||||||
#define D_GPIO "GPIO"
|
#define D_GPIO "GPIO"
|
||||||
#define D_SERIAL_IN "Entrée série"
|
#define D_SERIAL_IN "Entrée série"
|
||||||
#define D_SERIAL_OUT "Sortie série"
|
#define D_SERIAL_OUT "Sortie série"
|
||||||
|
@ -281,13 +281,15 @@
|
||||||
#define D_LOGGING_PARAMETERS "Paramètres du journal"
|
#define D_LOGGING_PARAMETERS "Paramètres du journal"
|
||||||
#define D_SERIAL_LOG_LEVEL "Niveau de journalisation série"
|
#define D_SERIAL_LOG_LEVEL "Niveau de journalisation série"
|
||||||
#define D_WEB_LOG_LEVEL "Niveau de journalisation web"
|
#define D_WEB_LOG_LEVEL "Niveau de journalisation web"
|
||||||
#define D_SYS_LOG_LEVEL "Niveau Syslog"
|
#define D_SYS_LOG_LEVEL "Niveau SysLog"
|
||||||
#define D_MORE_DEBUG "Plus de debug"
|
#define D_MORE_DEBUG "Plus de debug"
|
||||||
#define D_SYSLOG_HOST "Hôte Syslog"
|
#define D_SYSLOG_HOST "Hôte SysLog"
|
||||||
#define D_SYSLOG_PORT "Port Syslog"
|
#define D_SYSLOG_PORT "Port SysLog"
|
||||||
#define D_TELEMETRY_PERIOD "Période télémétrie"
|
#define D_TELEMETRY_PERIOD "Période télémétrie"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Autres paramètres"
|
#define D_OTHER_PARAMETERS "Autres paramètres"
|
||||||
|
#define D_TEMPLATE "Modèle"
|
||||||
|
#define D_ACTIVATE "Activer"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Mot de passe Web Admin"
|
#define D_WEB_ADMIN_PASSWORD "Mot de passe Web Admin"
|
||||||
#define D_MQTT_ENABLE "MQTT activé"
|
#define D_MQTT_ENABLE "MQTT activé"
|
||||||
#define D_FRIENDLY_NAME "Surnom"
|
#define D_FRIENDLY_NAME "Surnom"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "module unique"
|
#define D_SINGLE_DEVICE "module unique"
|
||||||
#define D_MULTI_DEVICE "multi module"
|
#define D_MULTI_DEVICE "multi module"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configuration du modèle"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Paramètres du modèle"
|
||||||
|
#define D_TEMPLATE_NAME "Nom"
|
||||||
|
#define D_BASE_TYPE "Basé sur"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "Entrée ADC0"
|
||||||
|
#define D_ALLOW_PULLUP "Choix de pull-up utilisateur"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Enregistrer la configuration"
|
#define D_SAVE_CONFIGURATION "Enregistrer la configuration"
|
||||||
#define D_CONFIGURATION_SAVED "Configuration enregistrée"
|
#define D_CONFIGURATION_SAVED "Configuration enregistrée"
|
||||||
#define D_CONFIGURATION_RESET "Configuration réinitialisée"
|
#define D_CONFIGURATION_RESET "Configuration réinitialisée"
|
||||||
|
@ -331,7 +341,7 @@
|
||||||
#define D_UPLOAD_ERR_3 "L'octet magique n'est pas 0xE9"
|
#define D_UPLOAD_ERR_3 "L'octet magique n'est pas 0xE9"
|
||||||
#define D_UPLOAD_ERR_4 "La taille du programme à flasher est plus grande que la taille réelle de la mémoire flash"
|
#define D_UPLOAD_ERR_4 "La taille du programme à flasher est plus grande que la taille réelle de la mémoire flash"
|
||||||
#define D_UPLOAD_ERR_5 "Erreur de comparaison du buffer de téléchargement"
|
#define D_UPLOAD_ERR_5 "Erreur de comparaison du buffer de téléchargement"
|
||||||
#define D_UPLOAD_ERR_6 "Téléchargement échoué. Activer Weblog 3"
|
#define D_UPLOAD_ERR_6 "Téléchargement échoué. Activer WebLog 3"
|
||||||
#define D_UPLOAD_ERR_7 "Téléchargement annulé"
|
#define D_UPLOAD_ERR_7 "Téléchargement annulé"
|
||||||
#define D_UPLOAD_ERR_8 "Fichier invalide"
|
#define D_UPLOAD_ERR_8 "Fichier invalide"
|
||||||
#define D_UPLOAD_ERR_9 "Fichier trop grand"
|
#define D_UPLOAD_ERR_9 "Fichier trop grand"
|
||||||
|
@ -342,7 +352,7 @@
|
||||||
#define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement"
|
#define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement"
|
||||||
|
|
||||||
#define D_ENTER_COMMAND "Saisir une commande"
|
#define D_ENTER_COMMAND "Saisir une commande"
|
||||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer Weblog 2 si une réponse est attendue"
|
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer WebLog 2 si une réponse est attendue"
|
||||||
#define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=<username>&password=<password>"
|
#define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=<username>&password=<password>"
|
||||||
|
|
||||||
// xdrv_01_mqtt.ino
|
// xdrv_01_mqtt.ino
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Aucun"
|
#define D_SENSOR_NONE "Aucun"
|
||||||
|
#define D_SENSOR_USER "Utilisateur"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetry period"
|
#define D_TELEMETRY_PERIOD "Telemetry period"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "פרמטרים שונים"
|
#define D_OTHER_PARAMETERS "פרמטרים שונים"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "סיסמת מנהל - אתר"
|
#define D_WEB_ADMIN_PASSWORD "סיסמת מנהל - אתר"
|
||||||
#define D_MQTT_ENABLE "MQTT אפשר"
|
#define D_MQTT_ENABLE "MQTT אפשר"
|
||||||
#define D_FRIENDLY_NAME "שם ידידותי"
|
#define D_FRIENDLY_NAME "שם ידידותי"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "התקן בודד"
|
#define D_SINGLE_DEVICE "התקן בודד"
|
||||||
#define D_MULTI_DEVICE "התקנים"
|
#define D_MULTI_DEVICE "התקנים"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "שמירת הגדרות"
|
#define D_SAVE_CONFIGURATION "שמירת הגדרות"
|
||||||
#define D_CONFIGURATION_SAVED "הגדרות נשמרו"
|
#define D_CONFIGURATION_SAVED "הגדרות נשמרו"
|
||||||
#define D_CONFIGURATION_RESET "איפוס הגדרות"
|
#define D_CONFIGURATION_RESET "איפוס הגדרות"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetria (mp.)"
|
#define D_TELEMETRY_PERIOD "Telemetria (mp.)"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Egyéb beállítások"
|
#define D_OTHER_PARAMETERS "Egyéb beállítások"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Web admin jelszó"
|
#define D_WEB_ADMIN_PASSWORD "Web admin jelszó"
|
||||||
#define D_MQTT_ENABLE "MQTT engedélyezése"
|
#define D_MQTT_ENABLE "MQTT engedélyezése"
|
||||||
#define D_FRIENDLY_NAME "Név"
|
#define D_FRIENDLY_NAME "Név"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "single device"
|
#define D_SINGLE_DEVICE "single device"
|
||||||
#define D_MULTI_DEVICE "multi device"
|
#define D_MULTI_DEVICE "multi device"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Beállítások mentése"
|
#define D_SAVE_CONFIGURATION "Beállítások mentése"
|
||||||
#define D_CONFIGURATION_SAVED "Beállítások elmentve"
|
#define D_CONFIGURATION_SAVED "Beállítások elmentve"
|
||||||
#define D_CONFIGURATION_RESET "Beállítások visszaállítása"
|
#define D_CONFIGURATION_RESET "Beállítások visszaállítása"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nincs"
|
#define D_SENSOR_NONE "Nincs"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Periodo Telemetria"
|
#define D_TELEMETRY_PERIOD "Periodo Telemetria"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Altri parametri"
|
#define D_OTHER_PARAMETERS "Altri parametri"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Password Amministratore Web"
|
#define D_WEB_ADMIN_PASSWORD "Password Amministratore Web"
|
||||||
#define D_MQTT_ENABLE "Abilita MQTT"
|
#define D_MQTT_ENABLE "Abilita MQTT"
|
||||||
#define D_FRIENDLY_NAME "Nome confidenziale"
|
#define D_FRIENDLY_NAME "Nome confidenziale"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "dispositivo singolo"
|
#define D_SINGLE_DEVICE "dispositivo singolo"
|
||||||
#define D_MULTI_DEVICE "dispositivo multiplo"
|
#define D_MULTI_DEVICE "dispositivo multiplo"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Salva configurazione"
|
#define D_SAVE_CONFIGURATION "Salva configurazione"
|
||||||
#define D_CONFIGURATION_SAVED "Configurazione salvata"
|
#define D_CONFIGURATION_SAVED "Configurazione salvata"
|
||||||
#define D_CONFIGURATION_RESET "Configurazione azzerata"
|
#define D_CONFIGURATION_RESET "Configurazione azzerata"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nessuno"
|
#define D_SENSOR_NONE "Nessuno"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetry periode"
|
#define D_TELEMETRY_PERIOD "Telemetry periode"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Overige parameters"
|
#define D_OTHER_PARAMETERS "Overige parameters"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord"
|
#define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord"
|
||||||
#define D_MQTT_ENABLE "MQTT ingeschakeld"
|
#define D_MQTT_ENABLE "MQTT ingeschakeld"
|
||||||
#define D_FRIENDLY_NAME "Beschrijvende naam"
|
#define D_FRIENDLY_NAME "Beschrijvende naam"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "een apparaat"
|
#define D_SINGLE_DEVICE "een apparaat"
|
||||||
#define D_MULTI_DEVICE "meer apparaten"
|
#define D_MULTI_DEVICE "meer apparaten"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Bewaar configuratie"
|
#define D_SAVE_CONFIGURATION "Bewaar configuratie"
|
||||||
#define D_CONFIGURATION_SAVED "Configuratie opgeslagen"
|
#define D_CONFIGURATION_SAVED "Configuratie opgeslagen"
|
||||||
#define D_CONFIGURATION_RESET "Configuratie ge-reset"
|
#define D_CONFIGURATION_RESET "Configuratie ge-reset"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Geen"
|
#define D_SENSOR_NONE "Geen"
|
||||||
|
#define D_SENSOR_USER "Gebruiker"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Okres telemetrii"
|
#define D_TELEMETRY_PERIOD "Okres telemetrii"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Inne parametry"
|
#define D_OTHER_PARAMETERS "Inne parametry"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Hasło administratora Web"
|
#define D_WEB_ADMIN_PASSWORD "Hasło administratora Web"
|
||||||
#define D_MQTT_ENABLE "MQTT aktywne"
|
#define D_MQTT_ENABLE "MQTT aktywne"
|
||||||
#define D_FRIENDLY_NAME "Twoja nazwa"
|
#define D_FRIENDLY_NAME "Twoja nazwa"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "single device"
|
#define D_SINGLE_DEVICE "single device"
|
||||||
#define D_MULTI_DEVICE "multi device"
|
#define D_MULTI_DEVICE "multi device"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Zapisz ustawienia"
|
#define D_SAVE_CONFIGURATION "Zapisz ustawienia"
|
||||||
#define D_CONFIGURATION_SAVED "Ustawienia zapisane"
|
#define D_CONFIGURATION_SAVED "Ustawienia zapisane"
|
||||||
#define D_CONFIGURATION_RESET "Ustawienia zresetowane"
|
#define D_CONFIGURATION_RESET "Ustawienia zresetowane"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Brak"
|
#define D_SENSOR_NONE "Brak"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Período de telemetria"
|
#define D_TELEMETRY_PERIOD "Período de telemetria"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Outros parâmetros"
|
#define D_OTHER_PARAMETERS "Outros parâmetros"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Senha de WEB Admin"
|
#define D_WEB_ADMIN_PASSWORD "Senha de WEB Admin"
|
||||||
#define D_MQTT_ENABLE "MQTT habilitado"
|
#define D_MQTT_ENABLE "MQTT habilitado"
|
||||||
#define D_FRIENDLY_NAME "Nome amigável"
|
#define D_FRIENDLY_NAME "Nome amigável"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "Dispositivo único"
|
#define D_SINGLE_DEVICE "Dispositivo único"
|
||||||
#define D_MULTI_DEVICE "Múltiplos dispositivos"
|
#define D_MULTI_DEVICE "Múltiplos dispositivos"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Gravar configuração"
|
#define D_SAVE_CONFIGURATION "Gravar configuração"
|
||||||
#define D_CONFIGURATION_SAVED "Configuração gravada"
|
#define D_CONFIGURATION_SAVED "Configuração gravada"
|
||||||
#define D_CONFIGURATION_RESET "Reinicialização da configuração"
|
#define D_CONFIGURATION_RESET "Reinicialização da configuração"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nenhum"
|
#define D_SENSOR_NONE "Nenhum"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Periodo de Telemetria"
|
#define D_TELEMETRY_PERIOD "Periodo de Telemetria"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Outros parametros"
|
#define D_OTHER_PARAMETERS "Outros parametros"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Palavra Chave de WEB Admin"
|
#define D_WEB_ADMIN_PASSWORD "Palavra Chave de WEB Admin"
|
||||||
#define D_MQTT_ENABLE "MQTT habilitado"
|
#define D_MQTT_ENABLE "MQTT habilitado"
|
||||||
#define D_FRIENDLY_NAME "Nome amigável"
|
#define D_FRIENDLY_NAME "Nome amigável"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "dispositivo único"
|
#define D_SINGLE_DEVICE "dispositivo único"
|
||||||
#define D_MULTI_DEVICE "multiplos dispositivos"
|
#define D_MULTI_DEVICE "multiplos dispositivos"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Salvar configuração"
|
#define D_SAVE_CONFIGURATION "Salvar configuração"
|
||||||
#define D_CONFIGURATION_SAVED "Configuração guardada"
|
#define D_CONFIGURATION_SAVED "Configuração guardada"
|
||||||
#define D_CONFIGURATION_RESET "Reinicialização da configuração"
|
#define D_CONFIGURATION_RESET "Reinicialização da configuração"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Nenhum"
|
#define D_SENSOR_NONE "Nenhum"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Период телеметрии"
|
#define D_TELEMETRY_PERIOD "Период телеметрии"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Параметры Прочие"
|
#define D_OTHER_PARAMETERS "Параметры Прочие"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Пароль Web администратора"
|
#define D_WEB_ADMIN_PASSWORD "Пароль Web администратора"
|
||||||
#define D_MQTT_ENABLE "MQTT активен"
|
#define D_MQTT_ENABLE "MQTT активен"
|
||||||
#define D_FRIENDLY_NAME "Дружественное Имя"
|
#define D_FRIENDLY_NAME "Дружественное Имя"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "одиночное"
|
#define D_SINGLE_DEVICE "одиночное"
|
||||||
#define D_MULTI_DEVICE "мульти"
|
#define D_MULTI_DEVICE "мульти"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Сохранить конфигурацию"
|
#define D_SAVE_CONFIGURATION "Сохранить конфигурацию"
|
||||||
#define D_CONFIGURATION_SAVED "Конфигурация сохранена "
|
#define D_CONFIGURATION_SAVED "Конфигурация сохранена "
|
||||||
#define D_CONFIGURATION_RESET "Конфигурация сброшена"
|
#define D_CONFIGURATION_RESET "Конфигурация сброшена"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "-нет-"
|
#define D_SENSOR_NONE "-нет-"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Interval telemetrie"
|
#define D_TELEMETRY_PERIOD "Interval telemetrie"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Ostatné nastavenia"
|
#define D_OTHER_PARAMETERS "Ostatné nastavenia"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora"
|
#define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora"
|
||||||
#define D_MQTT_ENABLE "MQTT aktívne"
|
#define D_MQTT_ENABLE "MQTT aktívne"
|
||||||
#define D_FRIENDLY_NAME "Friendly Name"
|
#define D_FRIENDLY_NAME "Friendly Name"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "single device"
|
#define D_SINGLE_DEVICE "single device"
|
||||||
#define D_MULTI_DEVICE "multi device"
|
#define D_MULTI_DEVICE "multi device"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ulož nastavenia"
|
#define D_SAVE_CONFIGURATION "Ulož nastavenia"
|
||||||
#define D_CONFIGURATION_SAVED "Nastavenia uložené"
|
#define D_CONFIGURATION_SAVED "Nastavenia uložené"
|
||||||
#define D_CONFIGURATION_RESET "Nastavenia resetované"
|
#define D_CONFIGURATION_RESET "Nastavenia resetované"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Žiaden"
|
#define D_SENSOR_NONE "Žiaden"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetriperiod"
|
#define D_TELEMETRY_PERIOD "Telemetriperiod"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Andra parametrar"
|
#define D_OTHER_PARAMETERS "Andra parametrar"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Webbadmin-lösenord"
|
#define D_WEB_ADMIN_PASSWORD "Webbadmin-lösenord"
|
||||||
#define D_MQTT_ENABLE "MQTT aktivera"
|
#define D_MQTT_ENABLE "MQTT aktivera"
|
||||||
#define D_FRIENDLY_NAME "Läsbart namn"
|
#define D_FRIENDLY_NAME "Läsbart namn"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "soloenhet"
|
#define D_SINGLE_DEVICE "soloenhet"
|
||||||
#define D_MULTI_DEVICE "multienhet"
|
#define D_MULTI_DEVICE "multienhet"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Spara konfiguration"
|
#define D_SAVE_CONFIGURATION "Spara konfiguration"
|
||||||
#define D_CONFIGURATION_SAVED "Konfiguration sparad"
|
#define D_CONFIGURATION_SAVED "Konfiguration sparad"
|
||||||
#define D_CONFIGURATION_RESET "Konfiguration nollställd"
|
#define D_CONFIGURATION_RESET "Konfiguration nollställd"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "Ingen"
|
#define D_SENSOR_NONE "Ingen"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Telemetri peryodu"
|
#define D_TELEMETRY_PERIOD "Telemetri peryodu"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Diğer parametreler"
|
#define D_OTHER_PARAMETERS "Diğer parametreler"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Web Yönetici Şifresi"
|
#define D_WEB_ADMIN_PASSWORD "Web Yönetici Şifresi"
|
||||||
#define D_MQTT_ENABLE "MQTT aktif"
|
#define D_MQTT_ENABLE "MQTT aktif"
|
||||||
#define D_FRIENDLY_NAME "Kullanıcı Dostu İsim"
|
#define D_FRIENDLY_NAME "Kullanıcı Dostu İsim"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "tekli cihaz"
|
#define D_SINGLE_DEVICE "tekli cihaz"
|
||||||
#define D_MULTI_DEVICE "çoklu cihaz"
|
#define D_MULTI_DEVICE "çoklu cihaz"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Ayarları Kaydet"
|
#define D_SAVE_CONFIGURATION "Ayarları Kaydet"
|
||||||
#define D_CONFIGURATION_SAVED "Ayarlar kaydedildi"
|
#define D_CONFIGURATION_SAVED "Ayarlar kaydedildi"
|
||||||
#define D_CONFIGURATION_RESET "Ayarlar resetlendi"
|
#define D_CONFIGURATION_RESET "Ayarlar resetlendi"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "Період телеметрії"
|
#define D_TELEMETRY_PERIOD "Період телеметрії"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "Параметри Інше"
|
#define D_OTHER_PARAMETERS "Параметри Інше"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "Гасло Web адміністратора"
|
#define D_WEB_ADMIN_PASSWORD "Гасло Web адміністратора"
|
||||||
#define D_MQTT_ENABLE "MQTT активний"
|
#define D_MQTT_ENABLE "MQTT активний"
|
||||||
#define D_FRIENDLY_NAME "Дружнє Ім'я"
|
#define D_FRIENDLY_NAME "Дружнє Ім'я"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "одиночне"
|
#define D_SINGLE_DEVICE "одиночне"
|
||||||
#define D_MULTI_DEVICE "мульти"
|
#define D_MULTI_DEVICE "мульти"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "Зберегти конфігурацію"
|
#define D_SAVE_CONFIGURATION "Зберегти конфігурацію"
|
||||||
#define D_CONFIGURATION_SAVED "Конфігурація збережена "
|
#define D_CONFIGURATION_SAVED "Конфігурація збережена "
|
||||||
#define D_CONFIGURATION_RESET "Конфігурація скинута"
|
#define D_CONFIGURATION_RESET "Конфігурація скинута"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "-відсутньо-"
|
#define D_SENSOR_NONE "-відсутньо-"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "上报周期"
|
#define D_TELEMETRY_PERIOD "上报周期"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "其他设置"
|
#define D_OTHER_PARAMETERS "其他设置"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "WEB 管理密码"
|
#define D_WEB_ADMIN_PASSWORD "WEB 管理密码"
|
||||||
#define D_MQTT_ENABLE "启用MQTT"
|
#define D_MQTT_ENABLE "启用MQTT"
|
||||||
#define D_FRIENDLY_NAME "昵称"
|
#define D_FRIENDLY_NAME "昵称"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "单设备"
|
#define D_SINGLE_DEVICE "单设备"
|
||||||
#define D_MULTI_DEVICE "多设备"
|
#define D_MULTI_DEVICE "多设备"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "保存设置"
|
#define D_SAVE_CONFIGURATION "保存设置"
|
||||||
#define D_CONFIGURATION_SAVED "设置已保存"
|
#define D_CONFIGURATION_SAVED "设置已保存"
|
||||||
#define D_CONFIGURATION_RESET "设置已重置"
|
#define D_CONFIGURATION_RESET "设置已重置"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "无"
|
#define D_SENSOR_NONE "无"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -288,6 +288,8 @@
|
||||||
#define D_TELEMETRY_PERIOD "上報周期"
|
#define D_TELEMETRY_PERIOD "上報周期"
|
||||||
|
|
||||||
#define D_OTHER_PARAMETERS "其他設置"
|
#define D_OTHER_PARAMETERS "其他設置"
|
||||||
|
#define D_TEMPLATE "Template"
|
||||||
|
#define D_ACTIVATE "Activate"
|
||||||
#define D_WEB_ADMIN_PASSWORD "WEB管理密碼"
|
#define D_WEB_ADMIN_PASSWORD "WEB管理密碼"
|
||||||
#define D_MQTT_ENABLE "啟用MQTT"
|
#define D_MQTT_ENABLE "啟用MQTT"
|
||||||
#define D_FRIENDLY_NAME "昵稱"
|
#define D_FRIENDLY_NAME "昵稱"
|
||||||
|
@ -296,6 +298,14 @@
|
||||||
#define D_SINGLE_DEVICE "單設備"
|
#define D_SINGLE_DEVICE "單設備"
|
||||||
#define D_MULTI_DEVICE "多設備"
|
#define D_MULTI_DEVICE "多設備"
|
||||||
|
|
||||||
|
#define D_CONFIGURE_TEMPLATE "Configure Template"
|
||||||
|
#define D_TEMPLATE_PARAMETERS "Template parameters"
|
||||||
|
#define D_TEMPLATE_NAME "Name"
|
||||||
|
#define D_BASE_TYPE "Based on"
|
||||||
|
#define D_TEMPLATE_FLAGS "Options"
|
||||||
|
#define D_ALLOW_ADC0 "ADC0 input"
|
||||||
|
#define D_ALLOW_PULLUP "User pull-up selection"
|
||||||
|
|
||||||
#define D_SAVE_CONFIGURATION "保存設置"
|
#define D_SAVE_CONFIGURATION "保存設置"
|
||||||
#define D_CONFIGURATION_SAVED "設置已保存"
|
#define D_CONFIGURATION_SAVED "設置已保存"
|
||||||
#define D_CONFIGURATION_RESET "設置已重置"
|
#define D_CONFIGURATION_RESET "設置已重置"
|
||||||
|
@ -483,6 +493,7 @@
|
||||||
|
|
||||||
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
// sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||||
#define D_SENSOR_NONE "None"
|
#define D_SENSOR_NONE "None"
|
||||||
|
#define D_SENSOR_USER "User"
|
||||||
#define D_SENSOR_DHT11 "DHT11"
|
#define D_SENSOR_DHT11 "DHT11"
|
||||||
#define D_SENSOR_AM2301 "AM2301"
|
#define D_SENSOR_AM2301 "AM2301"
|
||||||
#define D_SENSOR_SI7021 "SI7021"
|
#define D_SENSOR_SI7021 "SI7021"
|
||||||
|
|
|
@ -122,6 +122,7 @@
|
||||||
|
|
||||||
// -- MQTT - Telemetry ----------------------------
|
// -- MQTT - Telemetry ----------------------------
|
||||||
#define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds)
|
#define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds)
|
||||||
|
#define TELE_ON_POWER 0 // [SetOption59] send tele/STATE together with stat/RESULT (0 = Disable, 1 = Enable)
|
||||||
|
|
||||||
// -- MQTT - Domoticz -----------------------------
|
// -- MQTT - Domoticz -----------------------------
|
||||||
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds)
|
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds)
|
||||||
|
@ -278,6 +279,7 @@
|
||||||
|
|
||||||
// -- Rules ---------------------------------------
|
// -- Rules ---------------------------------------
|
||||||
#define USE_RULES // Add support for rules (+4k4 code)
|
#define USE_RULES // Add support for rules (+4k4 code)
|
||||||
|
#define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
|
||||||
|
|
||||||
// -- Internal Analog input -----------------------
|
// -- Internal Analog input -----------------------
|
||||||
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
||||||
|
|
|
@ -75,7 +75,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||||
uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13)
|
uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13)
|
||||||
uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep
|
uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep
|
||||||
uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set
|
uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set
|
||||||
uint32_t no_pullup : 1; // bit 12 (v6.4.1.7) - SetOption62 - Force no pull-up (0 = (no)pull-up, 1 = no pull-up)
|
uint32_t no_hold_retain : 1; // bit 12 (v6.4.1.19) - SetOption62 - Don't use retain flag on HOLD messages
|
||||||
uint32_t spare13 : 1;
|
uint32_t spare13 : 1;
|
||||||
uint32_t spare14 : 1;
|
uint32_t spare14 : 1;
|
||||||
uint32_t spare15 : 1;
|
uint32_t spare15 : 1;
|
||||||
|
|
|
@ -661,6 +661,7 @@ void SettingsDefaultSet2(void)
|
||||||
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
|
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
|
||||||
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
|
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
|
||||||
Settings.flag3.button_switch_force_local = MQTT_BUTTON_SWITCH_FORCE_LOCAL;
|
Settings.flag3.button_switch_force_local = MQTT_BUTTON_SWITCH_FORCE_LOCAL;
|
||||||
|
Settings.flag3.hass_tele_on_power = TELE_ON_POWER;
|
||||||
// Settings.flag.mqtt_sensor_retain = 0;
|
// Settings.flag.mqtt_sensor_retain = 0;
|
||||||
// Settings.flag.mqtt_offline = 0;
|
// Settings.flag.mqtt_offline = 0;
|
||||||
// Settings.flag.mqtt_serial = 0;
|
// Settings.flag.mqtt_serial = 0;
|
||||||
|
|
|
@ -104,6 +104,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
||||||
#define PWM_MIN 100 // [PWM_MIN] Minimum frequency - Default: 100
|
#define PWM_MIN 100 // [PWM_MIN] Minimum frequency - Default: 100
|
||||||
// For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz)
|
// For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz)
|
||||||
// For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS)
|
// For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS)
|
||||||
|
//#define PWM_LIGHTSCHEME0_IGNORE_SLEEP // Do not change sleep value for LightAnimate() scheme 0
|
||||||
|
|
||||||
#define DEFAULT_POWER_DELTA 80 // Power change percentage
|
#define DEFAULT_POWER_DELTA 80 // Power change percentage
|
||||||
#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power
|
#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power
|
||||||
|
@ -211,7 +212,7 @@ enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_ENERGY };
|
||||||
|
|
||||||
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||||
|
|
||||||
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, MAX_WIFI_OPTION};
|
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY, MAX_WIFI_OPTION};
|
||||||
|
|
||||||
enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION};
|
enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION};
|
||||||
|
|
||||||
|
|
|
@ -776,9 +776,6 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
if (10 == pindex) { // SetOption60 enable or disable traditional sleep
|
if (10 == pindex) { // SetOption60 enable or disable traditional sleep
|
||||||
WiFiSetSleepMode(); // Update WiFi sleep mode accordingly
|
WiFiSetSleepMode(); // Update WiFi sleep mode accordingly
|
||||||
}
|
}
|
||||||
if ((12 == pindex) && (my_module_flag.pullup)) { // SetOption62 change input pull-up
|
|
||||||
restart_flag = 2; // Only restart if module supports it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // SetOption32 .. 49
|
else { // SetOption32 .. 49
|
||||||
|
@ -869,9 +866,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
uint8_t module = Settings.module;
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, ModuleNr(), ModuleName().c_str());
|
||||||
if (USER_MODULE == Settings.module) { module = 0; } else { module++; }
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, module, ModuleName().c_str());
|
|
||||||
}
|
}
|
||||||
else if (CMND_MODULES == command_code) {
|
else if (CMND_MODULES == command_code) {
|
||||||
for (uint8_t i = 0; i <= MAXMODULE; i++) {
|
for (uint8_t i = 0; i <= MAXMODULE; i++) {
|
||||||
|
@ -952,85 +947,29 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
}
|
}
|
||||||
else if (CMND_TEMPLATE == command_code) {
|
else if (CMND_TEMPLATE == command_code) {
|
||||||
// {"NAME":"Generic","GPIO":[17,254,29,254,7,254,254,254,138,254,139,254,254],"FLAG":1,"TYPE":255}
|
// {"NAME":"Generic","GPIO":[17,254,29,254,7,254,254,254,138,254,139,254,254],"FLAG":1,"BASE":255}
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
if (!strstr(dataBuf, "{")) { // If no JSON it must be parameter
|
if (!strstr(dataBuf, "{")) { // If no JSON it must be parameter
|
||||||
bool update = false;
|
|
||||||
if ((payload > 0) && (payload <= MAXMODULE)) {
|
if ((payload > 0) && (payload <= MAXMODULE)) {
|
||||||
ModuleDefault(payload -1); // Copy template module
|
ModuleDefault(payload -1); // Copy template module
|
||||||
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
||||||
}
|
}
|
||||||
else if (0 == payload) { // Copy current module with user configured GPIO
|
else if (0 == payload) { // Copy current module with user configured GPIO
|
||||||
if (Settings.module < USER_MODULE) {
|
if (Settings.module != USER_MODULE) {
|
||||||
ModuleDefault(Settings.module);
|
ModuleDefault(Settings.module);
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (USER_MODULE == Settings.module) { // Update with latest changes
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
if (update) {
|
|
||||||
uint8_t src = 0;
|
|
||||||
for (uint8_t dst = 0; dst < sizeof(mycfgio); dst++) {
|
|
||||||
if (6 == dst) { src = 9; }
|
|
||||||
if (8 == dst) { src = 12; }
|
|
||||||
if (Settings.my_gp.io[src] > GPIO_NONE) {
|
|
||||||
if (Settings.user_template.gp.io[dst] != Settings.my_gp.io[src]) {
|
|
||||||
Settings.user_template.gp.io[dst] = Settings.my_gp.io[src];
|
|
||||||
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data_len > 9) { // Workaround exception if empty JSON like {} - Needs checks
|
else if (data_len > 9) { // Workaround exception if empty JSON like {} - Needs checks
|
||||||
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
|
if (JsonTemplate(dataBuf)) { // Free 336 bytes StaticJsonBuffer stack space by moving code to function
|
||||||
JsonObject& obj = jb.parseObject(dataBuf);
|
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
||||||
if (!obj.success()) {
|
} else {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
||||||
error = true;
|
error = true;
|
||||||
} else {
|
|
||||||
// All parameters are optional allowing for partial changes
|
|
||||||
const char* name = obj[D_JSON_NAME];
|
|
||||||
if (name != nullptr) {
|
|
||||||
strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name));
|
|
||||||
}
|
|
||||||
if (obj[D_JSON_GPIO].success()) {
|
|
||||||
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
|
|
||||||
Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (obj[D_JSON_FLAG].success()) {
|
if (!error) { TemplateJson(); }
|
||||||
uint8_t flag = obj[D_JSON_FLAG] | 0;
|
|
||||||
memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag));
|
|
||||||
}
|
|
||||||
if (obj[D_JSON_BASE].success()) {
|
|
||||||
uint8_t base = obj[D_JSON_BASE];
|
|
||||||
if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; }
|
|
||||||
Settings.user_template_base = base; // Default WEMOS
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate GPIO
|
|
||||||
// for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
|
|
||||||
// For now do not allow non-user configurable GPIO
|
|
||||||
// if ((Settings.user_template.gp.io[i] > GPIO_FIX_START) && (Settings.user_template.gp.io[i] < GPIO_USER)) {
|
|
||||||
// Settings.user_template.gp.io[i] = GPIO_NONE;
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
if (USER_MODULE == Settings.module) { restart_flag = 2; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!error) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
|
|
||||||
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", Settings.user_template.gp.io[i]);
|
|
||||||
}
|
|
||||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":\"%d (%s)\"}"),
|
|
||||||
// mqtt_data, Settings.user_template.flag, Settings.user_template_base +1, AnyModuleName(Settings.user_template_base).c_str());
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"),
|
|
||||||
mqtt_data, Settings.user_template.flag, Settings.user_template_base +1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ((CMND_PWM == command_code) && pwm_present && (index > 0) && (index <= MAX_PWMS)) {
|
else if ((CMND_PWM == command_code) && pwm_present && (index > 0) && (index <= MAX_PWMS)) {
|
||||||
if ((payload >= 0) && (payload <= Settings.pwm_range) && (pin[GPIO_PWM1 + index -1] < 99)) {
|
if ((payload >= 0) && (payload <= Settings.pwm_range) && (pin[GPIO_PWM1 + index -1] < 99)) {
|
||||||
|
@ -1203,7 +1142,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.sta_ssid[index -1]);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.sta_ssid[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_PASSWORD == command_code) && (index > 0) && (index <= 2)) {
|
else if ((CMND_PASSWORD == command_code) && (index > 0) && (index <= 2)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(Settings.sta_pwd[0]))) {
|
if ((data_len > 4 || SC_CLEAR == Shortcut(dataBuf) || SC_DEFAULT == Shortcut(dataBuf)) && (data_len < sizeof(Settings.sta_pwd[0]))) {
|
||||||
strlcpy(Settings.sta_pwd[index -1], (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0]));
|
strlcpy(Settings.sta_pwd[index -1], (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0]));
|
||||||
Settings.sta_active = index -1;
|
Settings.sta_active = index -1;
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
|
@ -1336,10 +1275,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
restart_flag = 211;
|
restart_flag = 211;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command , D_JSON_RESET_AND_RESTARTING);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command , D_JSON_RESET_AND_RESTARTING);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2 ... 6:
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
restart_flag = 210 + payload;
|
restart_flag = 210 + payload;
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_JSON_ERASE ", " D_JSON_RESET_AND_RESTARTING "\"}"));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_JSON_ERASE ", " D_JSON_RESET_AND_RESTARTING "\"}"));
|
||||||
break;
|
break;
|
||||||
|
@ -1496,10 +1432,10 @@ bool SendKey(uint8_t key, uint8_t device, uint8_t state)
|
||||||
}
|
}
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
if (!(DomoticzSendKey(key, device, state, strlen(mqtt_data)))) {
|
if (!(DomoticzSendKey(key, device, state, strlen(mqtt_data)))) {
|
||||||
MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain);
|
MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain);
|
MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain));
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
result = !Settings.flag3.button_switch_force_local;
|
result = !Settings.flag3.button_switch_force_local;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1628,8 +1564,6 @@ void StopAllPowerBlink(void)
|
||||||
|
|
||||||
void ExecuteCommand(char *cmnd, int source)
|
void ExecuteCommand(char *cmnd, int source)
|
||||||
{
|
{
|
||||||
char stopic[CMDSZ];
|
|
||||||
char svalue[INPUT_BUFFER_SIZE];
|
|
||||||
char *start;
|
char *start;
|
||||||
char *token;
|
char *token;
|
||||||
|
|
||||||
|
@ -1641,9 +1575,13 @@ void ExecuteCommand(char *cmnd, int source)
|
||||||
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
|
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
|
||||||
if (start) { token = start +1; }
|
if (start) { token = start +1; }
|
||||||
}
|
}
|
||||||
|
uint16_t size = (token != NULL) ? strlen(token) : 0;
|
||||||
|
char stopic[size +2]; // / + \0
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == NULL) ? "" : token);
|
snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == NULL) ? "" : token);
|
||||||
|
|
||||||
token = strtok(NULL, "");
|
token = strtok(NULL, "");
|
||||||
// snprintf_P(svalue, sizeof(svalue), (token == NULL) ? "" : token); // Fails with command FullTopic home/%prefix%/%topic% as it processes %p of %prefix%
|
size = (token != NULL) ? strlen(token) : 0;
|
||||||
|
char svalue[size +1];
|
||||||
strlcpy(svalue, (token == NULL) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b
|
strlcpy(svalue, (token == NULL) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b
|
||||||
MqttDataHandler(stopic, (uint8_t*)svalue, strlen(svalue));
|
MqttDataHandler(stopic, (uint8_t*)svalue, strlen(svalue));
|
||||||
}
|
}
|
||||||
|
@ -1672,13 +1610,13 @@ void PublishStatus(uint8_t payload)
|
||||||
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]);
|
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
|
||||||
(USER_MODULE == Settings.module)?0:Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain);
|
ModuleNr(), stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain);
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == payload) || (1 == payload)) {
|
if ((0 == payload) || (1 == payload)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.cfg_holder, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1712,8 +1650,8 @@ void PublishStatus(uint8_t payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) {
|
if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\"" D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"MqttType\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\"" D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"MqttType\":%d,\"" D_JSON_MQTT_COUNT "\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"),
|
||||||
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, mqtt_client, Settings.mqtt_user, MqttLibraryType(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
|
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, mqtt_client, Settings.mqtt_user, MqttLibraryType(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1805,8 +1743,8 @@ void MqttShowState(void)
|
||||||
MqttShowPWMState();
|
MqttShowPWMState();
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}}"),
|
||||||
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WiFi.BSSIDstr().c_str(), WiFi.channel(), WifiGetRssiAsQuality(WiFi.RSSI()));
|
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WiFi.BSSIDstr().c_str(), WiFi.channel(), WifiGetRssiAsQuality(WiFi.RSSI()), WifiLinkCount(), WifiDowntime().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MqttShowSensor(void)
|
bool MqttShowSensor(void)
|
||||||
|
@ -2114,14 +2052,33 @@ void Every250mSeconds(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (restart_flag && (backlog_pointer == backlog_index)) {
|
if (restart_flag && (backlog_pointer == backlog_index)) {
|
||||||
if ((214 == restart_flag) || (215 == restart_flag)) {
|
if ((214 == restart_flag) || (215 == restart_flag) || (216 == restart_flag)) {
|
||||||
char storage[sizeof(Settings.sta_ssid) + sizeof(Settings.sta_pwd)];
|
char storage[sizeof(Settings.sta_ssid) + sizeof(Settings.sta_pwd)];
|
||||||
|
char storage_mqtt_host[sizeof(Settings.mqtt_host)];
|
||||||
|
uint16_t storage_mqtt_port;
|
||||||
|
char storage_mqtt_user[sizeof(Settings.mqtt_user)];
|
||||||
|
char storage_mqtt_pwd[sizeof(Settings.mqtt_pwd)];
|
||||||
|
char storage_mqtt_topic[sizeof(Settings.mqtt_topic)];
|
||||||
memcpy(storage, Settings.sta_ssid, sizeof(storage)); // Backup current SSIDs and Passwords
|
memcpy(storage, Settings.sta_ssid, sizeof(storage)); // Backup current SSIDs and Passwords
|
||||||
if (215 == restart_flag) {
|
if (216 == restart_flag) {
|
||||||
|
memcpy(storage_mqtt_host, Settings.mqtt_host, sizeof(Settings.mqtt_host));
|
||||||
|
storage_mqtt_port = Settings.mqtt_port;
|
||||||
|
memcpy(storage_mqtt_user, Settings.mqtt_user, sizeof(Settings.mqtt_user));
|
||||||
|
memcpy(storage_mqtt_pwd, Settings.mqtt_pwd, sizeof(Settings.mqtt_pwd));
|
||||||
|
memcpy(storage_mqtt_topic, Settings.mqtt_topic, sizeof(Settings.mqtt_topic));
|
||||||
|
}
|
||||||
|
if ((215 == restart_flag) || (216 == restart_flag)) {
|
||||||
SettingsErase(0); // Erase all flash from program end to end of physical flash
|
SettingsErase(0); // Erase all flash from program end to end of physical flash
|
||||||
}
|
}
|
||||||
SettingsDefault();
|
SettingsDefault();
|
||||||
memcpy(Settings.sta_ssid, storage, sizeof(storage)); // Restore current SSIDs and Passwords
|
memcpy(Settings.sta_ssid, storage, sizeof(storage)); // Restore current SSIDs and Passwords
|
||||||
|
if (216 == restart_flag) { // Restore the mqtt host, port, username and password
|
||||||
|
memcpy(Settings.mqtt_host, storage_mqtt_host, sizeof(Settings.mqtt_host));
|
||||||
|
Settings.mqtt_port = storage_mqtt_port;
|
||||||
|
memcpy(Settings.mqtt_user, storage_mqtt_user, sizeof(Settings.mqtt_user));
|
||||||
|
memcpy(Settings.mqtt_pwd, storage_mqtt_pwd, sizeof(Settings.mqtt_pwd));
|
||||||
|
memcpy(Settings.mqtt_topic, storage_mqtt_topic, sizeof(Settings.mqtt_topic));
|
||||||
|
}
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
else if (213 == restart_flag) {
|
else if (213 == restart_flag) {
|
||||||
|
@ -2237,7 +2194,8 @@ void ArduinoOTAInit(void)
|
||||||
void SerialInput(void)
|
void SerialInput(void)
|
||||||
{
|
{
|
||||||
while (Serial.available()) {
|
while (Serial.available()) {
|
||||||
yield();
|
// yield();
|
||||||
|
delay(0);
|
||||||
serial_in_byte = Serial.read();
|
serial_in_byte = Serial.read();
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
|
@ -2346,17 +2304,23 @@ void GpioInit(void)
|
||||||
baudrate = APP_BAUDRATE;
|
baudrate = APP_BAUDRATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||||
|
if ((Settings.user_template.gp.io[i] >= GPIO_SENSOR_END) && (Settings.user_template.gp.io[i] < GPIO_USER)) {
|
||||||
|
Settings.user_template.gp.io[i] = GPIO_USER; // Fix not supported sensor ids in template
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
myio def_gp;
|
myio def_gp;
|
||||||
ModuleGpios(&def_gp);
|
ModuleGpios(&def_gp);
|
||||||
for (uint8_t i = 0; i < sizeof(Settings.my_gp); i++) {
|
for (uint8_t i = 0; i < sizeof(Settings.my_gp); i++) {
|
||||||
if (Settings.my_gp.io[i] > GPIO_NONE) {
|
if ((Settings.my_gp.io[i] >= GPIO_SENSOR_END) && (Settings.my_gp.io[i] < GPIO_USER)) {
|
||||||
|
Settings.my_gp.io[i] = GPIO_NONE; // Fix not supported sensor ids in module
|
||||||
|
}
|
||||||
|
else if (Settings.my_gp.io[i] > GPIO_NONE) {
|
||||||
my_module.io[i] = Settings.my_gp.io[i];
|
my_module.io[i] = Settings.my_gp.io[i];
|
||||||
}
|
}
|
||||||
if ((def_gp.io[i] > GPIO_NONE) && (def_gp.io[i] < GPIO_USER)) {
|
if ((def_gp.io[i] > GPIO_NONE) && (def_gp.io[i] < GPIO_USER)) {
|
||||||
my_module.io[i] = def_gp.io[i];
|
my_module.io[i] = def_gp.io[i];
|
||||||
if (USER_MODULE == Settings.module) {
|
|
||||||
Settings.my_gp.io[i] = def_gp.io[i]; // Copy user template settings
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_module_flag = ModuleFlag();
|
my_module_flag = ModuleFlag();
|
||||||
|
|
|
@ -335,8 +335,10 @@ typedef struct MYCFGIO {
|
||||||
uint8_t io[MAX_GPIO_PIN - MIN_FLASH_PINS];
|
uint8_t io[MAX_GPIO_PIN - MIN_FLASH_PINS];
|
||||||
} mycfgio;
|
} mycfgio;
|
||||||
|
|
||||||
|
#define GPIO_FLAG_USED 1 // Currently only one flag used
|
||||||
|
|
||||||
#define GPIO_FLAG_ADC0 1 // Allow ADC0 when define USE_ADC_VCC is disabled
|
#define GPIO_FLAG_ADC0 1 // Allow ADC0 when define USE_ADC_VCC is disabled
|
||||||
#define GPIO_FLAG_PULLUP 2 // Allow input pull-up control using SetOption62
|
#define GPIO_FLAG_SPARE01 2 // Allow input pull-up control using SetOption62 - Superseded by user template editing
|
||||||
#define GPIO_FLAG_SPARE02 4
|
#define GPIO_FLAG_SPARE02 4
|
||||||
#define GPIO_FLAG_SPARE03 8
|
#define GPIO_FLAG_SPARE03 8
|
||||||
#define GPIO_FLAG_SPARE04 16
|
#define GPIO_FLAG_SPARE04 16
|
||||||
|
@ -348,7 +350,7 @@ typedef union {
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
struct {
|
struct {
|
||||||
uint8_t adc0 : 1; // Allow ADC0 when define USE_ADC_VCC is disabled
|
uint8_t adc0 : 1; // Allow ADC0 when define USE_ADC_VCC is disabled
|
||||||
uint8_t pullup : 1; // Allow input pull-up control using SetOption62
|
uint8_t spare01 : 1;
|
||||||
uint8_t spare02 : 1;
|
uint8_t spare02 : 1;
|
||||||
uint8_t spare03 : 1;
|
uint8_t spare03 : 1;
|
||||||
uint8_t spare04 : 1;
|
uint8_t spare04 : 1;
|
||||||
|
@ -974,7 +976,6 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||||
GPIO_USER, // GPIO15 D8
|
GPIO_USER, // GPIO15 D8
|
||||||
GPIO_USER, // GPIO16 D0 Wemos Wake
|
GPIO_USER, // GPIO16 D0 Wemos Wake
|
||||||
GPIO_FLAG_ADC0 // ADC0 A0 Analog input
|
GPIO_FLAG_ADC0 // ADC0 A0 Analog input
|
||||||
// + GPIO_FLAG_PULLUP // Allow input pull-up control
|
|
||||||
},
|
},
|
||||||
{ "Sonoff Dev", // Sonoff Dev (ESP8266)
|
{ "Sonoff Dev", // Sonoff Dev (ESP8266)
|
||||||
GPIO_KEY1, // GPIO00 E-FW Button
|
GPIO_KEY1, // GPIO00 E-FW Button
|
||||||
|
@ -1503,7 +1504,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||||
GPIO_SWT2, // GPIO14
|
GPIO_SWT2, // GPIO14
|
||||||
GPIO_MCP39F5_RST, // GPIO15 MCP39F501 Reset
|
GPIO_MCP39F5_RST, // GPIO15 MCP39F501 Reset
|
||||||
0,
|
0,
|
||||||
GPIO_FLAG_PULLUP // Allow input pull-up control
|
0
|
||||||
},
|
},
|
||||||
{ "Xiaomi Philips", // Xiaomi Philips bulb (ESP8266)
|
{ "Xiaomi Philips", // Xiaomi Philips bulb (ESP8266)
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef _SONOFF_VERSION_H_
|
#ifndef _SONOFF_VERSION_H_
|
||||||
#define _SONOFF_VERSION_H_
|
#define _SONOFF_VERSION_H_
|
||||||
|
|
||||||
#define VERSION 0x06040110
|
#define VERSION 0x06040112
|
||||||
|
|
||||||
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
||||||
#define D_AUTHOR "Theo Arends"
|
#define D_AUTHOR "Theo Arends"
|
||||||
|
|
|
@ -154,7 +154,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CharToDouble(char *str)
|
double CharToDouble(const char *str)
|
||||||
{
|
{
|
||||||
// simple ascii to double, because atof or strtod are too large
|
// simple ascii to double, because atof or strtod are too large
|
||||||
char strbuf[24];
|
char strbuf[24];
|
||||||
|
@ -305,27 +305,6 @@ char* UpperCase_P(char* dest, const char* source)
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
char* LTrim(char* p)
|
|
||||||
{
|
|
||||||
while ((*p != '\0') && (isblank(*p))) {
|
|
||||||
p++; // Trim leading spaces
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* RTrim(char* p)
|
|
||||||
{
|
|
||||||
char* q = p + strlen(p) -1;
|
|
||||||
while ((q >= p) && (isblank(*q))) {
|
|
||||||
q--; // Trim trailing spaces
|
|
||||||
}
|
|
||||||
q++;
|
|
||||||
*q = '\0';
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
char* Trim(char* p)
|
char* Trim(char* p)
|
||||||
{
|
{
|
||||||
while ((*p != '\0') && isblank(*p)) { p++; } // Trim leading spaces
|
while ((*p != '\0') && isblank(*p)) { p++; } // Trim leading spaces
|
||||||
|
@ -505,162 +484,6 @@ String PressureUnit(void)
|
||||||
return (Settings.flag.pressure_conversion) ? String(D_UNIT_MILLIMETER_MERCURY) : String(D_UNIT_PRESSURE);
|
return (Settings.flag.pressure_conversion) ? String(D_UNIT_MILLIMETER_MERCURY) : String(D_UNIT_PRESSURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String AnyModuleName(uint8_t index)
|
|
||||||
{
|
|
||||||
if (USER_MODULE == index) {
|
|
||||||
return String(Settings.user_template.name);
|
|
||||||
} else {
|
|
||||||
return FPSTR(kModules[index].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String ModuleName()
|
|
||||||
{
|
|
||||||
return AnyModuleName(Settings.module);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleGpios(myio *gp)
|
|
||||||
{
|
|
||||||
uint8_t *dest = (uint8_t *)gp;
|
|
||||||
memset(dest, GPIO_NONE, sizeof(myio));
|
|
||||||
|
|
||||||
uint8_t src[sizeof(mycfgio)];
|
|
||||||
if (USER_MODULE == Settings.module) {
|
|
||||||
// src = Settings.user_template.gp;
|
|
||||||
memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio));
|
|
||||||
} else {
|
|
||||||
memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio));
|
|
||||||
}
|
|
||||||
// 11 85 00 85 85 00 00 00 15 38 85 00 00 81
|
|
||||||
|
|
||||||
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&src, sizeof(mycfgio));
|
|
||||||
|
|
||||||
uint8_t j = 0;
|
|
||||||
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
|
|
||||||
if (6 == i) { j = 9; }
|
|
||||||
if (8 == i) { j = 12; }
|
|
||||||
dest[j] = src[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
// 11 85 00 85 85 00 00 00 00 00 00 00 15 38 85 00 00 81
|
|
||||||
|
|
||||||
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)gp, sizeof(myio));
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_flag ModuleFlag()
|
|
||||||
{
|
|
||||||
gpio_flag flag;
|
|
||||||
|
|
||||||
if (USER_MODULE == Settings.module) {
|
|
||||||
flag = Settings.user_template.flag;
|
|
||||||
} else {
|
|
||||||
memcpy_P(&flag, &kModules[Settings.module].flag, sizeof(gpio_flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleDefault(uint8_t module)
|
|
||||||
{
|
|
||||||
if (USER_MODULE == module) { module = WEMOS; } // Generic
|
|
||||||
Settings.user_template_base = module;
|
|
||||||
memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetModuleType()
|
|
||||||
{
|
|
||||||
my_module_type = (USER_MODULE == Settings.module) ? Settings.user_template_base : Settings.module;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ValidPin(uint8_t pin, uint8_t gpio)
|
|
||||||
{
|
|
||||||
uint8_t result = gpio;
|
|
||||||
if ((pin > 5) && (pin < 12)) {
|
|
||||||
result = GPIO_NONE; // Disable all flash pins
|
|
||||||
}
|
|
||||||
if (Settings.flag3.user_esp8285_enable) {
|
|
||||||
if ((pin == 9) || (pin == 10)) {
|
|
||||||
result = gpio; // Allow optional flash pins
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ValidGPIO(uint8_t pin, uint8_t gpio)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (USER_MODULE == Settings.module) {
|
|
||||||
result = (ValidPin(pin, gpio) > GPIO_NONE); // Allow any pin
|
|
||||||
} else {
|
|
||||||
result = (GPIO_USER == ValidPin(pin, gpio)); // Only allow GPIO_USER pins
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetUsedInModule(uint8_t val, uint8_t *arr)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
if (USER_MODULE == Settings.module) { return false; }
|
|
||||||
|
|
||||||
if (!val) { return false; } // None
|
|
||||||
|
|
||||||
if ((val >= GPIO_KEY1) && (val < GPIO_KEY1 + MAX_KEYS)) {
|
|
||||||
offset = (GPIO_KEY1_NP - GPIO_KEY1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_KEY1_NP) && (val < GPIO_KEY1_NP + MAX_KEYS)) {
|
|
||||||
offset = -(GPIO_KEY1_NP - GPIO_KEY1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_KEY1_INV) && (val < GPIO_KEY1_INV + MAX_KEYS)) {
|
|
||||||
offset = -(GPIO_KEY1_INV - GPIO_KEY1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_KEY1_INV_NP) && (val < GPIO_KEY1_INV_NP + MAX_KEYS)) {
|
|
||||||
offset = -(GPIO_KEY1_INV_NP - GPIO_KEY1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val >= GPIO_SWT1) && (val < GPIO_SWT1 + MAX_SWITCHES)) {
|
|
||||||
offset = (GPIO_SWT1_NP - GPIO_SWT1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_SWT1_NP) && (val < GPIO_SWT1_NP + MAX_SWITCHES)) {
|
|
||||||
offset = -(GPIO_SWT1_NP - GPIO_SWT1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
|
|
||||||
offset = (GPIO_REL1_INV - GPIO_REL1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_REL1_INV) && (val < GPIO_REL1_INV + MAX_RELAYS)) {
|
|
||||||
offset = -(GPIO_REL1_INV - GPIO_REL1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val >= GPIO_LED1) && (val < GPIO_LED1 + MAX_LEDS)) {
|
|
||||||
offset = (GPIO_LED1_INV - GPIO_LED1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_LED1_INV) && (val < GPIO_LED1_INV + MAX_LEDS)) {
|
|
||||||
offset = -(GPIO_LED1_INV - GPIO_LED1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val >= GPIO_PWM1) && (val < GPIO_PWM1 + MAX_PWMS)) {
|
|
||||||
offset = (GPIO_PWM1_INV - GPIO_PWM1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) {
|
|
||||||
offset = -(GPIO_PWM1_INV - GPIO_PWM1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val >= GPIO_CNTR1) && (val < GPIO_CNTR1 + MAX_COUNTERS)) {
|
|
||||||
offset = (GPIO_CNTR1_NP - GPIO_CNTR1);
|
|
||||||
}
|
|
||||||
if ((val >= GPIO_CNTR1_NP) && (val < GPIO_CNTR1_NP + MAX_COUNTERS)) {
|
|
||||||
offset = -(GPIO_CNTR1_NP - GPIO_CNTR1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MAX_GPIO_PIN; i++) {
|
|
||||||
if (arr[i] == val) { return true; }
|
|
||||||
if (arr[i] == val + offset) { return true; }
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetGlobalValues(float temperature, float humidity)
|
void SetGlobalValues(float temperature, float humidity)
|
||||||
{
|
{
|
||||||
global_update = uptime;
|
global_update = uptime;
|
||||||
|
@ -872,6 +695,200 @@ void ShowSource(int source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* GPIO Module and Template management
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
uint8_t ModuleNr()
|
||||||
|
{
|
||||||
|
// 0 = User module (255)
|
||||||
|
// 1 up = Template module 0 up
|
||||||
|
return (USER_MODULE == Settings.module) ? 0 : Settings.module +1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String AnyModuleName(uint8_t index)
|
||||||
|
{
|
||||||
|
if (USER_MODULE == index) {
|
||||||
|
return String(Settings.user_template.name);
|
||||||
|
} else {
|
||||||
|
return FPSTR(kModules[index].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String ModuleName()
|
||||||
|
{
|
||||||
|
return AnyModuleName(Settings.module);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModuleGpios(myio *gp)
|
||||||
|
{
|
||||||
|
uint8_t *dest = (uint8_t *)gp;
|
||||||
|
memset(dest, GPIO_NONE, sizeof(myio));
|
||||||
|
|
||||||
|
uint8_t src[sizeof(mycfgio)];
|
||||||
|
if (USER_MODULE == Settings.module) {
|
||||||
|
memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio));
|
||||||
|
} else {
|
||||||
|
memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio));
|
||||||
|
}
|
||||||
|
// 11 85 00 85 85 00 00 00 15 38 85 00 00 81
|
||||||
|
|
||||||
|
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&src, sizeof(mycfgio));
|
||||||
|
|
||||||
|
uint8_t j = 0;
|
||||||
|
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
|
||||||
|
if (6 == i) { j = 9; }
|
||||||
|
if (8 == i) { j = 12; }
|
||||||
|
dest[j] = src[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
// 11 85 00 85 85 00 00 00 00 00 00 00 15 38 85 00 00 81
|
||||||
|
|
||||||
|
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)gp, sizeof(myio));
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_flag ModuleFlag()
|
||||||
|
{
|
||||||
|
gpio_flag flag;
|
||||||
|
|
||||||
|
if (USER_MODULE == Settings.module) {
|
||||||
|
flag = Settings.user_template.flag;
|
||||||
|
} else {
|
||||||
|
memcpy_P(&flag, &kModules[Settings.module].flag, sizeof(gpio_flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModuleDefault(uint8_t module)
|
||||||
|
{
|
||||||
|
if (USER_MODULE == module) { module = WEMOS; } // Generic
|
||||||
|
Settings.user_template_base = module;
|
||||||
|
memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetModuleType()
|
||||||
|
{
|
||||||
|
my_module_type = (USER_MODULE == Settings.module) ? Settings.user_template_base : Settings.module;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ValidPin(uint8_t pin, uint8_t gpio)
|
||||||
|
{
|
||||||
|
uint8_t result = gpio;
|
||||||
|
|
||||||
|
if (((pin > 5) && (pin < 9)) || (11 == pin)) {
|
||||||
|
result = GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
|
||||||
|
}
|
||||||
|
if ((WEMOS == Settings.module) && (!Settings.flag3.user_esp8285_enable)) {
|
||||||
|
if ((pin == 9) || (pin == 10)) { result = GPIO_NONE; } // Disable possible flash GPIO9 and GPIO10
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ValidGPIO(uint8_t pin, uint8_t gpio)
|
||||||
|
{
|
||||||
|
return (GPIO_USER == ValidPin(pin, gpio)); // Only allow GPIO_USER pins
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetUsedInModule(uint8_t val, uint8_t *arr)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
if (!val) { return false; } // None
|
||||||
|
|
||||||
|
if ((val >= GPIO_KEY1) && (val < GPIO_KEY1 + MAX_KEYS)) {
|
||||||
|
offset = (GPIO_KEY1_NP - GPIO_KEY1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_KEY1_NP) && (val < GPIO_KEY1_NP + MAX_KEYS)) {
|
||||||
|
offset = -(GPIO_KEY1_NP - GPIO_KEY1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_KEY1_INV) && (val < GPIO_KEY1_INV + MAX_KEYS)) {
|
||||||
|
offset = -(GPIO_KEY1_INV - GPIO_KEY1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_KEY1_INV_NP) && (val < GPIO_KEY1_INV_NP + MAX_KEYS)) {
|
||||||
|
offset = -(GPIO_KEY1_INV_NP - GPIO_KEY1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val >= GPIO_SWT1) && (val < GPIO_SWT1 + MAX_SWITCHES)) {
|
||||||
|
offset = (GPIO_SWT1_NP - GPIO_SWT1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_SWT1_NP) && (val < GPIO_SWT1_NP + MAX_SWITCHES)) {
|
||||||
|
offset = -(GPIO_SWT1_NP - GPIO_SWT1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
|
||||||
|
offset = (GPIO_REL1_INV - GPIO_REL1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_REL1_INV) && (val < GPIO_REL1_INV + MAX_RELAYS)) {
|
||||||
|
offset = -(GPIO_REL1_INV - GPIO_REL1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val >= GPIO_LED1) && (val < GPIO_LED1 + MAX_LEDS)) {
|
||||||
|
offset = (GPIO_LED1_INV - GPIO_LED1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_LED1_INV) && (val < GPIO_LED1_INV + MAX_LEDS)) {
|
||||||
|
offset = -(GPIO_LED1_INV - GPIO_LED1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val >= GPIO_PWM1) && (val < GPIO_PWM1 + MAX_PWMS)) {
|
||||||
|
offset = (GPIO_PWM1_INV - GPIO_PWM1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) {
|
||||||
|
offset = -(GPIO_PWM1_INV - GPIO_PWM1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val >= GPIO_CNTR1) && (val < GPIO_CNTR1 + MAX_COUNTERS)) {
|
||||||
|
offset = (GPIO_CNTR1_NP - GPIO_CNTR1);
|
||||||
|
}
|
||||||
|
if ((val >= GPIO_CNTR1_NP) && (val < GPIO_CNTR1_NP + MAX_COUNTERS)) {
|
||||||
|
offset = -(GPIO_CNTR1_NP - GPIO_CNTR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
|
if (arr[i] == val) { return true; }
|
||||||
|
if (arr[i] == val + offset) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonTemplate(const char* dataBuf)
|
||||||
|
{
|
||||||
|
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
|
||||||
|
JsonObject& obj = jb.parseObject(dataBuf);
|
||||||
|
if (!obj.success()) { return false; }
|
||||||
|
|
||||||
|
// All parameters are optional allowing for partial changes
|
||||||
|
const char* name = obj[D_JSON_NAME];
|
||||||
|
if (name != nullptr) {
|
||||||
|
strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name));
|
||||||
|
}
|
||||||
|
if (obj[D_JSON_GPIO].success()) {
|
||||||
|
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
|
||||||
|
Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj[D_JSON_FLAG].success()) {
|
||||||
|
uint8_t flag = obj[D_JSON_FLAG] | 0;
|
||||||
|
memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag));
|
||||||
|
}
|
||||||
|
if (obj[D_JSON_BASE].success()) {
|
||||||
|
uint8_t base = obj[D_JSON_BASE];
|
||||||
|
if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; }
|
||||||
|
Settings.user_template_base = base; // Default WEMOS
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TemplateJson()
|
||||||
|
{
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
|
||||||
|
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", Settings.user_template.gp.io[i]);
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"),
|
||||||
|
mqtt_data, Settings.user_template.flag, Settings.user_template_base +1);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Sleep aware time scheduler functions borrowed from ESPEasy
|
* Sleep aware time scheduler functions borrowed from ESPEasy
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
|
@ -50,12 +50,6 @@ void ButtonInvertFlag(uint8 button_bit)
|
||||||
|
|
||||||
void ButtonInit(void)
|
void ButtonInit(void)
|
||||||
{
|
{
|
||||||
if (my_module_flag.pullup) {
|
|
||||||
if (Settings.flag3.no_pullup) {
|
|
||||||
key_no_pullup = 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons_found = 0;
|
buttons_found = 0;
|
||||||
for (uint8_t i = 0; i < MAX_KEYS; i++) {
|
for (uint8_t i = 0; i < MAX_KEYS; i++) {
|
||||||
if (pin[GPIO_KEY1 +i] < 99) {
|
if (pin[GPIO_KEY1 +i] < 99) {
|
||||||
|
|
|
@ -87,6 +87,23 @@ String GetTimeZone(void)
|
||||||
return String(tz); // -03:45
|
return String(tz); // -03:45
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String GetDuration(uint32_t time)
|
||||||
|
{
|
||||||
|
char dt[16];
|
||||||
|
|
||||||
|
TIME_T ut;
|
||||||
|
BreakTime(time, ut);
|
||||||
|
|
||||||
|
// "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations
|
||||||
|
// snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second);
|
||||||
|
|
||||||
|
// "128 14:35:44" - OpenVMS
|
||||||
|
// "128T14:35:44" - Tasmota
|
||||||
|
snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), ut.days, ut.hour, ut.minute, ut.second);
|
||||||
|
|
||||||
|
return String(dt); // 128T14:35:44
|
||||||
|
}
|
||||||
|
|
||||||
String GetDT(uint32_t time)
|
String GetDT(uint32_t time)
|
||||||
{
|
{
|
||||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||||
|
@ -155,42 +172,26 @@ String GetTime(int type)
|
||||||
return String(stime); // Thu Nov 01 11:41:02 2018
|
return String(stime); // Thu Nov 01 11:41:02 2018
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t UpTime(void)
|
||||||
|
{
|
||||||
|
if (restart_time) {
|
||||||
|
return utc_time - restart_time;
|
||||||
|
} else {
|
||||||
|
return uptime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MinutesUptime(void)
|
||||||
|
{
|
||||||
|
return (UpTime() / 60);
|
||||||
|
}
|
||||||
|
|
||||||
String GetUptime(void)
|
String GetUptime(void)
|
||||||
{
|
{
|
||||||
char dt[16];
|
return GetDuration(UpTime());
|
||||||
|
|
||||||
TIME_T ut;
|
|
||||||
|
|
||||||
if (restart_time) {
|
|
||||||
BreakTime(utc_time - restart_time, ut);
|
|
||||||
} else {
|
|
||||||
BreakTime(uptime, ut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations
|
uint32_t MinutesPastMidnight(void)
|
||||||
// snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second);
|
|
||||||
|
|
||||||
// "128 14:35:44" - OpenVMS
|
|
||||||
// "128T14:35:44" - Tasmota
|
|
||||||
snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), ut.days, ut.hour, ut.minute, ut.second);
|
|
||||||
|
|
||||||
return String(dt); // 128T14:35:44
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetMinutesUptime(void)
|
|
||||||
{
|
|
||||||
TIME_T ut;
|
|
||||||
|
|
||||||
if (restart_time) {
|
|
||||||
BreakTime(utc_time - restart_time, ut);
|
|
||||||
} else {
|
|
||||||
BreakTime(uptime, ut);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ut.days *1440) + (ut.hour *60) + ut.minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetMinutesPastMidnight(void)
|
|
||||||
{
|
{
|
||||||
uint32_t minutes = 0;
|
uint32_t minutes = 0;
|
||||||
|
|
||||||
|
@ -322,6 +323,11 @@ uint32_t RuleToTime(TimeRule r, int yr)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t UtcTime(void)
|
||||||
|
{
|
||||||
|
return utc_time;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t LocalTime(void)
|
uint32_t LocalTime(void)
|
||||||
{
|
{
|
||||||
return local_time;
|
return local_time;
|
||||||
|
|
|
@ -110,12 +110,6 @@ void SwitchProbe(void)
|
||||||
|
|
||||||
void SwitchInit(void)
|
void SwitchInit(void)
|
||||||
{
|
{
|
||||||
if (my_module_flag.pullup) {
|
|
||||||
if (Settings.flag3.no_pullup) {
|
|
||||||
switch_no_pullup = 0xffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switches_found = 0;
|
switches_found = 0;
|
||||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||||
lastwallswitch[i] = 1; // Init global to virtual switch state;
|
lastwallswitch[i] = 1; // Init global to virtual switch state;
|
||||||
|
|
|
@ -49,6 +49,9 @@ using namespace axTLS;
|
||||||
*/
|
*/
|
||||||
#include <ESP8266WiFi.h> // Wifi, MQTT, Ota, WifiManager
|
#include <ESP8266WiFi.h> // Wifi, MQTT, Ota, WifiManager
|
||||||
|
|
||||||
|
uint32_t wifi_last_event = 0; // Last wifi connection event
|
||||||
|
uint32_t wifi_downtime = 0; // Wifi down duration
|
||||||
|
uint16_t wifi_link_count = 0; // Number of wifi re-connect
|
||||||
uint8_t wifi_counter;
|
uint8_t wifi_counter;
|
||||||
uint8_t wifi_retry_init;
|
uint8_t wifi_retry_init;
|
||||||
uint8_t wifi_retry;
|
uint8_t wifi_retry;
|
||||||
|
@ -171,9 +174,9 @@ void WifiConfig(uint8_t type)
|
||||||
}
|
}
|
||||||
#endif // USE_WPS
|
#endif // USE_WPS
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
else if (WIFI_MANAGER == wifi_config_type) {
|
else if (WIFI_MANAGER == wifi_config_type || WIFI_MANAGER_RESET_ONLY == wifi_config_type) {
|
||||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES));
|
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES));
|
||||||
WifiManagerBegin();
|
WifiManagerBegin(WIFI_MANAGER_RESET_ONLY == wifi_config_type);
|
||||||
}
|
}
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
|
@ -222,7 +225,8 @@ void WifiBegin(uint8_t flag, uint8_t channel)
|
||||||
delay(200);
|
delay(200);
|
||||||
WiFi.mode(WIFI_STA); // Disable AP mode
|
WiFi.mode(WIFI_STA); // Disable AP mode
|
||||||
WiFiSetSleepMode();
|
WiFiSetSleepMode();
|
||||||
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); }
|
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N
|
||||||
|
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11G) { WiFi.setPhyMode(WIFI_PHY_MODE_11G); } // B/G
|
||||||
if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); }
|
if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); }
|
||||||
// WiFi.setAutoReconnect(true);
|
// WiFi.setAutoReconnect(true);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
|
@ -339,13 +343,26 @@ void WifiBeginAfterScan()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t WifiLinkCount()
|
||||||
|
{
|
||||||
|
return wifi_link_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
String WifiDowntime()
|
||||||
|
{
|
||||||
|
return GetDuration(wifi_downtime);
|
||||||
|
}
|
||||||
|
|
||||||
void WifiSetState(uint8_t state)
|
void WifiSetState(uint8_t state)
|
||||||
{
|
{
|
||||||
if (state == global_state.wifi_down) {
|
if (state == global_state.wifi_down) {
|
||||||
if (state) {
|
if (state) {
|
||||||
rules_flag.wifi_connected = 1;
|
rules_flag.wifi_connected = 1;
|
||||||
|
wifi_link_count++;
|
||||||
|
wifi_downtime += UpTime() - wifi_last_event;
|
||||||
} else {
|
} else {
|
||||||
rules_flag.wifi_disconnected = 1;
|
rules_flag.wifi_disconnected = 1;
|
||||||
|
wifi_last_event = UpTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_state.wifi_down = state ^1;
|
global_state.wifi_down = state ^1;
|
||||||
|
|
|
@ -66,6 +66,7 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM =
|
||||||
"setTimeout(u,1000);"
|
"setTimeout(u,1000);"
|
||||||
"}"
|
"}"
|
||||||
"}"
|
"}"
|
||||||
|
"window.onload=u;"
|
||||||
"</script>";
|
"</script>";
|
||||||
|
|
||||||
const char HTTP_SCRIPT_ROOT[] PROGMEM =
|
const char HTTP_SCRIPT_ROOT[] PROGMEM =
|
||||||
|
@ -92,7 +93,8 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM =
|
||||||
"}"
|
"}"
|
||||||
"function lc(p){"
|
"function lc(p){"
|
||||||
"la('?t='+p);" // ?t related to WebGetArg("t", tmp, sizeof(tmp));
|
"la('?t='+p);" // ?t related to WebGetArg("t", tmp, sizeof(tmp));
|
||||||
"}";
|
"}"
|
||||||
|
"window.onload=la();";
|
||||||
|
|
||||||
const char HTTP_SCRIPT_WIFI[] PROGMEM =
|
const char HTTP_SCRIPT_WIFI[] PROGMEM =
|
||||||
"function c(l){"
|
"function c(l){"
|
||||||
|
@ -144,33 +146,80 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM =
|
||||||
"lt=setTimeout(l,{a});"
|
"lt=setTimeout(l,{a});"
|
||||||
"return false;"
|
"return false;"
|
||||||
"}"
|
"}"
|
||||||
|
"window.onload=l;"
|
||||||
"</script>";
|
"</script>";
|
||||||
const char HTTP_SCRIPT_MODULE1[] PROGMEM =
|
|
||||||
|
const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM =
|
||||||
"var os;"
|
"var os;"
|
||||||
"function sk(s,g){" // s = value, g = id and name
|
"function sk(s,g){" // s = value, g = id and name
|
||||||
"var o=os.replace(/}1/g,\"<option value=\").replace(/}2/g,\"</option>\").replace(\"value='\"+s+\"'\",\"selected value='\"+s+\"'\");"
|
"var o=os.replace(/}1/g,\"<option value=\").replace(/}2/g,\"</option>\");"
|
||||||
"eb('g'+g).innerHTML=o;"
|
"eb('g'+g).innerHTML=o;"
|
||||||
|
"eb('g'+g).value=s;"
|
||||||
"}"
|
"}"
|
||||||
"function sl(){"
|
"function ld(u,f){"
|
||||||
"a=new XMLHttpRequest();"
|
"var x=new XMLHttpRequest();"
|
||||||
"a.onreadystatechange=function(){"
|
"x.onreadystatechange=function(){"
|
||||||
"if(a.readyState==4&&a.status==200){"
|
"if(this.readyState==4&&this.status==200){"
|
||||||
|
"f(this);"
|
||||||
|
"}"
|
||||||
|
"};"
|
||||||
|
"x.open('GET',u,true);"
|
||||||
|
"x.send();"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
const char HTTP_SCRIPT_TEMPLATE[] PROGMEM =
|
||||||
|
"var c;" // Need a global for BASE
|
||||||
|
"function x1(b){"
|
||||||
|
"var i,j,g,k,m,o=b.responseText;"
|
||||||
|
"k=o.indexOf(\"}1\");" // Template name until }1
|
||||||
|
"if(eb('s1').value==''){"
|
||||||
|
"eb('s1').value=o.substring(0,k);" // Set NAME if not yet set
|
||||||
|
"}"
|
||||||
|
"m=o.indexOf(\"}3\");" // Sensor names until }3
|
||||||
|
"os=o.substring(k,m);" // Complete GPIO sensor list
|
||||||
|
"g=o.substring(m+2).split(',');" // +2 is length "}3"
|
||||||
|
"j=0;"
|
||||||
|
"for(i=0;i<13;i++){" // Supports 13 GPIOs
|
||||||
|
"if(6==i){j=9;}"
|
||||||
|
"if(8==i){j=12;}"
|
||||||
|
"sk(g[i],j);" // Set GPIO
|
||||||
|
"j++;"
|
||||||
|
"}"
|
||||||
|
"for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){"
|
||||||
|
"p=(g[13]>>i)&1;"
|
||||||
|
"eb('c'+i).checked=p;" // Set FLAG checkboxes
|
||||||
|
"}"
|
||||||
|
"if(" STR(USER_MODULE) "==c){"
|
||||||
|
"eb('g99').value=g[14];" // Set BASE for initial select
|
||||||
|
"}"
|
||||||
|
"}"
|
||||||
|
"function st(t){"
|
||||||
|
"c=t;" // Needed for initial BASE select
|
||||||
|
"var a='tp?t='+t;"
|
||||||
|
"ld(a,x1);" // ?t related to WebGetArg("t", stemp, sizeof(stemp));
|
||||||
|
"}"
|
||||||
|
|
||||||
|
"function x2(a){"
|
||||||
|
"os=a.responseText;"
|
||||||
|
"sk(17,99);" // 17 = WEMOS
|
||||||
|
"st(" STR(USER_MODULE) ");"
|
||||||
|
"}"
|
||||||
|
"window.onload=ld('tp?m=1',x2);"; // ?m related to WebServer->hasArg("m")
|
||||||
|
|
||||||
|
const char HTTP_SCRIPT_MODULE1[] PROGMEM =
|
||||||
|
"function x1(a){"
|
||||||
"os=a.responseText;"
|
"os=a.responseText;"
|
||||||
"sk(}4,99);"
|
"sk(}4,99);"
|
||||||
"}"
|
"}"
|
||||||
"};"
|
"function x2(b){"
|
||||||
"a.open('GET','md?m=1',true);" // ?m related to WebServer->hasArg("m")
|
|
||||||
"a.send();"
|
|
||||||
"b=new XMLHttpRequest();"
|
|
||||||
"b.onreadystatechange=function(){"
|
|
||||||
"if(b.readyState==4&&b.status==200){"
|
|
||||||
"os=b.responseText;";
|
"os=b.responseText;";
|
||||||
const char HTTP_SCRIPT_MODULE2[] PROGMEM =
|
const char HTTP_SCRIPT_MODULE2[] PROGMEM =
|
||||||
"}"
|
"}"
|
||||||
"};"
|
"function sl(){"
|
||||||
"b.open('GET','md?g=1',true);" // ?g related to WebServer->hasArg("g")
|
"ld('md?m=1',x1);" // ?m related to WebServer->hasArg("m")
|
||||||
"b.send();"
|
"ld('md?g=1',x2);" // ?m related to WebServer->hasArg("m")
|
||||||
"}";
|
"}"
|
||||||
|
"window.onload=sl;";
|
||||||
const char HTTP_SCRIPT_MODULE3[] PROGMEM =
|
const char HTTP_SCRIPT_MODULE3[] PROGMEM =
|
||||||
"}1'%d'>%s (%d)}2"; // "}1" and "}2" means do not use "}x" in Module name and Sensor name
|
"}1'%d'>%s (%d)}2"; // "}1" and "}2" means do not use "}x" in Module name and Sensor name
|
||||||
|
|
||||||
|
@ -182,6 +231,7 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM =
|
||||||
"s=o.replace(/}1/g,\"</td></tr><tr><th>\").replace(/}2/g,\"</th><td>\");"
|
"s=o.replace(/}1/g,\"</td></tr><tr><th>\").replace(/}2/g,\"</th><td>\");"
|
||||||
"eb('i').innerHTML=s;"
|
"eb('i').innerHTML=s;"
|
||||||
"}"
|
"}"
|
||||||
|
"window.onload=i;"
|
||||||
"</script>";
|
"</script>";
|
||||||
|
|
||||||
const char HTTP_HEAD_STYLE[] PROGMEM =
|
const char HTTP_HEAD_STYLE[] PROGMEM =
|
||||||
|
@ -189,7 +239,10 @@ const char HTTP_HEAD_STYLE[] PROGMEM =
|
||||||
|
|
||||||
"<style>"
|
"<style>"
|
||||||
"div,fieldset,input,select{padding:5px;font-size:1em;}"
|
"div,fieldset,input,select{padding:5px;font-size:1em;}"
|
||||||
|
"fieldset{background-color:#f2f2f2;}" // Also update HTTP_TIMER_STYLE
|
||||||
|
"p{margin:0.5em 0;}"
|
||||||
"input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;}"
|
"input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;}"
|
||||||
|
"input[type=checkbox],input[type=radio]{width:1em;margin-right:6px;vertical-align:-1px;}"
|
||||||
"select{width:100%;}"
|
"select{width:100%;}"
|
||||||
"textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}"
|
"textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}"
|
||||||
"body{text-align:center;font-family:verdana;}"
|
"body{text-align:center;font-family:verdana;}"
|
||||||
|
@ -226,82 +279,121 @@ const char HTTP_MSG_SLIDER2[] PROGMEM =
|
||||||
"<div><input type='range' min='1' max='100' value='%d' onchange='lb(value)'></div>";
|
"<div><input type='range' min='1' max='100' value='%d' onchange='lb(value)'></div>";
|
||||||
const char HTTP_MSG_RSTRT[] PROGMEM =
|
const char HTTP_MSG_RSTRT[] PROGMEM =
|
||||||
"<br/><div style='text-align:center;'>" D_DEVICE_WILL_RESTART "</div><br/>";
|
"<br/><div style='text-align:center;'>" D_DEVICE_WILL_RESTART "</div><br/>";
|
||||||
|
|
||||||
const char HTTP_BTN_MENU1[] PROGMEM =
|
const char HTTP_BTN_MENU1[] PROGMEM =
|
||||||
#ifndef FIRMWARE_MINIMAL
|
|
||||||
"<br/><form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>"
|
|
||||||
"<br/><form action='in' method='get'><button>" D_INFORMATION "</button></form>"
|
|
||||||
#endif
|
|
||||||
"<br/><form action='up' method='get'><button>" D_FIRMWARE_UPGRADE "</button></form>"
|
|
||||||
"<br/><form action='cs' method='get'><button>" D_CONSOLE "</button></form>";
|
|
||||||
const char HTTP_BTN_RSTRT[] PROGMEM =
|
|
||||||
"<br/><form action='.' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESTART "\");'><button name='rstrt' class='button bred'>" D_RESTART "</button></form>";
|
|
||||||
const char HTTP_BTN_MENU_MODULE[] PROGMEM =
|
|
||||||
"<br/><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form>"
|
|
||||||
"<br/><form action='wi' method='get'><button>" D_CONFIGURE_WIFI "</button></form>";
|
|
||||||
const char HTTP_BTN_MENU4[] PROGMEM =
|
|
||||||
"<br/><form action='lg' method='get'><button>" D_CONFIGURE_LOGGING "</button></form>"
|
|
||||||
"<br/><form action='co' method='get'><button>" D_CONFIGURE_OTHER "</button></form>"
|
|
||||||
"<br/>"
|
"<br/>"
|
||||||
"<br/><form action='rt' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESET_CONFIGURATION "\");'><button class='button bred'>" D_RESET_CONFIGURATION "</button></form>"
|
#ifndef FIRMWARE_MINIMAL
|
||||||
"<br/><form action='dl' method='get'><button>" D_BACKUP_CONFIGURATION "</button></form>"
|
"<form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>"
|
||||||
"<br/><form action='rs' method='get'><button>" D_RESTORE_CONFIGURATION "</button></form>";
|
"<p><form action='in' method='get'><button>" D_INFORMATION "</button></form></p>"
|
||||||
|
#endif
|
||||||
|
"<form action='up' method='get'><button>" D_FIRMWARE_UPGRADE "</button></form>"
|
||||||
|
"<p><form action='cs' method='get'><button>" D_CONSOLE "</button></form></p>";
|
||||||
|
const char HTTP_BTN_RSTRT[] PROGMEM =
|
||||||
|
"<form action='.' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESTART "\");'><button name='rstrt' class='button bred'>" D_RESTART "</button></form>";
|
||||||
|
|
||||||
|
const char HTTP_BTN_MENU_MODULE[] PROGMEM =
|
||||||
|
"<p><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form></p>"
|
||||||
|
"<p><form action='wi' method='get'><button>" D_CONFIGURE_WIFI "</button></form></p>";
|
||||||
|
const char HTTP_BTN_RESET[] PROGMEM =
|
||||||
|
"<br/>"
|
||||||
|
"<form action='rt' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESET_CONFIGURATION "\");'><button class='button bred'>" D_RESET_CONFIGURATION "</button></form>";
|
||||||
|
const char HTTP_BTN_MENU4[] PROGMEM =
|
||||||
|
"<p><form action='lg' method='get'><button>" D_CONFIGURE_LOGGING "</button></form></p>"
|
||||||
|
"<p><form action='co' method='get'><button>" D_CONFIGURE_OTHER "</button></form></p>"
|
||||||
|
"<p><form action='tp' method='get'><button>" D_CONFIGURE_TEMPLATE "</button></form></p>";
|
||||||
|
const char HTTP_BTN_MENU5[] PROGMEM =
|
||||||
|
"<p><form action='dl' method='get'><button>" D_BACKUP_CONFIGURATION "</button></form></p>"
|
||||||
|
"<p><form action='rs' method='get'><button>" D_RESTORE_CONFIGURATION "</button></form></p>";
|
||||||
const char HTTP_BTN_MAIN[] PROGMEM =
|
const char HTTP_BTN_MAIN[] PROGMEM =
|
||||||
"<br/><br/><form action='.' method='get'><button>" D_MAIN_MENU "</button></form>";
|
"<br/>"
|
||||||
|
"<form action='.' method='get'><button>" D_MAIN_MENU "</button></form>";
|
||||||
|
|
||||||
const char HTTP_FORM_LOGIN[] PROGMEM =
|
const char HTTP_FORM_LOGIN[] PROGMEM =
|
||||||
"<form method='post' action='/'>"
|
"<form method='post' action='/'>"
|
||||||
"<br/><b>" D_USER "</b><br/><input name='USER1' placeholder='" D_USER "'><br/>"
|
"<br/><b>" D_USER "</b><br/><input name='USER1' placeholder='" D_USER "'><br/>"
|
||||||
"<br/><b>" D_PASSWORD "</b><br/><input name='PASS1' type='password' placeholder='" D_PASSWORD "'><br/>"
|
"<br/><b>" D_PASSWORD "</b><br/><input name='PASS1' type='password' placeholder='" D_PASSWORD "'><br/>"
|
||||||
"<br/>"
|
"<br/>"
|
||||||
"<br/><button>" D_OK "</button></form>";
|
"<br/><button>" D_OK "</button></form>";
|
||||||
const char HTTP_BTN_CONF[] PROGMEM =
|
|
||||||
"<br/><br/><form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>";
|
|
||||||
const char HTTP_FORM_MODULE[] PROGMEM =
|
|
||||||
"<fieldset><legend><b> " D_MODULE_PARAMETERS " </b></legend><form method='get' action='md'>"
|
|
||||||
"<br/><b>" D_MODULE_TYPE "</b> ({mt)<br/><select id='g99' name='g99'></select><br/>";
|
|
||||||
|
|
||||||
const char HTTP_FORM_MODULE_PULLUP[] PROGMEM =
|
const char HTTP_BTN_CONF[] PROGMEM =
|
||||||
"<br/><input style='width:10%;' id='b1' name='b1' type='checkbox'{r1><b>" D_PULLUP_ENABLE "</b><br/>";
|
"<br/>"
|
||||||
|
"<form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>";
|
||||||
|
|
||||||
|
const char HTTP_FORM_TEMPLATE[] PROGMEM =
|
||||||
|
"<fieldset><legend><b> " D_TEMPLATE_PARAMETERS " </b></legend>"
|
||||||
|
"<form method='get' action='tp'>"
|
||||||
|
"<p><b>" D_TEMPLATE_NAME "</b><br/><input id='s1' name='s1' placeholder='" D_TEMPLATE_NAME "'></p>"
|
||||||
|
"<p></p><b>" D_BASE_TYPE "</b><br/><select id='g99' name='g99' onchange='st(this.value)'></select><br/>";
|
||||||
|
const char HTTP_FORM_TEMPLATE_FLAG[] PROGMEM =
|
||||||
|
"<p></p>" // Keep close so do not use <br/>
|
||||||
|
"<fieldset><legend><b> " D_TEMPLATE_FLAGS " </b></legend><p>"
|
||||||
|
"<input id='c0' name='c0' type='checkbox'><b>" D_ALLOW_ADC0 "</b><br/>"
|
||||||
|
"</p></fieldset>";
|
||||||
|
|
||||||
|
const char HTTP_FORM_MODULE[] PROGMEM =
|
||||||
|
"<fieldset><legend><b> " D_MODULE_PARAMETERS " </b></legend>"
|
||||||
|
"<form method='get' action='md'>"
|
||||||
|
"<p></p><b>" D_MODULE_TYPE "</b> ({mt)<br/><select id='g99' name='g99'></select><br/>";
|
||||||
|
|
||||||
const char HTTP_LNK_ITEM[] PROGMEM =
|
const char HTTP_LNK_ITEM[] PROGMEM =
|
||||||
"<div><a href='#p' onclick='c(this)'>{v}</a> ({w}) <span class='q'>{i} {r}%</span></div>";
|
"<div><a href='#p' onclick='c(this)'>{v}</a> ({w}) <span class='q'>{i} {r}%</span></div>";
|
||||||
const char HTTP_LNK_SCAN[] PROGMEM =
|
const char HTTP_LNK_SCAN[] PROGMEM =
|
||||||
"<div><a href='/wi?scan='>" D_SCAN_FOR_WIFI_NETWORKS "</a></div><br/>";
|
"<div><a href='/wi?scan='>" D_SCAN_FOR_WIFI_NETWORKS "</a></div><br/>";
|
||||||
const char HTTP_FORM_WIFI[] PROGMEM =
|
const char HTTP_FORM_WIFI[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_WIFI_PARAMETERS " </b></legend><form method='get' action='wi'>"
|
"<fieldset><legend><b> " D_WIFI_PARAMETERS " </b></legend>"
|
||||||
"<br/><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' placeholder='" STA_SSID1 "' value='{s1'><br/>"
|
"<form method='get' action='wi'>"
|
||||||
"<br/><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_AP1_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
"<p><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' placeholder='" STA_SSID1 "' value='{s1'></p>"
|
||||||
"<br/><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' placeholder='" STA_SSID2 "' value='{s2'><br/>"
|
"<p><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_AP1_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
|
||||||
"<br/><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" D_AP2_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
"<p><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' placeholder='" STA_SSID2 "' value='{s2'></p>"
|
||||||
"<br/><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' placeholder='" WIFI_HOSTNAME" ' value='{h1'><br/>";
|
"<p><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" D_AP2_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
|
||||||
|
"<p><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' placeholder='" WIFI_HOSTNAME" ' value='{h1'></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_LOG1[] PROGMEM =
|
const char HTTP_FORM_LOG1[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_LOGGING_PARAMETERS " </b></legend><form method='get' action='lg'>";
|
"<fieldset><legend><b> " D_LOGGING_PARAMETERS " </b>"
|
||||||
|
"</legend><form method='get' action='lg'>";
|
||||||
const char HTTP_FORM_LOG2[] PROGMEM =
|
const char HTTP_FORM_LOG2[] PROGMEM =
|
||||||
"<br/><b>{b0</b> ({b1)<br/><select id='{b2' name='{b2'>"
|
"<p><b>{b0</b> ({b1)<br/><select id='{b2' name='{b2'>"
|
||||||
"<option{a0value='0'>0 " D_NONE "</option>"
|
"<option{a0value='0'>0 " D_NONE "</option>"
|
||||||
"<option{a1value='1'>1 " D_ERROR "</option>"
|
"<option{a1value='1'>1 " D_ERROR "</option>"
|
||||||
"<option{a2value='2'>2 " D_INFO "</option>"
|
"<option{a2value='2'>2 " D_INFO "</option>"
|
||||||
"<option{a3value='3'>3 " D_DEBUG "</option>"
|
"<option{a3value='3'>3 " D_DEBUG "</option>"
|
||||||
"<option{a4value='4'>4 " D_MORE_DEBUG "</option>"
|
"<option{a4value='4'>4 " D_MORE_DEBUG "</option>"
|
||||||
"</select><br/>";
|
"</select></p>";
|
||||||
const char HTTP_FORM_LOG3[] PROGMEM =
|
const char HTTP_FORM_LOG3[] PROGMEM =
|
||||||
"<br/><b>" D_SYSLOG_HOST "</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' placeholder='" SYS_LOG_HOST "' value='{l2'><br/>"
|
"<p><b>" D_SYSLOG_HOST "</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' placeholder='" SYS_LOG_HOST "' value='{l2'></p>"
|
||||||
"<br/><b>" D_SYSLOG_PORT "</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' placeholder='" STR(SYS_LOG_PORT) "' value='{l3'><br/>"
|
"<p><b>" D_SYSLOG_PORT "</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' placeholder='" STR(SYS_LOG_PORT) "' value='{l3'></p>"
|
||||||
"<br/><b>" D_TELEMETRY_PERIOD "</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' placeholder='" STR(TELE_PERIOD) "' value='{l4'><br/>";
|
"<p><b>" D_TELEMETRY_PERIOD "</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' placeholder='" STR(TELE_PERIOD) "' value='{l4'></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_OTHER[] PROGMEM =
|
const char HTTP_FORM_OTHER[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_OTHER_PARAMETERS " </b></legend><form method='get' action='co'>"
|
"<fieldset><legend><b> " D_OTHER_PARAMETERS " </b></legend>"
|
||||||
// "<input id='w' name='w' value='5,1' hidden>"
|
"<form method='get' action='co'>"
|
||||||
"<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_WEB_ADMIN_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
"<p></p>"
|
||||||
"<br/><input style='width:10%;' id='b1' name='b1' type='checkbox'{r1><b>" D_MQTT_ENABLE "</b><br/>";
|
"<fieldset><legend><b> " D_TEMPLATE " </b></legend>"
|
||||||
|
"<p><input id='t1' name='t1' placeholder='" D_TEMPLATE "' value='{t1'></p>"
|
||||||
|
"<p><input id='t2' name='t2' type='checkbox'{t2><b>" D_ACTIVATE "</b></p>"
|
||||||
|
"</fieldset>"
|
||||||
|
"<br/>"
|
||||||
|
"<b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_WEB_ADMIN_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
||||||
|
"<br>"
|
||||||
|
"<input id='b1' name='b1' type='checkbox'{r1><b>" D_MQTT_ENABLE "</b><br/>"
|
||||||
|
"<br/>";
|
||||||
const char HTTP_FORM_OTHER2[] PROGMEM =
|
const char HTTP_FORM_OTHER2[] PROGMEM =
|
||||||
"<br/><b>" D_FRIENDLY_NAME " {1</b> ({2)<br/><input id='a{1' name='a{1' placeholder='{2' value='{3'><br/>";
|
"<b>" D_FRIENDLY_NAME " {1</b> ({2)<br/><input id='a{1' name='a{1' placeholder='{2' value='{3'><p></p>";
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
const char HTTP_FORM_OTHER3a[] PROGMEM =
|
const char HTTP_FORM_OTHER3a[] PROGMEM =
|
||||||
"<br/><fieldset><legend><b> " D_EMULATION " </b></legend>";
|
"<p></p>" // Keep close to Friendlynames so do not use <br/>
|
||||||
|
"<fieldset><legend><b> " D_EMULATION " </b></legend><p>";
|
||||||
const char HTTP_FORM_OTHER3b[] PROGMEM =
|
const char HTTP_FORM_OTHER3b[] PROGMEM =
|
||||||
"<br/><input style='width:10%;' id='r{1' name='b2' type='radio' value='{1'{2><b>{3</b>{4"; // Different id only used for labels
|
"<input id='r{1' name='b2' type='radio' value='{1'{2><b>{3</b>{4<br/>"; // Different id only used for labels
|
||||||
|
const char HTTP_FORM_OTHER3c[] PROGMEM =
|
||||||
|
"</p></fieldset>";
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
|
||||||
const char HTTP_FORM_END[] PROGMEM =
|
const char HTTP_FORM_END[] PROGMEM =
|
||||||
"<br/><button name='save' type='submit' class='button bgrn'>" D_SAVE "</button></form></fieldset>";
|
"<br/>"
|
||||||
|
"<button name='save' type='submit' class='button bgrn'>" D_SAVE "</button>"
|
||||||
|
"</form></fieldset>";
|
||||||
|
|
||||||
const char HTTP_FORM_RST[] PROGMEM =
|
const char HTTP_FORM_RST[] PROGMEM =
|
||||||
"<div id='f1' name='f1' style='display:block;'>"
|
"<div id='f1' name='f1' style='display:block;'>"
|
||||||
"<fieldset><legend><b> " D_RESTORE_CONFIGURATION " </b></legend>";
|
"<fieldset><legend><b> " D_RESTORE_CONFIGURATION " </b></legend>";
|
||||||
|
@ -309,7 +401,7 @@ const char HTTP_FORM_UPG[] PROGMEM =
|
||||||
"<div id='f1' name='f1' style='display:block;'>"
|
"<div id='f1' name='f1' style='display:block;'>"
|
||||||
"<fieldset><legend><b> " D_UPGRADE_BY_WEBSERVER " </b></legend>"
|
"<fieldset><legend><b> " D_UPGRADE_BY_WEBSERVER " </b></legend>"
|
||||||
"<form method='get' action='u1'>"
|
"<form method='get' action='u1'>"
|
||||||
"<br/>" D_OTA_URL "<br/><input id='o' name='o' placeholder='OTA_URL' value='{o1'><br/>"
|
"<br/><b>" D_OTA_URL "</b><br/><input id='o' name='o' placeholder='OTA_URL' value='{o1'><br/>"
|
||||||
"<br/><button type='submit'>" D_START_UPGRADE "</button></form>"
|
"<br/><button type='submit'>" D_START_UPGRADE "</button></form>"
|
||||||
"</fieldset><br/><br/>"
|
"</fieldset><br/><br/>"
|
||||||
"<fieldset><legend><b> " D_UPGRADE_BY_FILE_UPLOAD " </b></legend>";
|
"<fieldset><legend><b> " D_UPGRADE_BY_FILE_UPLOAD " </b></legend>";
|
||||||
|
@ -347,7 +439,7 @@ const char HDR_CTYPE_JSON[] PROGMEM = "application/json";
|
||||||
const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream";
|
const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream";
|
||||||
|
|
||||||
#define DNS_PORT 53
|
#define DNS_PORT 53
|
||||||
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER};
|
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY};
|
||||||
|
|
||||||
DNSServer *DnsServer;
|
DNSServer *DnsServer;
|
||||||
ESP8266WebServer *WebServer;
|
ESP8266WebServer *WebServer;
|
||||||
|
@ -370,6 +462,10 @@ static void WebGetArg(const char* arg, char* out, size_t max)
|
||||||
// out[max-1] = '\0'; // Ensure terminating NUL
|
// out[max-1] = '\0'; // Ensure terminating NUL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool WifiIsInManagerMode(){
|
||||||
|
return (HTTP_MANAGER == webserver_state || HTTP_MANAGER_RESET_ONLY == webserver_state);
|
||||||
|
}
|
||||||
|
|
||||||
void ShowWebSource(int source)
|
void ShowWebSource(int source)
|
||||||
{
|
{
|
||||||
if ((source > 0) && (source < SRC_MAX)) {
|
if ((source > 0) && (source < SRC_MAX)) {
|
||||||
|
@ -390,8 +486,13 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||||
if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; }
|
if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; }
|
||||||
if (!webserver_state) {
|
if (!webserver_state) {
|
||||||
if (!WebServer) {
|
if (!WebServer) {
|
||||||
WebServer = new ESP8266WebServer((HTTP_MANAGER==type) ? 80 : WEB_PORT);
|
WebServer = new ESP8266WebServer((HTTP_MANAGER==type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT);
|
||||||
WebServer->on("/", HandleRoot);
|
WebServer->on("/", HandleRoot);
|
||||||
|
WebServer->onNotFound(HandleNotFound);
|
||||||
|
#ifndef FIRMWARE_MINIMAL
|
||||||
|
WebServer->on("/rt", HandleResetConfiguration);
|
||||||
|
#endif // FIRMWARE_MINIMAL
|
||||||
|
if(HTTP_MANAGER_RESET_ONLY != type){
|
||||||
WebServer->on("/up", HandleUpgradeFirmware);
|
WebServer->on("/up", HandleUpgradeFirmware);
|
||||||
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
||||||
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
||||||
|
@ -400,12 +501,12 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||||
WebServer->on("/ax", HandleAjaxConsoleRefresh);
|
WebServer->on("/ax", HandleAjaxConsoleRefresh);
|
||||||
WebServer->on("/ay", HandleAjaxStatusRefresh);
|
WebServer->on("/ay", HandleAjaxStatusRefresh);
|
||||||
WebServer->on("/cm", HandleHttpCommand);
|
WebServer->on("/cm", HandleHttpCommand);
|
||||||
WebServer->onNotFound(HandleNotFound);
|
|
||||||
#ifndef FIRMWARE_MINIMAL
|
#ifndef FIRMWARE_MINIMAL
|
||||||
WebServer->on("/cn", HandleConfiguration);
|
WebServer->on("/cn", HandleConfiguration);
|
||||||
WebServer->on("/md", HandleModuleConfiguration);
|
WebServer->on("/md", HandleModuleConfiguration);
|
||||||
WebServer->on("/wi", HandleWifiConfiguration);
|
WebServer->on("/wi", HandleWifiConfiguration);
|
||||||
WebServer->on("/lg", HandleLoggingConfiguration);
|
WebServer->on("/lg", HandleLoggingConfiguration);
|
||||||
|
WebServer->on("/tp", HandleTemplateConfiguration);
|
||||||
WebServer->on("/co", HandleOtherConfiguration);
|
WebServer->on("/co", HandleOtherConfiguration);
|
||||||
WebServer->on("/dl", HandleBackupConfiguration);
|
WebServer->on("/dl", HandleBackupConfiguration);
|
||||||
WebServer->on("/rs", HandleRestoreConfiguration);
|
WebServer->on("/rs", HandleRestoreConfiguration);
|
||||||
|
@ -418,6 +519,7 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||||
XsnsCall(FUNC_WEB_ADD_HANDLER);
|
XsnsCall(FUNC_WEB_ADD_HANDLER);
|
||||||
#endif // Not FIRMWARE_MINIMAL
|
#endif // Not FIRMWARE_MINIMAL
|
||||||
}
|
}
|
||||||
|
}
|
||||||
reset_web_log_flag = false;
|
reset_web_log_flag = false;
|
||||||
WebServer->begin(); // Web server start
|
WebServer->begin(); // Web server start
|
||||||
}
|
}
|
||||||
|
@ -438,7 +540,7 @@ void StopWebserver(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiManagerBegin(void)
|
void WifiManagerBegin(bool reset_only)
|
||||||
{
|
{
|
||||||
// setup AP
|
// setup AP
|
||||||
if (!global_state.wifi_down) {
|
if (!global_state.wifi_down) {
|
||||||
|
@ -462,7 +564,7 @@ void WifiManagerBegin(void)
|
||||||
DnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
DnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
||||||
DnsServer->start(DNS_PORT, "*", WiFi.softAPIP());
|
DnsServer->start(DNS_PORT, "*", WiFi.softAPIP());
|
||||||
|
|
||||||
StartWebserver(HTTP_MANAGER, WiFi.softAPIP());
|
StartWebserver((reset_only ? HTTP_MANAGER_RESET_ONLY : HTTP_MANAGER), WiFi.softAPIP());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollDnsWebserver(void)
|
void PollDnsWebserver(void)
|
||||||
|
@ -485,7 +587,7 @@ void SetHeader(void)
|
||||||
|
|
||||||
bool WebAuthenticate(void)
|
bool WebAuthenticate(void)
|
||||||
{
|
{
|
||||||
if (Settings.web_password[0] != 0) {
|
if (Settings.web_password[0] != 0 && HTTP_MANAGER_RESET_ONLY != webserver_state) {
|
||||||
return WebServer->authenticate(WEB_USERNAME, Settings.web_password);
|
return WebServer->authenticate(WEB_USERNAME, Settings.web_password);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -520,10 +622,9 @@ void ShowPage(String &page, bool auth)
|
||||||
}
|
}
|
||||||
page.replace(F("{j}"), info);
|
page.replace(F("{j}"), info);
|
||||||
|
|
||||||
if (HTTP_MANAGER == webserver_state) {
|
if (WifiIsInManagerMode()) {
|
||||||
if (WifiConfigCounter()) {
|
if (WifiConfigCounter()) {
|
||||||
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_COUNTER));
|
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_COUNTER));
|
||||||
page.replace(F("<body>"), F("<body onload='u()'>"));
|
|
||||||
page += FPSTR(HTTP_COUNTER);
|
page += FPSTR(HTTP_COUNTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,14 +666,16 @@ void WebRestart(uint8_t type)
|
||||||
page.replace(F("{v}"), FPSTR(S_RESTART));
|
page.replace(F("{v}"), FPSTR(S_RESTART));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool reset_only = (HTTP_MANAGER_RESET_ONLY == webserver_state);
|
||||||
|
|
||||||
page += FPSTR(HTTP_MSG_RSTRT);
|
page += FPSTR(HTTP_MSG_RSTRT);
|
||||||
if (HTTP_MANAGER == webserver_state) {
|
if (HTTP_MANAGER == webserver_state || reset_only) {
|
||||||
webserver_state = HTTP_ADMIN;
|
webserver_state = HTTP_ADMIN;
|
||||||
} else {
|
} else {
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
}
|
}
|
||||||
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_RELOAD));
|
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_RELOAD));
|
||||||
ShowPage(page);
|
ShowPage(page, !reset_only);
|
||||||
|
|
||||||
ShowWebSource(SRC_WEBGUI);
|
ShowWebSource(SRC_WEBGUI);
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
|
@ -600,19 +703,12 @@ void HandleRoot(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HTTP_MANAGER == webserver_state) {
|
if (WifiIsInManagerMode()) {
|
||||||
#ifndef FIRMWARE_MINIMAL
|
#ifndef FIRMWARE_MINIMAL
|
||||||
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) {
|
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != webserver_state) {
|
||||||
HandleWifiLogin();
|
HandleWifiLogin();
|
||||||
} else {
|
} else {
|
||||||
/*
|
if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ) || HTTP_MANAGER_RESET_ONLY == webserver_state)) {
|
||||||
char tmp1[100];
|
|
||||||
WebGetArg("USER1", tmp1, sizeof(tmp1));
|
|
||||||
char tmp2[100];
|
|
||||||
WebGetArg("PASS1", tmp2, sizeof(tmp2));
|
|
||||||
if (!(Settings.web_password[0] != 0) || (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password)))) {
|
|
||||||
*/
|
|
||||||
if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ))) {
|
|
||||||
HandleWifiConfiguration();
|
HandleWifiConfiguration();
|
||||||
} else {
|
} else {
|
||||||
// wrong user and pass
|
// wrong user and pass
|
||||||
|
@ -626,7 +722,6 @@ void HandleRoot(void)
|
||||||
page.replace(F("{v}"), FPSTR(S_MAIN_MENU));
|
page.replace(F("{v}"), FPSTR(S_MAIN_MENU));
|
||||||
page += FPSTR(HTTP_SCRIPT_ROOT);
|
page += FPSTR(HTTP_SCRIPT_ROOT);
|
||||||
page += FPSTR(HTTP_HEAD_STYLE);
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
page.replace(F("<body>"), F("<body onload='la()'>"));
|
|
||||||
|
|
||||||
page += F("<div id='l1' name='l1'></div>");
|
page += F("<div id='l1' name='l1'></div>");
|
||||||
if (devices_present) {
|
if (devices_present) {
|
||||||
|
@ -792,12 +887,133 @@ void HandleConfiguration(void)
|
||||||
page += String(mqtt_data);
|
page += String(mqtt_data);
|
||||||
|
|
||||||
page += FPSTR(HTTP_BTN_MENU4);
|
page += FPSTR(HTTP_BTN_MENU4);
|
||||||
|
page += FPSTR(HTTP_BTN_RESET);
|
||||||
|
page += FPSTR(HTTP_BTN_MENU5);
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
ShowPage(page);
|
ShowPage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void HandleTemplateConfiguration(void)
|
||||||
|
{
|
||||||
|
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||||
|
|
||||||
|
if (WebServer->hasArg("save")) {
|
||||||
|
TemplateSaveSettings();
|
||||||
|
WebRestart(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char stemp[20];
|
||||||
|
|
||||||
|
if (WebServer->hasArg("m")) {
|
||||||
|
String page = "";
|
||||||
|
for (uint8_t i = 0; i < MAXMODULE; i++) { // "}1'%d'>%s (%d)}2" - "}1'0'>Sonoff Basic (1)}2"
|
||||||
|
uint8_t midx = pgm_read_byte(kModuleNiceList + i);
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE3, midx, AnyModuleName(midx).c_str(), midx +1);
|
||||||
|
page += mqtt_data;
|
||||||
|
}
|
||||||
|
WebServer->send(200, FPSTR(HDR_CTYPE_PLAIN), page);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGetArg("t", stemp, sizeof(stemp));
|
||||||
|
if (strlen(stemp)) {
|
||||||
|
uint8_t module = atoi(stemp);
|
||||||
|
uint8_t module_save = Settings.module;
|
||||||
|
Settings.module = module;
|
||||||
|
myio cmodule;
|
||||||
|
ModuleGpios(&cmodule);
|
||||||
|
gpio_flag flag = ModuleFlag();
|
||||||
|
Settings.module = module_save;
|
||||||
|
|
||||||
|
String page = AnyModuleName(module); // NAME: Generic
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(kGpioNiceList); i++) { // GPIO: }1'0'>None (0)}2}1'17'>Button1 (17)}2...
|
||||||
|
|
||||||
|
if (1 == i) {
|
||||||
|
page += F("}1'255'>" D_SENSOR_USER " (255)}2"); // }1'255'>User (255)}2
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t midx = pgm_read_byte(kGpioNiceList + i);
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE3, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames), midx);
|
||||||
|
page += mqtt_data;
|
||||||
|
}
|
||||||
|
page += F("}3"); // }3
|
||||||
|
|
||||||
|
mqtt_data[0] = '\0';
|
||||||
|
for (uint8_t i = 0; i < sizeof(cmodule); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255
|
||||||
|
if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", cmodule.io[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,%d,%d"), mqtt_data, flag, Settings.user_template_base); // FLAG: ,1 BASE: ,17
|
||||||
|
page += mqtt_data;
|
||||||
|
|
||||||
|
WebServer->send(200, FPSTR(HDR_CTYPE_PLAIN), page);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_TEMPLATE);
|
||||||
|
|
||||||
|
String page = FPSTR(HTTP_HEAD);
|
||||||
|
page.replace(F("{v}"), FPSTR(S_CONFIGURE_TEMPLATE));
|
||||||
|
page += FPSTR(HTTP_SCRIPT_MODULE_TEMPLATE);
|
||||||
|
page += FPSTR(HTTP_SCRIPT_TEMPLATE);
|
||||||
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
|
page += FPSTR(HTTP_FORM_TEMPLATE);
|
||||||
|
page += F("<br/><table>");
|
||||||
|
for (uint8_t i = 0; i < 17; i++) {
|
||||||
|
if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td%s><b>" D_GPIO "%d</b></td><td>%s</td><td%s><select id='g%d' name='g%d'></select></td></tr>"),
|
||||||
|
(0==i)?" style='width:74px'":"", i, ((9==i)||(10==i))? "<font color='red'>ESP8285</font>" :"", (0==i)?" style='width:176px'":"", i, i);
|
||||||
|
page += mqtt_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page += F("</table>");
|
||||||
|
page += FPSTR(HTTP_FORM_TEMPLATE_FLAG);
|
||||||
|
page += FPSTR(HTTP_FORM_END);
|
||||||
|
page += FPSTR(HTTP_BTN_CONF);
|
||||||
|
ShowPage(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TemplateSaveSettings(void)
|
||||||
|
{
|
||||||
|
char svalue[128];
|
||||||
|
char tmp[100];
|
||||||
|
char stemp[20];
|
||||||
|
|
||||||
|
WebGetArg("s1", tmp, sizeof(tmp)); // NAME
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp);
|
||||||
|
|
||||||
|
uint8_t j = 0;
|
||||||
|
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||||
|
if (6 == i) { j = 9; }
|
||||||
|
if (8 == i) { j = 12; }
|
||||||
|
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), j);
|
||||||
|
WebGetArg(stemp, tmp, sizeof(tmp)); // GPIO
|
||||||
|
uint8_t gpio = atoi(tmp);
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s%d"), svalue, (i>0)?",":"", gpio);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t flag = 0;
|
||||||
|
for (uint8_t i = 0; i < GPIO_FLAG_USED; i++) {
|
||||||
|
snprintf_P(stemp, sizeof(stemp), PSTR("c%d"), i);
|
||||||
|
uint8_t state = WebServer->hasArg(stemp) << i; // FLAG
|
||||||
|
flag += state;
|
||||||
|
}
|
||||||
|
WebGetArg("g99", tmp, sizeof(tmp)); // BASE
|
||||||
|
uint8_t base = atoi(tmp) +1;
|
||||||
|
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"),
|
||||||
|
svalue, flag, base);
|
||||||
|
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void HandleModuleConfiguration(void)
|
void HandleModuleConfiguration(void)
|
||||||
{
|
{
|
||||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||||
|
@ -815,13 +1031,6 @@ void HandleModuleConfiguration(void)
|
||||||
|
|
||||||
if (WebServer->hasArg("m")) {
|
if (WebServer->hasArg("m")) {
|
||||||
String page = "";
|
String page = "";
|
||||||
/*
|
|
||||||
for (uint8_t i = 0; i < MAXMODULE; i++) { // "}1'%d'>%s (%d)}2" - "}1'0'>Sonoff Basic (1)}2"
|
|
||||||
midx = pgm_read_byte(kModuleNiceList + i);
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE3, midx, AnyModuleName(midx).c_str(), midx +1);
|
|
||||||
page += mqtt_data;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
uint8_t vidx = 0;
|
uint8_t vidx = 0;
|
||||||
for (uint8_t i = 0; i <= MAXMODULE; i++) { // "}1'%d'>%s (%d)}2" - "}1'255'>UserTemplate (0)}2" - "}1'0'>Sonoff Basic (1)}2"
|
for (uint8_t i = 0; i <= MAXMODULE; i++) { // "}1'%d'>%s (%d)}2" - "}1'255'>UserTemplate (0)}2" - "}1'0'>Sonoff Basic (1)}2"
|
||||||
if (0 == i) {
|
if (0 == i) {
|
||||||
|
@ -855,6 +1064,7 @@ void HandleModuleConfiguration(void)
|
||||||
|
|
||||||
String page = FPSTR(HTTP_HEAD);
|
String page = FPSTR(HTTP_HEAD);
|
||||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
|
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
|
||||||
|
page += FPSTR(HTTP_SCRIPT_MODULE_TEMPLATE);
|
||||||
page += FPSTR(HTTP_SCRIPT_MODULE1);
|
page += FPSTR(HTTP_SCRIPT_MODULE1);
|
||||||
page.replace(F("}4"), String(Settings.module));
|
page.replace(F("}4"), String(Settings.module));
|
||||||
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
||||||
|
@ -865,21 +1075,14 @@ void HandleModuleConfiguration(void)
|
||||||
}
|
}
|
||||||
page += FPSTR(HTTP_SCRIPT_MODULE2);
|
page += FPSTR(HTTP_SCRIPT_MODULE2);
|
||||||
page += FPSTR(HTTP_HEAD_STYLE);
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
page.replace(F("<body>"), F("<body onload='sl()'>"));
|
|
||||||
page += FPSTR(HTTP_FORM_MODULE);
|
page += FPSTR(HTTP_FORM_MODULE);
|
||||||
page.replace(F("{mt"), AnyModuleName(MODULE));
|
page.replace(F("{mt"), AnyModuleName(MODULE));
|
||||||
|
|
||||||
if (my_module_flag.pullup) {
|
|
||||||
page += FPSTR(HTTP_FORM_MODULE_PULLUP);
|
|
||||||
page.replace(F("{r1"), (Settings.flag3.no_pullup) ? F(" checked") : F(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
page += F("<br/><table>");
|
page += F("<br/><table>");
|
||||||
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
for (uint8_t i = 0; i < sizeof(cmodule); i++) {
|
||||||
if (ValidGPIO(i, cmodule.io[i])) {
|
if (ValidGPIO(i, cmodule.io[i])) {
|
||||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d' name='g%d'></select></td></tr>"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||||
(WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "<font color='red'>ESP8285</font>" :(10==i)? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
(WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
||||||
page += mqtt_data;
|
page += mqtt_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -899,11 +1102,6 @@ void ModuleSaveSettings(void)
|
||||||
Settings.last_module = Settings.module;
|
Settings.last_module = Settings.module;
|
||||||
Settings.module = new_module;
|
Settings.module = new_module;
|
||||||
SetModuleType();
|
SetModuleType();
|
||||||
if (Settings.last_module == new_module) {
|
|
||||||
if (my_module_flag.pullup) {
|
|
||||||
Settings.flag3.no_pullup = WebServer->hasArg("b1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myio cmodule;
|
myio cmodule;
|
||||||
ModuleGpios(&cmodule);
|
ModuleGpios(&cmodule);
|
||||||
String gpios = "";
|
String gpios = "";
|
||||||
|
@ -942,7 +1140,7 @@ void HandleWifiConfiguration(void)
|
||||||
|
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI);
|
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI);
|
||||||
|
|
||||||
if (WebServer->hasArg("save")) {
|
if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != webserver_state) {
|
||||||
WifiSaveSettings();
|
WifiSaveSettings();
|
||||||
WebRestart(2);
|
WebRestart(2);
|
||||||
return;
|
return;
|
||||||
|
@ -953,6 +1151,8 @@ void HandleWifiConfiguration(void)
|
||||||
page += FPSTR(HTTP_SCRIPT_WIFI);
|
page += FPSTR(HTTP_SCRIPT_WIFI);
|
||||||
page += FPSTR(HTTP_HEAD_STYLE);
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
|
|
||||||
|
|
||||||
|
if(HTTP_MANAGER_RESET_ONLY != webserver_state){
|
||||||
if (WebServer->hasArg("scan")) {
|
if (WebServer->hasArg("scan")) {
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
UdpDisconnect();
|
UdpDisconnect();
|
||||||
|
@ -1030,13 +1230,17 @@ void HandleWifiConfiguration(void)
|
||||||
page.replace(F("{s1"), Settings.sta_ssid[0]);
|
page.replace(F("{s1"), Settings.sta_ssid[0]);
|
||||||
page.replace(F("{s2"), Settings.sta_ssid[1]);
|
page.replace(F("{s2"), Settings.sta_ssid[1]);
|
||||||
page += FPSTR(HTTP_FORM_END);
|
page += FPSTR(HTTP_FORM_END);
|
||||||
if (HTTP_MANAGER == webserver_state) {
|
}
|
||||||
|
if (WifiIsInManagerMode()) {
|
||||||
page += FPSTR(HTTP_BTN_RSTRT);
|
page += FPSTR(HTTP_BTN_RSTRT);
|
||||||
|
#ifndef FIRMWARE_MINIMAL
|
||||||
|
page += FPSTR(HTTP_BTN_RESET);
|
||||||
|
#endif // FIRMWARE_MINIMAL
|
||||||
} else {
|
} else {
|
||||||
page += FPSTR(HTTP_BTN_CONF);
|
page += FPSTR(HTTP_BTN_CONF);
|
||||||
}
|
}
|
||||||
// ShowPage(page);
|
// ShowPage(page);
|
||||||
ShowPage(page, !(HTTP_MANAGER == webserver_state));
|
ShowPage(page, !(WifiIsInManagerMode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiSaveSettings(void)
|
void WifiSaveSettings(void)
|
||||||
|
@ -1053,9 +1257,9 @@ void WifiSaveSettings(void)
|
||||||
WebGetArg("s2", tmp, sizeof(tmp));
|
WebGetArg("s2", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? STA_SSID2 : tmp, sizeof(Settings.sta_ssid[1]));
|
strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? STA_SSID2 : tmp, sizeof(Settings.sta_ssid[1]));
|
||||||
WebGetArg("p1", tmp, sizeof(tmp));
|
WebGetArg("p1", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0]));
|
strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0]));
|
||||||
WebGetArg("p2", tmp, sizeof(tmp));
|
WebGetArg("p2", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1]));
|
strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1]));
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_SSID "2 %s"),
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_SSID "2 %s"),
|
||||||
Settings.hostname, Settings.sta_ssid[0], Settings.sta_ssid[1]);
|
Settings.hostname, Settings.sta_ssid[0], Settings.sta_ssid[1]);
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
@ -1164,6 +1368,9 @@ void HandleOtherConfiguration(void)
|
||||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_OTHER));
|
page.replace(F("{v}"), FPSTR(S_CONFIGURE_OTHER));
|
||||||
page += FPSTR(HTTP_HEAD_STYLE);
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
page += FPSTR(HTTP_FORM_OTHER);
|
page += FPSTR(HTTP_FORM_OTHER);
|
||||||
|
TemplateJson();
|
||||||
|
page.replace(F("{t1"), mqtt_data);
|
||||||
|
page.replace(F("{t2"), (USER_MODULE == Settings.module) ? F(" checked disabled") : F(""));
|
||||||
page.replace(F("{r1"), (Settings.flag.mqtt_enabled) ? F(" checked") : F(""));
|
page.replace(F("{r1"), (Settings.flag.mqtt_enabled) ? F(" checked") : F(""));
|
||||||
|
|
||||||
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
||||||
|
@ -1175,6 +1382,7 @@ void HandleOtherConfiguration(void)
|
||||||
page.replace(F("{2"), (i) ? stemp : FRIENDLY_NAME);
|
page.replace(F("{2"), (i) ? stemp : FRIENDLY_NAME);
|
||||||
page.replace(F("{3"), Settings.friendlyname[i]);
|
page.replace(F("{3"), Settings.friendlyname[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
page += FPSTR(HTTP_FORM_OTHER3a);
|
page += FPSTR(HTTP_FORM_OTHER3a);
|
||||||
for (uint8_t i = 0; i < EMUL_MAX; i++) {
|
for (uint8_t i = 0; i < EMUL_MAX; i++) {
|
||||||
|
@ -1184,9 +1392,9 @@ void HandleOtherConfiguration(void)
|
||||||
page.replace(F("{3"), (i == EMUL_NONE) ? F(D_NONE) : (i == EMUL_WEMO) ? F(D_BELKIN_WEMO) : F(D_HUE_BRIDGE));
|
page.replace(F("{3"), (i == EMUL_NONE) ? F(D_NONE) : (i == EMUL_WEMO) ? F(D_BELKIN_WEMO) : F(D_HUE_BRIDGE));
|
||||||
page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
|
page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
|
||||||
}
|
}
|
||||||
page += F("<br/>");
|
page += FPSTR(HTTP_FORM_OTHER3c);
|
||||||
page += F("<br/></fieldset>");
|
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
|
||||||
page += FPSTR(HTTP_FORM_END);
|
page += FPSTR(HTTP_FORM_END);
|
||||||
page += FPSTR(HTTP_BTN_CONF);
|
page += FPSTR(HTTP_BTN_CONF);
|
||||||
ShowPage(page);
|
ShowPage(page);
|
||||||
|
@ -1194,7 +1402,7 @@ void HandleOtherConfiguration(void)
|
||||||
|
|
||||||
void OtherSaveSettings(void)
|
void OtherSaveSettings(void)
|
||||||
{
|
{
|
||||||
char tmp[100];
|
char tmp[128];
|
||||||
char stemp[TOPSZ];
|
char stemp[TOPSZ];
|
||||||
char stemp2[TOPSZ];
|
char stemp2[TOPSZ];
|
||||||
|
|
||||||
|
@ -1214,6 +1422,18 @@ void OtherSaveSettings(void)
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s %s"), log_data, (i) ? "," : "", Settings.friendlyname[i]);
|
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s %s"), log_data, (i) ? "," : "", Settings.friendlyname[i]);
|
||||||
}
|
}
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
WebGetArg("t1", tmp, sizeof(tmp));
|
||||||
|
if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
|
||||||
|
char svalue[128];
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " %s"), tmp);
|
||||||
|
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||||
|
|
||||||
|
if (WebServer->hasArg("t2")) {
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_MODULE " 0"));
|
||||||
|
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
@ -1276,7 +1496,7 @@ void HandleResetConfiguration(void)
|
||||||
page += F("<div style='text-align:center;'>" D_CONFIGURATION_RESET "</div>");
|
page += F("<div style='text-align:center;'>" D_CONFIGURATION_RESET "</div>");
|
||||||
page += FPSTR(HTTP_MSG_RSTRT);
|
page += FPSTR(HTTP_MSG_RSTRT);
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
ShowPage(page);
|
ShowPage(page, HTTP_MANAGER_RESET_ONLY != webserver_state);
|
||||||
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1"));
|
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1"));
|
||||||
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
ExecuteWebCommand(svalue, SRC_WEBGUI);
|
||||||
|
@ -1416,7 +1636,6 @@ void HandleInformation(void)
|
||||||
func += F("</td></tr></table>");
|
func += F("</td></tr></table>");
|
||||||
func += FPSTR(HTTP_SCRIPT_INFO_END);
|
func += FPSTR(HTTP_SCRIPT_INFO_END);
|
||||||
page.replace(F("</script>"), func);
|
page.replace(F("</script>"), func);
|
||||||
page.replace(F("<body>"), F("<body onload='i()'>"));
|
|
||||||
|
|
||||||
// page += F("</fieldset>");
|
// page += F("</fieldset>");
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
|
@ -1737,8 +1956,6 @@ void HandleHttpCommand(void)
|
||||||
{
|
{
|
||||||
if (!HttpCheckPriviledgedAccess(false)) { return; }
|
if (!HttpCheckPriviledgedAccess(false)) { return; }
|
||||||
|
|
||||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
|
||||||
|
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
|
||||||
|
|
||||||
uint8_t valid = 1;
|
uint8_t valid = 1;
|
||||||
|
@ -1753,9 +1970,9 @@ void HandleHttpCommand(void)
|
||||||
String message = F("{\"" D_RSLT_WARNING "\":\"");
|
String message = F("{\"" D_RSLT_WARNING "\":\"");
|
||||||
if (valid) {
|
if (valid) {
|
||||||
uint8_t curridx = web_log_index;
|
uint8_t curridx = web_log_index;
|
||||||
WebGetArg("cmnd", svalue, sizeof(svalue));
|
String svalue = WebServer->arg("cmnd");
|
||||||
if (strlen(svalue)) {
|
if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) {
|
||||||
ExecuteWebCommand(svalue, SRC_WEBCOMMAND);
|
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE);
|
||||||
|
|
||||||
if (web_log_index != curridx) {
|
if (web_log_index != curridx) {
|
||||||
uint8_t counter = curridx;
|
uint8_t counter = curridx;
|
||||||
|
@ -1770,6 +1987,7 @@ void HandleHttpCommand(void)
|
||||||
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||||
if (message.length() > 1) { message += F(","); }
|
if (message.length() > 1) { message += F(","); }
|
||||||
size_t JSONlen = len - (JSON - tmp);
|
size_t JSONlen = len - (JSON - tmp);
|
||||||
|
if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); }
|
||||||
strlcpy(mqtt_data, JSON +1, JSONlen -2);
|
strlcpy(mqtt_data, JSON +1, JSONlen -2);
|
||||||
message += mqtt_data;
|
message += mqtt_data;
|
||||||
}
|
}
|
||||||
|
@ -1803,7 +2021,6 @@ void HandleConsole(void)
|
||||||
page.replace(F("{v}"), FPSTR(S_CONSOLE));
|
page.replace(F("{v}"), FPSTR(S_CONSOLE));
|
||||||
page += FPSTR(HTTP_HEAD_STYLE);
|
page += FPSTR(HTTP_HEAD_STYLE);
|
||||||
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_CONSOL));
|
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_CONSOL));
|
||||||
page.replace(F("<body>"), F("<body onload='l()'>"));
|
|
||||||
page += FPSTR(HTTP_FORM_CMND);
|
page += FPSTR(HTTP_FORM_CMND);
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
ShowPage(page);
|
ShowPage(page);
|
||||||
|
@ -1813,19 +2030,19 @@ void HandleAjaxConsoleRefresh(void)
|
||||||
{
|
{
|
||||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||||
|
|
||||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
|
||||||
bool cflg = true;
|
bool cflg = true;
|
||||||
uint8_t counter = 0; // Initial start, should never be 0 again
|
uint8_t counter = 0; // Initial start, should never be 0 again
|
||||||
|
|
||||||
WebGetArg("c1", svalue, sizeof(svalue));
|
String svalue = WebServer->arg("c1");
|
||||||
if (strlen(svalue)) {
|
if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) {
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue);
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue.c_str());
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
ExecuteWebCommand(svalue, SRC_WEBCONSOLE);
|
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGetArg("c2", svalue, sizeof(svalue));
|
char stmp[10];
|
||||||
if (strlen(svalue)) { counter = atoi(svalue); }
|
WebGetArg("c2", stmp, sizeof(stmp));
|
||||||
|
if (strlen(stmp)) { counter = atoi(stmp); }
|
||||||
|
|
||||||
bool last_reset_web_log_flag = reset_web_log_flag;
|
bool last_reset_web_log_flag = reset_web_log_flag;
|
||||||
// mqtt_data used as scratch space
|
// mqtt_data used as scratch space
|
||||||
|
@ -1850,6 +2067,7 @@ void HandleAjaxConsoleRefresh(void)
|
||||||
} else {
|
} else {
|
||||||
cflg = true;
|
cflg = true;
|
||||||
}
|
}
|
||||||
|
if (len > sizeof(mqtt_data) -2) { len = sizeof(mqtt_data); }
|
||||||
strlcpy(mqtt_data, tmp, len);
|
strlcpy(mqtt_data, tmp, len);
|
||||||
message += mqtt_data; // mqtt_data used as scratch space
|
message += mqtt_data; // mqtt_data used as scratch space
|
||||||
}
|
}
|
||||||
|
@ -1890,7 +2108,7 @@ void HandleNotFound(void)
|
||||||
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
|
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
|
||||||
bool CaptivePortal(void)
|
bool CaptivePortal(void)
|
||||||
{
|
{
|
||||||
if ((HTTP_MANAGER == webserver_state) && !ValidIpAddress(WebServer->hostHeader())) {
|
if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader())) {
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
||||||
|
|
||||||
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
||||||
|
@ -1949,90 +2167,91 @@ String UrlEncode(const String& text)
|
||||||
|
|
||||||
int WebSend(char *buffer)
|
int WebSend(char *buffer)
|
||||||
{
|
{
|
||||||
/* [sonoff] POWER1 ON --> Sends http://sonoff/cm?cmnd=POWER1 ON
|
// [sonoff] POWER1 ON --> Sends http://sonoff/cm?cmnd=POWER1 ON
|
||||||
* [192.168.178.86:80,admin:joker] POWER1 ON --> Sends http://hostname:80/cm?user=admin&password=joker&cmnd=POWER1 ON
|
// [192.168.178.86:80,admin:joker] POWER1 ON --> Sends http://hostname:80/cm?user=admin&password=joker&cmnd=POWER1 ON
|
||||||
* [sonoff] /any/link/starting/with/a/slash.php?log=123 --> Sends http://sonoff/any/link/starting/with/a/slash.php?log=123
|
// [sonoff] /any/link/starting/with/a/slash.php?log=123 --> Sends http://sonoff/any/link/starting/with/a/slash.php?log=123
|
||||||
* [sonoff,admin:joker] /any/link/starting/with/a/slash.php?log=123 --> Sends http://sonoff/any/link/starting/with/a/slash.php?log=123
|
// [sonoff,admin:joker] /any/link/starting/with/a/slash.php?log=123 --> Sends http://sonoff/any/link/starting/with/a/slash.php?log=123
|
||||||
*/
|
|
||||||
|
|
||||||
char *host;
|
char *host;
|
||||||
char *port;
|
char *port;
|
||||||
char *user;
|
char *user;
|
||||||
char *password;
|
char *password;
|
||||||
char *command;
|
char *command;
|
||||||
uint16_t nport = 80;
|
|
||||||
int status = 1; // Wrong parameters
|
int status = 1; // Wrong parameters
|
||||||
|
|
||||||
// buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON |
|
// buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON |
|
||||||
host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON |
|
host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON |
|
||||||
if (host && command) {
|
if (host && command) {
|
||||||
|
String url = F("http://"); // url = |http://|
|
||||||
host = Trim(host); // host = |[ 192.168.178.86 : 80 , admin : joker|
|
host = Trim(host); // host = |[ 192.168.178.86 : 80 , admin : joker|
|
||||||
host++; // host = | 192.168.178.86 : 80 , admin : joker| - Skip [
|
host++; // host = | 192.168.178.86 : 80 , admin : joker| - Skip [
|
||||||
host = strtok_r(host, ",", &user); // host = | 192.168.178.86 : 80 |, user = | admin : joker|
|
host = strtok_r(host, ",", &user); // host = | 192.168.178.86 : 80 |, user = | admin : joker|
|
||||||
host = strtok_r(host, ":", &port); // host = | 192.168.178.86 |, port = | 80 |
|
host = strtok_r(host, ":", &port); // host = | 192.168.178.86 |, port = | 80 |
|
||||||
host = Trim(host); // host = |192.168.178.86|
|
host = Trim(host); // host = |192.168.178.86|
|
||||||
|
url += host; // url = |http://192.168.178.86|
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
port = Trim(port); // port = |80|
|
port = Trim(port); // port = |80|
|
||||||
nport = atoi(port);
|
url += F(":"); // url = |http://192.168.178.86:|
|
||||||
|
url += port; // url = |http://192.168.178.86:80|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
user = strtok_r(user, ":", &password); // user = | admin |, password = | joker|
|
user = strtok_r(user, ":", &password); // user = | admin |, password = | joker|
|
||||||
user = Trim(user); // user = |admin|
|
user = Trim(user); // user = |admin|
|
||||||
if (password) { password = Trim(password); } // password = |joker|
|
if (password) { password = Trim(password); } // password = |joker|
|
||||||
}
|
}
|
||||||
|
|
||||||
command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123|
|
command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123|
|
||||||
|
|
||||||
String nuri = "";
|
|
||||||
if (command[0] != '/') {
|
if (command[0] != '/') {
|
||||||
nuri = "/cm?";
|
url += F("/cm?"); // url = |http://192.168.178.86/cm?|
|
||||||
if (user && password) {
|
if (user && password) {
|
||||||
nuri += F("user=");
|
url += F("user="); // url = |http://192.168.178.86/cm?user=|
|
||||||
nuri += user;
|
url += user; // url = |http://192.168.178.86/cm?user=admin|
|
||||||
nuri += F("&password=");
|
url += F("&password="); // url = |http://192.168.178.86/cm?user=admin&password=|
|
||||||
nuri += password;
|
url += password; // url = |http://192.168.178.86/cm?user=admin&password=joker|
|
||||||
nuri += F("&");
|
url += F("&"); // url = |http://192.168.178.86/cm?user=admin&password=joker&|
|
||||||
}
|
}
|
||||||
nuri += F("cmnd=");
|
url += F("cmnd="); // url = |http://192.168.178.86/cm?cmnd=| or |http://192.168.178.86/cm?user=admin&password=joker&cmnd=|
|
||||||
}
|
}
|
||||||
nuri += command;
|
url += command; // url = |http://192.168.178.86/cm?cmnd=POWER1 ON|
|
||||||
String uri = UrlEncode(nuri);
|
|
||||||
|
|
||||||
IPAddress host_ip;
|
//snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Uri |%s|"), url.c_str());
|
||||||
if (WiFi.hostByName(host, host_ip)) {
|
|
||||||
WiFiClient client;
|
|
||||||
|
|
||||||
bool connected = false;
|
|
||||||
uint8_t retry = 2;
|
|
||||||
while ((retry > 0) && !connected) {
|
|
||||||
--retry;
|
|
||||||
connected = client.connect(host_ip, nport);
|
|
||||||
if (connected) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connected) {
|
|
||||||
String url = F("GET ");
|
|
||||||
url += uri;
|
|
||||||
url += F(" HTTP/1.1\r\nHost: ");
|
|
||||||
// url += IPAddress(host_ip).toString();
|
|
||||||
url += host; // https://tools.ietf.org/html/rfc7230#section-5.4 (#4331)
|
|
||||||
if (port) {
|
|
||||||
url += F(":");
|
|
||||||
url += port;
|
|
||||||
}
|
|
||||||
url += F("\r\nConnection: close\r\n\r\n");
|
|
||||||
|
|
||||||
//snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Url |%s|"), url.c_str());
|
|
||||||
//AddLog(LOG_LEVEL_DEBUG);
|
//AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
client.print(url.c_str());
|
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
|
||||||
client.flush();
|
HTTPClient http;
|
||||||
client.stop();
|
if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
|
||||||
|
#else
|
||||||
|
WiFiClient http_client;
|
||||||
|
HTTPClient http;
|
||||||
|
if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
|
||||||
|
#endif
|
||||||
|
int http_code = http.GET(); // Start connection and send HTTP header
|
||||||
|
if (http_code > 0) { // http_code will be negative on error
|
||||||
|
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||||
|
/*
|
||||||
|
// Return received data to the user - Adds 900+ bytes to the code
|
||||||
|
String result = http.getString(); // File found at server - may need lot of ram or trigger out of memory!
|
||||||
|
uint16_t j = 0;
|
||||||
|
for (uint16_t i = 0; i < result.length(); i++) {
|
||||||
|
char text = result.charAt(i);
|
||||||
|
if (text > 31) { // Remove control characters like linefeed
|
||||||
|
mqtt_data[j++] = text;
|
||||||
|
if (j == sizeof(mqtt_data) -2) { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mqtt_data[j] = '\0';
|
||||||
|
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WEBSEND));
|
||||||
|
*/
|
||||||
|
}
|
||||||
status = 0; // No error - Done
|
status = 0; // No error - Done
|
||||||
} else {
|
} else {
|
||||||
status = 2; // Connection failed
|
status = 2; // Connection failed
|
||||||
}
|
}
|
||||||
|
http.end(); // Clean up connection data
|
||||||
} else {
|
} else {
|
||||||
status = 3; // Host not found
|
status = 3; // Host not found or connection error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -73,6 +73,7 @@ const char kMqttCommands[] PROGMEM =
|
||||||
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
|
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
|
||||||
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ;
|
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ;
|
||||||
|
|
||||||
|
uint16_t mqtt_connect_count = 0; // MQTT re-connect count
|
||||||
uint16_t mqtt_retry_counter = 1; // MQTT connection retry counter
|
uint16_t mqtt_retry_counter = 1; // MQTT connection retry counter
|
||||||
uint8_t mqtt_initial_connection_state = 2; // MQTT connection messages state
|
uint8_t mqtt_initial_connection_state = 2; // MQTT connection messages state
|
||||||
bool mqtt_connected = false; // MQTT virtual connection status
|
bool mqtt_connected = false; // MQTT virtual connection status
|
||||||
|
@ -379,6 +380,11 @@ void MqttPublishPowerBlinkState(uint8_t device)
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
uint16_t MqttConnectCount()
|
||||||
|
{
|
||||||
|
return mqtt_connect_count;
|
||||||
|
}
|
||||||
|
|
||||||
void MqttDisconnected(int state)
|
void MqttDisconnected(int state)
|
||||||
{
|
{
|
||||||
mqtt_connected = false;
|
mqtt_connected = false;
|
||||||
|
@ -398,6 +404,7 @@ void MqttConnected(void)
|
||||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED));
|
AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED));
|
||||||
mqtt_connected = true;
|
mqtt_connected = true;
|
||||||
mqtt_retry_counter = 0;
|
mqtt_retry_counter = 0;
|
||||||
|
mqtt_connect_count++;
|
||||||
|
|
||||||
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
GetTopic_P(stopic, TELE, mqtt_topic, S_LWT);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE));
|
||||||
|
@ -868,17 +875,18 @@ bool MqttCommand(void)
|
||||||
const char S_CONFIGURE_MQTT[] PROGMEM = D_CONFIGURE_MQTT;
|
const char S_CONFIGURE_MQTT[] PROGMEM = D_CONFIGURE_MQTT;
|
||||||
|
|
||||||
const char HTTP_BTN_MENU_MQTT[] PROGMEM =
|
const char HTTP_BTN_MENU_MQTT[] PROGMEM =
|
||||||
"<br/><form action='" WEB_HANDLE_MQTT "' method='get'><button>" D_CONFIGURE_MQTT "</button></form>";
|
"<p><form action='" WEB_HANDLE_MQTT "' method='get'><button>" D_CONFIGURE_MQTT "</button></form></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_MQTT[] PROGMEM =
|
const char HTTP_FORM_MQTT[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_MQTT_PARAMETERS " </b></legend><form method='get' action='" WEB_HANDLE_MQTT "'>"
|
"<fieldset><legend><b> " D_MQTT_PARAMETERS " </b></legend>"
|
||||||
"<br/><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='{m1'><br/>"
|
"<form method='get' action='" WEB_HANDLE_MQTT "'>"
|
||||||
"<br/><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='{m2'><br/>"
|
"<p><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='{m1'></p>"
|
||||||
"<br/><b>" D_CLIENT "</b> ({m0)<br/><input id='mc' name='mc' placeholder='" MQTT_CLIENT_ID "' value='{m3'><br/>"
|
"<p><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='{m2'></p>"
|
||||||
"<br/><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='{m4'><br/>"
|
"<p><b>" D_CLIENT "</b> ({m0)<br/><input id='mc' name='mc' placeholder='" MQTT_CLIENT_ID "' value='{m3'></p>"
|
||||||
"<br/><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERIX "'><br/>"
|
"<p><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='{m4'></p>"
|
||||||
"<br/><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC" ' value='{m6'><br/>"
|
"<p><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
|
||||||
"<br/><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' placeholder='" MQTT_FULLTOPIC" ' value='{m7'><br/>";
|
"<p><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC" ' value='{m6'></p>"
|
||||||
|
"<p><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' placeholder='" MQTT_FULLTOPIC" ' value='{m7'></p>";
|
||||||
|
|
||||||
void HandleMqttConfiguration(void)
|
void HandleMqttConfiguration(void)
|
||||||
{
|
{
|
||||||
|
@ -938,7 +946,7 @@ void MqttSaveSettings(void)
|
||||||
WebGetArg("mu", tmp, sizeof(tmp));
|
WebGetArg("mu", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.mqtt_user, (!strlen(tmp)) ? MQTT_USER : (!strcmp(tmp,"0")) ? "" : tmp, sizeof(Settings.mqtt_user));
|
strlcpy(Settings.mqtt_user, (!strlen(tmp)) ? MQTT_USER : (!strcmp(tmp,"0")) ? "" : tmp, sizeof(Settings.mqtt_user));
|
||||||
WebGetArg("mp", tmp, sizeof(tmp));
|
WebGetArg("mp", tmp, sizeof(tmp));
|
||||||
strlcpy(Settings.mqtt_pwd, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.mqtt_pwd : tmp, sizeof(Settings.mqtt_pwd));
|
strlcpy(Settings.mqtt_pwd, (!strlen(tmp)) ? "" : (!strcmp(tmp, D_ASTERISK_PWD)) ? Settings.mqtt_pwd : tmp, sizeof(Settings.mqtt_pwd));
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CMND_MQTTHOST " %s, " D_CMND_MQTTPORT " %d, " D_CMND_MQTTCLIENT " %s, " D_CMND_MQTTUSER " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"),
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CMND_MQTTHOST " %s, " D_CMND_MQTTPORT " %d, " D_CMND_MQTTCLIENT " %s, " D_CMND_MQTTUSER " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"),
|
||||||
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, Settings.mqtt_user, Settings.mqtt_topic, Settings.mqtt_fulltopic);
|
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, Settings.mqtt_user, Settings.mqtt_topic, Settings.mqtt_fulltopic);
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
|
|
@ -896,7 +896,11 @@ void LightAnimate(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef PWM_LIGHTSCHEME0_IGNORE_SLEEP
|
||||||
sleep = (LS_POWER == Settings.light_scheme) ? Settings.sleep : 0; // If no animation then use sleep as is
|
sleep = (LS_POWER == Settings.light_scheme) ? Settings.sleep : 0; // If no animation then use sleep as is
|
||||||
|
#else
|
||||||
|
sleep = 0;
|
||||||
|
#endif // PWM_LIGHTSCHEME0_IGNORE_SLEEP
|
||||||
switch (Settings.light_scheme) {
|
switch (Settings.light_scheme) {
|
||||||
case LS_POWER:
|
case LS_POWER:
|
||||||
LightSetDimmer(Settings.light_dimmer);
|
LightSetDimmer(Settings.light_dimmer);
|
||||||
|
|
|
@ -431,11 +431,13 @@ void DomoticzSensorPowerEnergy(int power, char *energy)
|
||||||
const char S_CONFIGURE_DOMOTICZ[] PROGMEM = D_CONFIGURE_DOMOTICZ;
|
const char S_CONFIGURE_DOMOTICZ[] PROGMEM = D_CONFIGURE_DOMOTICZ;
|
||||||
|
|
||||||
const char HTTP_BTN_MENU_DOMOTICZ[] PROGMEM =
|
const char HTTP_BTN_MENU_DOMOTICZ[] PROGMEM =
|
||||||
"<br/><form action='" WEB_HANDLE_DOMOTICZ "' method='get'><button>" D_CONFIGURE_DOMOTICZ "</button></form>";
|
"<p><form action='" WEB_HANDLE_DOMOTICZ "' method='get'><button>" D_CONFIGURE_DOMOTICZ "</button></form></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_DOMOTICZ[] PROGMEM =
|
const char HTTP_FORM_DOMOTICZ[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_DOMOTICZ_PARAMETERS " </b></legend><form method='post' action='" WEB_HANDLE_DOMOTICZ "'>"
|
"<fieldset><legend><b> " D_DOMOTICZ_PARAMETERS " </b></legend>"
|
||||||
"<br/><table>";
|
"<form method='post' action='" WEB_HANDLE_DOMOTICZ "'>"
|
||||||
|
"<br/>"
|
||||||
|
"<table>";
|
||||||
const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
|
const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
|
||||||
"<tr><td style='width:260px'><b>" D_DOMOTICZ_IDX " {1</b></td><td style='width:70px'><input id='r{1' name='r{1' placeholder='0' value='{2'></td></tr>"
|
"<tr><td style='width:260px'><b>" D_DOMOTICZ_IDX " {1</b></td><td style='width:70px'><input id='r{1' name='r{1' placeholder='0' value='{2'></td></tr>"
|
||||||
"<tr><td style='width:260px'><b>" D_DOMOTICZ_KEY_IDX " {1</b></td><td style='width:70px'><input id='k{1' name='k{1' placeholder='0' value='{3'></td></tr>";
|
"<tr><td style='width:260px'><b>" D_DOMOTICZ_KEY_IDX " {1</b></td><td style='width:70px'><input id='k{1' name='k{1' placeholder='0' value='{3'></td></tr>";
|
||||||
|
|
|
@ -232,7 +232,7 @@ String GetSun(uint8_t dawn)
|
||||||
return String(stime);
|
return String(stime);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t GetSunMinutes(uint8_t dawn)
|
uint16_t SunMinutes(uint8_t dawn)
|
||||||
{
|
{
|
||||||
uint8_t hour[2];
|
uint8_t hour[2];
|
||||||
uint8_t minute[2];
|
uint8_t minute[2];
|
||||||
|
@ -517,7 +517,7 @@ bool TimerCommand(void)
|
||||||
const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER;
|
const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER;
|
||||||
|
|
||||||
const char HTTP_BTN_MENU_TIMER[] PROGMEM =
|
const char HTTP_BTN_MENU_TIMER[] PROGMEM =
|
||||||
"<br/><form action='" WEB_HANDLE_TIMER "' method='get'><button>" D_CONFIGURE_TIMER "</button></form>";
|
"<p><form action='" WEB_HANDLE_TIMER "' method='get'><button>" D_CONFIGURE_TIMER "</button></form></p>";
|
||||||
|
|
||||||
const char HTTP_TIMER_SCRIPT[] PROGMEM =
|
const char HTTP_TIMER_SCRIPT[] PROGMEM =
|
||||||
"var pt=[],ct=99;"
|
"var pt=[],ct=99;"
|
||||||
|
@ -593,8 +593,8 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
|
||||||
"if(ct<99){st();}" // Save changes
|
"if(ct<99){st();}" // Save changes
|
||||||
"ct=t;"
|
"ct=t;"
|
||||||
"o=document.getElementsByClassName('tl');" // Restore style to all tabs/buttons
|
"o=document.getElementsByClassName('tl');" // Restore style to all tabs/buttons
|
||||||
"for(i=0;i<o.length;i++){o[i].style.cssText=\"background-color:#ccc;color:#fff;font-weight:normal;\"}"
|
"for(i=0;i<o.length;i++){o[i].style.cssText=\"background-color:#999;color:#fff;font-weight:normal;\"}"
|
||||||
"e.style.cssText=\"background-color:#fff;color:#000;font-weight:bold;\";" // Change style to tab/button used to open content
|
"e.style.cssText=\"background-color:transparent;color:#000;font-weight:bold;\";" // Change style to tab/button used to open content
|
||||||
"s=pt[ct];" // Get parameters from array
|
"s=pt[ct];" // Get parameters from array
|
||||||
#ifdef USE_SUNRISE
|
#ifdef USE_SUNRISE
|
||||||
"p=(s>>29)&3;eb('b'+p).checked=1;" // Set mode
|
"p=(s>>29)&3;eb('b'+p).checked=1;" // Set mode
|
||||||
|
@ -637,36 +637,34 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
|
||||||
"o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options
|
"o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options
|
||||||
"o=qs('#d1');for(i=0;i<}1;i++){ce(i+1,o);}" // Create outputs
|
"o=qs('#d1');for(i=0;i<}1;i++){ce(i+1,o);}" // Create outputs
|
||||||
"var a='" D_DAY3LIST "';"
|
"var a='" D_DAY3LIST "';"
|
||||||
"s='';for(i=0;i<7;i++){s+=\"<input style='width:5%;' id='w\"+i+\"' name='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b>\"}"
|
"s='';for(i=0;i<7;i++){s+=\"<input id='w\"+i+\"' name='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b> \"}"
|
||||||
"eb('ds').innerHTML=s;" // Create weekdays
|
"eb('ds').innerHTML=s;" // Create weekdays
|
||||||
"eb('dP').click();" // Get the element with id='dP' and click on it
|
"eb('dP').click();" // Get the element with id='dP' and click on it
|
||||||
"}";
|
"}";
|
||||||
const char HTTP_TIMER_STYLE[] PROGMEM =
|
const char HTTP_TIMER_STYLE[] PROGMEM =
|
||||||
".tl{float:left;border-radius:0;border:1px solid #fff;padding:1px;width:6.25%;}"
|
".tl{float:left;border-radius:0;border:1px solid #f2f2f2;padding:1px;width:6.25%;}" // Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE (transparent won't work)
|
||||||
#ifdef USE_SUNRISE
|
|
||||||
"input[type='radio']{width:13px;height:24px;margin-top:-1px;margin-right:8px;vertical-align:middle;}"
|
|
||||||
#endif
|
|
||||||
"</style>";
|
"</style>";
|
||||||
const char HTTP_FORM_TIMER[] PROGMEM =
|
const char HTTP_FORM_TIMER[] PROGMEM =
|
||||||
"<fieldset style='min-width:470px;text-align:center;'>"
|
"<fieldset style='min-width:470px;text-align:center;'>"
|
||||||
"<legend style='text-align:left;'><b> " D_TIMER_PARAMETERS " </b></legend>"
|
"<legend style='text-align:left;'><b> " D_TIMER_PARAMETERS " </b></legend>"
|
||||||
"<form method='post' action='" WEB_HANDLE_TIMER "' onsubmit='return st();'>"
|
"<form method='post' action='" WEB_HANDLE_TIMER "' onsubmit='return st();'>"
|
||||||
"<br/><input style='width:5%;' id='e0' name='e0' type='checkbox'{e0><b>" D_TIMER_ENABLE "</b><br/><br/><hr/>"
|
"<br/><input id='e0' name='e0' type='checkbox'{e0><b>" D_TIMER_ENABLE "</b><br/><br/><hr/>"
|
||||||
"<input id='t0' name='t0' value='";
|
"<input id='t0' name='t0' value='";
|
||||||
const char HTTP_FORM_TIMER1[] PROGMEM =
|
const char HTTP_FORM_TIMER1[] PROGMEM =
|
||||||
"' hidden><div id='bt' name='bt'></div><br/><br/><br/>"
|
"' hidden><div id='bt' name='bt'></div><br/><br/><br/>"
|
||||||
"<div id='oa' name='oa'></div><br/>"
|
"<div id='oa' name='oa'></div><br/>"
|
||||||
"<div>"
|
"<div>"
|
||||||
"<input style='width:5%;' id='a0' name='a0' type='checkbox'><b>" D_TIMER_ARM "</b> "
|
"<input id='a0' name='a0' type='checkbox'><b>" D_TIMER_ARM "</b> "
|
||||||
"<input style='width:5%;' id='r0' name='r0' type='checkbox'><b>" D_TIMER_REPEAT "</b>"
|
"<input id='r0' name='r0' type='checkbox'><b>" D_TIMER_REPEAT "</b>"
|
||||||
"</div><br/>"
|
"</div><br/>"
|
||||||
"<div>"
|
"<div>"
|
||||||
#ifdef USE_SUNRISE
|
#ifdef USE_SUNRISE
|
||||||
"<fieldset style='width:299px;margin:auto;text-align:left;border:0;'>"
|
"<fieldset style='width:299px;margin:auto;text-align:left;border:0;'>" // 299 used in page.replace(F("299")
|
||||||
"<input id='b0' name='rd' type='radio' value='0' onclick='gt();'><b>" D_TIMER_TIME "</b><br/>"
|
"<input id='b0' name='rd' type='radio' value='0' onclick='gt();'><b>" D_TIMER_TIME "</b><br/>"
|
||||||
"<input id='b1' name='rd' type='radio' value='1' onclick='gt();'><b>" D_SUNRISE "</b> (}8)<br/>"
|
"<input id='b1' name='rd' type='radio' value='1' onclick='gt();'><b>" D_SUNRISE "</b> (}8)<br/>"
|
||||||
"<input id='b2' name='rd' type='radio' value='2' onclick='gt();'><b>" D_SUNSET "</b> (}9)<br/>"
|
"<input id='b2' name='rd' type='radio' value='2' onclick='gt();'><b>" D_SUNSET "</b> (}9)<br/>"
|
||||||
"</fieldset>"
|
"</fieldset>"
|
||||||
|
"<p></p>"
|
||||||
"<span><select style='width:46px;' id='dr' name='dr'></select></span>"
|
"<span><select style='width:46px;' id='dr' name='dr'></select></span>"
|
||||||
" "
|
" "
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -90,6 +90,21 @@
|
||||||
#define MAXIMUM_COMPARE_OPERATOR COMPARE_OPERATOR_SMALLER_EQUAL
|
#define MAXIMUM_COMPARE_OPERATOR COMPARE_OPERATOR_SMALLER_EQUAL
|
||||||
const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<=";
|
const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<=";
|
||||||
|
|
||||||
|
#ifdef USE_EXPRESSION
|
||||||
|
#include <LinkedList.h> // Import LinkedList library
|
||||||
|
|
||||||
|
const char kExpressionOperators[] PROGMEM = "+-*/%^";
|
||||||
|
#define EXPRESSION_OPERATOR_ADD 0
|
||||||
|
#define EXPRESSION_OPERATOR_SUBTRACT 1
|
||||||
|
#define EXPRESSION_OPERATOR_MULTIPLY 2
|
||||||
|
#define EXPRESSION_OPERATOR_DIVIDEDBY 3
|
||||||
|
#define EXPRESSION_OPERATOR_MODULO 4
|
||||||
|
#define EXPRESSION_OPERATOR_POWER 5
|
||||||
|
|
||||||
|
const uint8_t kExpressionOperatorsPriorities[] PROGMEM = {1, 1, 2, 2, 3, 4};
|
||||||
|
#define MAX_EXPRESSION_OPERATOR_PRIORITY 4
|
||||||
|
#endif // USE_EXPRESSION
|
||||||
|
|
||||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM, CMND_ADD, CMND_SUB, CMND_MULT, CMND_SCALE, CMND_CALC_RESOLUTION };
|
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM, CMND_ADD, CMND_SUB, CMND_MULT, CMND_SCALE, CMND_CALC_RESOLUTION };
|
||||||
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM "|" D_CMND_ADD "|" D_CMND_SUB "|" D_CMND_MULT "|" D_CMND_SCALE "|" D_CMND_CALC_RESOLUTION ;
|
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM "|" D_CMND_ADD "|" D_CMND_SUB "|" D_CMND_MULT "|" D_CMND_SCALE "|" D_CMND_CALC_RESOLUTION ;
|
||||||
|
|
||||||
|
@ -170,11 +185,11 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
||||||
}
|
}
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%TIME%%"));
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%TIME%%"));
|
||||||
if (rule_param.startsWith(stemp)) {
|
if (rule_param.startsWith(stemp)) {
|
||||||
rule_param = String(GetMinutesPastMidnight());
|
rule_param = String(MinutesPastMidnight());
|
||||||
}
|
}
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%UPTIME%%"));
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%UPTIME%%"));
|
||||||
if (rule_param.startsWith(stemp)) {
|
if (rule_param.startsWith(stemp)) {
|
||||||
rule_param = String(GetMinutesUptime());
|
rule_param = String(MinutesUptime());
|
||||||
}
|
}
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%TIMESTAMP%%"));
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%TIMESTAMP%%"));
|
||||||
if (rule_param.startsWith(stemp)) {
|
if (rule_param.startsWith(stemp)) {
|
||||||
|
@ -183,11 +198,11 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule)
|
||||||
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNRISE%%"));
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNRISE%%"));
|
||||||
if (rule_param.startsWith(stemp)) {
|
if (rule_param.startsWith(stemp)) {
|
||||||
rule_param = String(GetSunMinutes(0));
|
rule_param = String(SunMinutes(0));
|
||||||
}
|
}
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNSET%%"));
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNSET%%"));
|
||||||
if (rule_param.startsWith(stemp)) {
|
if (rule_param.startsWith(stemp)) {
|
||||||
rule_param = String(GetSunMinutes(1));
|
rule_param = String(SunMinutes(1));
|
||||||
}
|
}
|
||||||
#endif // USE_TIMERS and USE_SUNRISE
|
#endif // USE_TIMERS and USE_SUNRISE
|
||||||
rule_param.toUpperCase();
|
rule_param.toUpperCase();
|
||||||
|
@ -332,12 +347,12 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved)
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("%%mem%d%%"), i +1);
|
snprintf_P(stemp, sizeof(stemp), PSTR("%%mem%d%%"), i +1);
|
||||||
commands.replace(stemp, Settings.mems[i]);
|
commands.replace(stemp, Settings.mems[i]);
|
||||||
}
|
}
|
||||||
commands.replace(F("%time%"), String(GetMinutesPastMidnight()));
|
commands.replace(F("%time%"), String(MinutesPastMidnight()));
|
||||||
commands.replace(F("%uptime%"), String(GetMinutesUptime()));
|
commands.replace(F("%uptime%"), String(MinutesUptime()));
|
||||||
commands.replace(F("%timestamp%"), GetDateAndTime(DT_LOCAL).c_str());
|
commands.replace(F("%timestamp%"), GetDateAndTime(DT_LOCAL).c_str());
|
||||||
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
||||||
commands.replace(F("%sunrise%"), String(GetSunMinutes(0)));
|
commands.replace(F("%sunrise%"), String(SunMinutes(0)));
|
||||||
commands.replace(F("%sunset%"), String(GetSunMinutes(1)));
|
commands.replace(F("%sunset%"), String(SunMinutes(1)));
|
||||||
#endif // USE_TIMERS and USE_SUNRISE
|
#endif // USE_TIMERS and USE_SUNRISE
|
||||||
|
|
||||||
char command[commands.length() +1];
|
char command[commands.length() +1];
|
||||||
|
@ -490,8 +505,8 @@ void RulesEvery50ms(void)
|
||||||
json_event[0] = '\0';
|
json_event[0] = '\0';
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break;
|
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break;
|
||||||
case 1: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), GetMinutesPastMidnight()); break;
|
case 1: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break;
|
||||||
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), GetMinutesPastMidnight()); break;
|
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break;
|
||||||
case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||||
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||||
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||||
|
@ -534,7 +549,7 @@ void RulesEverySecond(void)
|
||||||
if (RtcTime.valid) {
|
if (RtcTime.valid) {
|
||||||
if ((uptime > 60) && (RtcTime.minute != rules_last_minute)) { // Execute from one minute after restart every minute only once
|
if ((uptime > 60) && (RtcTime.minute != rules_last_minute)) { // Execute from one minute after restart every minute only once
|
||||||
rules_last_minute = RtcTime.minute;
|
rules_last_minute = RtcTime.minute;
|
||||||
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Minute\":%d}}"), GetMinutesPastMidnight());
|
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Minute\":%d}}"), MinutesPastMidnight());
|
||||||
RulesProcessEvent(json_event);
|
RulesProcessEvent(json_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,6 +577,310 @@ void RulesTeleperiod(void)
|
||||||
rules_teleperiod = 0;
|
rules_teleperiod = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EXPRESSION
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Parse a number value
|
||||||
|
* Input:
|
||||||
|
* pNumber - A char pointer point to a digit started string (guaranteed)
|
||||||
|
* value - Reference a double variable used to accept the result
|
||||||
|
* Output:
|
||||||
|
* pNumber - Pointer forward to next character after the number
|
||||||
|
* value - double type, the result value
|
||||||
|
* Return:
|
||||||
|
* true - succeed
|
||||||
|
* false - failed
|
||||||
|
*/
|
||||||
|
bool findNextNumber(char * &pNumber, double &value)
|
||||||
|
{
|
||||||
|
bool bSucceed = false;
|
||||||
|
String sNumber = "";
|
||||||
|
while (*pNumber) {
|
||||||
|
if (isdigit(*pNumber) || (*pNumber == '.')) {
|
||||||
|
sNumber += *pNumber;
|
||||||
|
pNumber++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sNumber.length() > 0) {
|
||||||
|
value = CharToDouble(sNumber.c_str());
|
||||||
|
bSucceed = true;
|
||||||
|
}
|
||||||
|
return bSucceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Parse a variable (like VAR1, MEM3) and get its value (double type)
|
||||||
|
* Input:
|
||||||
|
* pVarname - A char pointer point to a variable name string
|
||||||
|
* value - Reference a double variable used to accept the result
|
||||||
|
* Output:
|
||||||
|
* pVarname - Pointer forward to next character after the variable
|
||||||
|
* value - double type, the result value
|
||||||
|
* Return:
|
||||||
|
* true - succeed
|
||||||
|
* false - failed
|
||||||
|
*/
|
||||||
|
bool findNextVariableValue(char * &pVarname, double &value)
|
||||||
|
{
|
||||||
|
bool succeed = true;
|
||||||
|
value = 0;
|
||||||
|
String sVarName = "";
|
||||||
|
while (*pVarname) {
|
||||||
|
if (isalpha(*pVarname) || isdigit(*pVarname)) {
|
||||||
|
sVarName.concat(*pVarname);
|
||||||
|
pVarname++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sVarName.toUpperCase();
|
||||||
|
if (sVarName.startsWith(F("VAR"))) {
|
||||||
|
int index = sVarName.substring(3).toInt();
|
||||||
|
if (index > 0 && index <= MAX_RULE_VARS) {
|
||||||
|
value = CharToDouble(vars[index -1]);
|
||||||
|
}
|
||||||
|
} else if (sVarName.startsWith(F("MEM"))) {
|
||||||
|
int index = sVarName.substring(3).toInt();
|
||||||
|
if (index > 0 && index <= MAX_RULE_MEMS) {
|
||||||
|
value = CharToDouble(Settings.mems[index -1]);
|
||||||
|
}
|
||||||
|
} else if (sVarName.equals(F("TIME"))) {
|
||||||
|
value = MinutesPastMidnight();
|
||||||
|
} else if (sVarName.equals(F("UPTIME"))) {
|
||||||
|
value = MinutesUptime();
|
||||||
|
} else if (sVarName.equals(F("UTCTIME"))) {
|
||||||
|
value = UtcTime();
|
||||||
|
} else if (sVarName.equals(F("LOCALTIME"))) {
|
||||||
|
value = LocalTime();
|
||||||
|
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
|
||||||
|
} else if (sVarName.equals(F("SUNRISE"))) {
|
||||||
|
value = SunMinutes(0);
|
||||||
|
} else if (sVarName.equals(F("SUNSET"))) {
|
||||||
|
value = SunMinutes(1);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
succeed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return succeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Find next object in expression and evaluate it
|
||||||
|
* An object could be:
|
||||||
|
* - A float number start with a digit, like 0.787
|
||||||
|
* - A variable name, like VAR1, MEM3
|
||||||
|
* - An expression enclosed with a pair of round brackets, (.....)
|
||||||
|
* Input:
|
||||||
|
* pointer - A char pointer point to a place of the expression string
|
||||||
|
* value - Reference a double variable used to accept the result
|
||||||
|
* Output:
|
||||||
|
* pointer - Pointer forward to next character after next object
|
||||||
|
* value - double type, the result value
|
||||||
|
* Return:
|
||||||
|
* true - succeed
|
||||||
|
* false - failed
|
||||||
|
*/
|
||||||
|
bool findNextObjectValue(char * &pointer, double &value)
|
||||||
|
{
|
||||||
|
bool bSucceed = false;
|
||||||
|
while (*pointer)
|
||||||
|
{
|
||||||
|
if (isspace(*pointer)) { //Skip leading spaces
|
||||||
|
pointer++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isdigit(*pointer)) { //This object is a number
|
||||||
|
bSucceed = findNextNumber(pointer, value);
|
||||||
|
break;
|
||||||
|
} else if (isalpha(*pointer)) { //Should be a variable like VAR12, MEM1
|
||||||
|
bSucceed = findNextVariableValue(pointer, value);
|
||||||
|
break;
|
||||||
|
} else if (*pointer == '(') { //It is a sub expression bracketed with ()
|
||||||
|
pointer++;
|
||||||
|
char * sub_exp_start = pointer; //Find out the sub expression between a pair of parenthesis. "()"
|
||||||
|
unsigned int sub_exp_len = 0;
|
||||||
|
//Look for the matched closure parenthesis.")"
|
||||||
|
bool bFindClosures = false;
|
||||||
|
uint8_t matchClosures = 1;
|
||||||
|
while (*pointer)
|
||||||
|
{
|
||||||
|
if (*pointer == ')') {
|
||||||
|
matchClosures--;
|
||||||
|
if (matchClosures == 0) {
|
||||||
|
sub_exp_len = pointer - sub_exp_start;
|
||||||
|
bFindClosures = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (*pointer == '(') {
|
||||||
|
matchClosures++;
|
||||||
|
}
|
||||||
|
pointer++;
|
||||||
|
}
|
||||||
|
if (bFindClosures) {
|
||||||
|
value = evaluateExpression(sub_exp_start, sub_exp_len);
|
||||||
|
bSucceed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else { //No number, no variable, no expression, then invalid object.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bSucceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Find next operator in expression
|
||||||
|
* An operator could be: +, - , * , / , %, ^
|
||||||
|
* Input:
|
||||||
|
* pointer - A char pointer point to a place of the expression string
|
||||||
|
* op - Reference to a variable used to accept the result
|
||||||
|
* Output:
|
||||||
|
* pointer - Pointer forward to next character after next operator
|
||||||
|
* op - The operator. 0, 1, 2, 3, 4, 5
|
||||||
|
* Return:
|
||||||
|
* true - succeed
|
||||||
|
* false - failed
|
||||||
|
*/
|
||||||
|
bool findNextOperator(char * &pointer, int8_t &op)
|
||||||
|
{
|
||||||
|
bool bSucceed = false;
|
||||||
|
while (*pointer)
|
||||||
|
{
|
||||||
|
if (isspace(*pointer)) { //Skip leading spaces
|
||||||
|
pointer++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (char *pch = strchr(kExpressionOperators, *pointer)) { //If it is an operator
|
||||||
|
op = (int8_t)(pch - kExpressionOperators);
|
||||||
|
pointer++;
|
||||||
|
bSucceed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bSucceed;
|
||||||
|
}
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Calculate a simple expression composed by 2 value and 1 operator, like 2 * 3
|
||||||
|
* Input:
|
||||||
|
* pointer - A char pointer point to a place of the expression string
|
||||||
|
* value - Reference a double variable used to accept the result
|
||||||
|
* Output:
|
||||||
|
* pointer - Pointer forward to next character after next object
|
||||||
|
* value - double type, the result value
|
||||||
|
* Return:
|
||||||
|
* true - succeed
|
||||||
|
* false - failed
|
||||||
|
*/
|
||||||
|
double calculateTwoValues(double v1, double v2, uint8_t op)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case EXPRESSION_OPERATOR_ADD:
|
||||||
|
return v1 + v2;
|
||||||
|
case EXPRESSION_OPERATOR_SUBTRACT:
|
||||||
|
return v1 - v2;
|
||||||
|
case EXPRESSION_OPERATOR_MULTIPLY:
|
||||||
|
return v1 * v2;
|
||||||
|
case EXPRESSION_OPERATOR_DIVIDEDBY:
|
||||||
|
return (0 == v2) ? 0 : (v1 / v2);
|
||||||
|
case EXPRESSION_OPERATOR_MODULO:
|
||||||
|
return (0 == v2) ? 0 : (int(v1) % int(v2));
|
||||||
|
case EXPRESSION_OPERATOR_POWER:
|
||||||
|
return FastPrecisePow(v1, v2);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Parse and evaluate an expression.
|
||||||
|
* For example: "10 * ( MEM2 + 1) / 2"
|
||||||
|
* Right now, only support operators listed here: (order by priority)
|
||||||
|
* Priority 4: ^ (power)
|
||||||
|
* Priority 3: % (modulo, always get integer result)
|
||||||
|
* Priority 2: *, /
|
||||||
|
* Priority 1: +, -
|
||||||
|
* Input:
|
||||||
|
* expression - The expression to be evaluated
|
||||||
|
* len - Length of the expression
|
||||||
|
* Return:
|
||||||
|
* double - result.
|
||||||
|
* 0 - if the expression is invalid
|
||||||
|
* An example:
|
||||||
|
* MEM1 = 3, MEM2 = 6, VAR2 = 15, VAR10 = 80
|
||||||
|
* At beginning, the expression might be complicated like: 3.14 * (MEM1 * (10 + VAR2 ^2) - 100) % 10 + VAR10 / (2 + MEM2)
|
||||||
|
* We are going to scan the whole expression, evaluate each object.
|
||||||
|
* Finally we will have a value list:.
|
||||||
|
* Order Object Value
|
||||||
|
* 0 3.14 3.14
|
||||||
|
* 1 (MEM1 * (10 + VAR2 ^2) - 100) 605
|
||||||
|
* 2 10 10
|
||||||
|
* 3 VAR10 80
|
||||||
|
* 4 (2 + MEM2) 8
|
||||||
|
* And an operator list:
|
||||||
|
* Order Operator Priority
|
||||||
|
* 0 * 2
|
||||||
|
* 1 % 3
|
||||||
|
* 2 + 1
|
||||||
|
* 3 / 2
|
||||||
|
*/
|
||||||
|
double evaluateExpression(const char * expression, unsigned int len)
|
||||||
|
{
|
||||||
|
char expbuf[len + 1];
|
||||||
|
memcpy(expbuf, expression, len);
|
||||||
|
expbuf[len] = '\0';
|
||||||
|
char * scan_pointer = expbuf;
|
||||||
|
|
||||||
|
LinkedList<double> object_values;
|
||||||
|
LinkedList<int8_t> operators;
|
||||||
|
int8_t op;
|
||||||
|
double va;
|
||||||
|
//Find and add the value of first object
|
||||||
|
if (findNextObjectValue(scan_pointer, va)) {
|
||||||
|
object_values.add(va);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (*scan_pointer)
|
||||||
|
{
|
||||||
|
if (findNextOperator(scan_pointer, op)
|
||||||
|
&& *scan_pointer
|
||||||
|
&& findNextObjectValue(scan_pointer, va))
|
||||||
|
{
|
||||||
|
operators.add(op);
|
||||||
|
object_values.add(va);
|
||||||
|
} else {
|
||||||
|
//No operator followed or no more object after this operator, we done.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Going to evaluate the whole expression
|
||||||
|
//Calculate by order of operator priorities. Looking for all operators with specified priority (from High to Low)
|
||||||
|
for (int8_t priority = MAX_EXPRESSION_OPERATOR_PRIORITY; priority>0; priority--) {
|
||||||
|
int index = 0;
|
||||||
|
while (index < operators.size()) {
|
||||||
|
if (priority == kExpressionOperatorsPriorities[(operators.get(index))]) { //need to calculate the operator first
|
||||||
|
//get current object value and remove the next object with current operator
|
||||||
|
va = calculateTwoValues(object_values.get(index), object_values.remove(index + 1), operators.remove(index));
|
||||||
|
//Replace the current value with the result
|
||||||
|
object_values.set(index, va);
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return object_values.get(0);
|
||||||
|
}
|
||||||
|
#endif //USE_EXPRESSION
|
||||||
|
|
||||||
bool RulesCommand(void)
|
bool RulesCommand(void)
|
||||||
{
|
{
|
||||||
char command[CMDSZ];
|
char command[CMDSZ];
|
||||||
|
@ -620,7 +939,12 @@ bool RulesCommand(void)
|
||||||
}
|
}
|
||||||
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
|
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
#ifdef USE_EXPRESSION
|
||||||
|
double timer_set = evaluateExpression(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
|
rules_timer[index -1] = (timer_set > 0) ? millis() + (1000 * timer_set) : 0;
|
||||||
|
#else
|
||||||
rules_timer[index -1] = (XdrvMailbox.payload > 0) ? millis() + (1000 * XdrvMailbox.payload) : 0;
|
rules_timer[index -1] = (XdrvMailbox.payload > 0) ? millis() + (1000 * XdrvMailbox.payload) : 0;
|
||||||
|
#endif //USE_EXPRESSION
|
||||||
}
|
}
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
for (uint8_t i = 0; i < MAX_RULE_TIMERS; i++) {
|
for (uint8_t i = 0; i < MAX_RULE_TIMERS; i++) {
|
||||||
|
@ -636,14 +960,22 @@ bool RulesCommand(void)
|
||||||
}
|
}
|
||||||
else if ((CMND_VAR == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
else if ((CMND_VAR == command_code) && (index > 0) && (index <= MAX_RULE_VARS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
#ifdef USE_EXPRESSION
|
||||||
|
dtostrfd(evaluateExpression(XdrvMailbox.data, XdrvMailbox.data_len), Settings.flag2.calc_resolution, vars[index -1]);
|
||||||
|
#else
|
||||||
strlcpy(vars[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(vars[index -1]));
|
strlcpy(vars[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(vars[index -1]));
|
||||||
|
#endif //USE_EXPRESSION
|
||||||
bitSet(vars_event, index -1);
|
bitSet(vars_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_MEM == command_code) && (index > 0) && (index <= MAX_RULE_MEMS)) {
|
else if ((CMND_MEM == command_code) && (index > 0) && (index <= MAX_RULE_MEMS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
#ifdef USE_EXPRESSION
|
||||||
|
dtostrfd(evaluateExpression(XdrvMailbox.data, XdrvMailbox.data_len), Settings.flag2.calc_resolution, Settings.mems[index -1]);
|
||||||
|
#else
|
||||||
strlcpy(Settings.mems[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.mems[index -1]));
|
strlcpy(Settings.mems[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.mems[index -1]));
|
||||||
|
#endif //USE_EXPRESSION
|
||||||
bitSet(mems_event, index -1);
|
bitSet(mems_event, index -1);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
||||||
|
|
|
@ -752,20 +752,21 @@ void KnxSensor(uint8_t sensor_type, float value)
|
||||||
const char S_CONFIGURE_KNX[] PROGMEM = D_CONFIGURE_KNX;
|
const char S_CONFIGURE_KNX[] PROGMEM = D_CONFIGURE_KNX;
|
||||||
|
|
||||||
const char HTTP_BTN_MENU_KNX[] PROGMEM =
|
const char HTTP_BTN_MENU_KNX[] PROGMEM =
|
||||||
"<br/><form action='kn' method='get'><button>" D_CONFIGURE_KNX "</button></form>";
|
"<p><form action='kn' method='get'><button>" D_CONFIGURE_KNX "</button></form></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_KNX[] PROGMEM =
|
const char HTTP_FORM_KNX[] PROGMEM =
|
||||||
"<fieldset><legend style='text-align:left;'><b> " D_KNX_PARAMETERS " </b></legend><form method='post' action='kn'>"
|
"<fieldset><legend style='text-align:left;'><b> " D_KNX_PARAMETERS " </b>"
|
||||||
|
"</legend><form method='post' action='kn'>"
|
||||||
"<br/><center>"
|
"<br/><center>"
|
||||||
"<b>" D_KNX_PHYSICAL_ADDRESS " </b>"
|
"<b>" D_KNX_PHYSICAL_ADDRESS " </b>"
|
||||||
"<input style='width:12%;' type='number' name='area' min='0' max='15' value='{kna'> . "
|
"<input style='width:12%;' type='number' name='area' min='0' max='15' value='{kna'> . "
|
||||||
"<input style='width:12%;' type='number' name='line' min='0' max='15' value='{knl'> . "
|
"<input style='width:12%;' type='number' name='line' min='0' max='15' value='{knl'> . "
|
||||||
"<input style='width:12%;' type='number' name='member' min='0' max='255' value='{knm'>"
|
"<input style='width:12%;' type='number' name='member' min='0' max='255' value='{knm'>"
|
||||||
"<br/><br/>" D_KNX_PHYSICAL_ADDRESS_NOTE "<br/><br/>"
|
"<br/><br/>" D_KNX_PHYSICAL_ADDRESS_NOTE "<br/><br/>"
|
||||||
"<input style='width:10%;' id='b1' name='b1' type='checkbox'";
|
"<input id='b1' name='b1' type='checkbox'";
|
||||||
|
|
||||||
const char HTTP_FORM_KNX1[] PROGMEM =
|
const char HTTP_FORM_KNX1[] PROGMEM =
|
||||||
"><b>" D_KNX_ENABLE " </b><input style='width:10%;' id='b2' name='b2' type='checkbox'";
|
"><b>" D_KNX_ENABLE "</b> <input id='b2' name='b2' type='checkbox'";
|
||||||
|
|
||||||
const char HTTP_FORM_KNX2[] PROGMEM =
|
const char HTTP_FORM_KNX2[] PROGMEM =
|
||||||
"><b>" D_KNX_ENHANCEMENT "</b><br/></center><br/>"
|
"><b>" D_KNX_ENHANCEMENT "</b><br/></center><br/>"
|
||||||
|
|
|
@ -205,17 +205,17 @@ bool CseCommand(void)
|
||||||
|
|
||||||
if (CMND_POWERSET == energy_command_code) {
|
if (CMND_POWERSET == energy_command_code) {
|
||||||
if (XdrvMailbox.data_len && power_cycle) {
|
if (XdrvMailbox.data_len && power_cycle) {
|
||||||
Settings.energy_power_calibration = ((unsigned long)CharToDouble(XdrvMailbox.data) * power_cycle) / CSE_PREF;
|
Settings.energy_power_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * power_cycle) / CSE_PREF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == energy_command_code) {
|
else if (CMND_VOLTAGESET == energy_command_code) {
|
||||||
if (XdrvMailbox.data_len && voltage_cycle) {
|
if (XdrvMailbox.data_len && voltage_cycle) {
|
||||||
Settings.energy_voltage_calibration = ((unsigned long)CharToDouble(XdrvMailbox.data) * voltage_cycle) / CSE_UREF;
|
Settings.energy_voltage_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * voltage_cycle) / CSE_UREF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == energy_command_code) {
|
else if (CMND_CURRENTSET == energy_command_code) {
|
||||||
if (XdrvMailbox.data_len && current_cycle) {
|
if (XdrvMailbox.data_len && current_cycle) {
|
||||||
Settings.energy_current_calibration = ((unsigned long)CharToDouble(XdrvMailbox.data) * current_cycle) / 1000;
|
Settings.energy_current_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * current_cycle) / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -103,7 +103,7 @@ void CounterShow(bool json)
|
||||||
dtostrfd((double)RtcSettings.pulse_counter[i] / 1000000, 6, counter);
|
dtostrfd((double)RtcSettings.pulse_counter[i] / 1000000, 6, counter);
|
||||||
} else {
|
} else {
|
||||||
dsxflg++;
|
dsxflg++;
|
||||||
dtostrfd(RtcSettings.pulse_counter[i], 0, counter);
|
snprintf_P(counter, sizeof(counter), PSTR("%lu"), RtcSettings.pulse_counter[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
|
|
@ -377,19 +377,19 @@ const char HTTP_BTN_MENU_MAIN_HX711[] PROGMEM =
|
||||||
"<br/><form action='" WEB_HANDLE_HX711 "' method='get'><button name='reset'>" D_RESET_HX711 "</button></form>";
|
"<br/><form action='" WEB_HANDLE_HX711 "' method='get'><button name='reset'>" D_RESET_HX711 "</button></form>";
|
||||||
|
|
||||||
const char HTTP_BTN_MENU_HX711[] PROGMEM =
|
const char HTTP_BTN_MENU_HX711[] PROGMEM =
|
||||||
"<br/><form action='" WEB_HANDLE_HX711 "' method='get'><button>" D_CONFIGURE_HX711 "</button></form>";
|
"<p><form action='" WEB_HANDLE_HX711 "' method='get'><button>" D_CONFIGURE_HX711 "</button></form></p>";
|
||||||
|
|
||||||
const char HTTP_FORM_HX711[] PROGMEM =
|
const char HTTP_FORM_HX711[] PROGMEM =
|
||||||
"<fieldset><legend><b> " D_CALIBRATION " </b></legend>"
|
"<fieldset><legend><b> " D_CALIBRATION " </b></legend>"
|
||||||
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
||||||
"<br/><b>" D_REFERENCE_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' step='0.001' id='p1' name='p1' placeholder='0' value='{1'><br/>"
|
"<p><b>" D_REFERENCE_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' step='0.001' id='p1' name='p1' placeholder='0' value='{1'></p>"
|
||||||
"<br/><button name='calibrate' type='submit'>" D_CALIBRATE "</button><br/>"
|
"<br/><button name='calibrate' type='submit'>" D_CALIBRATE "</button>"
|
||||||
"</form>"
|
"</form>"
|
||||||
"</fieldset><br/><br/>"
|
"</fieldset><br/><br/>"
|
||||||
|
|
||||||
"<fieldset><legend><b> " D_HX711_PARAMETERS " </b></legend>"
|
"<fieldset><legend><b> " D_HX711_PARAMETERS " </b></legend>"
|
||||||
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
||||||
"<br/><b>" D_ITEM_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' max='6.5535' step='0.0001' id='p2' name='p2' placeholder='0.0' value='{2'><br/>";
|
"<p><b>" D_ITEM_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' max='6.5535' step='0.0001' id='p2' name='p2' placeholder='0.0' value='{2'></p>";
|
||||||
|
|
||||||
void HandleHxAction(void)
|
void HandleHxAction(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
VER = '2.1.0020'
|
VER = '2.1.0021'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
decode-config.py - Backup/Restore Sonoff-Tasmota configuration data
|
decode-config.py - Backup/Restore Sonoff-Tasmota configuration data
|
||||||
|
@ -841,9 +841,41 @@ Setting_6_4_1_13.update ({
|
||||||
'mhz19b_abc_disable': ('B', (0x717,1, 7), (None, None, ('Sensor', '"Sensor15 {}".format($)')) ),
|
'mhz19b_abc_disable': ('B', (0x717,1, 7), (None, None, ('Sensor', '"Sensor15 {}".format($)')) ),
|
||||||
}, 0x717, (None, None, ('*', None)), (None, False) ),
|
}, 0x717, (None, None, ('*', None)), (None, False) ),
|
||||||
})
|
})
|
||||||
|
# ======================================================================
|
||||||
|
Setting_6_4_1_16 = copy.deepcopy(Setting_6_4_1_13)
|
||||||
|
Setting_6_4_1_16.update({
|
||||||
|
'user_template_base': ('B', 0x71F, (None, None, ('Management', '"Template {}".format($)')), ('$ + 1','$ - 1') ),
|
||||||
|
'user_template': ({
|
||||||
|
'name': ('15s', 0x720, (None, None, ('Management', '"Template {{\\\"NAME\\\":\\\"{}\\\"}}".format($)' )) ),
|
||||||
|
'gpio00': ('B', 0x72F, (None, None, ('Management', '"Template {{\\\"GPIO\\\":[{},{},{},{},{},{},{},{},{},{},{},{},{}]}}".format(@["user_template"]["gpio00"],@["user_template"]["gpio01"],@["user_template"]["gpio02"],@["user_template"]["gpio03"],@["user_template"]["gpio04"],@["user_template"]["gpio05"],@["user_template"]["gpio09"],@["user_template"]["gpio10"],@["user_template"]["gpio12"],@["user_template"]["gpio13"],@["user_template"]["gpio14"],@["user_template"]["gpio15"],@["user_template"]["gpio16"])')) ),
|
||||||
|
'gpio01': ('B', 0x730, (None, None, ('Management', None)) ),
|
||||||
|
'gpio02': ('B', 0x731, (None, None, ('Management', None)) ),
|
||||||
|
'gpio03': ('B', 0x732, (None, None, ('Management', None)) ),
|
||||||
|
'gpio04': ('B', 0x733, (None, None, ('Management', None)) ),
|
||||||
|
'gpio05': ('B', 0x734, (None, None, ('Management', None)) ),
|
||||||
|
'gpio09': ('B', 0x735, (None, None, ('Management', None)) ),
|
||||||
|
'gpio10': ('B', 0x736, (None, None, ('Management', None)) ),
|
||||||
|
'gpio12': ('B', 0x737, (None, None, ('Management', None)) ),
|
||||||
|
'gpio13': ('B', 0x738, (None, None, ('Management', None)) ),
|
||||||
|
'gpio14': ('B', 0x739, (None, None, ('Management', None)) ),
|
||||||
|
'gpio15': ('B', 0x73A, (None, None, ('Management', None)) ),
|
||||||
|
'gpio16': ('B', 0x73B, (None, None, ('Management', None)) ),
|
||||||
|
'flag': ({
|
||||||
|
'value': ('B', 0x73C , (None, None, ('Management', '"Template {{\\\"FLAG\\\":{}}}".format($)')) ),
|
||||||
|
'adc0': ('B', (0x73C,1,0), (None, None, ('Management', None)) ),
|
||||||
|
'pullup': ('B', (0x73C,1,1), (None, None, ('Management', None)) ),
|
||||||
|
}, 0x73C, (None, None, ('Management', None))
|
||||||
|
),
|
||||||
|
}, 0x720, (None, None, ('Management', None))
|
||||||
|
),
|
||||||
|
})
|
||||||
|
# ======================================================================
|
||||||
|
Setting_6_4_1_17 = copy.deepcopy(Setting_6_4_1_16)
|
||||||
|
Setting_6_4_1_17['flag3'][0].pop('no_pullup',None)
|
||||||
# ======================================================================
|
# ======================================================================
|
||||||
Settings = [
|
Settings = [
|
||||||
|
(0x6040111, 0xe00, Setting_6_4_1_17),
|
||||||
|
(0x6040110, 0xe00, Setting_6_4_1_16),
|
||||||
(0x604010D, 0xe00, Setting_6_4_1_13),
|
(0x604010D, 0xe00, Setting_6_4_1_13),
|
||||||
(0x604010B, 0xe00, Setting_6_4_1_11),
|
(0x604010B, 0xe00, Setting_6_4_1_11),
|
||||||
(0x6040108, 0xe00, Setting_6_4_1_8),
|
(0x6040108, 0xe00, Setting_6_4_1_8),
|
||||||
|
|
Loading…
Reference in New Issue